diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 15251b6577f8..7f057ea2f71f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,6 @@ { "name": "istio build-tools", - "image": "gcr.io/istio-testing/build-tools:master-4759bf88d40172234fc6a0b9e11a4c5f1ea58a90", + "image": "gcr.io/istio-testing/build-tools:master-0b8e6b9676d328fbeb28a23b8d1134dcc56d98ec", "privileged": true, "remoteEnv": { "USE_GKE_GCLOUD_AUTH_PLUGIN": "True", diff --git a/CODEOWNERS b/CODEOWNERS index 9472a5fdcb43..bfe0c6c275b0 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -63,7 +63,6 @@ Makefile* @istio/wg-test- /tools/ @istio/wg-test-and-release-maintainers /tools/packaging/common/envoy_bootstrap.json @istio/wg-networking-maintainers /tools/istio-iptables/ @istio/wg-networking-maintainers -/tools/istio-clean-iptables/ @istio/wg-networking-maintainers architecture/ambient @istio/wg-networking-maintainers-pilot @istio/wg-networking-maintainers-ztunnel architecture/environments @istio/wg-environments-maintainers architecture/networking @istio/wg-networking-maintainers diff --git a/Makefile.core.mk b/Makefile.core.mk index 3d6ce2e342da..ec7c37a566dd 100644 --- a/Makefile.core.mk +++ b/Makefile.core.mk @@ -49,7 +49,7 @@ endif export VERSION # Base version of Istio image to use -BASE_VERSION ?= master-2024-09-19T19-01-03 +BASE_VERSION ?= master-2024-12-17T19-00-43 ISTIO_BASE_REGISTRY ?= gcr.io/istio-release export GO111MODULE ?= on diff --git a/VERSION b/VERSION index 3900bcd9fd59..5e2b95002760 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.24 +1.25 diff --git a/cni/README.md b/cni/README.md index a65109784cf0..b16ead32b535 100644 --- a/cni/README.md +++ b/cni/README.md @@ -68,7 +68,7 @@ The annotation based control is currently only supported in 'sidecar' mode. See - includeInboudPorts, excludeInboundPorts - includeOutboutPorts, excludeOutboundPorts - excludeInterfaces -- kubevirtInterfaces +- kubevirtInterfaces (deprecated), reroute-virtual-interfaces - ISTIO_META_DNS_CAPTURE env variable on the proxy - enables dns redirect - INVALID_DROP env var on proxy - changes behavior from reset to drop in iptables - auto excluded inbound ports: 15020, 15021, 15090 diff --git a/cni/pkg/cmd/root.go b/cni/pkg/cmd/root.go index 71fbb4aa44f0..7650910eb97a 100644 --- a/cni/pkg/cmd/root.go +++ b/cni/pkg/cmd/root.go @@ -90,6 +90,8 @@ var rootCmd = &cobra.Command{ // TODO nodeagent watch server should affect this too, and drop atomic flag installDaemonReady, watchServerReady := nodeagent.StartHealthServer() + installer := install.NewInstaller(&cfg.InstallConfig, installDaemonReady) + if cfg.InstallConfig.AmbientEnabled { // Start ambient controller @@ -99,29 +101,63 @@ var rootCmd = &cobra.Command{ log.Infof("Starting ambient node agent with inpod redirect mode on socket %s", cniEventAddr) ambientAgent, err := nodeagent.NewServer(ctx, watchServerReady, cniEventAddr, nodeagent.AmbientArgs{ - SystemNamespace: nodeagent.SystemNamespace, - Revision: nodeagent.Revision, - ServerSocket: cfg.InstallConfig.ZtunnelUDSAddress, - DNSCapture: cfg.InstallConfig.AmbientDNSCapture, - EnableIPv6: cfg.InstallConfig.AmbientIPv6, - TPROXYRedirection: cfg.InstallConfig.AmbientTPROXYRedirection, + SystemNamespace: nodeagent.SystemNamespace, + Revision: nodeagent.Revision, + ServerSocket: cfg.InstallConfig.ZtunnelUDSAddress, + DNSCapture: cfg.InstallConfig.AmbientDNSCapture, + EnableIPv6: cfg.InstallConfig.AmbientIPv6, + ReconcilePodRulesOnStartup: cfg.InstallConfig.AmbientReconcilePodRulesOnStartup, }) if err != nil { return fmt.Errorf("failed to create ambient nodeagent service: %v", err) } + // Ambient watch server IS enabled - on shutdown + // we need to check and see if this is an upgrade. + // + // if it is, we do NOT remove the plugin, and do + // NOT do ambient watch server cleanup + defer func() { + var isUpgrade bool + if cfg.InstallConfig.AmbientDisableSafeUpgrade { + log.Info("Ambient node agent safe upgrade explicitly disabled via env") + isUpgrade = false + } else { + isUpgrade = ambientAgent.ShouldStopForUpgrade("istio-cni", nodeagent.PodNamespace) + } + log.Infof("Ambient node agent shutting down - is upgrade shutdown? %t", isUpgrade) + // if we are doing an "upgrade shutdown", then + // we do NOT want to remove/cleanup the CNI plugin. + // + // This is important - we want it to remain in place to "stall" + // new ambient-enabled pods while our replacement spins up. + if !isUpgrade { + if cleanErr := installer.Cleanup(); cleanErr != nil { + log.Error(cleanErr.Error()) + } + } + ambientAgent.Stop(isUpgrade) + }() + ambientAgent.Start() - defer ambientAgent.Stop() log.Info("Ambient node agent started, starting installer...") } else { // Ambient not enabled, so this readiness flag is no-op'd watchServerReady.Store(true) - } - - installer := install.NewInstaller(&cfg.InstallConfig, installDaemonReady) + // Ambient watch server not enabled - on shutdown + // we just need to remove CNI plugin. + defer func() { + log.Infof("CNI node agent shutting down") + if cleanErr := installer.Cleanup(); cleanErr != nil { + log.Error(cleanErr.Error()) + } + }() + } + // TODO Note that during an "upgrade shutdown" in ambient mode, + // repair will (necessarily) be unavailable. repair.StartRepair(ctx, cfg.RepairConfig) log.Info("initialization complete, watching node CNI dir") @@ -137,14 +173,6 @@ var rootCmd = &cobra.Command{ } } - if cleanErr := installer.Cleanup(); cleanErr != nil { - if err != nil { - err = fmt.Errorf("%s: %w", cleanErr.Error(), err) - } else { - err = cleanErr - } - } - return }, } @@ -264,10 +292,11 @@ func constructConfig() (*config.Config, error) { ExcludeNamespaces: viper.GetString(constants.ExcludeNamespaces), ZtunnelUDSAddress: viper.GetString(constants.ZtunnelUDSAddress), - AmbientEnabled: viper.GetBool(constants.AmbientEnabled), - AmbientDNSCapture: viper.GetBool(constants.AmbientDNSCapture), - AmbientIPv6: viper.GetBool(constants.AmbientIPv6), - AmbientTPROXYRedirection: viper.GetBool(constants.AmbientTPROXYRedirection), + AmbientEnabled: viper.GetBool(constants.AmbientEnabled), + AmbientDNSCapture: viper.GetBool(constants.AmbientDNSCapture), + AmbientIPv6: viper.GetBool(constants.AmbientIPv6), + AmbientDisableSafeUpgrade: viper.GetBool(constants.AmbientDisableSafeUpgrade), + AmbientReconcilePodRulesOnStartup: viper.GetBool(constants.AmbientReconcilePodRulesOnStartup), } if len(installCfg.K8sNodeName) == 0 { diff --git a/cni/pkg/config/config.go b/cni/pkg/config/config.go index fa79e084e777..f05e7ffffdc6 100644 --- a/cni/pkg/config/config.go +++ b/cni/pkg/config/config.go @@ -80,8 +80,11 @@ type InstallConfig struct { // Whether ipv6 is enabled for ambient capture AmbientIPv6 bool - // Feature flag to determined whether TPROXY is used for redirection. - AmbientTPROXYRedirection bool + // Feature flag to disable safe upgrade. Will be removed in future releases. + AmbientDisableSafeUpgrade bool + + // Whether reconciliation of iptables at post startup is enabled for Ambient workloads + AmbientReconcilePodRulesOnStartup bool } // RepairConfig struct defines the Istio CNI race repair configuration @@ -144,8 +147,9 @@ func (c InstallConfig) String() string { b.WriteString("AmbientEnabled: " + fmt.Sprint(c.AmbientEnabled) + "\n") b.WriteString("AmbientDNSCapture: " + fmt.Sprint(c.AmbientDNSCapture) + "\n") b.WriteString("AmbientIPv6: " + fmt.Sprint(c.AmbientIPv6) + "\n") - b.WriteString("AmbientRedirectTPROXY: " + fmt.Sprint(c.AmbientTPROXYRedirection) + "\n") + b.WriteString("AmbientDisableSafeUpgrade: " + fmt.Sprint(c.AmbientDisableSafeUpgrade) + "\n") + b.WriteString("AmbientReconcilePodRulesOnStartup: " + fmt.Sprint(c.AmbientReconcilePodRulesOnStartup) + "\n") return b.String() } diff --git a/cni/pkg/constants/constants.go b/cni/pkg/constants/constants.go index 82d9ad3be95e..fd30054df328 100644 --- a/cni/pkg/constants/constants.go +++ b/cni/pkg/constants/constants.go @@ -17,25 +17,26 @@ package constants // Command line arguments const ( // Install - MountedCNINetDir = "mounted-cni-net-dir" - CNIConfName = "cni-conf-name" - ChainedCNIPlugin = "chained-cni-plugin" - CNINetworkConfigFile = "cni-network-config-file" - CNINetworkConfig = "cni-network-config" - LogLevel = "log-level" - KubeconfigMode = "kubeconfig-mode" - KubeCAFile = "kube-ca-file" - SkipTLSVerify = "skip-tls-verify" - MonitoringPort = "monitoring-port" - LogUDSSocket = "log-uds-socket" - ZtunnelUDSAddress = "ztunnel-uds-address" - CNIEventSocket = "cni-event-address" - CNIAgentRunDir = "cni-agent-run-dir" - ExcludeNamespaces = "exclude-namespaces" - AmbientEnabled = "ambient-enabled" - AmbientDNSCapture = "ambient-dns-capture" - AmbientIPv6 = "ambient-ipv6" - AmbientTPROXYRedirection = "ambient-tproxy-redirection" + MountedCNINetDir = "mounted-cni-net-dir" + CNIConfName = "cni-conf-name" + ChainedCNIPlugin = "chained-cni-plugin" + CNINetworkConfigFile = "cni-network-config-file" + CNINetworkConfig = "cni-network-config" + LogLevel = "log-level" + KubeconfigMode = "kubeconfig-mode" + KubeCAFile = "kube-ca-file" + SkipTLSVerify = "skip-tls-verify" + MonitoringPort = "monitoring-port" + LogUDSSocket = "log-uds-socket" + ZtunnelUDSAddress = "ztunnel-uds-address" + CNIEventSocket = "cni-event-address" + CNIAgentRunDir = "cni-agent-run-dir" + ExcludeNamespaces = "exclude-namespaces" + AmbientEnabled = "ambient-enabled" + AmbientDNSCapture = "ambient-dns-capture" + AmbientIPv6 = "ambient-ipv6" + AmbientDisableSafeUpgrade = "ambient-disable-safe-upgrade" + AmbientReconcilePodRulesOnStartup = "ambient-reconcile-pod-rules-on-startup" // Repair RepairEnabled = "repair-enabled" diff --git a/cni/pkg/install/binaries.go b/cni/pkg/install/binaries.go index 804f1b162c59..5d78c307143c 100644 --- a/cni/pkg/install/binaries.go +++ b/cni/pkg/install/binaries.go @@ -40,6 +40,19 @@ func copyBinaries(srcDir string, targetDirs []string) (sets.String, error) { srcFilepath := filepath.Join(srcDir, filename) for _, targetDir := range targetDirs { + + // remove previous tmp file if some exist before creating a new one + // the only possible returned error is [ErrBadPattern], when pattern is malformed. Can be ignored in this case + matches, _ := filepath.Glob(filepath.Join(targetDir, filename) + ".tmp.*") + if len(matches) > 0 { + installLog.Infof("Target folder %s contains one or more temporary files with a %s name. The temp files will be deleted.", targetDir, filename) + for _, file := range matches { + if err := os.Remove(file); err != nil { + installLog.Warnf("Failed to delete tmp file %s from previous run: %s", file, err) + } + } + } + if err := file.AtomicCopy(srcFilepath, targetDir, filename); err != nil { installLog.Errorf("failed file copy of %s to %s: %s", srcFilepath, targetDir, err.Error()) return copiedFilenames, err diff --git a/cni/pkg/install/binaries_test.go b/cni/pkg/install/binaries_test.go index 5684cf4b797e..0a37447d1aa3 100644 --- a/cni/pkg/install/binaries_test.go +++ b/cni/pkg/install/binaries_test.go @@ -18,6 +18,7 @@ import ( "path/filepath" "testing" + file2 "istio.io/istio/pkg/file" "istio.io/istio/pkg/test/util/assert" "istio.io/istio/pkg/test/util/file" ) @@ -74,3 +75,22 @@ func TestCopyBinaries(t *testing.T) { }) } } + +func TestCopyBinariesWhenTmpExist(t *testing.T) { + srcDir := t.TempDir() + file.WriteOrFail(t, filepath.Join(srcDir, "testFile1"), []byte("content")) + file.WriteOrFail(t, filepath.Join(srcDir, "testFile2"), []byte("content")) + + targetDir := t.TempDir() + tmpFile1 := filepath.Join(targetDir, "testFile1.tmp.3816169537") + tmpFile2 := filepath.Join(targetDir, "testFile2.tmp.4977877") + file.WriteOrFail(t, tmpFile1, []byte("content")) + file.WriteOrFail(t, tmpFile2, []byte("content")) + + _, err := copyBinaries(srcDir, []string{targetDir}) + assert.NoError(t, err) + + // check that all old temp files were removed + assert.Equal(t, file2.Exists(tmpFile1), false) + assert.Equal(t, file2.Exists(tmpFile2), false) +} diff --git a/cni/pkg/ipset/ipset.go b/cni/pkg/ipset/ipset.go index 064f61b056b0..de41f35d4a79 100644 --- a/cni/pkg/ipset/ipset.go +++ b/cni/pkg/ipset/ipset.go @@ -39,6 +39,7 @@ type NetlinkIpsetDeps interface { deleteIP(name string, ip netip.Addr, ipProto uint8) error flush(name string) error clearEntriesWithComment(name string, comment string) error + clearEntriesWithIPAndComment(name string, ip netip.Addr, comment string) (string, error) clearEntriesWithIP(name string, ip netip.Addr) error listEntriesByIP(name string) ([]netip.Addr, error) } @@ -129,6 +130,15 @@ func (m *IPSet) ClearEntriesWithIP(ip netip.Addr) error { return m.Deps.clearEntriesWithIP(m.V4Name, ipToClear) } +func (m *IPSet) ClearEntriesWithIPAndComment(ip netip.Addr, comment string) (string, error) { + ipToClear := ip.Unmap() + + if ipToClear.Is6() { + return m.Deps.clearEntriesWithIPAndComment(m.V6Name, ipToClear, comment) + } + return m.Deps.clearEntriesWithIPAndComment(m.V4Name, ipToClear, comment) +} + func (m *IPSet) ListEntriesByIP() ([]netip.Addr, error) { var err error var set []netip.Addr diff --git a/cni/pkg/ipset/nldeps_linux.go b/cni/pkg/ipset/nldeps_linux.go index e9a9dc6cf2d6..ae6b9866ff35 100644 --- a/cni/pkg/ipset/nldeps_linux.go +++ b/cni/pkg/ipset/nldeps_linux.go @@ -39,7 +39,12 @@ func (m *realDeps) ipsetIPHashCreate(name string, v6 bool) error { } else { family = unix.AF_INET } - err := netlink.IpsetCreate(name, "hash:ip", netlink.IpsetCreateOptions{Comments: true, Replace: true, Family: family}) + + // Note: `vishvananda/netlink` seems to have a bug where it defaults to revision=1 for `hash:ip,port` but defaults to revision=0 for `hash:ip` + // This causes breakages in some cases with Docker-based nodes: https://github.com/istio/istio/issues/53512 + // Setting `Revision=2` here seems to work correctly in all cases found thus far. + // Source: https://github.com/Olipro/ipset/blob/9f145b49100104d6570fe5c31a5236816ebb4f8f/kernel/net/netfilter/ipset/ip_set_hash_ip.c#L28 + err := netlink.IpsetCreate(name, "hash:ip", netlink.IpsetCreateOptions{Comments: true, Replace: true, Revision: 2, Family: family}) // Note there appears to be a bug in vishvananda/netlink here: // https://github.com/vishvananda/netlink/issues/992 // @@ -116,6 +121,36 @@ func (m *realDeps) clearEntriesWithComment(name, comment string) error { return nil } +// clearEntriesWithIPAndComment takes an IP and a comment string and deletes any ipset entries where +// both match the entry. +// +// Returns a non-nil error if listing or deletion fails. +// For the first matching IP found in the list, *only* removes the entry if *both* the IP and comment match. +// If the IP matches but the comment does not, returns the actual comment found to the caller, and does not +// remove any entries. +// +// Otherwise, returns an empty string. +func (m *realDeps) clearEntriesWithIPAndComment(name string, ip netip.Addr, comment string) (string, error) { + delIP := net.IP(ip.AsSlice()) + res, err := netlink.IpsetList(name) + if err != nil { + return "", fmt.Errorf("failed to list ipset %s: %w", name, err) + } + for _, entry := range res.Entries { + if entry.IP.Equal(delIP) { + if entry.Comment == comment { + err := netlink.IpsetDel(name, &entry) + if err != nil { + return "", fmt.Errorf("failed to delete IP %s from ipset %s: %w", entry.IP, name, err) + } + } else { + return entry.Comment, nil + } + } + } + return "", nil +} + func (m *realDeps) clearEntriesWithIP(name string, ip netip.Addr) error { delIP := net.IP(ip.AsSlice()) res, err := netlink.IpsetList(name) diff --git a/cni/pkg/ipset/nldeps_mock.go b/cni/pkg/ipset/nldeps_mock.go index 5e6ac7f99c9d..8b56c22c04c1 100644 --- a/cni/pkg/ipset/nldeps_mock.go +++ b/cni/pkg/ipset/nldeps_mock.go @@ -63,6 +63,11 @@ func (m *MockedIpsetDeps) clearEntriesWithIP(name string, ip netip.Addr) error { return args.Error(0) } +func (m *MockedIpsetDeps) clearEntriesWithIPAndComment(name string, ip netip.Addr, comment string) (string, error) { + args := m.Called(name, ip, comment) + return args.Get(0).(string), args.Error(1) +} + func (m *MockedIpsetDeps) listEntriesByIP(name string) ([]netip.Addr, error) { args := m.Called(name) return args.Get(0).([]netip.Addr), args.Error(1) diff --git a/cni/pkg/iptables/common_test.go b/cni/pkg/iptables/common_test.go new file mode 100644 index 000000000000..bd69ab512ed0 --- /dev/null +++ b/cni/pkg/iptables/common_test.go @@ -0,0 +1,75 @@ +// Copyright Istio Authors +// +// Licensed 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 iptables + +func GetCommonInPodTestCases() []struct { + name string + config func(cfg *IptablesConfig) + podOverrides PodLevelOverrides +} { + return []struct { + name string + config func(cfg *IptablesConfig) + podOverrides PodLevelOverrides + }{ + { + name: "default", + config: func(cfg *IptablesConfig) { + cfg.RedirectDNS = true + }, + podOverrides: PodLevelOverrides{}, + }, + { + name: "ingress", + config: func(cfg *IptablesConfig) { + }, + podOverrides: PodLevelOverrides{IngressMode: true}, + }, + { + name: "virtual_interfaces", + config: func(cfg *IptablesConfig) { + }, + podOverrides: PodLevelOverrides{ + VirtualInterfaces: []string{"fake1s0f0", "fake1s0f1"}, + }, + }, + { + name: "ingress_and_virtual_interfaces", + config: func(cfg *IptablesConfig) { + }, + podOverrides: PodLevelOverrides{ + IngressMode: true, + VirtualInterfaces: []string{"fake1s0f0", "fake1s0f1"}, + }, + }, + } +} + +func GetCommonHostTestCases() []struct { + name string + config func(cfg *IptablesConfig) +} { + return []struct { + name string + config func(cfg *IptablesConfig) + }{ + { + name: "hostprobe", + config: func(cfg *IptablesConfig) { + cfg.RedirectDNS = true + }, + }, + } +} diff --git a/cni/pkg/iptables/iptables.go b/cni/pkg/iptables/iptables.go index b53910ccf470..29cf222baf4e 100644 --- a/cni/pkg/iptables/iptables.go +++ b/cni/pkg/iptables/iptables.go @@ -25,6 +25,7 @@ import ( istiolog "istio.io/istio/pkg/log" "istio.io/istio/pkg/ptr" "istio.io/istio/tools/istio-iptables/pkg/builder" + iptablescapture "istio.io/istio/tools/istio-iptables/pkg/capture" iptablesconfig "istio.io/istio/tools/istio-iptables/pkg/config" iptablesconstants "istio.io/istio/tools/istio-iptables/pkg/constants" dep "istio.io/istio/tools/istio-iptables/pkg/dependencies" @@ -52,45 +53,62 @@ const ( ProbeIPSet = "istio-inpod-probes" ) -type Config struct { - TraceLogging bool `json:"IPTABLES_TRACE_LOGGING"` - EnableIPv6 bool `json:"ENABLE_INBOUND_IPV6"` - RedirectDNS bool `json:"REDIRECT_DNS"` - // If true, TPROXY will be used for redirection. Else, REDIRECT will be used. - // Currently, this is treated as a feature flag, but may be promoted to a permanent feature if there is a need. - TPROXYRedirection bool `json:"TPROXY_REDIRECTION"` +// "global"/per-instance IptablesConfig +type IptablesConfig struct { + TraceLogging bool `json:"IPTABLES_TRACE_LOGGING"` + EnableIPv6 bool `json:"ENABLE_INBOUND_IPV6"` + RedirectDNS bool `json:"REDIRECT_DNS"` + HostProbeSNATAddress netip.Addr `json:"HOST_PROBE_SNAT_ADDRESS"` + HostProbeV6SNATAddress netip.Addr `json:"HOST_PROBE_V6_SNAT_ADDRESS"` + Reconcile bool `json:"RECONCILE"` + CleanupOnly bool `json:"CLEANUP_ONLY"` + ForceApply bool `json:"FORCE_APPLY"` +} + +// For inpod rules, any runtime/dynamic pod-level +// config overrides that may need to be taken into account +// when injecting pod rules +type PodLevelOverrides struct { + VirtualInterfaces []string + IngressMode bool } type IptablesConfigurator struct { ext dep.Dependencies nlDeps NetlinkDependencies - cfg *Config + cfg *IptablesConfig iptV dep.IptablesVersion ipt6V dep.IptablesVersion } -func ipbuildConfig(c *Config) *iptablesconfig.Config { +func ipbuildConfig(c *IptablesConfig) *iptablesconfig.Config { return &iptablesconfig.Config{ TraceLogging: c.TraceLogging, EnableIPv6: c.EnableIPv6, RedirectDNS: c.RedirectDNS, + Reconcile: c.Reconcile, + ForceApply: c.ForceApply, } } func NewIptablesConfigurator( - cfg *Config, + hostCfg *IptablesConfig, + podCfg *IptablesConfig, hostDeps dep.Dependencies, podDeps dep.Dependencies, nlDeps NetlinkDependencies, ) (*IptablesConfigurator, *IptablesConfigurator, error) { - if cfg == nil { - cfg = &Config{} + if hostCfg == nil { + hostCfg = &IptablesConfig{} + } + if podCfg == nil { + podCfg = &IptablesConfig{} } configurator := &IptablesConfigurator{ ext: hostDeps, nlDeps: nlDeps, - cfg: cfg, + cfg: hostCfg, } // By detecting iptables versions *here* once-for-all we are @@ -128,31 +146,29 @@ func NewIptablesConfigurator( // Setup another configurator with inpod configuration. Basically this will just change how locking is done. inPodConfigurator := ptr.Of(*configurator) inPodConfigurator.ext = podDeps + inPodConfigurator.cfg = podCfg return configurator, inPodConfigurator, nil } -func (cfg *IptablesConfigurator) DeleteInpodRules() error { +func (cfg *IptablesConfigurator) DeleteInpodRules(log *istiolog.Scope) error { var inpodErrs []error - log.Debug("Deleting iptables rules") - - inpodErrs = append(inpodErrs, cfg.executeDeleteCommands(), cfg.delInpodMarkIPRule(), cfg.delLoopbackRoute()) + log.Debug("deleting iptables rules") + cfg.executeDeleteCommands(log) + inpodErrs = append(inpodErrs, cfg.delInpodMarkIPRule(), cfg.delLoopbackRoute()) return errors.Join(inpodErrs...) } -func (cfg *IptablesConfigurator) executeDeleteCommands() error { +func (cfg *IptablesConfigurator) executeDeleteCommands(log *istiolog.Scope) { deleteCmds := [][]string{ {"-t", iptablesconstants.MANGLE, "-D", iptablesconstants.PREROUTING, "-j", ChainInpodPrerouting}, {"-t", iptablesconstants.MANGLE, "-D", iptablesconstants.OUTPUT, "-j", ChainInpodOutput}, - {"-t", iptablesconstants.NAT, "-D", iptablesconstants.PREROUTING, "-j", ChainInpodPrerouting}, {"-t", iptablesconstants.NAT, "-D", iptablesconstants.OUTPUT, "-j", ChainInpodOutput}, {"-t", iptablesconstants.RAW, "-D", iptablesconstants.PREROUTING, "-j", ChainInpodPrerouting}, {"-t", iptablesconstants.RAW, "-D", iptablesconstants.OUTPUT, "-j", ChainInpodOutput}, - } - - // these sometimes fail due to "Device or resource busy" - optionalDeleteCmds := [][]string{ + {"-t", iptablesconstants.NAT, "-D", iptablesconstants.PREROUTING, "-j", ChainInpodPrerouting}, // flush-then-delete our created chains + // these sometimes fail due to "Device or resource busy" or because they are optional given the iptables cfg {"-t", iptablesconstants.MANGLE, "-F", ChainInpodPrerouting}, {"-t", iptablesconstants.MANGLE, "-F", ChainInpodOutput}, {"-t", iptablesconstants.NAT, "-F", ChainInpodPrerouting}, @@ -167,8 +183,6 @@ func (cfg *IptablesConfigurator) executeDeleteCommands() error { {"-t", iptablesconstants.RAW, "-X", ChainInpodOutput}, } - var delErrs []error - iptablesVariant := []dep.IptablesVersion{} iptablesVariant = append(iptablesVariant, cfg.iptV) @@ -178,24 +192,16 @@ func (cfg *IptablesConfigurator) executeDeleteCommands() error { for _, iptVer := range iptablesVariant { for _, cmd := range deleteCmds { - delErrs = append(delErrs, cfg.ext.Run(iptablesconstants.IPTables, &iptVer, nil, cmd...)) - } - - for _, cmd := range optionalDeleteCmds { - err := cfg.ext.Run(iptablesconstants.IPTables, &iptVer, nil, cmd...) - if err != nil { - log.Debugf("ignoring error deleting optional iptables rule: %v", err) - } + cfg.ext.RunQuietlyAndIgnore(log, iptablesconstants.IPTables, &iptVer, nil, cmd...) } } - return errors.Join(delErrs...) } // Setup iptables rules for in-pod mode. Ideally this should be an idempotent function. // NOTE that this expects to be run from within the pod network namespace! -func (cfg *IptablesConfigurator) CreateInpodRules(log *istiolog.Scope, hostProbeSNAT, hostProbeV6SNAT netip.Addr, ingressMode bool) error { +func (cfg *IptablesConfigurator) CreateInpodRules(log *istiolog.Scope, podOverrides PodLevelOverrides) error { // Append our rules here - builder := cfg.appendInpodRules(hostProbeSNAT, hostProbeV6SNAT, ingressMode) + builder := cfg.AppendInpodRules(podOverrides) if err := cfg.addLoopbackRoute(); err != nil { return err @@ -214,13 +220,8 @@ func (cfg *IptablesConfigurator) CreateInpodRules(log *istiolog.Scope, hostProbe return nil } -func (cfg *IptablesConfigurator) appendInpodRules(hostProbeSNAT, hostProbeV6SNAT netip.Addr, ingressMode bool) *builder.IptablesRuleBuilder { +func (cfg *IptablesConfigurator) AppendInpodRules(podOverrides PodLevelOverrides) *builder.IptablesRuleBuilder { redirectDNS := cfg.cfg.RedirectDNS - if ingressMode && cfg.cfg.TPROXYRedirection { - ingressMode = false - // We could support this, but TPROXYRedirection is deprecated and will be removed soon, so we can just test less. - log.Warnf("ignoring ingressMode due to TPROXYRedirection being enabled. These are mutually exclusive") - } inpodMark := fmt.Sprintf("0x%x", InpodMark) + "/" + fmt.Sprintf("0x%x", InpodMask) inpodTproxyMark := fmt.Sprintf("0x%x", InpodTProxyMark) + "/" + fmt.Sprintf("0x%x", InpodTProxyMask) @@ -260,19 +261,48 @@ func (cfg *IptablesConfigurator) appendInpodRules(hostProbeSNAT, hostProbeV6SNAT ) } - natOrMangleBasedOnTproxy := iptablesconstants.MANGLE - if !cfg.cfg.TPROXYRedirection { - natOrMangleBasedOnTproxy = iptablesconstants.NAT - // -t nat -A PREROUTING -p tcp -j ISTIO_PRERT - iptablesBuilder.AppendRule( - iptableslog.UndefinedCommand, iptablesconstants.PREROUTING, iptablesconstants.NAT, - "-j", ChainInpodPrerouting, - ) - } + // -t nat -A PREROUTING -p tcp -j ISTIO_PRERT + iptablesBuilder.AppendRule( + iptableslog.UndefinedCommand, iptablesconstants.PREROUTING, iptablesconstants.NAT, + "-j", ChainInpodPrerouting, + ) // From here on, we should be only inserting rules into our custom chains. - if !ingressMode { + // To keep things manageable, the first rules in the ISTIO_PRERT chain should be short-circuits, like + // virtual interface exclusions/redirects: + if len(podOverrides.VirtualInterfaces) != 0 { + for _, virtInterface := range podOverrides.VirtualInterfaces { + // CLI: -t NAT -A ISTIO_PRERT -i virt0 -p tcp -j REDIRECT --to-ports 15001 + // + // DESC: For any configured virtual interfaces, treat inbound as outbound traffic (useful for kubeVirt, VMs, DinD, etc) + // and just shunt it directly to the outbound port of the proxy. + // Note that for now this explicitly excludes UDP traffic, as we can't proxy arbitrary UDP stuff, + // and this is a difference from the old sidecar `traffic.sidecar.istio.io/kubevirtInterfaces` annotation. + iptablesBuilder.AppendRule( + iptableslog.UndefinedCommand, ChainInpodPrerouting, iptablesconstants.NAT, + "-i", fmt.Sprint(virtInterface), + "-p", "tcp", + "-j", "REDIRECT", + "--to-ports", fmt.Sprint(ZtunnelOutboundPort), + ) + // CLI: -t NAT -A ISTIO_PRERT -i virt0 -p tcp -j RETURN + // + // DESC: Now that the virtual interface packet has been redirected, just stop processing and jump out of the istio PRERT chain. + // Another difference from the sidecar kubevirt rules is that this one RETURNs from the istio chain, + // and not the top-level PREROUTING table like the kubevirt rule does. + // Returning from the top-level PREROUTING table would skip other people's PRERT rules unconditionally, + // which is unsafe (and should not be needed anyway) - if we really find ourselves needing to do that, we should ACCEPT inside our chain instead. + iptablesBuilder.AppendRule( + iptableslog.UndefinedCommand, ChainInpodPrerouting, iptablesconstants.NAT, + "-i", fmt.Sprint(virtInterface), + "-p", "tcp", + "-j", "RETURN", + ) + } + } + + if !podOverrides.IngressMode { // CLI: -A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff // // DESC: If we have a packet mark, set a connmark. @@ -291,8 +321,8 @@ func (cfg *IptablesConfigurator) appendInpodRules(hostProbeSNAT, hostProbeV6SNAT // CLI: -t mangle -A ISTIO_PRERT -s fd16:9254:7127:1337:ffff:ffff:ffff:ffff -p tcp -m tcp --dport -j ACCEPT // // DESC: If this is one of our node-probe ports and is from our SNAT-ed/"special" hostside IP, short-circuit out here - iptablesBuilder.AppendVersionedRule(hostProbeSNAT.String(), hostProbeV6SNAT.String(), - iptableslog.UndefinedCommand, ChainInpodPrerouting, natOrMangleBasedOnTproxy, + iptablesBuilder.AppendVersionedRule(cfg.cfg.HostProbeSNATAddress.String(), cfg.cfg.HostProbeV6SNATAddress.String(), + iptableslog.UndefinedCommand, ChainInpodPrerouting, iptablesconstants.NAT, "-s", iptablesconstants.IPVersionSpecific, "-p", "tcp", "-m", "tcp", @@ -305,7 +335,7 @@ func (cfg *IptablesConfigurator) appendInpodRules(hostProbeSNAT, hostProbeV6SNAT // // DESC: Anything coming BACK from the pod healthcheck port with a dest of our SNAT-ed hostside IP // we also short-circuit. - iptablesBuilder.AppendVersionedRule(hostProbeSNAT.String(), hostProbeV6SNAT.String(), + iptablesBuilder.AppendVersionedRule(cfg.cfg.HostProbeSNATAddress.String(), cfg.cfg.HostProbeV6SNATAddress.String(), iptableslog.UndefinedCommand, ChainInpodOutput, iptablesconstants.NAT, "-d", iptablesconstants.IPVersionSpecific, "-p", "tcp", @@ -313,53 +343,7 @@ func (cfg *IptablesConfigurator) appendInpodRules(hostProbeSNAT, hostProbeV6SNAT "-j", "ACCEPT", ) - if cfg.cfg.TPROXYRedirection { - // prevent intercept traffic from app ==> app by pod ip - iptablesBuilder.AppendVersionedRule("127.0.0.1/32", "::1/128", - iptableslog.UndefinedCommand, ChainInpodPrerouting, iptablesconstants.MANGLE, - "!", "-d", iptablesconstants.IPVersionSpecific, // ignore traffic to localhost ip, as this rule means to catch traffic to pod ip. - "-p", iptablesconstants.TCP, - "-i", "lo", - "-j", "ACCEPT") - // CLI: -A ISTIO_PRERT -p tcp -m tcp --dport -m mark ! --mark 0x539/0xfff -j TPROXY --on-port --on-ip 127.0.0.1 --tproxy-mark 0x111/0xfff - // - // DESC: Anything heading to that does not have the mark, TPROXY to ztunnel inbound port - iptablesBuilder.AppendRule( - iptableslog.UndefinedCommand, ChainInpodPrerouting, iptablesconstants.MANGLE, - "-p", "tcp", - "-m", "tcp", - "--dport", fmt.Sprintf("%d", ZtunnelInboundPort), - "-m", "mark", "!", - "--mark", inpodMark, - "-j", "TPROXY", - "--on-port", fmt.Sprintf("%d", ZtunnelInboundPort), - // "--on-ip", "127.0.0.1", - "--tproxy-mark", inpodTproxyMark, - ) - // CLI: -A ISTIO_PRERT -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT - // - // DESC: Anything that's already in conntrack as an established connection, accept - iptablesBuilder.AppendRule( - iptableslog.UndefinedCommand, ChainInpodPrerouting, iptablesconstants.MANGLE, - "-p", "tcp", - "-m", "conntrack", - "--ctstate", "RELATED,ESTABLISHED", - "-j", "ACCEPT", - ) - // CLI: -A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j TPROXY --on-port --on-ip 127.0.0.1 --tproxy-mark 0x111/0xfff - // - // DESC: Anything that is not bound for localhost and does not have the mark, TPROXY to ztunnel inbound plaintext port - iptablesBuilder.AppendVersionedRule("127.0.0.1/32", "::1/128", - iptableslog.UndefinedCommand, ChainInpodPrerouting, iptablesconstants.MANGLE, - "!", "-d", iptablesconstants.IPVersionSpecific, - "-p", "tcp", - "-m", "mark", "!", - "--mark", inpodMark, - "-j", "TPROXY", - "--on-port", fmt.Sprintf("%d", ZtunnelInboundPlaintextPort), - "--tproxy-mark", inpodTproxyMark, - ) - } else if !ingressMode { + if !podOverrides.IngressMode { // CLI: -A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp ! --dport 15008 -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports // // DESC: Anything that is not bound for localhost and does not have the mark, REDIRECT to ztunnel inbound plaintext port @@ -479,16 +463,79 @@ func (cfg *IptablesConfigurator) appendInpodRules(hostProbeSNAT, hostProbeV6SNAT func (cfg *IptablesConfigurator) executeCommands(log *istiolog.Scope, iptablesBuilder *builder.IptablesRuleBuilder) error { var execErrs []error + guardrails := false + defer func() { + if guardrails { + log.Info("Removing guardrails") + guardrailsCleanup := iptablesBuilder.BuildCleanupGuardrails() + _ = cfg.executeIptablesCommands(log, &cfg.iptV, guardrailsCleanup) + _ = cfg.executeIptablesCommands(log, &cfg.ipt6V, guardrailsCleanup) + } + }() + residueExists, deltaExists := iptablescapture.VerifyIptablesState(log, cfg.ext, iptablesBuilder, &cfg.iptV, &cfg.ipt6V) + if residueExists && deltaExists && !cfg.cfg.Reconcile { + log.Warn("reconcile is needed but no-reconcile flag is set. Unexpected behavior may occur due to preexisting iptables rules") + } + // Cleanup Step + if (residueExists && deltaExists && cfg.cfg.Reconcile) || cfg.cfg.CleanupOnly { + // Apply safety guardrails + if !cfg.cfg.CleanupOnly { + log.Info("Setting up guardrails") + guardrailsCleanup := iptablesBuilder.BuildCleanupGuardrails() + guardrailsRules := iptablesBuilder.BuildGuardrails() + for _, ver := range []*dep.IptablesVersion{&cfg.iptV, &cfg.ipt6V} { + cfg.tryExecuteIptablesCommands(log, ver, guardrailsCleanup) + if err := cfg.executeIptablesCommands(log, ver, guardrailsRules); err != nil { + return err + } + guardrails = true + } + } + // Remove old iptables + log.Info("Performing cleanup of existing iptables") + cfg.tryExecuteIptablesCommands(log, &cfg.iptV, iptablesBuilder.BuildCleanupV4()) + cfg.tryExecuteIptablesCommands(log, &cfg.ipt6V, iptablesBuilder.BuildCleanupV6()) + + // Remove leftovers from non-matching istio iptables cfg + if cfg.cfg.Reconcile { + log.Info("Performing cleanup of any unexpected leftovers from previous iptables executions") + cfg.cleanupIstioLeftovers(log, cfg.ext, iptablesBuilder, &cfg.iptV, &cfg.ipt6V) + } + } - // Execute iptables-restore - execErrs = append(execErrs, cfg.executeIptablesRestoreCommand(log, iptablesBuilder.BuildV4Restore(), &cfg.iptV)) - // Execute ip6tables-restore - if cfg.cfg.EnableIPv6 { - execErrs = append(execErrs, cfg.executeIptablesRestoreCommand(log, iptablesBuilder.BuildV6Restore(), &cfg.ipt6V)) + // Apply Step + if (deltaExists || cfg.cfg.ForceApply) && !cfg.cfg.CleanupOnly { + log.Info("Applying iptables chains and rules") + // Execute iptables-restore + execErrs = append(execErrs, cfg.executeIptablesRestoreCommand(log, iptablesBuilder.BuildV4Restore(), &cfg.iptV)) + // Execute ip6tables-restore + if cfg.cfg.EnableIPv6 { + execErrs = append(execErrs, cfg.executeIptablesRestoreCommand(log, iptablesBuilder.BuildV6Restore(), &cfg.ipt6V)) + } } return errors.Join(execErrs...) } +func (cfg *IptablesConfigurator) cleanupIstioLeftovers(log *istiolog.Scope, ext dep.Dependencies, ruleBuilder *builder.IptablesRuleBuilder, + iptV *dep.IptablesVersion, ipt6V *dep.IptablesVersion, +) { + for _, ipVer := range []*dep.IptablesVersion{iptV, ipt6V} { + if ipVer == nil { + continue + } + output, err := ext.RunWithOutput(log, iptablesconstants.IPTablesSave, ipVer, nil) + if err == nil { + currentState := ruleBuilder.GetStateFromSave(output.String()) + leftovers := iptablescapture.HasIstioLeftovers(currentState) + if len(leftovers) > 0 { + log.Infof("Detected Istio iptables artifacts from a previous execution; initiating a second cleanup pass.") + log.Debugf("Istio iptables artifacts identified for cleanup: %+v", leftovers) + cfg.tryExecuteIptablesCommands(log, ipVer, builder.BuildCleanupFromState(leftovers)) + } + } + } +} + func (cfg *IptablesConfigurator) executeIptablesRestoreCommand( log *istiolog.Scope, data string, @@ -497,7 +544,22 @@ func (cfg *IptablesConfigurator) executeIptablesRestoreCommand( cmd := iptablesconstants.IPTablesRestore log.Infof("Running %s with the following input:\n%v", iptVer.CmdToString(cmd), strings.TrimSpace(data)) // --noflush to prevent flushing/deleting previous contents from table - return cfg.ext.Run(cmd, iptVer, strings.NewReader(data), "--noflush", "-v") + return cfg.ext.Run(log, cmd, iptVer, strings.NewReader(data), "--noflush", "-v") +} + +func (cfg *IptablesConfigurator) executeIptablesCommands(log *istiolog.Scope, iptVer *dep.IptablesVersion, args [][]string) error { + var iptErrs []error + // TODO: pass log all the way through + for _, argSet := range args { + iptErrs = append(iptErrs, cfg.ext.Run(log, iptablesconstants.IPTables, iptVer, nil, argSet...)) + } + return errors.Join(iptErrs...) +} + +func (cfg *IptablesConfigurator) tryExecuteIptablesCommands(log *istiolog.Scope, iptVer *dep.IptablesVersion, commands [][]string) { + for _, cmd := range commands { + cfg.ext.RunQuietlyAndIgnore(log, iptablesconstants.IPTables, iptVer, nil, cmd...) + } } func (cfg *IptablesConfigurator) addLoopbackRoute() error { @@ -523,9 +585,9 @@ func (cfg *IptablesConfigurator) delInpodMarkIPRule() error { // via the nodeIP // - kubelet (node-local healthchecks, which we do not capture) // - kube-proxy (fowarded/proxied traffic from LoadBalancer-backed services, potentially with public IPs, which we must capture) -func (cfg *IptablesConfigurator) CreateHostRulesForHealthChecks(hostSNATIP, hostSNATIPV6 *netip.Addr) error { +func (cfg *IptablesConfigurator) CreateHostRulesForHealthChecks() error { // Append our rules here - builder := cfg.appendHostRules(hostSNATIP, hostSNATIPV6) + builder := cfg.AppendHostRules() log.Info("Adding host netnamespace iptables rules") @@ -538,36 +600,22 @@ func (cfg *IptablesConfigurator) CreateHostRulesForHealthChecks(hostSNATIP, host func (cfg *IptablesConfigurator) DeleteHostRules() { log.Debug("Attempting to delete hostside iptables rules (if they exist)") - - cfg.executeHostDeleteCommands() -} - -func (cfg *IptablesConfigurator) executeHostDeleteCommands() { - optionalDeleteCmds := [][]string{ - // delete our main jump in the host ruleset. If it's not there, NBD. - {"-t", iptablesconstants.NAT, "-D", iptablesconstants.POSTROUTING, "-j", ChainHostPostrouting}, - // flush-then-delete our created chains - // these sometimes fail due to "Device or resource busy" - again NBD. - {"-t", iptablesconstants.NAT, "-F", ChainHostPostrouting}, - {"-t", iptablesconstants.NAT, "-X", ChainHostPostrouting}, + builder := cfg.AppendHostRules() + runCommands := func(cmds [][]string, version *dep.IptablesVersion) { + for _, cmd := range cmds { + // Ignore errors, as it is expected to fail in cases where the node is already cleaned up. + cfg.ext.RunQuietlyAndIgnore(log.WithLabels("component", "host"), iptablesconstants.IPTables, version, nil, cmd...) + } } - // iptablei seems like a reasonable pluralization of iptables - iptablesVariant := []dep.IptablesVersion{} - iptablesVariant = append(iptablesVariant, cfg.iptV) + runCommands(builder.BuildCleanupV4(), &cfg.iptV) if cfg.cfg.EnableIPv6 { - iptablesVariant = append(iptablesVariant, cfg.ipt6V) - } - for _, iptVer := range iptablesVariant { - for _, cmd := range optionalDeleteCmds { - // Ignore errors, as it is expected to fail in cases where the node is already cleaned up. - cfg.ext.RunQuietlyAndIgnore(iptablesconstants.IPTables, &iptVer, nil, cmd...) - } + runCommands(builder.BuildCleanupV6(), &cfg.ipt6V) } } -func (cfg *IptablesConfigurator) appendHostRules(hostSNATIP, hostSNATIPV6 *netip.Addr) *builder.IptablesRuleBuilder { +func (cfg *IptablesConfigurator) AppendHostRules() *builder.IptablesRuleBuilder { log.Info("configuring host-level iptables rules (healthchecks, etc)") iptablesBuilder := builder.NewIptablesRuleBuilder(ipbuildConfig(cfg.cfg)) @@ -604,7 +652,7 @@ func (cfg *IptablesConfigurator) appendHostRules(hostSNATIP, hostSNATIPV6 *netip "--match-set", fmt.Sprintf(ipset.V4Name, ProbeIPSet), "dst", "-j", "SNAT", - "--to-source", hostSNATIP.String(), + "--to-source", cfg.cfg.HostProbeSNATAddress.String(), ) // For V6 we have to use a different set and a different SNAT IP @@ -618,7 +666,7 @@ func (cfg *IptablesConfigurator) appendHostRules(hostSNATIP, hostSNATIPV6 *netip "--match-set", fmt.Sprintf(ipset.V6Name, ProbeIPSet), "dst", "-j", "SNAT", - "--to-source", hostSNATIPV6.String(), + "--to-source", cfg.cfg.HostProbeV6SNATAddress.String(), ) } diff --git a/cni/pkg/iptables/iptables_e2e_test.go b/cni/pkg/iptables/iptables_e2e_test.go index 72856e5cac2d..e00608de6c3b 100644 --- a/cni/pkg/iptables/iptables_e2e_test.go +++ b/cni/pkg/iptables/iptables_e2e_test.go @@ -15,11 +15,10 @@ package iptables import ( - "net/netip" + "bytes" "os" "os/exec" "path/filepath" - "strings" "sync" "testing" @@ -29,50 +28,258 @@ import ( _ "github.com/howardjohn/unshare-go/netns" "github.com/howardjohn/unshare-go/userns" + "istio.io/istio/cni/pkg/ipset" "istio.io/istio/cni/pkg/scopes" "istio.io/istio/pkg/test/util/assert" + iptablescapture "istio.io/istio/tools/istio-iptables/pkg/capture" dep "istio.io/istio/tools/istio-iptables/pkg/dependencies" ) -func TestIptablesCleanRoundTrip(t *testing.T) { +func createHostsideProbeIpset(isV6 bool) (ipset.IPSet, error) { + linDeps := ipset.RealNlDeps() + probeSet, err := ipset.NewIPSet(ProbeIPSet, isV6, linDeps) + if err != nil { + return probeSet, err + } + probeSet.Flush() + return probeSet, nil +} + +func TestIdempotentEquivalentInPodRerun(t *testing.T) { setup(t) - tt := struct { - name string - config func(cfg *Config) - }{ - "default", - func(cfg *Config) { - cfg.RedirectDNS = true - }, + + tests := GetCommonInPodTestCases() + + ext := &dep.RealDependencies{ + UsePodScopedXtablesLock: false, + NetworkNamespace: "", + } + iptVer, err := ext.DetectIptablesVersion(false) + if err != nil { + t.Fatalf("Can't detect iptables version: %v", err) + } + ipt6Ver, err := ext.DetectIptablesVersion(true) + if err != nil { + t.Fatalf("Can't detect ip6tables version") } - probeSNATipv4 := netip.MustParseAddr("169.254.7.127") - probeSNATipv6 := netip.MustParseAddr("e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164") + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := constructTestConfig() + tt.config(cfg) - cfg := &Config{} - tt.config(cfg) + deps := &dep.RealDependencies{} + iptConfigurator, _, err := NewIptablesConfigurator(cfg, cfg, deps, deps, EmptyNlDeps()) + builder := iptConfigurator.AppendInpodRules(tt.podOverrides) + if err != nil { + t.Fatalf("failed to setup iptables configurator: %v", err) + } + defer func() { + assert.NoError(t, iptConfigurator.DeleteInpodRules(log)) + residueExists, deltaExists := iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, false) + assert.Equal(t, deltaExists, true) + }() + assert.NoError(t, iptConfigurator.CreateInpodRules(scopes.CNIAgent, tt.podOverrides)) + residueExists, deltaExists := iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, true) + assert.Equal(t, deltaExists, false) - deps := &dep.RealDependencies{} - iptConfigurator, _, _ := NewIptablesConfigurator(cfg, deps, deps, EmptyNlDeps()) - assert.NoError(t, iptConfigurator.CreateInpodRules(scopes.CNIAgent, probeSNATipv4, probeSNATipv6, false)) + t.Log("Starting cleanup") + // Cleanup, should work + assert.NoError(t, iptConfigurator.DeleteInpodRules(log)) + residueExists, deltaExists = iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, false) + assert.Equal(t, deltaExists, true) - t.Log("starting cleanup") - // Cleanup, should work - assert.NoError(t, iptConfigurator.DeleteInpodRules()) - validateIptablesClean(t) + t.Log("Second run") + // Apply should work again + assert.NoError(t, iptConfigurator.CreateInpodRules(scopes.CNIAgent, tt.podOverrides)) + residueExists, deltaExists = iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, true) + assert.Equal(t, deltaExists, false) - t.Log("second run") - // Add again, should still work - assert.NoError(t, iptConfigurator.CreateInpodRules(scopes.CNIAgent, probeSNATipv4, probeSNATipv6, false)) + t.Log("Third run") + assert.NoError(t, iptConfigurator.CreateInpodRules(scopes.CNIAgent, tt.podOverrides)) + }) + } } -func validateIptablesClean(t *testing.T) { - cur := iptablesSave(t) - if strings.Contains(cur, "ISTIO") { - t.Fatalf("Istio rules leftover: %v", cur) +func TestIdempotentUnequalInPodRerun(t *testing.T) { + setup(t) + + tests := GetCommonInPodTestCases() + + ext := &dep.RealDependencies{ + UsePodScopedXtablesLock: false, + NetworkNamespace: "", } - if strings.Contains(cur, "-A") { - t.Fatalf("Rules: %v", cur) + iptVer, err := ext.DetectIptablesVersion(false) + if err != nil { + t.Fatalf("Can't detect iptables version: %v", err) + } + ipt6Ver, err := ext.DetectIptablesVersion(true) + if err != nil { + t.Fatalf("Can't detect ip6tables version") + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := constructTestConfig() + tt.config(cfg) + var stdout, stderr bytes.Buffer + deps := &dep.RealDependencies{} + iptConfigurator, _, err := NewIptablesConfigurator(cfg, cfg, deps, deps, EmptyNlDeps()) + builder := iptConfigurator.AppendInpodRules(tt.podOverrides) + if err != nil { + t.Fatalf("failed to setup iptables configurator: %v", err) + } + + defer func() { + assert.NoError(t, iptConfigurator.DeleteInpodRules(log)) + residueExists, deltaExists := iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, true) + assert.Equal(t, deltaExists, true) + // Remove additional rule + cmd := exec.Command("iptables", "-t", "nat", "-D", "OUTPUT", "-p", "tcp", "--dport", "123", "-j", "ACCEPT") + cmd.Stdout = &stdout + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + t.Errorf("iptables cmd (%s %s) failed: %s", cmd.Path, cmd.Args, stderr.String()) + } + residueExists, deltaExists = iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, false) + assert.Equal(t, deltaExists, true) + }() + + assert.NoError(t, iptConfigurator.CreateInpodRules(scopes.CNIAgent, tt.podOverrides)) + residueExists, deltaExists := iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, true) + assert.Equal(t, deltaExists, false) + + // Diverge by creating new ISTIO chains + cmd := exec.Command("iptables", "-t", "nat", "-N", "ISTIO_TEST") + cmd.Stdout = &stdout + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + t.Errorf("iptables cmd (%s %s) failed: %s", cmd.Path, cmd.Args, stderr.String()) + } + + cmd = exec.Command("iptables", "-t", "nat", "-A", "OUTPUT", "-j", "ISTIO_TEST") + cmd.Stdout = &stdout + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + t.Errorf("iptables cmd (%s %s) failed: %s", cmd.Path, cmd.Args, stderr.String()) + } + + cmd = exec.Command("iptables", "-t", "nat", "-A", "ISTIO_TEST", "-p", "tcp", "--dport", "123", "-j", "ACCEPT") + cmd.Stdout = &stdout + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + t.Errorf("iptables cmd (%s %s) failed: %s", cmd.Path, cmd.Args, stderr.String()) + } + + // Apply required after tempering with ISTIO chains + residueExists, deltaExists = iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, true) + assert.Equal(t, deltaExists, true) + + // Creating new inpod rules should fail if reconciliation is disabled + cfg.Reconcile = false + assert.Error(t, iptConfigurator.CreateInpodRules(scopes.CNIAgent, tt.podOverrides)) + + // Creating new inpod rules should succeed if reconciliation is enabled + cfg.Reconcile = true + assert.NoError(t, iptConfigurator.CreateInpodRules(scopes.CNIAgent, tt.podOverrides)) + residueExists, deltaExists = iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, true) + assert.Equal(t, deltaExists, false) + + // Jump added by tempering shall no longer exist + cmd = exec.Command("iptables", "-t", "nat", "-C", "OUTPUT", "-j", "ISTIO_TEST") + assert.Error(t, cmd.Run()) + + // Diverge from installation + cmd = exec.Command("iptables", "-t", "nat", "-A", "OUTPUT", "-p", "tcp", "--dport", "123", "-j", "ACCEPT") + cmd.Stdout = &stdout + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + t.Errorf("iptables cmd (%s %s) failed: %s", cmd.Path, cmd.Args, stderr.String()) + } + + // No delta after tempering with non-ISTIO chains + residueExists, deltaExists = iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, true) + assert.Equal(t, deltaExists, false) + }) + } +} + +func TestIptablesHostCleanRoundTrip(t *testing.T) { + setup(t) + + tests := GetCommonHostTestCases() + + ext := &dep.RealDependencies{ + UsePodScopedXtablesLock: false, + NetworkNamespace: "", + } + iptVer, err := ext.DetectIptablesVersion(false) + if err != nil { + t.Fatalf("Can't detect iptables version: %v", err) + } + ipt6Ver, err := ext.DetectIptablesVersion(true) + if err != nil { + t.Fatalf("Can't detect ip6tables version") + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := constructTestConfig() + tt.config(cfg) + + deps := &dep.RealDependencies{} + set, err := createHostsideProbeIpset(true) + if err != nil { + t.Fatalf("failed to create hostside probe ipset: %v", err) + } + defer func() { + assert.NoError(t, set.DestroySet()) + }() + + iptConfigurator, _, err := NewIptablesConfigurator(cfg, cfg, deps, deps, RealNlDeps()) + builder := iptConfigurator.AppendHostRules() + if err != nil { + t.Fatalf("failed to setup iptables configurator: %v", err) + } + defer func() { + iptConfigurator.DeleteHostRules() + residueExists, deltaExists := iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, false) + assert.Equal(t, deltaExists, true) + }() + + assert.NoError(t, iptConfigurator.CreateHostRulesForHealthChecks()) + residueExists, deltaExists := iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, true) + assert.Equal(t, deltaExists, false) + + // Round-trip deletion and recreation to test clean-up and re-setup + t.Log("Starting cleanup") + iptConfigurator.DeleteHostRules() + residueExists, deltaExists = iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, false) + assert.Equal(t, deltaExists, true) + + t.Log("Second run") + assert.NoError(t, iptConfigurator.CreateHostRulesForHealthChecks()) + residueExists, deltaExists = iptablescapture.VerifyIptablesState(log, iptConfigurator.ext, builder, &iptVer, &ipt6Ver) + assert.Equal(t, residueExists, true) + assert.Equal(t, deltaExists, false) + + t.Log("Third run") + assert.NoError(t, iptConfigurator.CreateHostRulesForHealthChecks()) + }) } } @@ -92,9 +299,3 @@ func setup(t *testing.T) { _ = mountns.BindMount(xtables, "/run/xtables.lock") }) } - -func iptablesSave(t *testing.T) string { - res, err := exec.Command("iptables-save").CombinedOutput() - assert.NoError(t, err) - return string(res) -} diff --git a/cni/pkg/iptables/iptables_linux.go b/cni/pkg/iptables/iptables_linux.go index 021ee326181b..8834b0d7a29a 100644 --- a/cni/pkg/iptables/iptables_linux.go +++ b/cni/pkg/iptables/iptables_linux.go @@ -27,7 +27,7 @@ import ( "istio.io/istio/pkg/ptr" ) -func AddInpodMarkIPRule(cfg *Config) error { +func AddInpodMarkIPRule(cfg *IptablesConfig) error { err := forEachInpodMarkIPRule(cfg, netlink.RuleAdd) if errors.Is(err, unix.EEXIST) { log.Debugf("Ignoring exists error adding inpod mark ip rule: %v", err) @@ -36,11 +36,11 @@ func AddInpodMarkIPRule(cfg *Config) error { return err } -func DelInpodMarkIPRule(cfg *Config) error { +func DelInpodMarkIPRule(cfg *IptablesConfig) error { return forEachInpodMarkIPRule(cfg, netlink.RuleDel) } -func forEachInpodMarkIPRule(cfg *Config, f func(*netlink.Rule) error) error { +func forEachInpodMarkIPRule(cfg *IptablesConfig, f func(*netlink.Rule) error) error { var rules []*netlink.Rule families := []int{unix.AF_INET} if cfg.EnableIPv6 { @@ -73,11 +73,11 @@ func forEachInpodMarkIPRule(cfg *Config, f func(*netlink.Rule) error) error { return nil } -func AddLoopbackRoutes(cfg *Config) error { +func AddLoopbackRoutes(cfg *IptablesConfig) error { return forEachLoopbackRoute(cfg, "add", netlink.RouteReplace) } -func DelLoopbackRoutes(cfg *Config) error { +func DelLoopbackRoutes(cfg *IptablesConfig) error { return forEachLoopbackRoute(cfg, "remove", netlink.RouteDel) } @@ -91,7 +91,7 @@ func ReadSysctl(key string) (string, error) { return strings.TrimSpace(string(data)), nil } -func forEachLoopbackRoute(cfg *Config, operation string, f func(*netlink.Route) error) error { +func forEachLoopbackRoute(cfg *IptablesConfig, operation string, f func(*netlink.Route) error) error { loopbackLink, err := netlink.LinkByName("lo") if err != nil { return fmt.Errorf("failed to find 'lo' link: %v", err) diff --git a/cni/pkg/iptables/iptables_test.go b/cni/pkg/iptables/iptables_test.go index c73588ae80c0..2c8e774f58c3 100644 --- a/cni/pkg/iptables/iptables_test.go +++ b/cni/pkg/iptables/iptables_test.go @@ -25,34 +25,8 @@ import ( dep "istio.io/istio/tools/istio-iptables/pkg/dependencies" ) -func TestIptables(t *testing.T) { - cases := []struct { - name string - config func(cfg *Config) - ingressMode bool - }{ - { - name: "default", - config: func(cfg *Config) { - cfg.RedirectDNS = true - }, - }, - { - name: "tproxy", - config: func(cfg *Config) { - cfg.TPROXYRedirection = true - cfg.RedirectDNS = true - }, - }, - { - name: "ingress", - config: func(cfg *Config) { - }, - ingressMode: true, - }, - } - probeSNATipv4 := netip.MustParseAddr("169.254.7.127") - probeSNATipv6 := netip.MustParseAddr("e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164") +func TestIptablesPodOverrides(t *testing.T) { + cases := GetCommonInPodTestCases() for _, tt := range cases { for _, ipv6 := range []bool{false, true} { @@ -61,8 +35,8 @@ func TestIptables(t *testing.T) { cfg.EnableIPv6 = ipv6 tt.config(cfg) ext := &dep.DependenciesStub{} - iptConfigurator, _, _ := NewIptablesConfigurator(cfg, ext, ext, EmptyNlDeps()) - err := iptConfigurator.CreateInpodRules(scopes.CNIAgent, probeSNATipv4, probeSNATipv6, tt.ingressMode) + iptConfigurator, _, _ := NewIptablesConfigurator(cfg, cfg, ext, ext, EmptyNlDeps()) + err := iptConfigurator.CreateInpodRules(scopes.CNIAgent, tt.podOverrides) if err != nil { t.Fatal(err) } @@ -74,28 +48,19 @@ func TestIptables(t *testing.T) { } func TestIptablesHostRules(t *testing.T) { - cases := []struct { - name string - config func(cfg *Config) - }{ - { - "hostprobe", - func(cfg *Config) { - }, - }, - } - probeSNATipv4 := netip.MustParseAddr("169.254.7.127") - probeSNATipv6 := netip.MustParseAddr("fd16:9254:7127:1337:ffff:ffff:ffff:ffff") + cases := GetCommonHostTestCases() for _, tt := range cases { for _, ipv6 := range []bool{false, true} { t.Run(tt.name+"_"+ipstr(ipv6), func(t *testing.T) { cfg := constructTestConfig() cfg.EnableIPv6 = ipv6 + cfg.HostProbeSNATAddress = netip.MustParseAddr("169.254.7.127") + cfg.HostProbeV6SNATAddress = netip.MustParseAddr("fd16:9254:7127:1337:ffff:ffff:ffff:ffff") tt.config(cfg) ext := &dep.DependenciesStub{} - iptConfigurator, _, _ := NewIptablesConfigurator(cfg, ext, ext, EmptyNlDeps()) - err := iptConfigurator.CreateHostRulesForHealthChecks(&probeSNATipv4, &probeSNATipv6) + iptConfigurator, _, _ := NewIptablesConfigurator(cfg, cfg, ext, ext, EmptyNlDeps()) + err := iptConfigurator.CreateHostRulesForHealthChecks() if err != nil { t.Fatal(err) } @@ -107,37 +72,29 @@ func TestIptablesHostRules(t *testing.T) { } func TestInvokedTwiceIsIdempotent(t *testing.T) { - tt := struct { - name string - config func(cfg *Config) - }{ - "default", - func(cfg *Config) { - cfg.RedirectDNS = true - }, - } - - probeSNATipv4 := netip.MustParseAddr("169.254.7.127") - probeSNATipv6 := netip.MustParseAddr("e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164") - - cfg := constructTestConfig() - tt.config(cfg) - ext := &dep.DependenciesStub{} - iptConfigurator, _, _ := NewIptablesConfigurator(cfg, ext, ext, EmptyNlDeps()) - err := iptConfigurator.CreateInpodRules(scopes.CNIAgent, probeSNATipv4, probeSNATipv6, false) - if err != nil { - t.Fatal(err) - } - compareToGolden(t, false, tt.name, ext.ExecutedAll) - - *ext = dep.DependenciesStub{} - // run another time to make sure we are idempotent - err = iptConfigurator.CreateInpodRules(scopes.CNIAgent, probeSNATipv4, probeSNATipv6, false) - if err != nil { - t.Fatal(err) + tests := GetCommonInPodTestCases() + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := constructTestConfig() + tt.config(cfg) + ext := &dep.DependenciesStub{} + iptConfigurator, _, _ := NewIptablesConfigurator(cfg, cfg, ext, ext, EmptyNlDeps()) + err := iptConfigurator.CreateInpodRules(scopes.CNIAgent, tt.podOverrides) + if err != nil { + t.Fatal(err) + } + compareToGolden(t, false, tt.name, ext.ExecutedAll) + + *ext = dep.DependenciesStub{} + // run another time to make sure we are idempotent + err = iptConfigurator.CreateInpodRules(scopes.CNIAgent, tt.podOverrides) + if err != nil { + t.Fatal(err) + } + compareToGolden(t, false, tt.name, ext.ExecutedAll) + }) } - - compareToGolden(t, false, tt.name, ext.ExecutedAll) } func ipstr(ipv6 bool) string { @@ -157,6 +114,11 @@ func compareToGolden(t *testing.T, ipv6 bool, name string, actual []string) { testutil.CompareContent(t, gotBytes, goldenFile) } -func constructTestConfig() *Config { - return &Config{} +func constructTestConfig() *IptablesConfig { + probeSNATipv4 := netip.MustParseAddr("169.254.7.127") + probeSNATipv6 := netip.MustParseAddr("e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164") + return &IptablesConfig{ + HostProbeSNATAddress: probeSNATipv4, + HostProbeV6SNATAddress: probeSNATipv6, + } } diff --git a/cni/pkg/iptables/nldeps.go b/cni/pkg/iptables/nldeps.go index af554d341245..79daedd7fea3 100644 --- a/cni/pkg/iptables/nldeps.go +++ b/cni/pkg/iptables/nldeps.go @@ -15,10 +15,10 @@ package iptables type NetlinkDependencies interface { - AddInpodMarkIPRule(cfg *Config) error - DelInpodMarkIPRule(cfg *Config) error - AddLoopbackRoutes(cfg *Config) error - DelLoopbackRoutes(cfg *Config) error + AddInpodMarkIPRule(cfg *IptablesConfig) error + DelInpodMarkIPRule(cfg *IptablesConfig) error + AddLoopbackRoutes(cfg *IptablesConfig) error + DelLoopbackRoutes(cfg *IptablesConfig) error } func RealNlDeps() NetlinkDependencies { @@ -27,19 +27,19 @@ func RealNlDeps() NetlinkDependencies { type realDeps struct{} -func (r *realDeps) AddInpodMarkIPRule(cfg *Config) error { +func (r *realDeps) AddInpodMarkIPRule(cfg *IptablesConfig) error { return AddInpodMarkIPRule(cfg) } -func (r *realDeps) DelInpodMarkIPRule(cfg *Config) error { +func (r *realDeps) DelInpodMarkIPRule(cfg *IptablesConfig) error { return DelInpodMarkIPRule(cfg) } -func (r *realDeps) AddLoopbackRoutes(cfg *Config) error { +func (r *realDeps) AddLoopbackRoutes(cfg *IptablesConfig) error { return AddLoopbackRoutes(cfg) } -func (r *realDeps) DelLoopbackRoutes(cfg *Config) error { +func (r *realDeps) DelLoopbackRoutes(cfg *IptablesConfig) error { return DelLoopbackRoutes(cfg) } @@ -49,18 +49,18 @@ func EmptyNlDeps() NetlinkDependencies { return &emptyDeps{} } -func (r *emptyDeps) AddInpodMarkIPRule(cfg *Config) error { +func (r *emptyDeps) AddInpodMarkIPRule(cfg *IptablesConfig) error { return nil } -func (r *emptyDeps) DelInpodMarkIPRule(cfg *Config) error { +func (r *emptyDeps) DelInpodMarkIPRule(cfg *IptablesConfig) error { return nil } -func (r *emptyDeps) AddLoopbackRoutes(cfg *Config) error { +func (r *emptyDeps) AddLoopbackRoutes(cfg *IptablesConfig) error { return nil } -func (r *emptyDeps) DelLoopbackRoutes(cfg *Config) error { +func (r *emptyDeps) DelLoopbackRoutes(cfg *IptablesConfig) error { return nil } diff --git a/cni/pkg/iptables/testdata/default.golden b/cni/pkg/iptables/testdata/default.golden index ff29ed2134d8..a20bc81980b2 100644 --- a/cni/pkg/iptables/testdata/default.golden +++ b/cni/pkg/iptables/testdata/default.golden @@ -1,3 +1,5 @@ +iptables-save +ip6tables-save * mangle -N ISTIO_PRERT -N ISTIO_OUTPUT diff --git a/cni/pkg/iptables/testdata/default_ipv6.golden b/cni/pkg/iptables/testdata/default_ipv6.golden index ebbf9993a31d..acf33c2d455d 100644 --- a/cni/pkg/iptables/testdata/default_ipv6.golden +++ b/cni/pkg/iptables/testdata/default_ipv6.golden @@ -1,3 +1,5 @@ +iptables-save +ip6tables-save * mangle -N ISTIO_PRERT -N ISTIO_OUTPUT diff --git a/cni/pkg/iptables/testdata/hostprobe.golden b/cni/pkg/iptables/testdata/hostprobe.golden index 53bb1a040ba0..c6df88ab1ef4 100644 --- a/cni/pkg/iptables/testdata/hostprobe.golden +++ b/cni/pkg/iptables/testdata/hostprobe.golden @@ -1,3 +1,5 @@ +iptables-save +ip6tables-save * nat -N ISTIO_POSTRT -A POSTROUTING -j ISTIO_POSTRT diff --git a/cni/pkg/iptables/testdata/hostprobe_ipv6.golden b/cni/pkg/iptables/testdata/hostprobe_ipv6.golden index ff10f890f3f2..b41e59726ae9 100644 --- a/cni/pkg/iptables/testdata/hostprobe_ipv6.golden +++ b/cni/pkg/iptables/testdata/hostprobe_ipv6.golden @@ -1,3 +1,5 @@ +iptables-save +ip6tables-save * nat -N ISTIO_POSTRT -A POSTROUTING -j ISTIO_POSTRT diff --git a/cni/pkg/iptables/testdata/ingress.golden b/cni/pkg/iptables/testdata/ingress.golden index b98b97159b53..76b95b727ea1 100644 --- a/cni/pkg/iptables/testdata/ingress.golden +++ b/cni/pkg/iptables/testdata/ingress.golden @@ -1,3 +1,5 @@ +iptables-save +ip6tables-save * mangle -N ISTIO_OUTPUT -N ISTIO_PRERT diff --git a/cni/pkg/iptables/testdata/ingress_and_virtual_interfaces.golden b/cni/pkg/iptables/testdata/ingress_and_virtual_interfaces.golden new file mode 100644 index 000000000000..fb88a3f00d3d --- /dev/null +++ b/cni/pkg/iptables/testdata/ingress_and_virtual_interfaces.golden @@ -0,0 +1,23 @@ +iptables-save +ip6tables-save +* mangle +-N ISTIO_OUTPUT +-N ISTIO_PRERT +-A PREROUTING -j ISTIO_PRERT +-A OUTPUT -j ISTIO_OUTPUT +-A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff +COMMIT +* nat +-N ISTIO_PRERT +-N ISTIO_OUTPUT +-A OUTPUT -j ISTIO_OUTPUT +-A PREROUTING -j ISTIO_PRERT +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j RETURN +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j RETURN +-A ISTIO_OUTPUT -d 169.254.7.127 -p tcp -m tcp -j ACCEPT +-A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT +-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ACCEPT +-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001 +COMMIT diff --git a/cni/pkg/iptables/testdata/ingress_and_virtual_interfaces_ipv6.golden b/cni/pkg/iptables/testdata/ingress_and_virtual_interfaces_ipv6.golden new file mode 100644 index 000000000000..5db3fda625b0 --- /dev/null +++ b/cni/pkg/iptables/testdata/ingress_and_virtual_interfaces_ipv6.golden @@ -0,0 +1,44 @@ +iptables-save +ip6tables-save +* mangle +-N ISTIO_OUTPUT +-N ISTIO_PRERT +-A PREROUTING -j ISTIO_PRERT +-A OUTPUT -j ISTIO_OUTPUT +-A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff +COMMIT +* nat +-N ISTIO_PRERT +-N ISTIO_OUTPUT +-A OUTPUT -j ISTIO_OUTPUT +-A PREROUTING -j ISTIO_PRERT +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j RETURN +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j RETURN +-A ISTIO_OUTPUT -d 169.254.7.127 -p tcp -m tcp -j ACCEPT +-A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT +-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ACCEPT +-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001 +COMMIT +* mangle +-N ISTIO_OUTPUT +-N ISTIO_PRERT +-A PREROUTING -j ISTIO_PRERT +-A OUTPUT -j ISTIO_OUTPUT +-A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff +COMMIT +* nat +-N ISTIO_PRERT +-N ISTIO_OUTPUT +-A OUTPUT -j ISTIO_OUTPUT +-A PREROUTING -j ISTIO_PRERT +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j RETURN +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j RETURN +-A ISTIO_OUTPUT -d e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164 -p tcp -m tcp -j ACCEPT +-A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT +-A ISTIO_OUTPUT ! -d ::1/128 -o lo -j ACCEPT +-A ISTIO_OUTPUT ! -d ::1/128 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001 +COMMIT diff --git a/cni/pkg/iptables/testdata/ingress_ipv6.golden b/cni/pkg/iptables/testdata/ingress_ipv6.golden index fc07a530ad10..acc712ab625c 100644 --- a/cni/pkg/iptables/testdata/ingress_ipv6.golden +++ b/cni/pkg/iptables/testdata/ingress_ipv6.golden @@ -1,3 +1,5 @@ +iptables-save +ip6tables-save * mangle -N ISTIO_OUTPUT -N ISTIO_PRERT diff --git a/cni/pkg/iptables/testdata/tproxy.golden b/cni/pkg/iptables/testdata/tproxy.golden deleted file mode 100644 index 33e102ccd6ee..000000000000 --- a/cni/pkg/iptables/testdata/tproxy.golden +++ /dev/null @@ -1,31 +0,0 @@ -* mangle --N ISTIO_PRERT --N ISTIO_OUTPUT --A PREROUTING -j ISTIO_PRERT --A OUTPUT -j ISTIO_OUTPUT --A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff --A ISTIO_PRERT -s 169.254.7.127 -p tcp -m tcp -j ACCEPT --A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp -i lo -j ACCEPT --A ISTIO_PRERT -p tcp -m tcp --dport 15008 -m mark ! --mark 0x539/0xfff -j TPROXY --on-port 15008 --tproxy-mark 0x111/0xfff --A ISTIO_PRERT -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT --A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j TPROXY --on-port 15006 --tproxy-mark 0x111/0xfff --A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff -COMMIT -* nat --N ISTIO_OUTPUT --A OUTPUT -j ISTIO_OUTPUT --A ISTIO_OUTPUT -d 169.254.7.127 -p tcp -m tcp -j ACCEPT --A ISTIO_OUTPUT ! -o lo -p udp -m mark ! --mark 0x539/0xfff -m udp --dport 53 -j REDIRECT --to-port 15053 --A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp --dport 53 -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15053 --A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT --A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ACCEPT --A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001 -COMMIT -* raw --N ISTIO_OUTPUT --N ISTIO_PRERT --A PREROUTING -j ISTIO_PRERT --A OUTPUT -j ISTIO_OUTPUT --A ISTIO_OUTPUT -p udp -m mark --mark 0x539/0xfff -m udp --dport 53 -j CT --zone 1 --A ISTIO_PRERT -p udp -m mark ! --mark 0x539/0xfff -m udp --sport 53 -j CT --zone 1 -COMMIT \ No newline at end of file diff --git a/cni/pkg/iptables/testdata/tproxy_ipv6.golden b/cni/pkg/iptables/testdata/tproxy_ipv6.golden deleted file mode 100644 index 8c04a0a9f8ac..000000000000 --- a/cni/pkg/iptables/testdata/tproxy_ipv6.golden +++ /dev/null @@ -1,62 +0,0 @@ -* mangle --N ISTIO_PRERT --N ISTIO_OUTPUT --A PREROUTING -j ISTIO_PRERT --A OUTPUT -j ISTIO_OUTPUT --A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff --A ISTIO_PRERT -s 169.254.7.127 -p tcp -m tcp -j ACCEPT --A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp -i lo -j ACCEPT --A ISTIO_PRERT -p tcp -m tcp --dport 15008 -m mark ! --mark 0x539/0xfff -j TPROXY --on-port 15008 --tproxy-mark 0x111/0xfff --A ISTIO_PRERT -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT --A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j TPROXY --on-port 15006 --tproxy-mark 0x111/0xfff --A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff -COMMIT -* nat --N ISTIO_OUTPUT --A OUTPUT -j ISTIO_OUTPUT --A ISTIO_OUTPUT -d 169.254.7.127 -p tcp -m tcp -j ACCEPT --A ISTIO_OUTPUT ! -o lo -p udp -m mark ! --mark 0x539/0xfff -m udp --dport 53 -j REDIRECT --to-port 15053 --A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp --dport 53 -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15053 --A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT --A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ACCEPT --A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001 -COMMIT -* raw --N ISTIO_OUTPUT --N ISTIO_PRERT --A PREROUTING -j ISTIO_PRERT --A OUTPUT -j ISTIO_OUTPUT --A ISTIO_OUTPUT -p udp -m mark --mark 0x539/0xfff -m udp --dport 53 -j CT --zone 1 --A ISTIO_PRERT -p udp -m mark ! --mark 0x539/0xfff -m udp --sport 53 -j CT --zone 1 -COMMIT -* mangle --N ISTIO_PRERT --N ISTIO_OUTPUT --A PREROUTING -j ISTIO_PRERT --A OUTPUT -j ISTIO_OUTPUT --A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff --A ISTIO_PRERT -s e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164 -p tcp -m tcp -j ACCEPT --A ISTIO_PRERT ! -d ::1/128 -p tcp -i lo -j ACCEPT --A ISTIO_PRERT -p tcp -m tcp --dport 15008 -m mark ! --mark 0x539/0xfff -j TPROXY --on-port 15008 --tproxy-mark 0x111/0xfff --A ISTIO_PRERT -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT --A ISTIO_PRERT ! -d ::1/128 -p tcp -m mark ! --mark 0x539/0xfff -j TPROXY --on-port 15006 --tproxy-mark 0x111/0xfff --A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff -COMMIT -* nat --N ISTIO_OUTPUT --A OUTPUT -j ISTIO_OUTPUT --A ISTIO_OUTPUT -d e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164 -p tcp -m tcp -j ACCEPT --A ISTIO_OUTPUT ! -o lo -p udp -m mark ! --mark 0x539/0xfff -m udp --dport 53 -j REDIRECT --to-port 15053 --A ISTIO_OUTPUT ! -d ::1/128 -p tcp --dport 53 -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15053 --A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT --A ISTIO_OUTPUT ! -d ::1/128 -o lo -j ACCEPT --A ISTIO_OUTPUT ! -d ::1/128 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001 -COMMIT -* raw --N ISTIO_OUTPUT --N ISTIO_PRERT --A PREROUTING -j ISTIO_PRERT --A OUTPUT -j ISTIO_OUTPUT --A ISTIO_OUTPUT -p udp -m mark --mark 0x539/0xfff -m udp --dport 53 -j CT --zone 1 --A ISTIO_PRERT -p udp -m mark ! --mark 0x539/0xfff -m udp --sport 53 -j CT --zone 1 -COMMIT \ No newline at end of file diff --git a/cni/pkg/iptables/testdata/virtual_interfaces.golden b/cni/pkg/iptables/testdata/virtual_interfaces.golden new file mode 100644 index 000000000000..f193c3f667b1 --- /dev/null +++ b/cni/pkg/iptables/testdata/virtual_interfaces.golden @@ -0,0 +1,26 @@ +iptables-save +ip6tables-save +* mangle +-N ISTIO_PRERT +-N ISTIO_OUTPUT +-A PREROUTING -j ISTIO_PRERT +-A OUTPUT -j ISTIO_OUTPUT +-A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff +-A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff +COMMIT +* nat +-N ISTIO_PRERT +-N ISTIO_OUTPUT +-A OUTPUT -j ISTIO_OUTPUT +-A PREROUTING -j ISTIO_PRERT +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j RETURN +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j RETURN +-A ISTIO_PRERT -s 169.254.7.127 -p tcp -m tcp -j ACCEPT +-A ISTIO_OUTPUT -d 169.254.7.127 -p tcp -m tcp -j ACCEPT +-A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp ! --dport 15008 -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15006 +-A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT +-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ACCEPT +-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001 +COMMIT diff --git a/cni/pkg/iptables/testdata/virtual_interfaces_ipv6.golden b/cni/pkg/iptables/testdata/virtual_interfaces_ipv6.golden new file mode 100644 index 000000000000..4bd63981b02d --- /dev/null +++ b/cni/pkg/iptables/testdata/virtual_interfaces_ipv6.golden @@ -0,0 +1,50 @@ +iptables-save +ip6tables-save +* mangle +-N ISTIO_PRERT +-N ISTIO_OUTPUT +-A PREROUTING -j ISTIO_PRERT +-A OUTPUT -j ISTIO_OUTPUT +-A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff +-A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff +COMMIT +* nat +-N ISTIO_PRERT +-N ISTIO_OUTPUT +-A OUTPUT -j ISTIO_OUTPUT +-A PREROUTING -j ISTIO_PRERT +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j RETURN +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j RETURN +-A ISTIO_PRERT -s 169.254.7.127 -p tcp -m tcp -j ACCEPT +-A ISTIO_OUTPUT -d 169.254.7.127 -p tcp -m tcp -j ACCEPT +-A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp ! --dport 15008 -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15006 +-A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT +-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ACCEPT +-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001 +COMMIT +* mangle +-N ISTIO_PRERT +-N ISTIO_OUTPUT +-A PREROUTING -j ISTIO_PRERT +-A OUTPUT -j ISTIO_OUTPUT +-A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff +-A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff +COMMIT +* nat +-N ISTIO_PRERT +-N ISTIO_OUTPUT +-A OUTPUT -j ISTIO_OUTPUT +-A PREROUTING -j ISTIO_PRERT +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f0 -p tcp -j RETURN +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j REDIRECT --to-ports 15001 +-A ISTIO_PRERT -i fake1s0f1 -p tcp -j RETURN +-A ISTIO_PRERT -s e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164 -p tcp -m tcp -j ACCEPT +-A ISTIO_OUTPUT -d e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164 -p tcp -m tcp -j ACCEPT +-A ISTIO_PRERT ! -d ::1/128 -p tcp ! --dport 15008 -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15006 +-A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT +-A ISTIO_OUTPUT ! -d ::1/128 -o lo -j ACCEPT +-A ISTIO_OUTPUT ! -d ::1/128 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001 +COMMIT diff --git a/cni/pkg/nodeagent/cni-watcher.go b/cni/pkg/nodeagent/cni-watcher.go index 274ae17975dc..476732828aaf 100644 --- a/cni/pkg/nodeagent/cni-watcher.go +++ b/cni/pkg/nodeagent/cni-watcher.go @@ -198,7 +198,7 @@ func (s *CniPluginServer) getPodWithRetry(log *istiolog.Scope, name, namespace s // The plugin already consulted the k8s API - but on this end handler caches may be stale, so retry a few times if we get no pod. // if err is returned, we couldn't find the pod // if nil is returned, we found it but ambient is not enabled - for ambientPod, err = s.handlers.GetPodIfAmbient(name, namespace); (err != nil) && (retries < maxStaleRetries); retries++ { + for ambientPod, err = s.handlers.GetPodIfAmbientEnabled(name, namespace); (err != nil) && (retries < maxStaleRetries); retries++ { log.Warnf("got an event for pod %s in namespace %s not found in current pod cache, retry %d of %d", name, namespace, retries, maxStaleRetries) if !sleep.UntilContext(s.ctx, time.Duration(msInterval)*time.Millisecond) { @@ -209,9 +209,10 @@ func (s *CniPluginServer) getPodWithRetry(log *istiolog.Scope, name, namespace s return nil, fmt.Errorf("failed to get pod %s/%s: %v", namespace, name, err) } - // This shouldn't happen - we only trigger this when a pod is added to ambient. + // This shouldn't happen - the CNI plugin should only invoke us when a pod starts up that already meets + // ambient eligibility requirements. if ambientPod == nil { - return nil, fmt.Errorf("pod %s/%s is unexpectedly not enrolled in ambient", namespace, name) + return nil, fmt.Errorf("pod %s/%s is unexpectedly not eligible for ambient enrollment", namespace, name) } return ambientPod, nil } diff --git a/cni/pkg/nodeagent/cni-watcher_test.go b/cni/pkg/nodeagent/cni-watcher_test.go index b2348ee7dab7..05665c009fcb 100644 --- a/cni/pkg/nodeagent/cni-watcher_test.go +++ b/cni/pkg/nodeagent/cni-watcher_test.go @@ -211,7 +211,7 @@ func TestGetPodWithRetry(t *testing.T) { t.Run("pod out of ambient", func(t *testing.T) { p, err := pluginServer.getPodWithRetry(log, podOutOfAmbient.Name, pod.Namespace) assert.Error(t, err) - assert.Equal(t, true, strings.Contains(err.Error(), "unexpectedly not enrolled in ambient")) + assert.Equal(t, true, strings.Contains(err.Error(), "unexpectedly not eligible for ambient enrollment")) assert.Equal(t, p, nil) }) } diff --git a/cni/pkg/nodeagent/fakes_test.go b/cni/pkg/nodeagent/fakes_test.go index 129200320fb4..9e7ae099a747 100644 --- a/cni/pkg/nodeagent/fakes_test.go +++ b/cni/pkg/nodeagent/fakes_test.go @@ -154,22 +154,22 @@ type fakeIptablesDeps struct { var _ iptables.NetlinkDependencies = &fakeIptablesDeps{} -func (r *fakeIptablesDeps) AddInpodMarkIPRule(cfg *iptables.Config) error { +func (r *fakeIptablesDeps) AddInpodMarkIPRule(cfg *iptables.IptablesConfig) error { r.AddInpodMarkIPRuleCnt.Add(1) return nil } -func (r *fakeIptablesDeps) DelInpodMarkIPRule(cfg *iptables.Config) error { +func (r *fakeIptablesDeps) DelInpodMarkIPRule(cfg *iptables.IptablesConfig) error { r.DelInpodMarkIPRuleCnt.Add(1) return nil } -func (r *fakeIptablesDeps) AddLoopbackRoutes(cfg *iptables.Config) error { +func (r *fakeIptablesDeps) AddLoopbackRoutes(cfg *iptables.IptablesConfig) error { r.AddLoopbackRoutesCnt.Add(1) return r.AddRouteErr } -func (r *fakeIptablesDeps) DelLoopbackRoutes(cfg *iptables.Config) error { +func (r *fakeIptablesDeps) DelLoopbackRoutes(cfg *iptables.IptablesConfig) error { r.DelLoopbackRoutesCnt.Add(1) return nil } diff --git a/cni/pkg/nodeagent/informers.go b/cni/pkg/nodeagent/informers.go index 3351aa19d984..884af1453d02 100644 --- a/cni/pkg/nodeagent/informers.go +++ b/cni/pkg/nodeagent/informers.go @@ -22,7 +22,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" klabels "k8s.io/apimachinery/pkg/labels" - "istio.io/api/annotation" "istio.io/api/label" "istio.io/istio/cni/pkg/util" "istio.io/istio/pkg/config/constants" @@ -41,7 +40,7 @@ var ( ) type K8sHandlers interface { - GetPodIfAmbient(podName, podNamespace string) (*corev1.Pod, error) + GetPodIfAmbientEnabled(podName, podNamespace string) (*corev1.Pod, error) GetActiveAmbientPodSnapshot() []*corev1.Pod Start() } @@ -84,11 +83,11 @@ func setupHandlers(ctx context.Context, kubeClient kube.Client, dataplane MeshDa return s } -// GetPodIfAmbient looks up a pod. It returns: +// GetPodIfAmbientEnabled looks up a pod. It returns: // * An error if the pod cannot be found -// * nil if the pod is found, but does not have ambient enabled -// * the pod, if it is found and ambient is enabled -func (s *InformerHandlers) GetPodIfAmbient(podName, podNamespace string) (*corev1.Pod, error) { +// * nil if the pod is found, but is not currently eligible for ambient enrollment +// * the pod, if it is found and is currently eligible for ambient enrollment +func (s *InformerHandlers) GetPodIfAmbientEnabled(podName, podNamespace string) (*corev1.Pod, error) { ns := s.namespaces.Get(podNamespace, "") if ns == nil { return nil, fmt.Errorf("failed to find namespace %v", ns) @@ -159,9 +158,13 @@ func (s *InformerHandlers) enqueueNamespace(o controllers.Object) { func (s *InformerHandlers) reconcile(input any) error { event := input.(controllers.Event) + + defer EventTotals.With(eventTypeTag.Value(event.Event.String())).Increment() + switch event.Latest().(type) { case *corev1.Namespace: - return s.reconcileNamespace(input) + s.reconcileNamespace(input) + return nil case *corev1.Pod: return s.reconcilePod(input) default: @@ -169,7 +172,7 @@ func (s *InformerHandlers) reconcile(input any) error { } } -func (s *InformerHandlers) reconcileNamespace(input any) error { +func (s *InformerHandlers) reconcileNamespace(input any) { event := input.(controllers.Event) ns := event.Latest().(*corev1.Namespace) @@ -187,7 +190,6 @@ func (s *InformerHandlers) reconcileNamespace(input any) error { s.enqueueNamespace(newNs) } } - return nil } func getModeLabel(m map[string]string) string { @@ -199,10 +201,14 @@ func getModeLabel(m map[string]string) string { func (s *InformerHandlers) reconcilePod(input any) error { event := input.(controllers.Event) - pod := event.Latest().(*corev1.Pod) - log := log.WithLabels("ns", pod.Namespace, "name", pod.Name) + latestEventPod := event.Latest().(*corev1.Pod) - defer EventTotals.With(eventTypeTag.Value(event.Event.String())).Increment() + log := log.WithLabels("ns", latestEventPod.Namespace, "name", latestEventPod.Name) + + ns := s.namespaces.Get(latestEventPod.Namespace, "") + if ns == nil { + return fmt.Errorf("failed to find namespace %v", ns) + } switch event.Event { case controllers.EventAdd: @@ -216,23 +222,30 @@ func (s *InformerHandlers) reconcilePod(input any) error { // and the initial enqueueNamespace, and new pods will be handled by the CNI. case controllers.EventUpdate: - // For update, we just need to handle opt outs - newPod := event.New.(*corev1.Pod) - oldPod := event.Old.(*corev1.Pod) - ns := s.namespaces.Get(newPod.Namespace, "") - if ns == nil { - return fmt.Errorf("failed to find namespace %v", ns) + // The pod data in the event may be stale, and we always want to operate on the most recent + // instance of the pod data in the former cache, so fetch it here. + currentPod := s.pods.Get(latestEventPod.Name, ns.Name) + + // if the pod we get an Update event for no longer actually exists in the cluster, + // we should just skip handling the update event - we (probably) will get a Delete event. + if currentPod == nil { + log.Warnf("update event skipped - pod no longer exists") + return nil } - wasAnnotated := oldPod.Annotations != nil && oldPod.Annotations[annotation.AmbientRedirection.Name] == constants.AmbientRedirectionEnabled - isAnnotated := newPod.Annotations != nil && newPod.Annotations[annotation.AmbientRedirection.Name] == constants.AmbientRedirectionEnabled - shouldBeEnabled := util.PodRedirectionEnabled(ns, newPod) - isTerminated := kube.CheckPodTerminal(newPod) + // NOTE that we *do not* consult the old pod state for `update` events, and that is intentional, + // with 2 exceptions: + // 1. Logging (so the change event diff is more obvious) + // 2. To work around a potential k8s pod removal bug + oldPod := event.Old.(*corev1.Pod) + isAnnotated := util.PodRedirectionActive(currentPod) + shouldBeEnabled := util.PodRedirectionEnabled(ns, currentPod) + isTerminated := kube.CheckPodTerminal(currentPod) // Check intent (labels) versus status (annotation) - is there a delta we need to fix? changeNeeded := (isAnnotated != shouldBeEnabled) && !isTerminated // nolint: lll - log.Debugf("pod update: annotation=%v->%v shouldBeEnabled=%v changeNeeded=%v isTerminated=%v, oldPod=%+v, newPod=%+v", - wasAnnotated, isAnnotated, shouldBeEnabled, changeNeeded, isTerminated, oldPod.ObjectMeta, newPod.ObjectMeta) + log.Debugf("pod update: annotation=%v shouldBeEnabled=%v changeNeeded=%v isTerminated=%v, oldPod=%+v, newPod=%+v", + isAnnotated, shouldBeEnabled, changeNeeded, isTerminated, oldPod.ObjectMeta, currentPod.ObjectMeta) // If it was a job pod that (a) we captured and (b) just terminated (successfully or otherwise) // remove it (the pod process is gone, but kube will keep the Pods around in @@ -245,6 +258,8 @@ func (s *InformerHandlers) reconcilePod(input any) error { // // We will get subsequent events that append a new status with the IP put back, but it's simpler // and safer to just check the old pod status for the IP. + // + // https://github.com/kubernetes/kubernetes/issues/125370 err := s.dataplane.RemovePodFromMesh(s.ctx, oldPod, true) log.Debugf("RemovePodFromMesh returned: %v", err) return nil @@ -258,54 +273,44 @@ func (s *InformerHandlers) reconcilePod(input any) error { // Pod is not terminated, and has changed in a way we care about - so reconcile if !shouldBeEnabled { log.Debugf("removing pod from mesh: no longer should be enabled") - err := s.dataplane.RemovePodFromMesh(s.ctx, pod, false) + err := s.dataplane.RemovePodFromMesh(s.ctx, currentPod, false) log.Debugf("RemovePodFromMesh returned: %v", err) + return err // we ignore errors here as we don't want this event to be retried by the queue. - } else { - // If oldpod != ready && newpod != ready, but the ambient annotation was added, - // then assume this event was generated by the CNI plugin labeling the pod on startup, - // and skip the event. - // - // This isn't perfect (someone could manually annotate an unready pod, - // then install Istio, then the pod goes ready, and we'd miss capture) - but that - // seems vanishingly unlikely - wasReady := kube.CheckPodReadyOrComplete(oldPod) - isReady := kube.CheckPodReadyOrComplete(newPod) - if wasReady != nil && isReady != nil && isAnnotated { - log.Infof("pod update event skipped: added/labeled by CNI plugin") - return nil - } - - // netns == ""; at this point netns should have been added via the initial snapshot, - // or via the cni plugin. If it happens to get here before the cni plugin somehow, - // then we will just fail to add the pod to the mesh, and it will be retried later when cni plugin adds it. + } - // We need a pod IP - if the pod was added via the CNI plugin, that plugin told us the IPs - // for the pod. If this is a pod added via informer, the pod should have already gone thru - // the CNI plugin chain, and have a PodIP. - // - // If PodIPs exists, it is preferred, otherwise fallback to PodIP. - // - // If we get to this point and have a pod that really and truly has no IP in either of those, - // it's not routable at this point and something is wrong/we should discard this event. - podIPs := util.GetPodIPsIfPresent(pod) - if len(podIPs) == 0 { - log.Debugf("pod update event skipped: no IP assigned yet") - return nil - } + // netns == ""; at this point netns should have been added via the initial snapshot, + // or via the cni plugin. If it happens to get here before the cni plugin somehow, + // then we will just fail to add the pod to the mesh, and it will be retried later when cni plugin adds it. + + // We need a pod IP - if the pod was added via the CNI plugin, that plugin told us the IPs + // for the pod. If this is a pod added via informer, the pod should have already gone thru + // the CNI plugin chain, and have a PodIP. + // + // If PodIPs exists, it is preferred, otherwise fallback to PodIP. + // + // If we get to this point and have a pod that really and truly has no IP in either of those, + // it's not routable at this point and something is wrong/we should discard this event. + podIPs := util.GetPodIPsIfPresent(currentPod) + if len(podIPs) == 0 { + log.Debugf("pod update event skipped: no IP assigned yet") + return nil + } - log.Debugf("pod is now enrolled, adding to mesh") - err := s.dataplane.AddPodToMesh(s.ctx, pod, podIPs, "") - if err != nil { - log.Warnf("AddPodToMesh returned: %v", err) - } + log.Debugf("pod is now enrolled, adding to mesh") + err := s.dataplane.AddPodToMesh(s.ctx, currentPod, podIPs, "") + if err != nil { + log.Warnf("AddPodToMesh returned: %v", err) } case controllers.EventDelete: - // We are the only thing that should be annotating the pods for mesh inclusion. - // If we did, remove it from ztunnel - if util.PodRedirectionActive(pod) { + // If the pod was annotated (by informer or plugin) remove pod from mesh. + // NOTE that unlike the other event handling cases (ADD/UPDATE), for DELETE + // we *do not* want to check the cache for the pod - because it (probably) + // won't be there anymore. So for this case *alone*, we check the most recent + // pod information from the triggering event. + if util.PodRedirectionActive(latestEventPod) { log.Debugf("pod is deleted and was captured, removing from ztunnel") - err := s.dataplane.RemovePodFromMesh(s.ctx, pod, true) + err := s.dataplane.RemovePodFromMesh(s.ctx, latestEventPod, true) if err != nil { log.Warnf("DelPodFromMesh returned: %v", err) } diff --git a/cni/pkg/nodeagent/informers_test.go b/cni/pkg/nodeagent/informers_test.go index e2160245b242..304192c37272 100644 --- a/cni/pkg/nodeagent/informers_test.go +++ b/cni/pkg/nodeagent/informers_test.go @@ -30,11 +30,12 @@ import ( "istio.io/istio/cni/pkg/util" "istio.io/istio/pkg/config/constants" "istio.io/istio/pkg/kube" + "istio.io/istio/pkg/kube/controllers" "istio.io/istio/pkg/monitoring/monitortest" "istio.io/istio/pkg/test/util/assert" ) -func TestExistingPodAddedWhenNsLabeled(t *testing.T) { +func TestInformerExistingPodAddedWhenNsLabeled(t *testing.T) { setupLogging() NodeName = "testnode" ctx, cancel := context.WithCancel(context.Background()) @@ -53,25 +54,17 @@ func TestExistingPodAddedWhenNsLabeled(t *testing.T) { }, } ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test"}} - client := kube.NewFakeClient(ns, pod) - - // We are expecting at most 1 calls to the mock, wait for them - wg, waitForMockCalls := NewWaitForNCalls(t, 1) - fs := &fakeServer{testWG: wg} + fs := &fakeServer{} fs.On("AddPodToMesh", ctx, mock.IsType(pod), util.GetPodIPsIfPresent(pod), "", - ).Return(nil) + ).Once().Return(nil) - server := getFakeDP(fs, client.Kube()) - - handlers := setupHandlers(ctx, client, server, "istio-system") - client.RunAndWait(ctx.Done()) - go handlers.Start() + _, mt := populateClientAndWaitForInformer(ctx, t, client, fs, 2, 1) // label the namespace labelsPatch := []byte(fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s"}}}`, @@ -80,7 +73,7 @@ func TestExistingPodAddedWhenNsLabeled(t *testing.T) { types.MergePatchType, labelsPatch, metav1.PatchOptions{}) assert.NoError(t, err) - waitForMockCalls() + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(4)) assertPodAnnotated(t, client, pod) @@ -88,7 +81,7 @@ func TestExistingPodAddedWhenNsLabeled(t *testing.T) { fs.AssertExpectations(t) } -func TestExistingPodAddedWhenDualStack(t *testing.T) { +func TestInformerExistingPodAddedWhenDualStack(t *testing.T) { setupLogging() NodeName = "testnode" ctx, cancel := context.WithCancel(context.Background()) @@ -114,24 +107,16 @@ func TestExistingPodAddedWhenDualStack(t *testing.T) { client := kube.NewFakeClient(ns, pod) - // We are expecting at most 1 calls to the mock, wait for them - wg, waitForMockCalls := NewWaitForNCalls(t, 1) - - fs := &fakeServer{testWG: wg} + fs := &fakeServer{} fs.On("AddPodToMesh", ctx, mock.IsType(pod), util.GetPodIPsIfPresent(pod), "", - ).Return(nil) - - server := getFakeDP(fs, client.Kube()) + ).Once().Return(nil) - fs.Start(ctx) - handlers := setupHandlers(ctx, client, server, "istio-system") - client.RunAndWait(ctx.Done()) - go handlers.Start() + _, mt := populateClientAndWaitForInformer(ctx, t, client, fs, 2, 1) // label the namespace labelsPatch := []byte(fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s"}}}`, @@ -140,7 +125,7 @@ func TestExistingPodAddedWhenDualStack(t *testing.T) { types.MergePatchType, labelsPatch, metav1.PatchOptions{}) assert.NoError(t, err) - waitForMockCalls() + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(4)) assertPodAnnotated(t, client, pod) @@ -148,14 +133,12 @@ func TestExistingPodAddedWhenDualStack(t *testing.T) { fs.AssertExpectations(t) } -func TestExistingPodNotAddedIfNoIPInAnyStatusField(t *testing.T) { +func TestInformerExistingPodNotAddedIfNoIPInAnyStatusField(t *testing.T) { setupLogging() NodeName = "testnode" ctx, cancel := context.WithCancel(context.Background()) defer cancel() - mt := monitortest.New(t) - pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -175,11 +158,7 @@ func TestExistingPodNotAddedIfNoIPInAnyStatusField(t *testing.T) { fs := &fakeServer{} - server := getFakeDP(fs, client.Kube()) - - handlers := setupHandlers(ctx, client, server, "istio-system") - client.RunAndWait(ctx.Done()) - go handlers.Start() + _, mt := populateClientAndWaitForInformer(ctx, t, client, fs, 2, 1) // label the namespace labelsPatch := []byte(fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s"}}}`, @@ -188,8 +167,9 @@ func TestExistingPodNotAddedIfNoIPInAnyStatusField(t *testing.T) { types.MergePatchType, labelsPatch, metav1.PatchOptions{}) assert.NoError(t, err) - // wait until at least one add event happens - mt.Assert(EventTotals.Name(), map[string]string{"type": "add"}, monitortest.AtLeast(1)) + // wait for all update events to settle + // total 3: 1. init ns reconcile 2. ns label reconcile 3. pod reconcile + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(3)) assertPodNotAnnotated(t, client, pod) @@ -197,9 +177,8 @@ func TestExistingPodNotAddedIfNoIPInAnyStatusField(t *testing.T) { fs.AssertExpectations(t) } -func TestExistingPodRemovedWhenNsUnlabeled(t *testing.T) { +func TestInformerExistingPodRemovedWhenNsUnlabeled(t *testing.T) { setupLogging() - mt := monitortest.New(t) NodeName = "testnode" ctx, cancel := context.WithCancel(context.Background()) @@ -226,24 +205,16 @@ func TestExistingPodRemovedWhenNsUnlabeled(t *testing.T) { client := kube.NewFakeClient(ns, pod) - // We are expecting at most 2 calls to the mock, wait for them - wg, waitForMockCalls := NewWaitForNCalls(t, 2) - fs := &fakeServer{testWG: wg} + fs := &fakeServer{} fs.On("AddPodToMesh", ctx, mock.IsType(pod), util.GetPodIPsIfPresent(pod), "", - ).Return(nil) - - server := getFakeDP(fs, client.Kube()) + ).Once().Return(nil) - handlers := setupHandlers(ctx, client, server, "istio-system") - client.RunAndWait(ctx.Done()) - go handlers.Start() - // wait until pod add was called - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(1)) + _, mt := populateClientAndWaitForInformer(ctx, t, client, fs, 2, 1) log.Debug("labeling namespace") _, err := client.Kube().CoreV1().Namespaces().Patch(ctx, ns.Name, @@ -251,8 +222,10 @@ func TestExistingPodRemovedWhenNsUnlabeled(t *testing.T) { label.IoIstioDataplaneMode.Name, constants.DataplaneModeAmbient)), metav1.PatchOptions{}) assert.NoError(t, err) - // wait for an update event - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(2)) + // wait for all update events to settle + // total 3: 1. init ns reconcile 2. ns label reconcile 3. pod reconcile 4. pod annotate + // for all that tho, we should only get 1 ADD, as enforced by mock + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(4)) // wait for the pod to be annotated // after Pod annotated, another update event will be triggered. @@ -275,11 +248,8 @@ func TestExistingPodRemovedWhenNsUnlabeled(t *testing.T) { types.MergePatchType, labelsPatch, metav1.PatchOptions{}) assert.NoError(t, err) - // wait for another two update events - // total 3 update at before unlabel point: 1. init ns reconcile 2. ns label reconcile 3. pod annotation update - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(5)) - - waitForMockCalls() + // wait for another 3 update events for unlabel, total of 7 + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(7)) assertPodNotAnnotated(t, client, pod) @@ -287,9 +257,8 @@ func TestExistingPodRemovedWhenNsUnlabeled(t *testing.T) { fs.AssertExpectations(t) } -func TestExistingPodRemovedWhenPodLabelRemoved(t *testing.T) { +func TestInformerExistingPodRemovedWhenPodLabelRemoved(t *testing.T) { setupLogging() - mt := monitortest.New(t) NodeName = "testnode" ctx, cancel := context.WithCancel(context.Background()) @@ -309,31 +278,20 @@ func TestExistingPodRemovedWhenPodLabelRemoved(t *testing.T) { } ns := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{Name: "test"}, - // TODO: once we if the add pod bug, re-enable this and remove the patch below - // Labels: map[string]string{label.IoIstioDataplaneMode.Name: constants.DataplaneModeAmbient}, - } client := kube.NewFakeClient(ns, pod) - // We are expecting at most 2 calls to the mock, wait for them - wg, waitForMockCalls := NewWaitForNCalls(t, 2) - fs := &fakeServer{testWG: wg} + fs := &fakeServer{} fs.On("AddPodToMesh", ctx, mock.IsType(pod), util.GetPodIPsIfPresent(pod), "", - ).Return(nil) - - server := getFakeDP(fs, client.Kube()) + ).Once().Return(nil) - handlers := setupHandlers(ctx, client, server, "istio-system") - client.RunAndWait(ctx.Done()) - go handlers.Start() - // wait until pod add was called - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(1)) + _, mt := populateClientAndWaitForInformer(ctx, t, client, fs, 2, 1) log.Debug("labeling namespace") _, err := client.Kube().CoreV1().Namespaces().Patch(ctx, ns.Name, @@ -341,8 +299,10 @@ func TestExistingPodRemovedWhenPodLabelRemoved(t *testing.T) { label.IoIstioDataplaneMode.Name, constants.DataplaneModeAmbient)), metav1.PatchOptions{}) assert.NoError(t, err) - // wait for an update event - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(2)) + // wait for all update events to settle + // total 3: 1. init ns reconcile 2. ns label reconcile 3. pod reconcile 4. pod annotate + // for all that tho, we should only get 1 ADD, as enforced by mock + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(4)) // wait for the pod to be annotated // after Pod annotated, another update event will be triggered. @@ -365,11 +325,9 @@ func TestExistingPodRemovedWhenPodLabelRemoved(t *testing.T) { types.MergePatchType, labelsPatch, metav1.PatchOptions{}) assert.NoError(t, err) - // wait for an update events - // total 3 update at before unlabel point: 1. init ns reconcile 2. ns label reconcile 3. pod annotation update - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(4)) - - waitForMockCalls() + // wait for update events + // Expecting 2 - 1. pod unlabel (us) 2. pod un-annotate (informer) + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(6)) assertPodNotAnnotated(t, client, pod) @@ -378,8 +336,8 @@ func TestExistingPodRemovedWhenPodLabelRemoved(t *testing.T) { types.MergePatchType, []byte(`{"metadata":{"labels":{"test":"update"}}}`), metav1.PatchOptions{}) assert.NoError(t, err) - // wait for an update events - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(5)) + // wait for an update event + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(7)) assertPodNotAnnotated(t, client, pod) @@ -387,9 +345,8 @@ func TestExistingPodRemovedWhenPodLabelRemoved(t *testing.T) { fs.AssertExpectations(t) } -func TestJobPodRemovedWhenPodTerminates(t *testing.T) { +func TestInformerJobPodRemovedWhenPodTerminates(t *testing.T) { setupLogging() - mt := monitortest.New(t) NodeName = "testnode" ctx, cancel := context.WithCancel(context.Background()) @@ -416,24 +373,16 @@ func TestJobPodRemovedWhenPodTerminates(t *testing.T) { client := kube.NewFakeClient(ns, pod) - // We are expecting at most 2 calls to the mock, wait for them - wg, waitForMockCalls := NewWaitForNCalls(t, 2) - fs := &fakeServer{testWG: wg} + fs := &fakeServer{} fs.On("AddPodToMesh", ctx, mock.IsType(pod), util.GetPodIPsIfPresent(pod), "", - ).Return(nil) + ).Once().Return(nil) - server := getFakeDP(fs, client.Kube()) - - handlers := setupHandlers(ctx, client, server, "istio-system") - client.RunAndWait(ctx.Done()) - go handlers.Start() - // wait until pod add was called - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(1)) + _, mt := populateClientAndWaitForInformer(ctx, t, client, fs, 2, 1) log.Debug("labeling namespace") _, err := client.Kube().CoreV1().Namespaces().Patch(ctx, ns.Name, @@ -441,8 +390,10 @@ func TestJobPodRemovedWhenPodTerminates(t *testing.T) { label.IoIstioDataplaneMode.Name, constants.DataplaneModeAmbient)), metav1.PatchOptions{}) assert.NoError(t, err) - // wait for an update event - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(2)) + // wait for all update events to settle + // total 3: 1. init ns reconcile 2. ns label reconcile 3. pod reconcile 4. Pod annotate. + // for all that tho, we should only get 1 ADD, as enforced by mock + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(4)) // wait for the pod to be annotated // after Pod annotated, another update event will be triggered. @@ -464,11 +415,8 @@ func TestJobPodRemovedWhenPodTerminates(t *testing.T) { types.MergePatchType, phasePatch, metav1.PatchOptions{}) assert.NoError(t, err) - // wait for an update events - // total 3 update at before unlabel point: 1. init ns reconcile 2. ns label reconcile 3. pod status update - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(4)) - - waitForMockCalls() + // wait for 2 more update events (status change + un-annotate) + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(6)) assertPodNotAnnotated(t, client, pod) @@ -477,7 +425,7 @@ func TestJobPodRemovedWhenPodTerminates(t *testing.T) { mock.Anything, util.GetPodIPsIfPresent(pod), "", - ).Return(nil) + ).Once().Return(nil) // Now bring it back // Patch the pod back to a running status @@ -486,8 +434,8 @@ func TestJobPodRemovedWhenPodTerminates(t *testing.T) { types.MergePatchType, phaseRunPatch, metav1.PatchOptions{}) assert.NoError(t, err) - // wait for an update events - mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.AtLeast(5)) + // wait for 2 more update events (status change (again) + re-annotate) + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(8)) assertPodAnnotated(t, client, pod) @@ -495,7 +443,7 @@ func TestJobPodRemovedWhenPodTerminates(t *testing.T) { fs.AssertExpectations(t) } -func TestGetActiveAmbientPodSnapshotOnlyReturnsActivePods(t *testing.T) { +func TestInformerGetActiveAmbientPodSnapshotOnlyReturnsActivePods(t *testing.T) { setupLogging() NodeName = "testnode" @@ -553,7 +501,7 @@ func TestGetActiveAmbientPodSnapshotOnlyReturnsActivePods(t *testing.T) { assert.Equal(t, pods[0], redirectedNotEnrolled) } -func TestGetActiveAmbientPodSnapshotSkipsTerminatedJobPods(t *testing.T) { +func TestInformerGetActiveAmbientPodSnapshotSkipsTerminatedJobPods(t *testing.T) { setupLogging() NodeName = "testnode" @@ -611,7 +559,7 @@ func TestGetActiveAmbientPodSnapshotSkipsTerminatedJobPods(t *testing.T) { assert.Equal(t, len(pods), 0) } -func TestAmbientEnabledReturnsPodIfEnabled(t *testing.T) { +func TestInformerAmbientEnabledReturnsPodIfEnabled(t *testing.T) { setupLogging() NodeName = "testnode" @@ -646,12 +594,12 @@ func TestAmbientEnabledReturnsPodIfEnabled(t *testing.T) { handlers := setupHandlers(ctx, client, server, "istio-system") client.RunAndWait(ctx.Done()) - _, err := handlers.GetPodIfAmbient(pod.Name, ns.Name) + _, err := handlers.GetPodIfAmbientEnabled(pod.Name, ns.Name) assert.NoError(t, err) } -func TestAmbientEnabledReturnsNoPodIfNotEnabled(t *testing.T) { +func TestInformerAmbientEnabledReturnsNoPodIfNotEnabled(t *testing.T) { setupLogging() NodeName = "testnode" @@ -681,19 +629,16 @@ func TestAmbientEnabledReturnsNoPodIfNotEnabled(t *testing.T) { client := kube.NewFakeClient(ns, pod) fs := &fakeServer{} - fs.Start(ctx) - server := getFakeDP(fs, client.Kube()) + handlers, _ := populateClientAndWaitForInformer(ctx, t, client, fs, 2, 1) - handlers := setupHandlers(ctx, client, server, "istio-system") - client.RunAndWait(ctx.Done()) - disabledPod, err := handlers.GetPodIfAmbient(pod.Name, ns.Name) + disabledPod, err := handlers.GetPodIfAmbientEnabled(pod.Name, ns.Name) assert.NoError(t, err) assert.Equal(t, disabledPod, nil) } -func TestAmbientEnabledReturnsErrorIfBogusNS(t *testing.T) { +func TestInformerAmbientEnabledReturnsErrorIfBogusNS(t *testing.T) { setupLogging() NodeName = "testnode" @@ -729,18 +674,15 @@ func TestAmbientEnabledReturnsErrorIfBogusNS(t *testing.T) { handlers := setupHandlers(ctx, client, server, "istio-system") client.RunAndWait(ctx.Done()) - disabledPod, err := handlers.GetPodIfAmbient(pod.Name, "what") + disabledPod, err := handlers.GetPodIfAmbientEnabled(pod.Name, "what") assert.Error(t, err) assert.Equal(t, disabledPod, nil) } -func TestExistingPodAddedWhenItPreExists(t *testing.T) { +func TestInformerExistingPodAddedWhenItPreExists(t *testing.T) { setupLogging() NodeName = "testnode" - - mt := monitortest.New(t) - ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -765,30 +707,189 @@ func TestExistingPodAddedWhenItPreExists(t *testing.T) { client := kube.NewFakeClient(ns, pod) - // We are expecting at most 1 calls to the mock, wait for them - wg, waitForMockCalls := NewWaitForNCalls(t, 1) - fs := &fakeServer{testWG: wg} + fs := &fakeServer{} fs.On("AddPodToMesh", ctx, mock.IsType(pod), util.GetPodIPsIfPresent(pod), "", - ).Return(nil) + ).Once().Return(nil) - server := getFakeDP(fs, client.Kube()) + _, _ = populateClientAndWaitForInformer(ctx, t, client, fs, 2, 2) - handlers := setupHandlers(ctx, client, server, "istio-system") - client.RunAndWait(ctx.Done()) - go handlers.Start() + assertPodAnnotated(t, client, pod) - waitForMockCalls() - // wait until pod add was called - mt.Assert(EventTotals.Name(), map[string]string{"type": "add"}, monitortest.AtLeast(1)) + // check expectations on mocked calls + fs.AssertExpectations(t) +} + +// Double-adds are something we want to guard against - this is because unlike +// Remove operations, there are 2 sources of Adds (potentially) - the CNI plugin +// and the informer. This test is designed to simulate the case where the informer +// gets a stale event for a pod that has already been Added by the CNI plugin. +func TestInformerPendingPodSkippedIfAlreadyLabeledAndEventStale(t *testing.T) { + setupLogging() + NodeName = "testnode" + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "test", + Annotations: map[string]string{annotation.AmbientRedirection.Name: constants.AmbientRedirectionEnabled}, + }, + Spec: corev1.PodSpec{ + NodeName: NodeName, + }, + Status: corev1.PodStatus{ + PodIP: "11.1.1.12", + Phase: corev1.PodPending, + }, + } + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Labels: map[string]string{label.IoIstioDataplaneMode.Name: constants.DataplaneModeAmbient}, + }, + } + + client := kube.NewFakeClient(ns, pod) + + fs := &fakeServer{} + + handlers, mt := populateClientAndWaitForInformer(ctx, t, client, fs, 2, 1) + + // We've started the informer with a Pending pod that has an + // annotation indicating it was already enrolled + + // Now, force thru a stale pod event that lacks that annotation + fakePod := pod.DeepCopy() + fakePod.ObjectMeta.Annotations = map[string]string{} + + fakeEvent := controllers.Event{ + Event: controllers.EventUpdate, + Old: fakePod, + New: fakePod, + } + handlers.reconcile(fakeEvent) + + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(2)) + + // Pod should still be annotated assertPodAnnotated(t, client, pod) - // check expectations on mocked calls + // None of our remove or add mocks should have been called + fs.AssertExpectations(t) +} + +func TestInformerSkipsUpdateEventIfPodNotActuallyPresentAnymore(t *testing.T) { + setupLogging() + NodeName = "testnode" + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + fakePod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "test", + Annotations: map[string]string{annotation.AmbientRedirection.Name: constants.AmbientRedirectionEnabled}, + }, + Spec: corev1.PodSpec{ + NodeName: NodeName, + }, + Status: corev1.PodStatus{ + PodIP: "11.1.1.12", + Phase: corev1.PodPending, + }, + } + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Labels: map[string]string{label.IoIstioDataplaneMode.Name: constants.DataplaneModeAmbient}, + }, + } + + client := kube.NewFakeClient(ns) + + fs := &fakeServer{} + + handlers, mt := populateClientAndWaitForInformer(ctx, t, client, fs, 1, 0) + + // Now, force thru a stale pod update event that would normally trigger add/remove + // in the informer if the pod existed + fakePodNew := fakePod.DeepCopy() + fakePodNew.ObjectMeta.Annotations = map[string]string{} + // We've started the informer, but there is no pod in the cluster. + // Now force thru a "stale" event for an enrolled pod no longer in the cluster. + fakeEvent := controllers.Event{ + Event: controllers.EventUpdate, + Old: fakePod, + New: fakePodNew, + } + handlers.reconcile(fakeEvent) + + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(1)) + + // None of our remove or add mocks should have been called + fs.AssertExpectations(t) +} + +func TestInformerStillHandlesDeleteEventIfPodNotActuallyPresentAnymore(t *testing.T) { + setupLogging() + NodeName = "testnode" + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + fakePod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "test", + Annotations: map[string]string{annotation.AmbientRedirection.Name: constants.AmbientRedirectionEnabled}, + }, + Spec: corev1.PodSpec{ + NodeName: NodeName, + }, + Status: corev1.PodStatus{ + PodIP: "11.1.1.12", + Phase: corev1.PodPending, + }, + } + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Labels: map[string]string{label.IoIstioDataplaneMode.Name: constants.DataplaneModeAmbient}, + }, + } + + client := kube.NewFakeClient(ns) + + fs := &fakeServer{} + + // Pod deletion event should trigger one RemovePodFromMesh, even if the pod doesn't exist anymore + fs.On("RemovePodFromMesh", + ctx, + mock.Anything, + true, + ).Once().Return(nil) + + handlers, mt := populateClientAndWaitForInformer(ctx, t, client, fs, 1, 0) + + // Now, force thru a pod delete + fakePodNew := fakePod.DeepCopy() + fakePodNew.ObjectMeta.Annotations = map[string]string{} + // We've started the informer, but there is no pod in the cluster. + // Now force thru a "stale" event for an enrolled pod no longer in the cluster. + fakeEvent := controllers.Event{ + Event: controllers.EventDelete, + Old: fakePod, + New: nil, + } + handlers.reconcile(fakeEvent) + + mt.Assert(EventTotals.Name(), map[string]string{"type": "delete"}, monitortest.Exactly(1)) + fs.AssertExpectations(t) } @@ -819,3 +920,24 @@ func assertPodNotAnnotated(t *testing.T, client kube.Client, pod *corev1.Pod) { } t.Fatal("Pod annotated") } + +// nolint: lll +func populateClientAndWaitForInformer(ctx context.Context, t *testing.T, client kube.Client, fs *fakeServer, expectAddEvents, expectUpdateEvents int) (*InformerHandlers, *monitortest.MetricsTest) { + mt := monitortest.New(t) + + server := getFakeDP(fs, client.Kube()) + + handlers := setupHandlers(ctx, client, server, "istio-system") + client.RunAndWait(ctx.Done()) + go handlers.Start() + + // Unfortunately mt asserts cannot assert on 0 events (which makes a certain amount of sense) + if expectAddEvents > 0 { + mt.Assert(EventTotals.Name(), map[string]string{"type": "add"}, monitortest.Exactly(float64(expectAddEvents))) + } + if expectUpdateEvents > 0 { + mt.Assert(EventTotals.Name(), map[string]string{"type": "update"}, monitortest.Exactly(float64(expectUpdateEvents))) + } + + return handlers, mt +} diff --git a/cni/pkg/nodeagent/net.go b/cni/pkg/nodeagent/net.go index b9a150e3bfab..bca859def0f4 100644 --- a/cni/pkg/nodeagent/net.go +++ b/cni/pkg/nodeagent/net.go @@ -20,6 +20,7 @@ import ( "fmt" "net/netip" "strconv" + "strings" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -57,7 +58,7 @@ func (s *NetServer) Start(ctx context.Context) { go s.ztunnelServer.Run(ctx) } -func (s *NetServer) Stop() { +func (s *NetServer) Stop(_ bool) { log.Debug("stopping ztunnel server") s.ztunnelServer.Close() } @@ -127,22 +128,11 @@ func (s *NetServer) AddPodToMesh(ctx context.Context, pod *corev1.Pod, podIPs [] return err } - // If true, the pod will run in 'ingress mode'. This is intended to be used for "ingress" type workloads which handle - // non-mesh traffic on inbound, and send to the mesh on outbound. - // Basically, this just disables inbound redirection. - // We use the SidecarTrafficExcludeInboundPorts annotation for compatibility (its somewhat widely used) but don't support all values. - ingressMode := false - if a, f := pod.Annotations[annotation.AmbientBypassInboundCapture.Name]; f { - var err error - ingressMode, err = strconv.ParseBool(a) - if err != nil { - log.Warnf("annotation %v=%q found, but only '*' is supported", annotation.AmbientBypassInboundCapture.Name, a) - } - } + podCfg := getPodLevelTrafficOverrides(pod) log.Debug("calling CreateInpodRules") if err := s.netnsRunner(openNetns, func() error { - return s.podIptables.CreateInpodRules(log, HostProbeSNATIP, HostProbeSNATIPV6, ingressMode) + return s.podIptables.CreateInpodRules(log, podCfg) }); err != nil { log.Errorf("failed to update POD inpod: %s/%s %v", pod.Namespace, pod.Name, err) return err @@ -204,19 +194,43 @@ func (s *NetServer) scanProcForPodsAndCache(pods map[types.UID]*corev1.Pod) erro return nil } +func getPodLevelTrafficOverrides(pod *corev1.Pod) iptables.PodLevelOverrides { + // If true, the pod will run in 'ingress mode'. This is intended to be used for "ingress" type workloads which handle + // non-mesh traffic on inbound, and send to the mesh on outbound. + // Basically, this just disables inbound redirection. + podCfg := iptables.PodLevelOverrides{IngressMode: false} + if a, f := pod.Annotations[annotation.AmbientBypassInboundCapture.Name]; f { + var err error + podCfg.IngressMode, err = strconv.ParseBool(a) + if err != nil { + log.Warnf("annotation %v=%q found, but only '*' is supported", annotation.AmbientBypassInboundCapture.Name, a) + } + } + + if virt, hasVirt := pod.Annotations[annotation.IoIstioRerouteVirtualInterfaces.Name]; hasVirt { + virtInterfaces := strings.Split(virt, ",") + for _, splitVirt := range virtInterfaces { + trim := strings.TrimSpace(splitVirt) + if trim != "" { + podCfg.VirtualInterfaces = append(podCfg.VirtualInterfaces, trim) + } + } + } + + return podCfg +} + func realDependenciesHost() *dep.RealDependencies { return &dep.RealDependencies{ - // We are in the host FS *and* the Host network - HostFilesystemPodNetwork: false, - NetworkNamespace: "", + UsePodScopedXtablesLock: false, + NetworkNamespace: "", } } -func realDependenciesInpod() *dep.RealDependencies { +func realDependenciesInpod(useScopedLocks bool) *dep.RealDependencies { return &dep.RealDependencies{ - // We are running the host FS, but the pod network -- setup rules differently (locking, etc) - HostFilesystemPodNetwork: true, - NetworkNamespace: "", + UsePodScopedXtablesLock: useScopedLocks, + NetworkNamespace: "", } } @@ -239,7 +253,7 @@ func (s *NetServer) RemovePodFromMesh(ctx context.Context, pod *corev1.Pod, isDe if openNetns != nil { // pod is removed from the mesh, but is still running. remove iptables rules log.Debugf("calling DeleteInpodRules") - if err := s.netnsRunner(openNetns, func() error { return s.podIptables.DeleteInpodRules() }); err != nil { + if err := s.netnsRunner(openNetns, func() error { return s.podIptables.DeleteInpodRules(log) }); err != nil { return fmt.Errorf("failed to delete inpod rules: %w", err) } } else { diff --git a/cni/pkg/nodeagent/net_test.go b/cni/pkg/nodeagent/net_test.go index 14b4ab6b32f8..107a83eea4e7 100644 --- a/cni/pkg/nodeagent/net_test.go +++ b/cni/pkg/nodeagent/net_test.go @@ -54,7 +54,7 @@ type netTestFixture struct { func getTestFixure(ctx context.Context) netTestFixture { podNsMap := newPodNetnsCache(openNsTestOverride) nlDeps := &fakeIptablesDeps{} - iptablesConfigurator, _, _ := iptables.NewIptablesConfigurator(nil, &dependencies.DependenciesStub{}, &dependencies.DependenciesStub{}, nlDeps) + iptablesConfigurator, _, _ := iptables.NewIptablesConfigurator(nil, nil, &dependencies.DependenciesStub{}, &dependencies.DependenciesStub{}, nlDeps) ztunnelServer := &fakeZtunnel{} diff --git a/cni/pkg/nodeagent/options.go b/cni/pkg/nodeagent/options.go index e9ffe0d4c256..8605a60fb2af 100644 --- a/cni/pkg/nodeagent/options.go +++ b/cni/pkg/nodeagent/options.go @@ -22,13 +22,14 @@ import ( ) var ( - PodNamespace = env.RegisterStringVar("POD_NAMESPACE", "", "pod's namespace").Get() - SystemNamespace = env.RegisterStringVar("SYSTEM_NAMESPACE", constants.IstioSystemNamespace, "istio system namespace").Get() - PodName = env.RegisterStringVar("POD_NAME", "", "").Get() - NodeName = env.RegisterStringVar("NODE_NAME", "", "").Get() - Revision = env.RegisterStringVar("REVISION", "", "").Get() - HostProbeSNATIP = netip.MustParseAddr(env.RegisterStringVar("HOST_PROBE_SNAT_IP", DefaultHostProbeSNATIP, "").Get()) - HostProbeSNATIPV6 = netip.MustParseAddr(env.RegisterStringVar("HOST_PROBE_SNAT_IPV6", DefaultHostProbeSNATIPV6, "").Get()) + PodNamespace = env.RegisterStringVar("POD_NAMESPACE", "", "pod's namespace").Get() + SystemNamespace = env.RegisterStringVar("SYSTEM_NAMESPACE", constants.IstioSystemNamespace, "istio system namespace").Get() + PodName = env.RegisterStringVar("POD_NAME", "", "").Get() + NodeName = env.RegisterStringVar("NODE_NAME", "", "").Get() + Revision = env.RegisterStringVar("REVISION", "", "").Get() + HostProbeSNATIP = netip.MustParseAddr(env.RegisterStringVar("HOST_PROBE_SNAT_IP", DefaultHostProbeSNATIP, "").Get()) + HostProbeSNATIPV6 = netip.MustParseAddr(env.RegisterStringVar("HOST_PROBE_SNAT_IPV6", DefaultHostProbeSNATIPV6, "").Get()) + UseScopedIptablesLegacyLocking = env.RegisterBoolVar("AMBIENT_USE_SCOPED_XTABLES_LOCKING", true, "").Get() ) const ( @@ -44,11 +45,11 @@ const ( ) type AmbientArgs struct { - SystemNamespace string - Revision string - KubeConfig string - ServerSocket string - DNSCapture bool - EnableIPv6 bool - TPROXYRedirection bool + SystemNamespace string + Revision string + KubeConfig string + ServerSocket string + DNSCapture bool + EnableIPv6 bool + ReconcilePodRulesOnStartup bool } diff --git a/cni/pkg/nodeagent/podcgroupns_test.go b/cni/pkg/nodeagent/podcgroupns_test.go index f13fa5e80aa6..fe2e50dfd1ce 100644 --- a/cni/pkg/nodeagent/podcgroupns_test.go +++ b/cni/pkg/nodeagent/podcgroupns_test.go @@ -133,7 +133,6 @@ func TestGetContainerIDFromCGroups(t *testing.T) { expectMsg: "multiple pod UIDs found in cgroups (11111111-b29f-11e7-9350-020968147796, 22222222-b29f-11e7-9350-020968147796)", }, } { - tt := tt t.Run(tt.name, func(t *testing.T) { podUID, containerID, err := getPodUIDAndContainerIDFromCGroups(makeCGroups(tt.cgroupPaths)) diff --git a/cni/pkg/nodeagent/server.go b/cni/pkg/nodeagent/server.go index 05087f2f158c..9a13aa7f9c8e 100644 --- a/cni/pkg/nodeagent/server.go +++ b/cni/pkg/nodeagent/server.go @@ -25,6 +25,7 @@ import ( "golang.org/x/sys/unix" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -44,11 +45,10 @@ type MeshDataplane interface { ConstructInitialSnapshot(ambientPods []*corev1.Pod) error Start(ctx context.Context) - // IsPodInMesh(ctx context.Context, pod *metav1.ObjectMeta, netNs string) (bool, error) AddPodToMesh(ctx context.Context, pod *corev1.Pod, podIPs []netip.Addr, netNs string) error RemovePodFromMesh(ctx context.Context, pod *corev1.Pod, isDelete bool) error - Stop() + Stop(skipCleanup bool) } type Server struct { @@ -69,14 +69,23 @@ func NewServer(ctx context.Context, ready *atomic.Value, pluginSocket string, ar return nil, fmt.Errorf("error initializing kube client: %w", err) } - cfg := &iptables.Config{ - RedirectDNS: args.DNSCapture, - EnableIPv6: args.EnableIPv6, - TPROXYRedirection: args.TPROXYRedirection, + hostCfg := &iptables.IptablesConfig{ + RedirectDNS: args.DNSCapture, + EnableIPv6: args.EnableIPv6, + HostProbeSNATAddress: HostProbeSNATIP, + HostProbeV6SNATAddress: HostProbeSNATIPV6, + } + + podCfg := &iptables.IptablesConfig{ + RedirectDNS: args.DNSCapture, + EnableIPv6: args.EnableIPv6, + HostProbeSNATAddress: HostProbeSNATIP, + HostProbeV6SNATAddress: HostProbeSNATIPV6, + Reconcile: args.ReconcilePodRulesOnStartup, } log.Debug("creating ipsets in the node netns") - set, err := createHostsideProbeIpset(cfg.EnableIPv6) + set, err := createHostsideProbeIpset(hostCfg.EnableIPv6) if err != nil { return nil, fmt.Errorf("error initializing hostside probe ipset: %w", err) } @@ -87,7 +96,13 @@ func NewServer(ctx context.Context, ready *atomic.Value, pluginSocket string, ar return nil, fmt.Errorf("error initializing the ztunnel server: %w", err) } - hostIptables, podIptables, err := iptables.NewIptablesConfigurator(cfg, realDependenciesHost(), realDependenciesInpod(), iptables.RealNlDeps()) + hostIptables, podIptables, err := iptables.NewIptablesConfigurator( + hostCfg, + podCfg, + realDependenciesHost(), + realDependenciesInpod(UseScopedIptablesLegacyLocking), + iptables.RealNlDeps(), + ) if err != nil { return nil, fmt.Errorf("error configuring iptables: %w", err) } @@ -95,7 +110,7 @@ func NewServer(ctx context.Context, ready *atomic.Value, pluginSocket string, ar // Create hostprobe rules now, in the host netns hostIptables.DeleteHostRules() - if err := hostIptables.CreateHostRulesForHealthChecks(&HostProbeSNATIP, &HostProbeSNATIPV6); err != nil { + if err := hostIptables.CreateHostRulesForHealthChecks(); err != nil { return nil, fmt.Errorf("error initializing the host rules for health checks: %w", err) } @@ -184,9 +199,23 @@ func (s *Server) Start() { s.handlers.Start() } -func (s *Server) Stop() { +func (s *Server) Stop(skipCleanup bool) { s.cniServerStopFunc() - s.dataplane.Stop() + s.dataplane.Stop(skipCleanup) +} + +func (s *Server) ShouldStopForUpgrade(selfName, selfNamespace string) bool { + dsName := fmt.Sprintf("%s-node", selfName) + cniDS, err := s.kubeClient.Kube().AppsV1().DaemonSets(selfNamespace).Get(context.Background(), dsName, metav1.GetOptions{}) + log.Debugf("Daemonset %s has deletion timestamp?: %+v", dsName, cniDS.DeletionTimestamp) + if err == nil && cniDS != nil && cniDS.DeletionTimestamp == nil { + log.Infof("terminating, but parent DS %s is still present, this is an upgrade, leaving plugin in place", dsName) + return true + } + + // If the DS is gone, it's definitely not an upgrade, so carry on like normal. + log.Infof("parent DS %s is gone or marked for deletion, this is not an upgrade, shutting down normally %s", dsName, err) + return false } type meshDataplane struct { @@ -200,19 +229,24 @@ func (s *meshDataplane) Start(ctx context.Context) { s.netServer.Start(ctx) } -func (s *meshDataplane) Stop() { - log.Info("CNI ambient server terminating, cleaning up node net rules") +func (s *meshDataplane) Stop(skipCleanup bool) { + // Remove host rules (or not) that allow pod healthchecks to work. + // These are not critical but if they are not in place pods that have + // already been captured will eventually start to fail kubelet healthchecks. + if !skipCleanup { + log.Info("CNI ambient server terminating, cleaning up node net rules") - log.Debug("removing host iptables rules") - s.hostIptables.DeleteHostRules() + log.Debug("removing host iptables rules") + s.hostIptables.DeleteHostRules() - log.Debug("destroying host ipset") - s.hostsideProbeIPSet.Flush() - if err := s.hostsideProbeIPSet.DestroySet(); err != nil { - log.Warnf("could not destroy host ipset on shutdown") + log.Debug("destroying host ipset") + s.hostsideProbeIPSet.Flush() + if err := s.hostsideProbeIPSet.DestroySet(); err != nil { + log.Warnf("could not destroy host ipset on shutdown") + } } - s.netServer.Stop() + s.netServer.Stop(skipCleanup) } func (s *meshDataplane) ConstructInitialSnapshot(ambientPods []*corev1.Pod) error { @@ -225,6 +259,12 @@ func (s *meshDataplane) ConstructInitialSnapshot(ambientPods []*corev1.Pod) erro } func (s *meshDataplane) AddPodToMesh(ctx context.Context, pod *corev1.Pod, podIPs []netip.Addr, netNs string) error { + // Ordering is important in this func: + // + // - Inject rules and add to ztunnel FIRST + // - Annotate IF rule injection doesn't fail. + // - Add pod IP to ipset IF none of the above has failed, as a last step + log := log.WithLabels("ns", pod.Namespace, "name", pod.Name) var retErr error err := s.netServer.AddPodToMesh(ctx, pod, podIPs, netNs) if err != nil { @@ -235,7 +275,7 @@ func (s *meshDataplane) AddPodToMesh(ctx context.Context, pod *corev1.Pod, podIP retErr = err } - log.Debugf("annotating pod %s", pod.Name) + log.Debugf("annotating pod") if err := util.AnnotateEnrolledPod(s.kubeClient, &pod.ObjectMeta); err != nil { log.Errorf("failed to annotate pod enrollment: %v", err) retErr = err @@ -260,11 +300,11 @@ func (s *meshDataplane) AddPodToMesh(ctx context.Context, pod *corev1.Pod, podIP // Handle node healthcheck probe rewrites _, err = s.addPodToHostNSIpset(pod, podIPs) if err != nil { - log.Errorf("failed to add pod to ipset: %s/%s %v", pod.Namespace, pod.Name, err) + log.Errorf("failed to add pod to ipset: %v", err) return err } } else { - log.Errorf("pod: %s/%s was not enrolled and is unhealthy: %v", pod.Namespace, pod.Name, retErr) + log.Errorf("pod was not enrolled and is unhealthy: %v", retErr) } return retErr @@ -272,6 +312,7 @@ func (s *meshDataplane) AddPodToMesh(ctx context.Context, pod *corev1.Pod, podIP func (s *meshDataplane) RemovePodFromMesh(ctx context.Context, pod *corev1.Pod, isDelete bool) error { log := log.WithLabels("ns", pod.Namespace, "name", pod.Name) + log.WithLabels("deleted", isDelete).Info("removing pod from mesh") // Aggregate errors together, so that if part of the removal fails we still proceed with other steps. var errs []error @@ -335,12 +376,28 @@ func (s *meshDataplane) syncHostIPSets(ambientPods []*corev1.Pod) error { // 3. update ipsets accordingly // 4. return the ones we added successfully, and errors for any we couldn't (dupes) // -// Dupe IPs should be considered an IPAM error and should never happen. +// For each set (v4, v6), each pod IP can appear exactly once. +// +// Note that for adds, because we have 2 potential sources of async adds (CNI plugin and informer) +// we want this to be an upsert. +// +// This is important to make sure reconciliation and overlapping events do not cause problems - +// adds can come from two sources, but removes can only come from one source (informer). +// +// Ex: +// Pod UID "A", IP 1.1.1.1 +// Pod UID "B", IP 1.1.1.1 +// +// Add for UID "B", IP 1.1.1.1 is handled before Remove for UID "A", IP 1.1.1.1 +// -> we no longer have an entry for either, which is bad (pod fails healthchecks) +// +// So "add" always overwrites, and remove only removes if the pod IP AND the pod UID match. func (s *meshDataplane) addPodToHostNSIpset(pod *corev1.Pod, podIPs []netip.Addr) ([]netip.Addr, error) { // Add the pod UID as an ipset entry comment, so we can (more) easily find and delete // all relevant entries for a pod later. podUID := string(pod.ObjectMeta.UID) ipProto := uint8(unix.IPPROTO_TCP) + log := log.WithLabels("ns", pod.Namespace, "name", pod.Name, "podUID", podUID, "ipset", s.hostsideProbeIPSet.Prefix) var ipsetAddrErrs []error var addedIps []netip.Addr @@ -348,19 +405,15 @@ func (s *meshDataplane) addPodToHostNSIpset(pod *corev1.Pod, podIPs []netip.Addr // For each pod IP for _, pip := range podIPs { // Add to host ipset - log.Debugf("adding pod %s probe to ipset %s with ip %s", pod.Name, s.hostsideProbeIPSet.Prefix, pip) + log.Debugf("adding probe ip %s to set", pip) // Add IP/port combo to set. Note that we set Replace to false here - we _did_ previously // set it to true, but in theory that could mask weird scenarios where K8S triggers events out of order -> // an add(sameIPreused) then delete(originalIP). // Which will result in the new pod starting to fail healthchecks. - // - // Since we purge on restart of CNI, and remove pod IPs from the set on every pod removal/deletion, - // we _shouldn't_ get any overwrite/overlap, unless something is wrong and we are asked to add - // a pod by an IP we already have in the set (which will give an error, which we want). - if err := s.hostsideProbeIPSet.AddIP(pip, ipProto, podUID, false); err != nil { + if err := s.hostsideProbeIPSet.AddIP(pip, ipProto, podUID, true); err != nil { ipsetAddrErrs = append(ipsetAddrErrs, err) - log.Errorf("failed adding pod %s to ipset %s with ip %s, error was %s", - pod.Name, &s.hostsideProbeIPSet.Prefix, pip, err) + log.Errorf("failed adding ip %s to set, error was %s", + pod.Name, &s.hostsideProbeIPSet.Prefix, pip, podUID, err) } else { addedIps = append(addedIps, pip) } @@ -369,13 +422,21 @@ func (s *meshDataplane) addPodToHostNSIpset(pod *corev1.Pod, podIPs []netip.Addr return addedIps, errors.Join(ipsetAddrErrs...) } +// removePodFromHostNSIpset will remove (v4, v6) pod IPs from the host IP set(s). +// Note that unlike when we add the IP to the set, on removal we will simply +// skip removing the IP if the IP matches, but the UID comment does not match our pod. func removePodFromHostNSIpset(pod *corev1.Pod, hostsideProbeSet *ipset.IPSet) error { + podUID := string(pod.ObjectMeta.UID) + log := log.WithLabels("ns", pod.Namespace, "name", pod.Name, "podUID", podUID, "ipset", hostsideProbeSet.Prefix) + podIPs := util.GetPodIPsIfPresent(pod) for _, pip := range podIPs { - if err := hostsideProbeSet.ClearEntriesWithIP(pip); err != nil { + if uidMismatch, err := hostsideProbeSet.ClearEntriesWithIPAndComment(pip, podUID); err != nil { return err + } else if uidMismatch != "" { + log.Warnf("pod ip %s could not be removed from ipset, found entry with pod UID %s instead", pip, uidMismatch) } - log.Debugf("removed pod name %s with UID %s from host ipset %s by ip %s", pod.Name, pod.UID, hostsideProbeSet.Prefix, pip) + log.Debugf("removed pod from host ipset by ip %s", pip) } return nil diff --git a/cni/pkg/nodeagent/server_test.go b/cni/pkg/nodeagent/server_test.go index 821fcb23ab9c..aae1ce67021a 100644 --- a/cni/pkg/nodeagent/server_test.go +++ b/cni/pkg/nodeagent/server_test.go @@ -178,7 +178,7 @@ func TestMeshDataplaneRemovePodRemovesAnnotation(t *testing.T) { set := ipset.IPSet{V4Name: "foo-v4", Prefix: "foo", Deps: fakeIPSetDeps} m := getFakeDPWithIPSet(server, fakeClientSet, set) - expectPodRemovedFromIPSet(fakeIPSetDeps, pod.Status.PodIPs) + expectPodRemovedFromIPSet(fakeIPSetDeps, string(pod.ObjectMeta.UID), pod.Status.PodIPs) err := m.RemovePodFromMesh(fakeCtx, pod, false) assert.NoError(t, err) @@ -208,7 +208,7 @@ func TestMeshDataplaneRemovePodErrorDoesntRemoveAnnotation(t *testing.T) { set := ipset.IPSet{V4Name: "foo-v4", Prefix: "foo", Deps: fakeIPSetDeps} m := getFakeDPWithIPSet(server, fakeClientSet, set) - expectPodRemovedFromIPSet(fakeIPSetDeps, pod.Status.PodIPs) + expectPodRemovedFromIPSet(fakeIPSetDeps, string(pod.ObjectMeta.UID), pod.Status.PodIPs) err := m.RemovePodFromMesh(fakeCtx, pod, false) assert.Error(t, err) @@ -238,7 +238,7 @@ func TestMeshDataplaneDelPod(t *testing.T) { fakeIPSetDeps := ipset.FakeNLDeps() set := ipset.IPSet{V4Name: "foo-v4", Prefix: "foo", Deps: fakeIPSetDeps} m := getFakeDPWithIPSet(server, fakeClientSet, set) - expectPodRemovedFromIPSet(fakeIPSetDeps, pod.Status.PodIPs) + expectPodRemovedFromIPSet(fakeIPSetDeps, string(pod.ObjectMeta.UID), pod.Status.PodIPs) // pod is not in fake client, so if this will try to remove annotation, it will fail. err := m.RemovePodFromMesh(fakeCtx, pod, true) @@ -267,7 +267,7 @@ func TestMeshDataplaneDelPodErrorDoesntPatchPod(t *testing.T) { set := ipset.IPSet{V4Name: "foo-v4", Prefix: "foo", Deps: fakeIPSetDeps} m := getFakeDPWithIPSet(server, fakeClientSet, set) - expectPodRemovedFromIPSet(fakeIPSetDeps, pod.Status.PodIPs) + expectPodRemovedFromIPSet(fakeIPSetDeps, string(pod.ObjectMeta.UID), pod.Status.PodIPs) // pod is not in fake client, so if this will try to remove annotation, it will fail. err := m.RemovePodFromMesh(fakeCtx, pod, true) @@ -297,7 +297,7 @@ func TestMeshDataplaneAddPodToHostNSIPSets(t *testing.T) { netip.MustParseAddr("99.9.9.9"), ipProto, podUID, - false, + true, ).Return(nil) fakeIPSetDeps.On("addIP", @@ -305,7 +305,7 @@ func TestMeshDataplaneAddPodToHostNSIPSets(t *testing.T) { netip.MustParseAddr("2.2.2.2"), ipProto, podUID, - false, + true, ).Return(nil) podIPs := []netip.Addr{netip.MustParseAddr("99.9.9.9"), netip.MustParseAddr("2.2.2.2")} @@ -335,7 +335,7 @@ func TestMeshDataplaneAddPodToHostNSIPSetsV6(t *testing.T) { netip.MustParseAddr("e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3164"), ipProto, podUID, - false, + true, ).Return(nil) fakeIPSetDeps.On("addIP", @@ -343,7 +343,7 @@ func TestMeshDataplaneAddPodToHostNSIPSetsV6(t *testing.T) { netip.MustParseAddr("e9ac:1e77:90ca:399f:4d6d:ece2:2f9b:3165"), ipProto, podUID, - false, + true, ).Return(nil) podIPs := []netip.Addr{netip.MustParseAddr(pod.Status.PodIPs[0].IP), netip.MustParseAddr(pod.Status.PodIPs[1].IP)} @@ -373,7 +373,7 @@ func TestMeshDataplaneAddPodToHostNSIPSetsDualstack(t *testing.T) { netip.MustParseAddr("e9ac:1e77:90ca:399f:4d6d:ece3:2f9b:3162"), ipProto, podUID, - false, + true, ).Return(nil) fakeIPSetDeps.On("addIP", @@ -381,7 +381,7 @@ func TestMeshDataplaneAddPodToHostNSIPSetsDualstack(t *testing.T) { netip.MustParseAddr("99.9.9.9"), ipProto, podUID, - false, + true, ).Return(nil) podIPs := []netip.Addr{netip.MustParseAddr("e9ac:1e77:90ca:399f:4d6d:ece3:2f9b:3162"), netip.MustParseAddr("99.9.9.9")} @@ -411,7 +411,7 @@ func TestMeshDataplaneAddPodIPToHostNSIPSetsReturnsErrorIfOneFails(t *testing.T) netip.MustParseAddr("99.9.9.9"), ipProto, podUID, - false, + true, ).Return(nil) fakeIPSetDeps.On("addIP", @@ -419,7 +419,7 @@ func TestMeshDataplaneAddPodIPToHostNSIPSetsReturnsErrorIfOneFails(t *testing.T) netip.MustParseAddr("2.2.2.2"), ipProto, podUID, - false, + true, ).Return(errors.New("bwoah")) podIPs := []netip.Addr{netip.MustParseAddr("99.9.9.9"), netip.MustParseAddr("2.2.2.2")} @@ -436,15 +436,40 @@ func TestMeshDataplaneRemovePodIPFromHostNSIPSets(t *testing.T) { fakeIPSetDeps := ipset.FakeNLDeps() set := ipset.IPSet{V4Name: "foo-v4", Prefix: "foo", Deps: fakeIPSetDeps} - fakeIPSetDeps.On("clearEntriesWithIP", + fakeIPSetDeps.On("clearEntriesWithIPAndComment", "foo-v4", netip.MustParseAddr("3.3.3.3"), - ).Return(nil) + string(pod.ObjectMeta.UID), + ).Return("", nil) - fakeIPSetDeps.On("clearEntriesWithIP", + fakeIPSetDeps.On("clearEntriesWithIPAndComment", "foo-v4", netip.MustParseAddr("2.2.2.2"), - ).Return(nil) + string(pod.ObjectMeta.UID), + ).Return("", nil) + + err := removePodFromHostNSIpset(pod, &set) + assert.NoError(t, err) + fakeIPSetDeps.AssertExpectations(t) +} + +func TestMeshDataplaneRemovePodIPFromHostNSIPSetsIgnoresEntriesWithMismatchedUIDs(t *testing.T) { + pod := buildConvincingPod(false) + + fakeIPSetDeps := ipset.FakeNLDeps() + set := ipset.IPSet{V4Name: "foo-v4", Prefix: "foo", Deps: fakeIPSetDeps} + + fakeIPSetDeps.On("clearEntriesWithIPAndComment", + "foo-v4", + netip.MustParseAddr("3.3.3.3"), + string(pod.ObjectMeta.UID), + ).Return("mismatched-uid", nil) + + fakeIPSetDeps.On("clearEntriesWithIPAndComment", + "foo-v4", + netip.MustParseAddr("2.2.2.2"), + string(pod.ObjectMeta.UID), + ).Return("mismatched-uid", nil) err := removePodFromHostNSIpset(pod, &set) assert.NoError(t, err) @@ -472,7 +497,7 @@ func TestMeshDataplaneSyncHostIPSetsPrunesNothingIfNoExtras(t *testing.T) { netip.MustParseAddr("3.3.3.3"), ipProto, podUID, - false, + true, ).Return(nil) fakeIPSetDeps.On("addIP", @@ -480,7 +505,7 @@ func TestMeshDataplaneSyncHostIPSetsPrunesNothingIfNoExtras(t *testing.T) { netip.MustParseAddr("2.2.2.2"), ipProto, podUID, - false, + true, ).Return(nil) fakeIPSetDeps.On("listEntriesByIP", @@ -518,7 +543,7 @@ func TestMeshDataplaneSyncHostIPSetsIgnoresPodIPAddErrorAndContinues(t *testing. netip.MustParseAddr("3.3.3.3"), ipProto, pod1UID, - false, + true, ).Return(errors.New("CANNOT ADD")) fakeIPSetDeps.On("addIP", @@ -526,7 +551,7 @@ func TestMeshDataplaneSyncHostIPSetsIgnoresPodIPAddErrorAndContinues(t *testing. netip.MustParseAddr("2.2.2.2"), ipProto, pod1UID, - false, + true, ).Return(nil) fakeIPSetDeps.On("addIP", @@ -534,7 +559,7 @@ func TestMeshDataplaneSyncHostIPSetsIgnoresPodIPAddErrorAndContinues(t *testing. netip.MustParseAddr("3.3.3.3"), ipProto, pod2UID, - false, + true, ).Return(errors.New("CANNOT ADD")) fakeIPSetDeps.On("addIP", @@ -542,7 +567,7 @@ func TestMeshDataplaneSyncHostIPSetsIgnoresPodIPAddErrorAndContinues(t *testing. netip.MustParseAddr("2.2.2.2"), ipProto, pod2UID, - false, + true, ).Return(nil) fakeIPSetDeps.On("listEntriesByIP", @@ -599,7 +624,7 @@ func TestMeshDataplaneSyncHostIPSetsPrunesIfExtras(t *testing.T) { netip.MustParseAddr("3.3.3.3"), ipProto, podUID, - false, + true, ).Return(nil) fakeIPSetDeps.On("addIP", @@ -607,7 +632,7 @@ func TestMeshDataplaneSyncHostIPSetsPrunesIfExtras(t *testing.T) { netip.MustParseAddr("2.2.2.2"), ipProto, podUID, - false, + true, ).Return(nil) // List should return one IP not in our "pod snapshot", which means we prune @@ -666,7 +691,7 @@ func (f *fakeServer) RemovePodFromMesh(ctx context.Context, pod *corev1.Pod, isD func (f *fakeServer) Start(ctx context.Context) { } -func (f *fakeServer) Stop() { +func (f *fakeServer) Stop(_ bool) { } func (f *fakeServer) ConstructInitialSnapshot(ambientPods []*corev1.Pod) error { @@ -731,16 +756,17 @@ func expectPodAddedToIPSet(ipsetDeps *ipset.MockedIpsetDeps, podIP netip.Addr, p podIP, uint8(unix.IPPROTO_TCP), string(podMeta.UID), - false, + true, ).Return(nil) } -func expectPodRemovedFromIPSet(ipsetDeps *ipset.MockedIpsetDeps, podIPs []corev1.PodIP) { +func expectPodRemovedFromIPSet(ipsetDeps *ipset.MockedIpsetDeps, podUID string, podIPs []corev1.PodIP) { for _, ip := range podIPs { - ipsetDeps.On("clearEntriesWithIP", + ipsetDeps.On("clearEntriesWithIPAndComment", "foo-v4", netip.MustParseAddr(ip.IP), - ).Return(nil) + podUID, + ).Return("", nil) } } @@ -763,7 +789,7 @@ func getFakeDP(fs *fakeServer, fakeClient kubernetes.Interface) *meshDataplane { mock.Anything, ).Return(nil).Maybe() - fakeIPSetDeps.On("clearEntriesWithIP", mock.Anything, mock.Anything).Return(nil).Maybe() + fakeIPSetDeps.On("clearEntriesWithIPAndComment", mock.Anything, mock.Anything, mock.Anything).Return("", nil).Maybe() fakeSet := ipset.IPSet{V4Name: "foo-v4", Prefix: "foo", Deps: fakeIPSetDeps} return getFakeDPWithIPSet(fs, fakeClient, fakeSet) diff --git a/cni/pkg/nodeagent/ztunnelserver.go b/cni/pkg/nodeagent/ztunnelserver.go index c18591e39e19..cfedac1f2198 100644 --- a/cni/pkg/nodeagent/ztunnelserver.go +++ b/cni/pkg/nodeagent/ztunnelserver.go @@ -327,6 +327,7 @@ func (z *ztunnelServer) PodAdded(ctx context.Context, pod *v1.Pod, netns Netns) if err != nil { return err } + log.Debug("sent pod add to ztunnel") if resp.GetAck().GetError() != "" { log.Errorf("failed to add workload: %s", resp.GetAck().GetError()) diff --git a/cni/pkg/plugin/sidecar_iptables_linux.go b/cni/pkg/plugin/sidecar_iptables_linux.go index 31a8d0f37cb4..625d687bec4c 100644 --- a/cni/pkg/plugin/sidecar_iptables_linux.go +++ b/cni/pkg/plugin/sidecar_iptables_linux.go @@ -47,7 +47,7 @@ func (ipt *iptables) Program(podName, netns string, rdrct *Redirect) error { cfg.OutboundPortsExclude = rdrct.excludeOutboundPorts cfg.OutboundPortsInclude = rdrct.includeOutboundPorts cfg.OutboundIPRangesExclude = rdrct.excludeIPCidrs - cfg.KubeVirtInterfaces = rdrct.kubevirtInterfaces + cfg.RerouteVirtualInterfaces = rdrct.rerouteVirtualInterfaces cfg.DryRun = dependencies.DryRunFilePath.Get() != "" cfg.RedirectDNS = rdrct.dnsRedirect cfg.CaptureAllDNS = rdrct.dnsRedirect diff --git a/cni/pkg/plugin/sidecar_redirect.go b/cni/pkg/plugin/sidecar_redirect.go index a1f95dcdd813..cb9e209726c7 100644 --- a/cni/pkg/plugin/sidecar_redirect.go +++ b/cni/pkg/plugin/sidecar_redirect.go @@ -55,41 +55,43 @@ var ( sidecarInterceptModeKey = annotation.SidecarInterceptionMode.Name sidecarPortListKey = annotation.SidecarStatusPort.Name - kubevirtInterfacesKey = annotation.SidecarTrafficKubevirtInterfaces.Name + kubevirtInterfacesKey = annotation.SidecarTrafficKubevirtInterfaces.Name + rerouteVirtInterfacesKey = annotation.IoIstioRerouteVirtualInterfaces.Name annotationRegistry = map[string]*annotationParam{ - "inject": {injectAnnotationKey, "", alwaysValidFunc}, - "status": {sidecarStatusKey, "", alwaysValidFunc}, - "redirectMode": {sidecarInterceptModeKey, defaultRedirectMode, validateInterceptionMode}, - "ports": {sidecarPortListKey, "", validatePortList}, - "includeIPCidrs": {includeIPCidrsKey, defaultRedirectIPCidr, validateCIDRListWithWildcard}, - "excludeIPCidrs": {excludeIPCidrsKey, defaultRedirectExcludeIPCidr, validateCIDRList}, - "excludeInboundPorts": {excludeInboundPortsKey, defaultRedirectExcludePort, validatePortListWithWildcard}, - "includeInboundPorts": {includeInboundPortsKey, defaultIncludeInboundPorts, validatePortListWithWildcard}, - "excludeOutboundPorts": {excludeOutboundPortsKey, defaultRedirectExcludePort, validatePortListWithWildcard}, - "includeOutboundPorts": {includeOutboundPortsKey, defaultIncludeOutboundPorts, validatePortListWithWildcard}, - "kubevirtInterfaces": {kubevirtInterfacesKey, defaultKubevirtInterfaces, alwaysValidFunc}, - "excludeInterfaces": {excludeInterfacesKey, defaultExcludeInterfaces, alwaysValidFunc}, + "inject": {injectAnnotationKey, "", alwaysValidFunc}, + "status": {sidecarStatusKey, "", alwaysValidFunc}, + "redirectMode": {sidecarInterceptModeKey, defaultRedirectMode, validateInterceptionMode}, + "ports": {sidecarPortListKey, "", validatePortList}, + "includeIPCidrs": {includeIPCidrsKey, defaultRedirectIPCidr, validateCIDRListWithWildcard}, + "excludeIPCidrs": {excludeIPCidrsKey, defaultRedirectExcludeIPCidr, validateCIDRList}, + "excludeInboundPorts": {excludeInboundPortsKey, defaultRedirectExcludePort, validatePortListWithWildcard}, + "includeInboundPorts": {includeInboundPortsKey, defaultIncludeInboundPorts, validatePortListWithWildcard}, + "excludeOutboundPorts": {excludeOutboundPortsKey, defaultRedirectExcludePort, validatePortListWithWildcard}, + "includeOutboundPorts": {includeOutboundPortsKey, defaultIncludeOutboundPorts, validatePortListWithWildcard}, + "kubevirtInterfaces": {kubevirtInterfacesKey, defaultKubevirtInterfaces, alwaysValidFunc}, // DEPRECATED + "reroute-virtual-interfaces": {rerouteVirtInterfacesKey, defaultKubevirtInterfaces, alwaysValidFunc}, + "excludeInterfaces": {excludeInterfacesKey, defaultExcludeInterfaces, alwaysValidFunc}, } ) // Redirect -- the istio-cni redirect object type Redirect struct { - targetPort string - redirectMode string - noRedirectUID string - noRedirectGID string - includeIPCidrs string - excludeIPCidrs string - excludeInboundPorts string - excludeOutboundPorts string - includeInboundPorts string - includeOutboundPorts string - kubevirtInterfaces string - excludeInterfaces string - dnsRedirect bool - dualStack bool - invalidDrop bool + targetPort string + redirectMode string + noRedirectUID string + noRedirectGID string + includeIPCidrs string + excludeIPCidrs string + excludeInboundPorts string + excludeOutboundPorts string + includeInboundPorts string + includeOutboundPorts string + rerouteVirtualInterfaces string + excludeInterfaces string + dnsRedirect bool + dualStack bool + invalidDrop bool } type annotationValidationFunc func(value string) error @@ -273,11 +275,18 @@ func NewRedirect(pi *PodInfo) (*Redirect, error) { return nil, fmt.Errorf("annotation value error for value %s; annotationFound = %t: %v", "excludeInterfaces", isFound, valErr) } - isFound, redir.kubevirtInterfaces, valErr = getAnnotationOrDefault("kubevirtInterfaces", pi.Annotations) + // kubeVirtInterfaces is deprecated, so check it first, but prefer`reroute-virtual-interfaces` + // if both are defined. + isFound, redir.rerouteVirtualInterfaces, valErr = getAnnotationOrDefault("kubevirtInterfaces", pi.Annotations) if valErr != nil { return nil, fmt.Errorf("annotation value error for value %s; annotationFound = %t: %v", "kubevirtInterfaces", isFound, valErr) } + isFound, redir.rerouteVirtualInterfaces, valErr = getAnnotationOrDefault("reroute-virtual-interfaces", pi.Annotations) + if valErr != nil { + return nil, fmt.Errorf("annotation value error for value %s; annotationFound = %t: %v", + "reroute-virtual-interfaces", isFound, valErr) + } if v, found := pi.ProxyEnvironments["ISTIO_META_DNS_CAPTURE"]; found { // parse and set the bool value of dnsRedirect redir.dnsRedirect, valErr = strconv.ParseBool(v) diff --git a/cni/pkg/util/executil.go b/cni/pkg/util/executil.go deleted file mode 100644 index 260c293f3314..000000000000 --- a/cni/pkg/util/executil.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright Istio Authors -// -// Licensed 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 util - -import ( - "bytes" - "errors" - "os/exec" - "strings" - - "istio.io/istio/pkg/log" -) - -type ExecList struct { - Cmd string - Args []string -} - -func NewExec(cmd string, args []string) *ExecList { - return &ExecList{ - Cmd: cmd, - Args: args, - } -} - -func ExecuteOutput(cmd string, args ...string) (string, error) { - externalCommand := exec.Command(cmd, args...) - stdout := &bytes.Buffer{} - stderr := &bytes.Buffer{} - externalCommand.Stdout = stdout - externalCommand.Stderr = stderr - - err := externalCommand.Run() - - if err != nil || len(stderr.Bytes()) != 0 { - return stderr.String(), err - } - - return strings.TrimSuffix(stdout.String(), "\n"), err -} - -func Execute(cmd string, args ...string) error { - log.Debugf("Running command: %s %s", cmd, strings.Join(args, " ")) - externalCommand := exec.Command(cmd, args...) - stdout := &bytes.Buffer{} - stderr := &bytes.Buffer{} - externalCommand.Stdout = stdout - externalCommand.Stderr = stderr - - err := externalCommand.Run() - - if len(stdout.String()) != 0 { - log.Debugf("Command output: \n%v", stdout.String()) - } - - if err != nil || len(stderr.Bytes()) != 0 { - log.Debugf("Command error output: \n%v", stderr.String()) - return errors.New(stderr.String()) - } - - return nil -} diff --git a/cni/pkg/util/podutil.go b/cni/pkg/util/podutil.go index 90becc25a114..8c23f7fd63cf 100644 --- a/cni/pkg/util/podutil.go +++ b/cni/pkg/util/podutil.go @@ -71,7 +71,10 @@ func PodRedirectionEnabled(namespace *corev1.Namespace, pod *corev1.Pod) bool { // // If you just want to know if the pod _should be_ configured for traffic redirection, see PodRedirectionEnabled func PodRedirectionActive(pod *corev1.Pod) bool { - return pod.GetAnnotations()[annotation.AmbientRedirection.Name] == constants.AmbientRedirectionEnabled + if pod != nil { + return pod.GetAnnotations()[annotation.AmbientRedirection.Name] == constants.AmbientRedirectionEnabled + } + return false } func podHasSidecar(pod *corev1.Pod) bool { @@ -101,10 +104,6 @@ func AnnotateEnrolledPod(client kubernetes.Interface, pod *metav1.ObjectMeta) er } func AnnotateUnenrollPod(client kubernetes.Interface, pod *metav1.ObjectMeta) error { - if pod.Annotations[annotation.AmbientRedirection.Name] != constants.AmbientRedirectionEnabled { - return nil - } - // TODO: do not overwrite if already none _, err := client.CoreV1(). Pods(pod.Namespace). Patch( diff --git a/cni/test/install_k8s_test.go b/cni/test/install_k8s_test.go index 9690a86861f1..5ca455232f53 100644 --- a/cni/test/install_k8s_test.go +++ b/cni/test/install_k8s_test.go @@ -23,11 +23,6 @@ import ( "istio.io/istio/pkg/test/env" ) -var ( - Hub = "gcr.io/istio-release" - Tag = "master-latest-daily" -) - type testCase struct { name string chainedCNIPlugin bool diff --git a/common/.commonfiles.sha b/common/.commonfiles.sha index aebb24f3e7da..3df74a12eaac 100644 --- a/common/.commonfiles.sha +++ b/common/.commonfiles.sha @@ -1 +1 @@ -82dc68a737b72d394c344d4fd71ff9e9ebf01852 +ad4552bfdc5ead45c5d8084e4bf254b788090603 diff --git a/common/Makefile.common.mk b/common/Makefile.common.mk index 384737d7b56a..6e9b85bb0f80 100644 --- a/common/Makefile.common.mk +++ b/common/Makefile.common.mk @@ -106,13 +106,11 @@ update-common: @if [ "$(CONTRIB_OVERRIDE)" != "CONTRIBUTING.md" ]; then\ rm $(TMP)/common-files/files/CONTRIBUTING.md;\ fi -# istio/istio.io uses the Creative Commons Attribution 4.0 license. Don't update LICENSE with the common Apache license. - @LICENSE_OVERRIDE=$(shell grep -l "Creative Commons Attribution 4.0 International Public License" LICENSE) - @if [ "$(LICENSE_OVERRIDE)" != "LICENSE" ]; then\ - rm $(TMP)/common-files/files/LICENSE;\ - fi @cp -a $(TMP)/common-files/files/* $(TMP)/common-files/files/.devcontainer $(TMP)/common-files/files/.gitattributes $(shell pwd) @rm -fr $(TMP)/common-files + @if [ "$(AUTOMATOR_REPO)" == "proxy" ]; then\ + sed -i -e 's/build-tools:/build-tools-proxy:/g' .devcontainer/devcontainer.json;\ + fi @$(or $(COMMONFILES_POSTPROCESS), true) check-clean-repo: diff --git a/common/config/.golangci.yml b/common/config/.golangci.yml index a8948028c45e..52b9481b4e5c 100644 --- a/common/config/.golangci.yml +++ b/common/config/.golangci.yml @@ -16,7 +16,7 @@ linters: disable-all: true enable: - errcheck - - exportloopref + - copyloopvar - depguard - gocritic - gofumpt diff --git a/common/scripts/kind_provisioner.sh b/common/scripts/kind_provisioner.sh index 9e9ea59cff86..4650ba5c5d7e 100644 --- a/common/scripts/kind_provisioner.sh +++ b/common/scripts/kind_provisioner.sh @@ -32,7 +32,7 @@ set -x #################################################################### # DEFAULT_KIND_IMAGE is used to set the Kubernetes version for KinD unless overridden in params to setup_kind_cluster(s) -DEFAULT_KIND_IMAGE="gcr.io/istio-testing/kind-node:v1.28.4" +DEFAULT_KIND_IMAGE="gcr.io/istio-testing/kind-node:v1.32.0" # the default kind cluster should be ipv4 if not otherwise specified IP_FAMILY="${IP_FAMILY:-ipv4}" @@ -195,7 +195,7 @@ function setup_kind_cluster() { kubectl taint nodes "${NAME}"-control-plane node-role.kubernetes.io/control-plane- 2>/dev/null || true # Determine what CNI to install - case "${KUBERNETES_CNI:-}" in + case "${KUBERNETES_CNI:-}" in "calico") echo "Installing Calico CNI" diff --git a/common/scripts/setup_env.sh b/common/scripts/setup_env.sh index c63f1fa33ea7..82ab624996b7 100755 --- a/common/scripts/setup_env.sh +++ b/common/scripts/setup_env.sh @@ -75,7 +75,7 @@ fi TOOLS_REGISTRY_PROVIDER=${TOOLS_REGISTRY_PROVIDER:-gcr.io} PROJECT_ID=${PROJECT_ID:-istio-testing} if [[ "${IMAGE_VERSION:-}" == "" ]]; then - IMAGE_VERSION=master-4759bf88d40172234fc6a0b9e11a4c5f1ea58a90 + IMAGE_VERSION=master-0b8e6b9676d328fbeb28a23b8d1134dcc56d98ec fi if [[ "${IMAGE_NAME:-}" == "" ]]; then IMAGE_NAME=build-tools diff --git a/go.mod b/go.mod index 6c98b9da43a5..da448b1e34d1 100644 --- a/go.mod +++ b/go.mod @@ -1,36 +1,33 @@ module istio.io/istio -go 1.22.0 - -// Client-go does not handle different versions of mergo due to some breaking changes - use the matching version -replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.5 +go 1.23.0 require ( - cloud.google.com/go/compute/metadata v0.5.2 + cloud.google.com/go/compute/metadata v0.6.0 github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 - github.com/Masterminds/semver/v3 v3.3.0 + github.com/Masterminds/semver/v3 v3.3.1 github.com/Masterminds/sprig/v3 v3.3.0 - github.com/alecholmes/xfccparser v0.3.0 + github.com/alecholmes/xfccparser v0.4.0 github.com/cenkalti/backoff/v4 v4.3.0 github.com/cespare/xxhash/v2 v2.3.0 github.com/cheggaaa/pb/v3 v3.1.5 - github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 + github.com/cncf/xds/go v0.0.0-20241213214725-57cfbe6fad57 github.com/containernetworking/cni v1.2.3 - github.com/containernetworking/plugins v1.5.1 + github.com/containernetworking/plugins v1.6.1 github.com/coreos/go-oidc/v3 v3.11.0 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc - github.com/docker/cli v27.3.1+incompatible - github.com/envoyproxy/go-control-plane v0.13.2-0.20241022220226-23b7e55d7f65 + github.com/docker/cli v27.4.0+incompatible + github.com/envoyproxy/go-control-plane v0.13.2-0.20241125134052-fc612d4a3afa github.com/evanphx/json-patch/v5 v5.9.0 - github.com/fatih/color v1.17.0 + github.com/fatih/color v1.18.0 github.com/felixge/fgprof v0.9.5 github.com/florianl/go-nflog/v2 v2.1.0 - github.com/fsnotify/fsnotify v1.7.0 + github.com/fsnotify/fsnotify v1.8.0 github.com/go-jose/go-jose/v3 v3.0.3 github.com/go-logr/logr v1.4.2 github.com/gogo/protobuf v1.3.2 github.com/golang/protobuf v1.5.4 - github.com/google/cel-go v0.21.0 + github.com/google/cel-go v0.22.1 github.com/google/go-cmp v0.6.0 github.com/google/go-containerregistry v0.20.2 github.com/google/gofuzz v1.2.0 @@ -48,155 +45,154 @@ require ( github.com/mattn/go-isatty v0.0.20 github.com/miekg/dns v1.1.62 github.com/mitchellh/copystructure v1.2.0 - github.com/moby/buildkit v0.16.0 - github.com/onsi/gomega v1.34.2 - github.com/openshift/api v0.0.0-20241003161011-3f43768f3915 - github.com/pires/go-proxyproto v0.7.0 + github.com/moby/buildkit v0.18.1 + github.com/onsi/gomega v1.36.0 + github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43 + github.com/pires/go-proxyproto v0.8.0 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 - github.com/prometheus/client_golang v1.20.4 + github.com/prometheus/client_golang v1.20.5 github.com/prometheus/client_model v0.6.1 - github.com/prometheus/common v0.60.0 + github.com/prometheus/common v0.61.0 github.com/prometheus/procfs v0.15.1 - github.com/prometheus/prometheus v0.54.1 - github.com/quic-go/quic-go v0.47.0 + github.com/prometheus/prometheus v0.300.1 + github.com/quic-go/quic-go v0.48.2 github.com/ryanuber/go-glob v1.0.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stoewer/go-strcase v1.3.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/vishvananda/netlink v1.3.0 - github.com/vishvananda/netns v0.0.4 + github.com/vishvananda/netns v0.0.5 github.com/yl2chen/cidranger v1.0.2 - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 - go.opentelemetry.io/otel/exporters/prometheus v0.52.0 - go.opentelemetry.io/otel/metric v1.30.0 - go.opentelemetry.io/otel/sdk v1.30.0 - go.opentelemetry.io/otel/sdk/metric v1.30.0 - go.opentelemetry.io/otel/trace v1.30.0 - go.opentelemetry.io/proto/otlp v1.3.1 + go.opentelemetry.io/otel v1.33.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 + go.opentelemetry.io/otel/exporters/prometheus v0.55.0 + go.opentelemetry.io/otel/metric v1.33.0 + go.opentelemetry.io/otel/sdk v1.33.0 + go.opentelemetry.io/otel/sdk/metric v1.33.0 + go.opentelemetry.io/otel/trace v1.33.0 + go.opentelemetry.io/proto/otlp v1.4.0 go.uber.org/atomic v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/net v0.29.0 - golang.org/x/oauth2 v0.23.0 - golang.org/x/sync v0.8.0 - golang.org/x/sys v0.25.0 - golang.org/x/time v0.6.0 + golang.org/x/net v0.32.0 + golang.org/x/oauth2 v0.24.0 + golang.org/x/sync v0.10.0 + golang.org/x/sys v0.28.0 + golang.org/x/time v0.8.0 gomodules.xyz/jsonpatch/v2 v2.4.0 - google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f - google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f - google.golang.org/grpc v1.67.1 - google.golang.org/protobuf v1.34.2 + google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 + google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 + google.golang.org/grpc v1.69.0 + google.golang.org/protobuf v1.36.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 - helm.sh/helm/v3 v3.16.1 - istio.io/api v1.24.0-alpha.0.0.20241018201654-7c8ec5b5ab72 - istio.io/client-go v1.24.0-alpha.0.0.20241018201953-b3ca3b2a6ef6 - k8s.io/api v0.31.1 - k8s.io/apiextensions-apiserver v0.31.1 - k8s.io/apimachinery v0.31.1 - k8s.io/apiserver v0.31.1 - k8s.io/cli-runtime v0.31.1 - k8s.io/client-go v0.31.1 + helm.sh/helm/v3 v3.16.3 + istio.io/api v1.24.0-alpha.0.0.20241217180900-c363ca75e894 + istio.io/client-go v1.24.0-alpha.0.0.20241217181500-0630716ab2c6 + k8s.io/api v0.32.0 + k8s.io/apiextensions-apiserver v0.32.0 + k8s.io/apimachinery v0.32.0 + k8s.io/apiserver v0.32.0 + k8s.io/cli-runtime v0.32.0 + k8s.io/client-go v0.32.0 k8s.io/klog/v2 v2.130.1 - k8s.io/kubectl v0.31.1 - k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 - sigs.k8s.io/controller-runtime v0.19.0 - sigs.k8s.io/gateway-api v1.2.0 + k8s.io/kubectl v0.32.0 + k8s.io/utils v0.0.0-20241210054802-24370beab758 + sigs.k8s.io/controller-runtime v0.19.3 + sigs.k8s.io/gateway-api v1.2.1 sigs.k8s.io/mcs-api v0.1.1-0.20240624222831-d7001fe1d21c sigs.k8s.io/yaml v1.4.0 ) require ( - cel.dev/expr v0.16.0 // indirect + cel.dev/expr v0.19.1 // indirect dario.cat/mergo v1.0.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/BurntSushi/toml v1.3.2 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/VividCortex/ewma v1.2.0 // indirect - github.com/alecthomas/participle/v2 v2.1.0 // indirect - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/alecthomas/participle/v2 v2.1.1 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect - github.com/chai2010/gettext-go v1.0.2 // indirect - github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect - github.com/containerd/typeurl/v2 v2.2.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect - github.com/cyphar/filepath-securejoin v0.3.1 // indirect + github.com/chai2010/gettext-go v1.0.3 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect + github.com/containerd/typeurl/v2 v2.2.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect + github.com/cyphar/filepath-securejoin v0.3.5 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect - github.com/emicklei/go-restful/v3 v3.12.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/fatih/camelcase v1.0.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-errors/errors v1.5.1 // indirect - github.com/go-jose/go-jose/v4 v4.0.2 // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/goccy/go-json v0.10.3 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/btree v1.1.2 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect + github.com/goccy/go-json v0.10.4 // indirect + github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect - github.com/imdario/mergo v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/josharian/native v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/magiconair/properties v1.8.9 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mdlayher/netlink v1.7.2 // indirect - github.com/mdlayher/socket v0.5.0 // indirect + github.com/mdlayher/socket v0.5.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/moby/spdystream v0.4.0 // indirect + github.com/moby/spdystream v0.5.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/onsi/ginkgo/v2 v2.20.1 // indirect + github.com/onsi/ginkgo/v2 v2.22.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240409071808-615f978279ca // indirect github.com/quic-go/qpack v0.5.1 // indirect - github.com/rivo/uniseg v0.4.6 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect @@ -205,30 +201,30 @@ require ( github.com/spf13/cast v1.7.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/vbatts/tar-split v0.11.5 // indirect + github.com/vbatts/tar-split v0.11.6 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect - go.starlark.net v0.0.0-20231121155337-90ade8b19d09 // indirect - go.uber.org/mock v0.4.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect + go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect + golang.org/x/tools v0.28.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - k8s.io/component-base v0.31.1 // indirect - k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.17.2 // indirect - sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + k8s.io/component-base v0.32.0 // indirect + k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.1 // indirect + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/kustomize/api v0.18.0 // indirect + sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect ) diff --git a/go.sum b/go.sum index c71585ecb4e3..1d355b919e31 100644 --- a/go.sum +++ b/go.sum @@ -1,41 +1,58 @@ -cel.dev/expr v0.16.0 h1:yloc84fytn4zmJX2GU3TkXGsaieaV7dQ057Qs4sIG2Y= -cel.dev/expr v0.16.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= +cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= +cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= -cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go/auth v0.9.5 h1:4CTn43Eynw40aFVr3GpPqsQponx2jv0BQpjvajsbbzw= +cloud.google.com/go/auth v0.9.5/go.mod h1:Xo0n7n66eHyOWWCnitop6870Ilwo3PiZyodVkkH1xWM= +cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= +cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= +cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= +cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= +github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= -github.com/alecholmes/xfccparser v0.3.0 h1:SI/zhgFw+CsoHnR2VXcbVg/9gij6T/ENT+1yqBOeLNA= -github.com/alecholmes/xfccparser v0.3.0/go.mod h1:J9fzzUOtjw74IwNdGVbjnOVj1UDlwGQj1zZzgQRlRDY= +github.com/alecholmes/xfccparser v0.4.0 h1:IFB4bP34oorjcV3n8utZtBhEwlAw9rZ43pb4LgT23Vo= +github.com/alecholmes/xfccparser v0.4.0/go.mod h1:J9fzzUOtjw74IwNdGVbjnOVj1UDlwGQj1zZzgQRlRDY= github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0= github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= -github.com/alecthomas/participle/v2 v2.1.0 h1:z7dElHRrOEEq45F2TG5cbQihMtNTv8vwldytDj7Wrz4= -github.com/alecthomas/participle/v2 v2.1.0/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= +github.com/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8= +github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= -github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 h1:t3eaIm0rUkzbrIewtiFmMK5RXHej2XnoXNhxVsAYUfg= +github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= +github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -48,8 +65,8 @@ github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMr github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= -github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= +github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnTiM80= +github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk= github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI= github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= @@ -60,47 +77,48 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= -github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= -github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= -github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= -github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= -github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= +github.com/cncf/xds/go v0.0.0-20241213214725-57cfbe6fad57 h1:put7Je9ZyxbHtwr7IqGrW4LLVUupJQ2gbsDshKISSgU= +github.com/cncf/xds/go v0.0.0-20241213214725-57cfbe6fad57/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8= +github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU= +github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40= +github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8FuJbEslXM= github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M= -github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ= -github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM= +github.com/containernetworking/plugins v1.6.1 h1:bYd2bpE6hEBqexyaiI2/sst0xJ+v7pEMWrjA5qtkxiU= +github.com/containernetworking/plugins v1.6.1/go.mod h1:SP5UG3jDO9LtmfbBJdP+nl3A1atOtbj2MBOYsnaxy64= github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.3.1 h1:1V7cHiaW+C+39wEfpH6XlLBQo3j/PciWFrgfCLS8XrE= -github.com/cyphar/filepath-securejoin v0.3.1/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc= +github.com/cyphar/filepath-securejoin v0.3.5 h1:L81NHjquoQmcPgXcttUS9qTSR/+bXry6pbSINQGpjj4= +github.com/cyphar/filepath-securejoin v0.3.5/go.mod h1:edhVd3c6OXKjUmSrVa/tGJRS9joFTxlslFCAyaxigkE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= -github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.4.0+incompatible h1:/nJzWkcI1MDMN+U+px/YXnQWJqnu4J+QKGTfD6ptiTc= +github.com/docker/cli v27.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= -github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= -github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.13.2-0.20241022220226-23b7e55d7f65 h1:MyrjwzTD9X0BbbUDh5WT2IUkFP8adIF90TQFxDpTZ1w= -github.com/envoyproxy/go-control-plane v0.13.2-0.20241022220226-23b7e55d7f65/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw= +github.com/envoyproxy/go-control-plane v0.13.2-0.20241125134052-fc612d4a3afa h1:cx/trvN4+WDYHYjeSzXZTYOlPi0Ok1RfZlz35oSKgbk= +github.com/envoyproxy/go-control-plane v0.13.2-0.20241125134052-fc612d4a3afa/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= @@ -112,8 +130,8 @@ github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2 github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY= github.com/felixge/fgprof v0.9.5/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -122,22 +140,18 @@ github.com/florianl/go-nflog/v2 v2.1.0 h1:yXvA/ZWMS2dXBBM364xOEaW4WX14RjvsGCVt+y github.com/florianl/go-nflog/v2 v2.1.0/go.mod h1:U8o3DfjAAIMuW3/IHS3KmTccSMLyRbr09dImALuwEI8= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= -github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -159,25 +173,27 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= +github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= +github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= -github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40= +github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= @@ -190,12 +206,16 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= -github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= +github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= +github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= @@ -208,8 +228,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDa github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -228,10 +248,10 @@ github.com/howardjohn/unshare-go v0.5.0/go.mod h1:cJjyFAN6qTA70ovC2VR23iAZuJ8X3J github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= -github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= @@ -243,8 +263,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -273,23 +293,24 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= +github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA= github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs= -github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI= -github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI= +github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= +github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -302,10 +323,10 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/buildkit v0.16.0 h1:wOVBj1o5YNVad/txPQNXUXdelm7Hs/i0PUFjzbK0VKE= -github.com/moby/buildkit v0.16.0/go.mod h1:Xqx/5GlrqE1yIRORk0NSCVDFpQAU1WjlT6KHYZdisIQ= -github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= -github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/buildkit v0.18.1 h1:Iwrz2F/Za2Gjkpwu3aM2LX92AFfJCJe2oNnvGNvh2Rc= +github.com/moby/buildkit v0.18.1/go.mod h1:vCR5CX8NGsPTthTg681+9kdmfvkvqJBXEv71GZe5msU= +github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -321,24 +342,26 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo= -github.com/onsi/ginkgo/v2 v2.20.1/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= -github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= -github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.36.0 h1:Pb12RlruUtj4XUuPUqeEWc6j5DkVVVA49Uf6YLfC95Y= +github.com/onsi/gomega v1.36.0/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/openshift/api v0.0.0-20241003161011-3f43768f3915 h1:+fTuA1mBFrepQU7GsQ0idp2cay2/FBOUl0jGxXIW/RA= -github.com/openshift/api v0.0.0-20241003161011-3f43768f3915/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= +github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43 h1:3lcB5nqOOfsJzY4JD12AMKyg3+yQhAdJzNDenbmbMQg= +github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs= -github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4= +github.com/pires/go-proxyproto v0.8.0 h1:5unRmEAPbHXHuLjDg01CxJWf91cw3lKHc/0xzKpXEe0= +github.com/pires/go-proxyproto v0.8.0/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM0jx2xmKqnVY= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -347,32 +370,34 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240409071808-615f978279ca/go.mod h1 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= -github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= -github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= +github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= +github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= +github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/prometheus v0.54.1 h1:vKuwQNjnYN2/mDoWfHXDhAsz/68q/dQDb+YbcEqU7MQ= -github.com/prometheus/prometheus v0.54.1/go.mod h1:xlLByHhk2g3ycakQGrMaU8K7OySZx98BzeCR99991NY= +github.com/prometheus/prometheus v0.300.1 h1:9KKcTTq80gkzmXW0Et/QCFSrBPgmwiS3Hlcxc6o8KlM= +github.com/prometheus/prometheus v0.300.1/go.mod h1:gtTPY/XVyCdqqnjA3NzDMb0/nc5H9hOu1RMame+gHyM= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.47.0 h1:yXs3v7r2bm1wmPTYNLKAAJTHMYkPEsfYJmTazXrCZ7Y= -github.com/quic-go/quic-go v0.47.0/go.mod h1:3bCapYsJvXGZcipOHuu7plYtaV6tnF+z7wIFsU0WK9E= +github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= +github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg= -github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= +github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= @@ -410,17 +435,17 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= -github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= +github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs= +github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI= github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk= github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= -github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= +github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -437,46 +462,48 @@ github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.etcd.io/etcd/api/v3 v3.5.14 h1:vHObSCxyB9zlF60w7qzAdTcGaglbJOpSj1Xj9+WGxq0= -go.etcd.io/etcd/api/v3 v3.5.14/go.mod h1:BmtWcRlQvwa1h3G2jvKYwIQy4PkHlDej5t7uLMUdJUU= -go.etcd.io/etcd/client/pkg/v3 v3.5.14 h1:SaNH6Y+rVEdxfpA2Jr5wkEvN6Zykme5+YnbCkxvuWxQ= -go.etcd.io/etcd/client/pkg/v3 v3.5.14/go.mod h1:8uMgAokyG1czCtIdsq+AGyYQMvpIKnSvPjFMunkgeZI= -go.etcd.io/etcd/client/v3 v3.5.14 h1:CWfRs4FDaDoSz81giL7zPpZH2Z35tbOrAJkkjMqOupg= -go.etcd.io/etcd/client/v3 v3.5.14/go.mod h1:k3XfdV/VIHy/97rqWjoUzrj9tk7GgJGH9J8L4dNXmAk= +go.etcd.io/etcd/api/v3 v3.5.16 h1:WvmyJVbjWqK4R1E+B12RRHz3bRGy9XVfh++MgbN+6n0= +go.etcd.io/etcd/api/v3 v3.5.16/go.mod h1:1P4SlIP/VwkDmGo3OlOD7faPeP8KDIFhqvciH5EfN28= +go.etcd.io/etcd/client/pkg/v3 v3.5.16 h1:ZgY48uH6UvB+/7R9Yf4x574uCO3jIx0TRDyetSfId3Q= +go.etcd.io/etcd/client/pkg/v3 v3.5.16/go.mod h1:V8acl8pcEK0Y2g19YlOV9m9ssUe6MgiDSobSoaBAM0E= +go.etcd.io/etcd/client/v3 v3.5.16 h1:sSmVYOAHeC9doqi0gv7v86oY/BTld0SEFGaxsU9eRhE= +go.etcd.io/etcd/client/v3 v3.5.16/go.mod h1:X+rExSGkyqxvu276cr2OwPLBaeqFu1cIl4vmRjAD/50= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8= -go.opentelemetry.io/otel/exporters/prometheus v0.52.0 h1:kmU3H0b9ufFSi8IQCcxack+sWUblKkFbqWYs6YiACGQ= -go.opentelemetry.io/otel/exporters/prometheus v0.52.0/go.mod h1:+wsAp2+JhuGXX7YRkjlkx6hyWY3ogFPfNA4x3nyiAh0= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM= -go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.starlark.net v0.0.0-20231121155337-90ade8b19d09 h1:hzy3LFnSN8kuQK8h9tHl4ndF6UruMj47OqwqsS+/Ai4= -go.starlark.net v0.0.0-20231121155337-90ade8b19d09/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= +go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0= +go.opentelemetry.io/otel/exporters/prometheus v0.55.0 h1:sSPw658Lk2NWAv74lkD3B/RSDb+xRFx46GjkrL3VUZo= +go.opentelemetry.io/otel/exporters/prometheus v0.55.0/go.mod h1:nC00vyCmQixoeaxF6KNyP42II/RHa9UdruK02qBmHvI= +go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= +go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= +go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= +go.opentelemetry.io/otel/sdk/metric v1.33.0 h1:Gs5VK9/WUJhNXZgn8MR6ITatvAmKeIuCtNbsP3JkNqU= +go.opentelemetry.io/otel/sdk/metric v1.33.0/go.mod h1:dL5ykHZmm1B1nVRk9dDjChwDmt81MjVp3gLkQRwKf/Q= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg= +go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= @@ -488,11 +515,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e h1:4qufH0hlUYs6AO6XmZC3GqfDPGSXHVXUFR6OND+iJX4= +golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -501,8 +528,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -517,11 +544,11 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= +golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -530,8 +557,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -556,15 +583,15 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -572,10 +599,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= +golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -587,32 +614,34 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/api v0.199.0 h1:aWUXClp+VFJmqE0JPvpZOK3LDQMyFKYIow4etYd9qxs= +google.golang.org/api v0.199.0/go.mod h1:ohG4qSztDJmZdjK/Ar6MhbAmb/Rpi4JHOqagsh90K28= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f h1:jTm13A2itBi3La6yTGqn8bVSrc3ZZ1r8ENHlIXBfnRA= -google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f/go.mod h1:CLGoBuH1VHxAUXVPP8FfPwPEVJB6lz3URE5mY2SuayE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/grpc v1.69.0 h1:quSiOM1GJPmPH5XtU+BCoVXcDVJJAzNcoyfC2cCjGkI= +google.golang.org/grpc v1.69.0/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= +google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ= +google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -633,51 +662,51 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -helm.sh/helm/v3 v3.16.1 h1:cER6tI/8PgUAsaJaQCVBUg3VI9KN4oVaZJgY60RIc0c= -helm.sh/helm/v3 v3.16.1/go.mod h1:r+xBHHP20qJeEqtvBXMf7W35QDJnzY/eiEBzt+TfHps= +helm.sh/helm/v3 v3.16.3 h1:kb8bSxMeRJ+knsK/ovvlaVPfdis0X3/ZhYCSFRP+YmY= +helm.sh/helm/v3 v3.16.3/go.mod h1:zeVWGDR4JJgiRbT3AnNsjYaX8OTJlIE9zC+Q7F7iUSU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -istio.io/api v1.24.0-alpha.0.0.20241018201654-7c8ec5b5ab72 h1:AVg/4p5sVhZT6JwBczgvAy9idbVYiCqZFE/QVXNKy/k= -istio.io/api v1.24.0-alpha.0.0.20241018201654-7c8ec5b5ab72/go.mod h1:MQnRok7RZ20/PE56v0LxmoWH0xVxnCQPNuf9O7PAN1I= -istio.io/client-go v1.24.0-alpha.0.0.20241018201953-b3ca3b2a6ef6 h1:qVjgBbqg19vZCpeTMQR0QM8SRfLZTtaSXgWbnWRb0fo= -istio.io/client-go v1.24.0-alpha.0.0.20241018201953-b3ca3b2a6ef6/go.mod h1:usBQZ/vvpGAUA6yGiz6x9ufG50gRC9v0332MesA/lNw= -k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU= -k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI= -k8s.io/apiextensions-apiserver v0.31.1 h1:L+hwULvXx+nvTYX/MKM3kKMZyei+UiSXQWciX/N6E40= -k8s.io/apiextensions-apiserver v0.31.1/go.mod h1:tWMPR3sgW+jsl2xm9v7lAyRF1rYEK71i9G5dRtkknoQ= -k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U= -k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c= -k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM= -k8s.io/cli-runtime v0.31.1 h1:/ZmKhmZ6hNqDM+yf9s3Y4KEYakNXUn5sod2LWGGwCuk= -k8s.io/cli-runtime v0.31.1/go.mod h1:pKv1cDIaq7ehWGuXQ+A//1OIF+7DI+xudXtExMCbe9U= -k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0= -k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg= -k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8= -k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w= +istio.io/api v1.24.0-alpha.0.0.20241217180900-c363ca75e894 h1:IkLD81TBt8sgw34R61NUwQj6ROoAwe0tmHwflZW9aV8= +istio.io/api v1.24.0-alpha.0.0.20241217180900-c363ca75e894/go.mod h1:QFzEXv/IT582T0FHZVp1QoolvE4ws0zz/vVO55blmlE= +istio.io/client-go v1.24.0-alpha.0.0.20241217181500-0630716ab2c6 h1:ap5cWLUUsrYVvXEKbzIP8jnkHgnoGbTPFwQHHjzXcVE= +istio.io/client-go v1.24.0-alpha.0.0.20241217181500-0630716ab2c6/go.mod h1:IGo0SAVOwyjuHSAFNisNUCRBl/W76qAfjiIA2Y68yMg= +k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= +k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= +k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= +k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= +k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= +k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apiserver v0.32.0 h1:VJ89ZvQZ8p1sLeiWdRJpRD6oLozNZD2+qVSLi+ft5Qs= +k8s.io/apiserver v0.32.0/go.mod h1:HFh+dM1/BE/Hm4bS4nTXHVfN6Z6tFIZPi649n83b4Ag= +k8s.io/cli-runtime v0.32.0 h1:dP+OZqs7zHPpGQMCGAhectbHU2SNCuZtIimRKTv2T1c= +k8s.io/cli-runtime v0.32.0/go.mod h1:Mai8ht2+esoDRK5hr861KRy6z0zHsSTYttNVJXgP3YQ= +k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= +k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= +k8s.io/component-base v0.32.0 h1:d6cWHZkCiiep41ObYQS6IcgzOUQUNpywm39KVYaUqzU= +k8s.io/component-base v0.32.0/go.mod h1:JLG2W5TUxUu5uDyKiH2R/7NnxJo1HlPoRIIbVLkK5eM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108 h1:Q8Z7VlGhcJgBHJHYugJ/K/7iB8a2eSxCyxdVjJp+lLY= -k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/kubectl v0.31.1 h1:ih4JQJHxsEggFqDJEHSOdJ69ZxZftgeZvYo7M/cpp24= -k8s.io/kubectl v0.31.1/go.mod h1:aNuQoR43W6MLAtXQ/Bu4GDmoHlbhHKuyD49lmTC8eJM= -k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY9mD9fNT47QO6HI= -k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= -sigs.k8s.io/gateway-api v1.2.0 h1:LrToiFwtqKTKZcZtoQPTuo3FxhrrhTgzQG0Te+YGSo8= -sigs.k8s.io/gateway-api v1.2.0/go.mod h1:EpNfEXNjiYfUJypf0eZ0P5iXA9ekSGWaS1WgPaM42X0= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= -sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= -sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= -sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= +k8s.io/kubectl v0.32.0 h1:rpxl+ng9qeG79YA4Em9tLSfX0G8W0vfaiPVrc/WR7Xw= +k8s.io/kubectl v0.32.0/go.mod h1:qIjSX+QgPQUgdy8ps6eKsYNF+YmFOAO3WygfucIqFiE= +k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= +k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.1 h1:uOuSLOMBWkJH0TWa9X6l+mj5nZdm6Ay6Bli8HL8rNfk= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.1/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw= +sigs.k8s.io/controller-runtime v0.19.3/go.mod h1:j4j87DqtsThvwTv5/Tc5NFRyyF/RF0ip4+62tbTSIUM= +sigs.k8s.io/gateway-api v1.2.1 h1:fZZ/+RyRb+Y5tGkwxFKuYuSRQHu9dZtbjenblleOLHM= +sigs.k8s.io/gateway-api v1.2.1/go.mod h1:EpNfEXNjiYfUJypf0eZ0P5iXA9ekSGWaS1WgPaM42X0= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo= +sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U= +sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E= +sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo= sigs.k8s.io/mcs-api v0.1.1-0.20240624222831-d7001fe1d21c h1:F7hIEutAxtXDOQX9NXFdvhWmWETu2zmUPHuPPcAez7g= sigs.k8s.io/mcs-api v0.1.1-0.20240624222831-d7001fe1d21c/go.mod h1:DPFniRsBzCeLB4ANjlPEvQQt9QGIX489d1faK+GPvI4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk= +sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/istio.deps b/istio.deps index 71eb154b3c5f..98fc3c1ab8f3 100644 --- a/istio.deps +++ b/istio.deps @@ -4,13 +4,13 @@ "name": "PROXY_REPO_SHA", "repoName": "proxy", "file": "", - "lastStableSHA": "a0129815ff04aefd303aee9b29bba5a3ff6d6b06" + "lastStableSHA": "5d72fdac4820ca856e272aabba46b95fefedcf7c" }, { "_comment": "", "name": "ZTUNNEL_REPO_SHA", "repoName": "ztunnel", "file": "", - "lastStableSHA": "3cf0060179b6902cd1676d98475af1f027dc73c2" + "lastStableSHA": "0ad78e3dcf1497d6cf7aca674865936dc5dc8be9" } ] diff --git a/istioctl/pkg/analyze/analyze.go b/istioctl/pkg/analyze/analyze.go index 1c228b2aab9c..82d8d9369eab 100644 --- a/istioctl/pkg/analyze/analyze.go +++ b/istioctl/pkg/analyze/analyze.go @@ -91,6 +91,8 @@ func Analyze(ctx cli.Context) *cobra.Command { analysisCmd := &cobra.Command{ Use: "analyze ...", Short: "Analyze Istio configuration and print validation messages", + Long: fmt.Sprintf("Analyze Istio configuration and print validation messages.\n"+ + "For more information about message codes, refer to:\n%s", url.ConfigAnalysis), Example: ` # Analyze the current live cluster istioctl analyze @@ -100,9 +102,6 @@ func Analyze(ctx cli.Context) *cobra.Command { # Analyze the current live cluster, simulating the effect of applying additional yaml files istioctl analyze a.yaml b.yaml my-app-config/ - # Analyze the current live cluster, simulating the effect of applying a directory of config recursively - istioctl analyze --recursive my-istio-config/ - # Analyze yaml files without connecting to a live cluster istioctl analyze --use-kube=false a.yaml b.yaml my-app-config/ @@ -129,6 +128,11 @@ func Analyze(ctx cli.Context) *cobra.Command { return nil } + if recursive { + fmt.Println("The recursive flag has been removed and is hardcoded to true without explicitly specifying it.") + return nil + } + readers, err := gatherFiles(cmd, args) if err != nil { return err @@ -273,7 +277,11 @@ func Analyze(ctx cli.Context) *cobra.Command { for _, r := range readers { files = append(files, r.Name) } - fmt.Fprintf(cmd.ErrOrStderr(), "\u2714 No validation issues found when analyzing %s.\n", strings.Join(files, "\n")) + if len(files) > 1 { + fmt.Fprintf(cmd.ErrOrStderr(), "\u2714 No validation issues found when analyzing:\n - %s\n", strings.Join(files, "\n - ")) + } else { + fmt.Fprintf(cmd.ErrOrStderr(), "\u2714 No validation issues found when analyzing %s.\n", strings.Join(files, "\n")) + } } else { fmt.Fprintf(cmd.ErrOrStderr(), "\u2714 No validation issues found when analyzing %s.\n", analyzeTargetAsString()) } @@ -329,10 +337,10 @@ func Analyze(ctx cli.Context) *cobra.Command { analysisCmd.PersistentFlags().DurationVar(&analysisTimeout, "timeout", 30*time.Second, "The duration to wait before failing") analysisCmd.PersistentFlags().BoolVarP(&recursive, "recursive", "R", false, - "Process directory arguments recursively. Useful when you want to analyze related manifests organized within the same directory.") + "[Removed: The recursive flag has been removed and is hardcoded to true] Process directory arguments recursively.") analysisCmd.PersistentFlags().BoolVar(&ignoreUnknown, "ignore-unknown", false, "Don't complain about un-parseable input documents, for cases where analyze should run only on k8s compliant inputs.") - analysisCmd.PersistentFlags().StringVarP(&revisionSpecified, "revision", "", "default", + analysisCmd.PersistentFlags().StringVarP(&revisionSpecified, "revision", "r", "default", "analyze a specific revision deployed.") analysisCmd.PersistentFlags().StringArrayVar(&remoteContexts, "remote-contexts", []string{}, `Kubernetes configuration contexts for remote clusters to be used in multi-cluster analysis. Not to be confused with '--context'. `+ @@ -402,12 +410,8 @@ func gatherFilesInDirectory(cmd *cobra.Command, dir string) ([]local.ReaderSourc if err != nil { return err } - // If we encounter a directory, recurse only if the --recursive option - // was provided and the directory is not the same as dir. + if info.IsDir() { - if !recursive && dir != path { - return filepath.SkipDir - } return nil } diff --git a/istioctl/pkg/authz/authz_test.go b/istioctl/pkg/authz/authz_test.go index d18c7cca9f05..da7d7c0a09e5 100644 --- a/istioctl/pkg/authz/authz_test.go +++ b/istioctl/pkg/authz/authz_test.go @@ -35,6 +35,7 @@ func TestAuthz(t *testing.T) { ExpectedOutput: `ACTION AuthorizationPolicy RULES ALLOW _anonymous_match_nothing_ 1 ALLOW httpbin.default 1 +CUSTOM ext-authz.default 1 `, }, } diff --git a/istioctl/pkg/authz/listener.go b/istioctl/pkg/authz/listener.go index e5b42a731509..4a80b84980d1 100644 --- a/istioctl/pkg/authz/listener.go +++ b/istioctl/pkg/authz/listener.go @@ -23,7 +23,6 @@ import ( "text/tabwriter" listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" - rbacpb "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" rbachttp "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3" hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" rbactcp "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/rbac/v3" @@ -37,8 +36,9 @@ const ( anonymousName = "_anonymous_match_nothing_" ) -// Matches the policy name in RBAC filter config with format like ns[default]-policy[some-policy]-rule[1]. -var re = regexp.MustCompile(`ns\[(.+)\]-policy\[(.+)\]-rule\[(.+)\]`) +// Matches the policy name in RBAC filter config with format like ns[default]-policy[some-policy]-rule[1] +// and istio-ext-authz-ns[default]-policy[some-policy]-rule[1]. +var re = regexp.MustCompile(`(?:istio-ext-authz-)?ns\[(.+)\]-policy\[(.+)\]-rule\[(.+)\]`) type filterChain struct { rbacHTTP []*rbachttp.RBAC @@ -127,6 +127,15 @@ func extractName(name string) (string, string) { return fmt.Sprintf("%s.%s", parts[2], parts[1]), parts[3] } +type policyAction string + +const ( + policyActionAllow policyAction = "ALLOW" + policyActionDeny policyAction = "DENY" + policyActionLog policyAction = "LOG" + policyActionCustom policyAction = "CUSTOM" +) + // Print prints the AuthorizationPolicy in the listener. func Print(writer io.Writer, listeners []*listener.Listener) { parsedListeners := parse(listeners) @@ -134,10 +143,10 @@ func Print(writer io.Writer, listeners []*listener.Listener) { return } - actionToPolicy := map[rbacpb.RBAC_Action]map[string]struct{}{} + actionToPolicy := map[policyAction]map[string]struct{}{} policyToRule := map[string]map[string]struct{}{} - addPolicy := func(action rbacpb.RBAC_Action, name string, rule string) { + addPolicy := func(action policyAction, name string, rule string) { if actionToPolicy[action] == nil { actionToPolicy[action] = map[string]struct{}{} } @@ -151,21 +160,33 @@ func Print(writer io.Writer, listeners []*listener.Listener) { for _, parsed := range parsedListeners { for _, fc := range parsed.filterChains { for _, rbacHTTP := range fc.rbacHTTP { - action := rbacHTTP.GetRules().GetAction() + action := policyAction(rbacHTTP.GetRules().GetAction().String()) for name := range rbacHTTP.GetRules().GetPolicies() { nameOfPolicy, indexOfRule := extractName(name) addPolicy(action, nameOfPolicy, indexOfRule) } + for name := range rbacHTTP.GetShadowRules().GetPolicies() { + if strings.HasPrefix(name, "istio-ext-authz-") { + nameOfPolicy, indexOfRule := extractName(name) + addPolicy(policyActionCustom, nameOfPolicy, indexOfRule) + } + } if len(rbacHTTP.GetRules().GetPolicies()) == 0 { addPolicy(action, anonymousName, "0") } } for _, rbacTCP := range fc.rbacTCP { - action := rbacTCP.GetRules().GetAction() + action := policyAction(rbacTCP.GetRules().GetAction().String()) for name := range rbacTCP.GetRules().GetPolicies() { nameOfPolicy, indexOfRule := extractName(name) addPolicy(action, nameOfPolicy, indexOfRule) } + for name := range rbacTCP.GetShadowRules().GetPolicies() { + if strings.HasPrefix(name, "istio-ext-authz-") { + nameOfPolicy, indexOfRule := extractName(name) + addPolicy(policyActionCustom, nameOfPolicy, indexOfRule) + } + } if len(rbacTCP.GetRules().GetPolicies()) == 0 { addPolicy(action, anonymousName, "0") } @@ -175,7 +196,7 @@ func Print(writer io.Writer, listeners []*listener.Listener) { buf := strings.Builder{} buf.WriteString("ACTION\tAuthorizationPolicy\tRULES\n") - for _, action := range []rbacpb.RBAC_Action{rbacpb.RBAC_DENY, rbacpb.RBAC_ALLOW, rbacpb.RBAC_LOG} { + for _, action := range []policyAction{policyActionDeny, policyActionAllow, policyActionLog, policyActionCustom} { if names, ok := actionToPolicy[action]; ok { sortedNames := make([]string, 0, len(names)) for name := range names { diff --git a/istioctl/pkg/authz/testdata/configdump.yaml b/istioctl/pkg/authz/testdata/configdump.yaml index f9ea9ae55342..7ab349aaa662 100644 --- a/istioctl/pkg/authz/testdata/configdump.yaml +++ b/istioctl/pkg/authz/testdata/configdump.yaml @@ -4255,6 +4255,214 @@ "shadow_rules_stat_prefix": "istio_dry_run_allow_" } }, + { + "name": "envoy.filters.http.rbac", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "shadow_rules": { + "action": "DENY", + "policies": { + "istio-ext-authz-ns[default]-policy[ext-authz]-rule[0]": { + "permissions": [ + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "GET" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "prefix": "/info" + } + } + } + ] + } + } + ] + } + }, + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "POST" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "exact": "/data" + } + } + } + ] + } + } + ] + } + } + ], + "principals": [ + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "exact": "spiffe://cluster.local/ns/default/sa/sleep" + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + }, + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "safe_regex": { + "regex": ".*/ns/test/.*" + } + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + } + ] + } + } + }, + "shadow_rules_stat_prefix": "istio_ext_authz_" + } + }, + { + "name": "envoy.filters.http.ext_authz", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz", + "grpc_service": { + "envoy_grpc": { + "cluster_name": "outbound|9191||sample-ext-authz-grpc", + "authority": "sample-ext-authz-grpc.local" + }, + "timeout": "600s" + }, + "with_request_body": { + "max_request_bytes": 8000 + }, + "transport_api_version": "V3", + "filter_enabled_metadata": { + "filter": "envoy.filters.http.rbac", + "path": [ + { + "key": "istio_ext_authz_shadow_effective_policy_id" + } + ], + "value": { + "string_match": { + "prefix": "istio-ext-authz" + } + } + } + } + }, { "name": "envoy.filters.http.grpc_stats", "typed_config": { @@ -4754,75 +4962,283 @@ } }, { - "name": "envoy.filters.http.grpc_stats", - "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig", - "emit_filter_state": true, - "stats_for_all_methods": false - } - }, - { - "name": "envoy.filters.http.fault", - "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault" - } - }, - { - "name": "envoy.filters.http.cors", - "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors" - } - }, - { - "name": "istio.stats", - "typed_config": { - "@type": "type.googleapis.com/stats.PluginConfig", - "disable_host_header_fallback": true - } - }, - { - "name": "envoy.filters.http.router", + "name": "envoy.filters.http.rbac", "typed_config": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "client_sampling": { - "value": 100 - }, - "random_sampling": { - "value": 1 - }, - "overall_sampling": { - "value": 100 - }, - "custom_tags": [ - { - "tag": "istio.authorization.dry_run.allow_policy.name", - "metadata": { - "kind": { - "request": {} - }, - "metadata_key": { - "key": "envoy.filters.http.rbac", - "path": [ - { - "key": "istio_dry_run_allow_shadow_effective_policy_id" - } - ] - } - } - }, - { - "tag": "istio.authorization.dry_run.allow_policy.result", - "metadata": { - "kind": { - "request": {} - }, - "metadata_key": { - "key": "envoy.filters.http.rbac", - "path": [ + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "shadow_rules": { + "action": "DENY", + "policies": { + "istio-ext-authz-ns[default]-policy[ext-authz]-rule[0]": { + "permissions": [ + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "GET" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "prefix": "/info" + } + } + } + ] + } + } + ] + } + }, + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "POST" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "exact": "/data" + } + } + } + ] + } + } + ] + } + } + ], + "principals": [ + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "exact": "spiffe://cluster.local/ns/default/sa/sleep" + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + }, + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "safe_regex": { + "regex": ".*/ns/test/.*" + } + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + } + ] + } + } + }, + "shadow_rules_stat_prefix": "istio_ext_authz_" + } + }, + { + "name": "envoy.filters.http.ext_authz", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz", + "grpc_service": { + "envoy_grpc": { + "cluster_name": "outbound|9191||sample-ext-authz-grpc", + "authority": "sample-ext-authz-grpc.local" + }, + "timeout": "600s" + }, + "with_request_body": { + "max_request_bytes": 8000 + }, + "transport_api_version": "V3", + "filter_enabled_metadata": { + "filter": "envoy.filters.http.rbac", + "path": [ + { + "key": "istio_ext_authz_shadow_effective_policy_id" + } + ], + "value": { + "string_match": { + "prefix": "istio-ext-authz" + } + } + } + } + }, + { + "name": "envoy.filters.http.grpc_stats", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig", + "emit_filter_state": true, + "stats_for_all_methods": false + } + }, + { + "name": "envoy.filters.http.fault", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault" + } + }, + { + "name": "envoy.filters.http.cors", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors" + } + }, + { + "name": "istio.stats", + "typed_config": { + "@type": "type.googleapis.com/stats.PluginConfig", + "disable_host_header_fallback": true + } + }, + { + "name": "envoy.filters.http.router", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "client_sampling": { + "value": 100 + }, + "random_sampling": { + "value": 1 + }, + "overall_sampling": { + "value": 100 + }, + "custom_tags": [ + { + "tag": "istio.authorization.dry_run.allow_policy.name", + "metadata": { + "kind": { + "request": {} + }, + "metadata_key": { + "key": "envoy.filters.http.rbac", + "path": [ + { + "key": "istio_dry_run_allow_shadow_effective_policy_id" + } + ] + } + } + }, + { + "tag": "istio.authorization.dry_run.allow_policy.result", + "metadata": { + "kind": { + "request": {} + }, + "metadata_key": { + "key": "envoy.filters.http.rbac", + "path": [ { "key": "istio_dry_run_allow_shadow_engine_result" } @@ -5411,7 +5827,215 @@ } }, { - "name": "envoy.filters.http.grpc_stats", + "name": "envoy.filters.http.rbac", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "shadow_rules": { + "action": "DENY", + "policies": { + "istio-ext-authz-ns[default]-policy[ext-authz]-rule[0]": { + "permissions": [ + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "GET" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "prefix": "/info" + } + } + } + ] + } + } + ] + } + }, + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "POST" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "exact": "/data" + } + } + } + ] + } + } + ] + } + } + ], + "principals": [ + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "exact": "spiffe://cluster.local/ns/default/sa/sleep" + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + }, + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "safe_regex": { + "regex": ".*/ns/test/.*" + } + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + } + ] + } + } + }, + "shadow_rules_stat_prefix": "istio_ext_authz_" + } + }, + { + "name": "envoy.filters.http.ext_authz", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz", + "grpc_service": { + "envoy_grpc": { + "cluster_name": "outbound|9191||sample-ext-authz-grpc", + "authority": "sample-ext-authz-grpc.local" + }, + "timeout": "600s" + }, + "with_request_body": { + "max_request_bytes": 8000 + }, + "transport_api_version": "V3", + "filter_enabled_metadata": { + "filter": "envoy.filters.http.rbac", + "path": [ + { + "key": "istio_ext_authz_shadow_effective_policy_id" + } + ], + "value": { + "string_match": { + "prefix": "istio-ext-authz" + } + } + } + } + }, + { + "name": "envoy.filters.http.grpc_stats", "typed_config": { "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig", "emit_filter_state": true, @@ -5715,20 +6339,198 @@ "inline_string": "envoy.wasm.metadata_exchange" } } - }, - "configuration": { - "@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange" + }, + "configuration": { + "@type": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange" + } + } + } + }, + { + "name": "envoy.filters.http.rbac", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": { + "policies": { + "ns[default]-policy[httpbin]-rule[0]": { + "permissions": [ + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "GET" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "prefix": "/info" + } + } + } + ] + } + } + ] + } + }, + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "POST" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "exact": "/data" + } + } + } + ] + } + } + ] + } + } + ], + "principals": [ + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "exact": "spiffe://cluster.local/ns/default/sa/sleep" + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + }, + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "safe_regex": { + "regex": ".*/ns/test/.*" + } + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + } + ] + } } - } + }, + "shadow_rules_stat_prefix": "istio_dry_run_allow_" } }, { "name": "envoy.filters.http.rbac", "typed_config": { "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": { + "shadow_rules": { + "action": "DENY", "policies": { - "ns[default]-policy[httpbin]-rule[0]": { + "istio-ext-authz-ns[default]-policy[ext-authz]-rule[0]": { "permissions": [ { "and_rules": { @@ -5896,7 +6698,37 @@ } } }, - "shadow_rules_stat_prefix": "istio_dry_run_allow_" + "shadow_rules_stat_prefix": "istio_ext_authz_" + } + }, + { + "name": "envoy.filters.http.ext_authz", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz", + "grpc_service": { + "envoy_grpc": { + "cluster_name": "outbound|9191||sample-ext-authz-grpc", + "authority": "sample-ext-authz-grpc.local" + }, + "timeout": "600s" + }, + "with_request_body": { + "max_request_bytes": 8000 + }, + "transport_api_version": "V3", + "filter_enabled_metadata": { + "filter": "envoy.filters.http.rbac", + "path": [ + { + "key": "istio_ext_authz_shadow_effective_policy_id" + } + ], + "value": { + "string_match": { + "prefix": "istio-ext-authz" + } + } + } } }, { @@ -6525,6 +7357,214 @@ "shadow_rules_stat_prefix": "istio_dry_run_allow_" } }, + { + "name": "envoy.filters.http.rbac", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "shadow_rules": { + "action": "DENY", + "policies": { + "istio-ext-authz-ns[default]-policy[ext-authz]-rule[0]": { + "permissions": [ + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "GET" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "prefix": "/info" + } + } + } + ] + } + } + ] + } + }, + { + "and_rules": { + "rules": [ + { + "or_rules": { + "rules": [ + { + "header": { + "name": ":method", + "exact_match": "POST" + } + } + ] + } + }, + { + "or_rules": { + "rules": [ + { + "url_path": { + "path": { + "exact": "/data" + } + } + } + ] + } + } + ] + } + } + ], + "principals": [ + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "exact": "spiffe://cluster.local/ns/default/sa/sleep" + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + }, + { + "and_ids": { + "ids": [ + { + "or_ids": { + "ids": [ + { + "filter_state": { + "key": "io.istio.peer_principal", + "string_match": { + "safe_regex": { + "regex": ".*/ns/test/.*" + } + } + } + } + ] + } + }, + { + "or_ids": { + "ids": [ + { + "metadata": { + "filter": "istio_authn", + "path": [ + { + "key": "request.auth.claims" + }, + { + "key": "iss" + } + ], + "value": { + "list_match": { + "one_of": { + "string_match": { + "exact": "https://accounts.google.com" + } + } + } + } + } + } + ] + } + } + ] + } + } + ] + } + } + }, + "shadow_rules_stat_prefix": "istio_ext_authz_" + } + }, + { + "name": "envoy.filters.http.ext_authz", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz", + "grpc_service": { + "envoy_grpc": { + "cluster_name": "outbound|9191||sample-ext-authz-grpc", + "authority": "sample-ext-authz-grpc.local" + }, + "timeout": "600s" + }, + "with_request_body": { + "max_request_bytes": 8000 + }, + "transport_api_version": "V3", + "filter_enabled_metadata": { + "filter": "envoy.filters.http.rbac", + "path": [ + { + "key": "istio_ext_authz_shadow_effective_policy_id" + } + ], + "value": { + "string_match": { + "prefix": "istio-ext-authz" + } + } + } + } + }, { "name": "envoy.filters.http.grpc_stats", "typed_config": { diff --git a/istioctl/pkg/describe/describe.go b/istioctl/pkg/describe/describe.go index 148ec9b94565..8bc9ff76cbf6 100644 --- a/istioctl/pkg/describe/describe.go +++ b/istioctl/pkg/describe/describe.go @@ -1434,7 +1434,6 @@ func describePeerAuthentication( var cfgs []*config.Config for _, pa := range allPAs { - pa := pa cfg := crdclient.TranslateObject(pa, config.GroupVersionKind(pa.GroupVersionKind()), "") cfgs = append(cfgs, &cfg) } @@ -1463,7 +1462,6 @@ func findMatchedConfigs(podsLabels klabels.Set, configs []*config.Config) []*con var cfgs []*config.Config for _, cfg := range configs { - cfg := cfg labels := cfg.Spec.(Workloader).GetSelector().GetMatchLabels() selector := klabels.SelectorFromSet(labels) if selector.Matches(podsLabels) { diff --git a/istioctl/pkg/injector/injector-list.go b/istioctl/pkg/injector/injector-list.go index 7e73896193ee..56b85e4680a9 100644 --- a/istioctl/pkg/injector/injector-list.go +++ b/istioctl/pkg/injector/injector-list.go @@ -249,6 +249,9 @@ func getMatchingNamespaces(hook *admitv1.MutatingWebhookConfiguration, namespace retval := make([]corev1.Namespace, 0, len(namespaces)) seen := sets.String{} for _, webhook := range hook.Webhooks { + if webhook.Name != "rev.namespace.sidecar-injector.istio.io" && webhook.Name != "namespace.sidecar-injector.istio.io" { + continue + } nsSelector, err := metav1.LabelSelectorAsSelector(webhook.NamespaceSelector) if err != nil { return retval diff --git a/istioctl/pkg/install/k8sversion/version.go b/istioctl/pkg/install/k8sversion/version.go index b399b5b275da..f3aaa05ef1d8 100644 --- a/istioctl/pkg/install/k8sversion/version.go +++ b/istioctl/pkg/install/k8sversion/version.go @@ -28,7 +28,7 @@ import ( const ( // MinK8SVersion is the minimum k8s version required to run this version of Istio // https://istio.io/docs/setup/platform-setup/ - MinK8SVersion = 26 + MinK8SVersion = 28 UnSupportedK8SVersionLogMsg = "\nThe Kubernetes version %s is not supported by Istio %s. The minimum supported Kubernetes version is 1.%d.\n" + "Proceeding with the installation, but you might experience problems. " + "See https://istio.io/latest/docs/releases/supported-releases/ for a list of supported versions.\n" diff --git a/istioctl/pkg/install/k8sversion/version_test.go b/istioctl/pkg/install/k8sversion/version_test.go index 749fc7014fe0..5a992495a61f 100644 --- a/istioctl/pkg/install/k8sversion/version_test.go +++ b/istioctl/pkg/install/k8sversion/version_test.go @@ -79,6 +79,11 @@ var ( Minor: "26", GitVersion: "v1.26", } + version1_28 = &version.Info{ + Major: "1", + Minor: "28", + GitVersion: "v1.28", + } version1_19RC = &version.Info{ Major: "1", Minor: "19", @@ -244,6 +249,11 @@ func TestIsK8VersionSupported(t *testing.T) { }, { version: version1_26, + logMsg: fmt.Sprintf(UnSupportedK8SVersionLogMsg, version1_26.GitVersion, pkgVersion.Info.Version, MinK8SVersion), + isValid: false, + }, + { + version: version1_28, isValid: true, }, } diff --git a/istioctl/pkg/multicluster/remote_secret_test.go b/istioctl/pkg/multicluster/remote_secret_test.go index 502461cf1a9b..ce8793e4897e 100644 --- a/istioctl/pkg/multicluster/remote_secret_test.go +++ b/istioctl/pkg/multicluster/remote_secret_test.go @@ -440,7 +440,6 @@ func mustFindObject(t test.Failer, objs []manifest.Manifest, name, kind string) t.Helper() var obj *manifest.Manifest for _, o := range objs { - o := o if o.GetKind() == kind && o.GetName() == name { obj = &o break diff --git a/istioctl/pkg/precheck/precheck.go b/istioctl/pkg/precheck/precheck.go index 6b976f70bcd8..916c31b738f4 100644 --- a/istioctl/pkg/precheck/precheck.go +++ b/istioctl/pkg/precheck/precheck.go @@ -27,16 +27,12 @@ import ( crd "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/yaml" - "istio.io/api/label" - networking "istio.io/api/networking/v1alpha3" "istio.io/istio/istioctl/pkg/cli" "istio.io/istio/istioctl/pkg/clioptions" "istio.io/istio/istioctl/pkg/install/k8sversion" "istio.io/istio/istioctl/pkg/util/formatting" istiocluster "istio.io/istio/pkg/cluster" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/analysis" "istio.io/istio/pkg/config/analysis/analyzers/maturity" "istio.io/istio/pkg/config/analysis/diag" @@ -149,15 +145,6 @@ func checkFromVersion(ctx cli.Context, revision, version string) (diag.Messages, var messages diag.Messages = make([]diag.Message, 0) if minor <= 21 { - // ENHANCED_RESOURCE_SCOPING - if err := checkPilot(cli, ctx.IstioNamespace(), &messages); err != nil { - return nil, err - } - } - if minor <= 21 { - if err := checkPassthroughTargetPorts(cli, &messages); err != nil { - return nil, err - } if err := checkTracing(cli, &messages); err != nil { return nil, err } @@ -186,92 +173,6 @@ func checkTracing(cli kube.CLIClient, messages *diag.Messages) error { return nil } -func checkPassthroughTargetPorts(cli kube.CLIClient, messages *diag.Messages) error { - ses, err := cli.Istio().NetworkingV1().ServiceEntries(metav1.NamespaceAll).List(context.Background(), metav1.ListOptions{}) - if err != nil { - return err - } - for _, se := range ses.Items { - if se.Spec.Resolution != networking.ServiceEntry_NONE { - continue - } - changed := false - for _, p := range se.Spec.Ports { - if p.TargetPort != 0 && p.Number != p.TargetPort { - changed = true - } - } - if changed { - res := ObjectToInstance(se) - messages.Add(msg.NewUpdateIncompatibility(res, - "ENABLE_RESOLUTION_NONE_TARGET_PORT", "1.21", - "ServiceEntry with resolution NONE and a targetPort set previously did nothing but now is respected", "1.21")) - } - } - return nil -} - -func checkPilot(cli kube.CLIClient, namespace string, messages *diag.Messages) error { - deployments, err := cli.Kube().AppsV1().Deployments(namespace).List(context.TODO(), metav1.ListOptions{ - LabelSelector: "app=istiod", - }) - if err != nil { - return err - } - for _, deployment := range deployments.Items { - scopingImpacted := false - - // Obtain configmap to verify if affected features are used - configMapName := "istio" - if rev := deployment.Labels[label.IoIstioRev.Name]; rev != "default" { - configMapName += fmt.Sprintf("-%s", rev) - } - configMap, err := cli.Kube().CoreV1().ConfigMaps(namespace).Get(context.TODO(), configMapName, metav1.GetOptions{}) - if err != nil { - fmt.Printf("Error getting configmap %s: %v\n", configMapName, err) - } - meshData := make(map[string]interface{}) - if data, exists := configMap.Data["mesh"]; exists { - if err := yaml.Unmarshal([]byte(data), &meshData); err != nil { - fmt.Printf("Error parsing meshConfig: %v\n", err) - return err - } - } - if scopingImpacted = meshData["discoverySelectors"] != nil; !scopingImpacted { - continue - } - // Check if mitigation is already in place - for _, container := range deployment.Spec.Template.Spec.Containers { - if container.Name == "discovery" { - for _, envVar := range container.Env { - if envVar.Name == "ENHANCED_RESOURCE_SCOPING" && envVar.Value == "true" { - scopingImpacted = false - break - } - } - } - } - if scopingImpacted { - res := &resource.Instance{ - Origin: &legacykube.Origin{ - Type: config.GroupVersionKind(deployment.GroupVersionKind()), - FullName: resource.FullName{ - Namespace: resource.Namespace(deployment.GetNamespace()), - Name: resource.LocalName(deployment.GetName()), - }, - ResourceVersion: resource.Version(deployment.GetResourceVersion()), - Ref: nil, - FieldsMap: nil, - }, - } - messages.Add(msg.NewUpdateIncompatibility(res, - "ENHANCED_RESOURCE_SCOPING", "1.22", - "previously, the enhanced scoping of custom resources was disabled by default; now it will be enabled by default", "1.21")) - } - } - return nil -} - func ObjectToInstance(c controllers.Object) *resource.Instance { return &resource.Instance{ Origin: &legacykube.Origin{ diff --git a/istioctl/pkg/precheck/precheck_test.go b/istioctl/pkg/precheck/precheck_test.go index 020913958ce5..3b929eac29f9 100644 --- a/istioctl/pkg/precheck/precheck_test.go +++ b/istioctl/pkg/precheck/precheck_test.go @@ -15,14 +15,11 @@ package precheck import ( - "context" "fmt" "net/http" "testing" "github.com/stretchr/testify/assert" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/cli-runtime/pkg/resource" "k8s.io/client-go/rest/fake" cmdtesting "k8s.io/kubectl/pkg/cmd/testing" @@ -30,7 +27,6 @@ import ( "istio.io/istio/istioctl/pkg/cli" "istio.io/istio/pkg/config/analysis/diag" - "istio.io/istio/pkg/config/analysis/msg" "istio.io/istio/pkg/kube" ) @@ -67,13 +63,6 @@ func Test_checkFromVersion(t *testing.T) { expectedOutput: nil, expectedError: fmt.Errorf("minor version is not a number: X"), }, - // TODO: add more test cases - // minor <= 21 and checkPilot failing - // minor <= 20 and checkDestinationRuleTLS failing - // minor <= 20 and checkExternalNameAlias failing - // minor <= 20 and checkVirtualServiceHostMatching failing - // minor <= 21 and checkPassthroughTargetPorts failing - // minor <= 21 and checkTracing failing } for _, c := range cases { @@ -94,31 +83,6 @@ func Test_checkFromVersion(t *testing.T) { } } -func Test_checkTracing(t *testing.T) { - cli := kube.NewFakeClient() - messages := diag.Messages{} - - zipkinSvc := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: "zipkin", - Namespace: "istio-system", - }, - } - cli.Kube().CoreV1().Services("istio-system").Create(context.Background(), zipkinSvc, metav1.CreateOptions{}) - - err := checkTracing(cli, &messages) - assert.NoError(t, err) - assert.Equal(t, 1, len(messages)) - - expectedOutput := msg.NewUpdateIncompatibility(ObjectToInstance(zipkinSvc), - "meshConfig.defaultConfig.tracer", "1.21", - "tracing is no longer by default enabled to send to 'zipkin.istio-system.svc'; "+ - "follow https://istio.io/latest/docs/tasks/observability/distributed-tracing/telemetry-api/", - "1.21") - - assert.Equal(t, expectedOutput, messages[0]) -} - func init() { cli.MakeKubeFactory = func(k kube.CLIClient) cmdutil.Factory { tf := cmdtesting.NewTestFactory() diff --git a/istioctl/pkg/proxyconfig/proxyconfig.go b/istioctl/pkg/proxyconfig/proxyconfig.go index 3ba18b8392de..aeaf60434497 100644 --- a/istioctl/pkg/proxyconfig/proxyconfig.go +++ b/istioctl/pkg/proxyconfig/proxyconfig.go @@ -102,6 +102,21 @@ const ( TraceLevel ) +const ( + // edsPath get eds info + edsPath = "?include_eds=true" + // secretPath get secrets info + secretPath = "?mask=dynamic_active_secrets" + // clusterPath get cluster info + clusterPath = "?mask=dynamic_active_clusters,static_clusters" + // listenerPath get listener info + listenerPath = "?mask=dynamic_listeners,static_listeners" + // routePath get route info + routePath = "?mask=dynamic_route_configs,static_route_configs" + // bootstrapPath get bootstrap info + bootstrapPath = "?mask=bootstrap" +) + var levelToString = map[Level]string{ TraceLevel: "trace", DebugLevel: "debug", @@ -128,11 +143,8 @@ var ( reset = false ) -func extractConfigDump(kubeClient kube.CLIClient, podName, podNamespace string, eds bool) ([]byte, error) { - path := "config_dump" - if eds { - path += "?include_eds=true" - } +func extractConfigDump(kubeClient kube.CLIClient, podName, podNamespace string, addtionPath string) ([]byte, error) { + path := "config_dump" + addtionPath debug, err := kubeClient.EnvoyDoWithPort(context.TODO(), podName, podNamespace, "GET", path, proxyAdminPort) if err != nil { return nil, fmt.Errorf("failed to execute command on %s.%s sidecar: %v", podName, podNamespace, err) @@ -140,8 +152,8 @@ func extractConfigDump(kubeClient kube.CLIClient, podName, podNamespace string, return debug, err } -func setupPodConfigdumpWriter(kubeClient kube.CLIClient, podName, podNamespace string, includeEds bool, out io.Writer) (*configdump.ConfigWriter, error) { - debug, err := extractConfigDump(kubeClient, podName, podNamespace, includeEds) +func setupPodConfigdumpWriter(kubeClient kube.CLIClient, podName, podNamespace string, addtionPath string, out io.Writer) (*configdump.ConfigWriter, error) { + debug, err := extractConfigDump(kubeClient, podName, podNamespace, addtionPath) if err != nil { return nil, err } @@ -184,9 +196,13 @@ func setupConfigdumpEnvoyConfigWriter(debug []byte, out io.Writer) (*configdump. func setupEnvoyClusterStatsConfig(kubeClient kube.CLIClient, podName, podNamespace string, outputFormat string) (string, error) { path := "clusters" - if outputFormat == jsonOutput || outputFormat == yamlOutput { + switch outputFormat { + case "", summaryOutput: + case jsonOutput, yamlOutput: // for yaml output we will convert the json to yaml when printed path += "?format=json" + default: + return "", fmt.Errorf("unable to match a printer suitable for the output format %s, allowed formats are: json,yaml,short", outputFormat) } result, err := kubeClient.EnvoyDoWithPort(context.TODO(), podName, podNamespace, "GET", path, proxyAdminPort) if err != nil { @@ -197,12 +213,14 @@ func setupEnvoyClusterStatsConfig(kubeClient kube.CLIClient, podName, podNamespa func setupEnvoyServerStatsConfig(kubeClient kube.CLIClient, podName, podNamespace string, outputFormat string) (string, error) { path := "stats" - if outputFormat == jsonOutput || outputFormat == yamlOutput { + switch outputFormat { + case "", summaryOutput: + case jsonOutput, yamlOutput: // for yaml output we will convert the json to yaml when printed path += "?format=json" - } else if outputFormat == prometheusOutput { + case prometheusOutput: path += "/prometheus" - } else if outputFormat == prometheusMergedOutput { + case prometheusMergedOutput: pod, err := kubeClient.Kube().CoreV1().Pods(podNamespace).Get(context.Background(), podName, metav1.GetOptions{}) if err != nil { return "", fmt.Errorf("failed to retrieve Pod %s/%s: %v", podNamespace, podName, err) @@ -214,6 +232,8 @@ func setupEnvoyServerStatsConfig(kubeClient kube.CLIClient, podName, podNamespac } path = promPath port = promPort + default: + return "", fmt.Errorf("unable to match a printer suitable for the output format %s, allowed formats are: json,yaml,short,prom,prom-merged", outputFormat) } result, err := kubeClient.EnvoyDoWithPort(context.Background(), podName, podNamespace, "GET", path, proxyAdminPort) @@ -365,7 +385,7 @@ func clusterConfigCmd(ctx cli.Context) *cobra.Command { if podName, podNamespace, err = getPodName(ctx, args[0]); err != nil { return err } - configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, false, c.OutOrStdout()) + configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, clusterPath, c.OutOrStdout()) } else { configWriter, err = setupFileConfigdumpWriter(configDumpFile, c.OutOrStdout()) } @@ -444,7 +464,7 @@ func allConfigCmd(ctx cli.Context) *cobra.Command { if err != nil { return err } - dump, err = extractConfigDump(kubeClient, podName, podNamespace, true) + dump, err = extractConfigDump(kubeClient, podName, podNamespace, edsPath) if err != nil { return err } @@ -469,7 +489,7 @@ func allConfigCmd(ctx cli.Context) *cobra.Command { return err } - configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, true, c.OutOrStdout()) + configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, edsPath, c.OutOrStdout()) if err != nil { return err } @@ -578,7 +598,7 @@ func listenerConfigCmd(ctx cli.Context) *cobra.Command { if podName, podNamespace, err = getPodName(ctx, args[0]); err != nil { return err } - configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, false, c.OutOrStdout()) + configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, listenerPath, c.OutOrStdout()) } else { configWriter, err = setupFileConfigdumpWriter(configDumpFile, c.OutOrStdout()) } @@ -876,7 +896,7 @@ func routeConfigCmd(ctx cli.Context) *cobra.Command { if podName, podNamespace, err = getPodName(ctx, args[0]); err != nil { return err } - configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, false, c.OutOrStdout()) + configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, routePath, c.OutOrStdout()) } else { configWriter, err = setupFileConfigdumpWriter(configDumpFile, c.OutOrStdout()) } @@ -1043,7 +1063,7 @@ func edsConfigCmd(ctx cli.Context) *cobra.Command { if podName, podNamespace, err = getPodName(ctx, args[0]); err != nil { return err } - configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, true, c.OutOrStdout()) + configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, edsPath, c.OutOrStdout()) } else { configWriter, err = setupFileConfigdumpWriter(configDumpFile, c.OutOrStdout()) } @@ -1122,7 +1142,7 @@ func bootstrapConfigCmd(ctx cli.Context) *cobra.Command { if podName, podNamespace, err = getPodName(ctx, args[0]); err != nil { return err } - configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, false, c.OutOrStdout()) + configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, bootstrapPath, c.OutOrStdout()) } else { configWriter, err = setupFileConfigdumpWriter(configDumpFile, c.OutOrStdout()) } @@ -1183,7 +1203,7 @@ func secretConfigCmd(ctx cli.Context) *cobra.Command { if podName, podNamespace, err = getPodName(ctx, args[0]); err != nil { return err } - cw, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, false, c.OutOrStdout()) + cw, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, secretPath, c.OutOrStdout()) } else { cw, err = setupFileConfigdumpWriter(configDumpFile, c.OutOrStdout()) if err != nil { @@ -1277,7 +1297,7 @@ func rootCACompareConfigCmd(ctx cli.Context) *cobra.Command { } func extractRootCA(client kube.CLIClient, podName, podNamespace string, out io.Writer) (string, error) { - configWriter, err := setupPodConfigdumpWriter(client, podName, podNamespace, false, out) + configWriter, err := setupPodConfigdumpWriter(client, podName, podNamespace, secretPath, out) if err != nil { return "", err } @@ -1388,7 +1408,7 @@ func ecdsConfigCmd(ctx cli.Context) *cobra.Command { if podName, podNamespace, err = getPodName(ctx, args[0]); err != nil { return err } - configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, true, c.OutOrStdout()) + configWriter, err = setupPodConfigdumpWriter(kubeClient, podName, podNamespace, edsPath, c.OutOrStdout()) } else { configWriter, err = setupFileConfigdumpWriter(configDumpFile, c.OutOrStdout()) } diff --git a/istioctl/pkg/version/version.go b/istioctl/pkg/version/version.go index c9d284adbe62..86a64a9a3133 100644 --- a/istioctl/pkg/version/version.go +++ b/istioctl/pkg/version/version.go @@ -203,6 +203,9 @@ func xdsRemoteVersionWrapper(ctx cli.Context, opts *clioptions.ControlPlaneOptio func xdsProxyVersionWrapper(xdsResponse **discovery.DiscoveryResponse) func() (*[]istioVersion.ProxyInfo, error) { return func() (*[]istioVersion.ProxyInfo, error) { pi := []istioVersion.ProxyInfo{} + if *xdsResponse == nil { + return nil, fmt.Errorf("invalid xdsResponse") + } for _, resource := range (*xdsResponse).Resources { switch resource.TypeUrl { case "type.googleapis.com/envoy.config.core.v3.Node": diff --git a/istioctl/pkg/waypoint/waypoint.go b/istioctl/pkg/waypoint/waypoint.go index 2414ebded5ea..ada671fbafd2 100644 --- a/istioctl/pkg/waypoint/waypoint.go +++ b/istioctl/pkg/waypoint/waypoint.go @@ -470,6 +470,9 @@ func deleteWaypoints(cmd *cobra.Command, kubeClient kube.CLIClient, namespace st return err } for _, gw := range waypoints.Items { + if gw.Spec.GatewayClassName != constants.WaypointGatewayClassName { + continue + } names = append(names, gw.Name) } } diff --git a/istioctl/pkg/workload/workload.go b/istioctl/pkg/workload/workload.go index e72c576bba98..b85d2a64ef35 100644 --- a/istioctl/pkg/workload/workload.go +++ b/istioctl/pkg/workload/workload.go @@ -72,6 +72,7 @@ var ( resourceLabels []string annotations []string namespace string + network string ) const ( @@ -151,6 +152,7 @@ The default output is serialized YAML, which can be piped into 'kubectl apply -f Template: &networkingv1alpha3.WorkloadEntry{ Ports: convertToUnsignedInt32Map(ports), ServiceAccount: serviceAccount, + Network: network, }, } wgYAML, err := generateWorkloadGroupYAML(u, spec) @@ -167,6 +169,7 @@ The default output is serialized YAML, which can be piped into 'kubectl apply -f createCmd.PersistentFlags().StringSliceVarP(&annotations, "annotations", "a", nil, "The annotations to apply to the workload instances") createCmd.PersistentFlags().StringSliceVarP(&ports, "ports", "p", nil, "The incoming ports exposed by the workload instance") createCmd.PersistentFlags().StringVarP(&serviceAccount, "serviceAccount", "s", "default", "The service identity to associate with the workload instances") + createCmd.PersistentFlags().StringVar(&network, "network", "", "Network enables Istio to group endpoints resident in the same L3 domain/network.") _ = createCmd.RegisterFlagCompletionFunc("serviceAccount", func( cmd *cobra.Command, args []string, toComplete string, ) ([]string, cobra.ShellCompDirective) { diff --git a/istioctl/pkg/writer/compare/sds/util.go b/istioctl/pkg/writer/compare/sds/util.go index 419faa85895a..e5b763dfea80 100644 --- a/istioctl/pkg/writer/compare/sds/util.go +++ b/istioctl/pkg/writer/compare/sds/util.go @@ -42,6 +42,7 @@ type SecretItem struct { Source string `json:"source"` Destination string `json:"destination"` State string `json:"state"` + TrustDomain string `json:"trust_domain"` SecretMeta } @@ -52,6 +53,7 @@ type SecretMeta struct { NotAfter string `json:"not_after"` NotBefore string `json:"not_before"` Type string `json:"type"` + TrustDomain string `json:"trust_domain"` } // NewSecretItemBuilder returns a new builder to create a secret item @@ -67,16 +69,18 @@ type SecretItemBuilder interface { Source(string) SecretItemBuilder Destination(string) SecretItemBuilder State(string) SecretItemBuilder + TrustDomain(string) SecretItemBuilder Build() (SecretItem, error) } // secretItemBuilder implements SecretItemBuilder, and acts as an intermediate before SecretItem generation type secretItemBuilder struct { - name string - data string - source string - dest string - state string + name string + data string + source string + dest string + state string + trustDomain string SecretMeta } @@ -110,6 +114,12 @@ func (s *secretItemBuilder) State(state string) SecretItemBuilder { return s } +// TrustDomain sets the trust domain of the secret on the agent or sidecar +func (s *secretItemBuilder) TrustDomain(trustDomain string) SecretItemBuilder { + s.trustDomain = trustDomain + return s +} + // Build takes the set fields from the builder and constructs the actual SecretItem // including generating the SecretMeta from the supplied cert data, if present func (s *secretItemBuilder) Build() (SecretItem, error) { @@ -119,12 +129,13 @@ func (s *secretItemBuilder) Build() (SecretItem, error) { Source: s.source, Destination: s.dest, State: s.state, + TrustDomain: s.trustDomain, } var meta SecretMeta var err error if s.data != "" { - meta, err = secretMetaFromCert([]byte(s.data)) + meta, err = secretMetaFromCert([]byte(s.data), result.TrustDomain) if err != nil { log.Debugf("failed to parse secret resource %s from source %s: %v", s.name, s.source, err) @@ -150,35 +161,37 @@ func GetEnvoySecrets( proxySecretItems := make([]SecretItem, 0) for _, warmingSecret := range secretConfigDump.DynamicWarmingSecrets { - secret, err := parseDynamicSecret(warmingSecret, "WARMING") + secrets, err := parseDynamicSecret(warmingSecret, "WARMING") if err != nil { return nil, fmt.Errorf("failed building warming secret %s: %v", warmingSecret.Name, err) } - proxySecretItems = append(proxySecretItems, secret) + proxySecretItems = append(proxySecretItems, secrets...) } for _, activeSecret := range secretConfigDump.DynamicActiveSecrets { - secret, err := parseDynamicSecret(activeSecret, "ACTIVE") + secrets, err := parseDynamicSecret(activeSecret, "ACTIVE") if err != nil { return nil, fmt.Errorf("failed building warming secret %s: %v", activeSecret.Name, err) } - if activeSecret.VersionInfo == "uninitialized" { - secret.State = "UNINITIALIZED" + for _, secret := range secrets { + if activeSecret.VersionInfo == "uninitialized" { + secret.State = "UNINITIALIZED" + } } - proxySecretItems = append(proxySecretItems, secret) + proxySecretItems = append(proxySecretItems, secrets...) } return proxySecretItems, nil } -func parseDynamicSecret(s *envoy_admin.SecretsConfigDump_DynamicSecret, state string) (SecretItem, error) { +func parseDynamicSecret(s *envoy_admin.SecretsConfigDump_DynamicSecret, state string) ([]SecretItem, error) { builder := NewSecretItemBuilder() builder.Name(s.Name).State(state) secretTyped := &auth.Secret{} err := s.GetSecret().UnmarshalTo(secretTyped) if err != nil { - return SecretItem{}, err + return []SecretItem{}, err } certChainSecret := secretTyped. @@ -196,17 +209,19 @@ func parseDynamicSecret(s *envoy_admin.SecretsConfigDump_DynamicSecret, state st builder.Data(string(certChainSecret)) } else if len(caDataSecret) > 0 { builder.Data(string(caDataSecret)) + } else { + return parseTrustBundles(secretTyped, state) } secret, err := builder.Build() if err != nil { - return SecretItem{}, fmt.Errorf("error building secret: %v", err) + return []SecretItem{}, fmt.Errorf("error building secret: %v", err) } - return secret, nil + return []SecretItem{secret}, nil } -func secretMetaFromCert(rawCert []byte) (SecretMeta, error) { +func secretMetaFromCert(rawCert []byte, trustDomain string) (SecretMeta, error) { block, _ := pem.Decode(rawCert) if block == nil { return SecretMeta{}, fmt.Errorf("failed to parse certificate PEM") @@ -221,6 +236,15 @@ func secretMetaFromCert(rawCert []byte) (SecretMeta, error) { } else { certType = "Cert Chain" } + // Trust domain is already known for CAs from SPIFFECertValidator that includes this information, + // so skip determining this information, because usually it will be not included in the certificate. + if trustDomain == "" { + for _, uri := range cert.URIs { + if uri.Scheme == "spiffe" { + trustDomain = uri.Host + } + } + } today := time.Now() return SecretMeta{ @@ -229,5 +253,30 @@ func secretMetaFromCert(rawCert []byte) (SecretMeta, error) { NotBefore: cert.NotBefore.Format(time.RFC3339), Type: certType, Valid: today.After(cert.NotBefore) && today.Before(cert.NotAfter), + TrustDomain: trustDomain, }, nil } + +func parseTrustBundles(secret *auth.Secret, state string) ([]SecretItem, error) { + var secretItems []SecretItem + if customValidator := secret.GetValidationContext().GetCustomValidatorConfig(); customValidator != nil { + if customValidator.GetTypedConfig().GetTypeUrl() == "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig" { + spiffeConfig := &auth.SPIFFECertValidatorConfig{} + if err := customValidator.GetTypedConfig().UnmarshalTo(spiffeConfig); err != nil { + return nil, fmt.Errorf("error unmarshaling spiffe config: %v", err) + } + for _, td := range spiffeConfig.GetTrustDomains() { + builder := NewSecretItemBuilder() + builder.Name(secret.Name).State(state) + builder.TrustDomain(td.GetName()) + builder.Data(string(td.GetTrustBundle().GetInlineBytes())) + secretItem, err := builder.Build() + if err != nil { + return []SecretItem{}, err + } + secretItems = append(secretItems, secretItem) + } + } + } + return secretItems, nil +} diff --git a/istioctl/pkg/writer/compare/sds/writer.go b/istioctl/pkg/writer/compare/sds/writer.go index 06d3d2b6600e..8f5da51e6b48 100644 --- a/istioctl/pkg/writer/compare/sds/writer.go +++ b/istioctl/pkg/writer/compare/sds/writer.go @@ -79,14 +79,32 @@ func (w *sdsWriter) printSecretItemsTabular(secrets []SecretItem) error { fmt.Fprintln(w.w, "No secret items to show.") return nil } + var hasUnknownTrustDomain bool + for _, secret := range secrets { + if secret.SecretMeta.TrustDomain == "" { + hasUnknownTrustDomain = true + break + } + } + if !hasUnknownTrustDomain { + secretItemColumns = append(secretItemColumns, "TRUST DOMAIN") + } tw := new(tabwriter.Writer).Init(w.w, 0, 5, 5, ' ', 0) fmt.Fprintln(tw, strings.Join(secretItemColumns, "\t")) for _, s := range secrets { if includeConfigType { s.Name = fmt.Sprintf("secret/%s", s.Name) } - fmt.Fprintf(tw, "%s\t%s\t%s\t%t\t%s\t%s\t%s\n", - s.Name, s.Type, s.State, s.Valid, s.SerialNumber, s.NotAfter, s.NotBefore) + // If all secrets have a trust domain, we are probably dealing with trust domain federation, so print trust domains. + // Otherwise, do not do that, because we do not know how to determine that information from the certificate, + // so the output would be confusing. + if !hasUnknownTrustDomain { + fmt.Fprintf(tw, "%s\t%s\t%s\t%t\t%s\t%s\t%s\t%s\n", + s.Name, s.Type, s.State, s.Valid, s.SerialNumber, s.NotAfter, s.NotBefore, s.SecretMeta.TrustDomain) + } else { + fmt.Fprintf(tw, "%s\t%s\t%s\t%t\t%s\t%s\t%s\n", + s.Name, s.Type, s.State, s.Valid, s.SerialNumber, s.NotAfter, s.NotBefore) + } } return tw.Flush() } diff --git a/istioctl/pkg/writer/envoy/configdump/secret_test.go b/istioctl/pkg/writer/envoy/configdump/secret_test.go index ab8dca16fd01..67314b0beb25 100644 --- a/istioctl/pkg/writer/envoy/configdump/secret_test.go +++ b/istioctl/pkg/writer/envoy/configdump/secret_test.go @@ -16,6 +16,7 @@ package configdump import ( "bytes" + "fmt" "io" "os" "testing" @@ -24,32 +25,40 @@ import ( ) func TestSDSWriter_ValidCert(t *testing.T) { - configDumpFile, err := os.Open("testdata/secret/config_dump.json") - if err != nil { - t.Errorf("error opening test data file: %v", err) - } - defer configDumpFile.Close() - configDump, err := io.ReadAll(configDumpFile) - if err != nil { - t.Errorf("error reading test data file: %v", err) + testCases := []struct{ sds string }{ + {sds: "istio"}, + {sds: "spire"}, } + for _, tc := range testCases { + t.Run(tc.sds, func(t *testing.T) { + configDumpFile, err := os.Open(fmt.Sprintf("testdata/secret/%s/config_dump.json", tc.sds)) + if err != nil { + t.Errorf("error opening test data file: %v", err) + } + defer configDumpFile.Close() + configDump, err := io.ReadAll(configDumpFile) + if err != nil { + t.Errorf("error reading test data file: %v", err) + } - outFile, err := os.Open("testdata/secret/output") - if err != nil { - t.Errorf("error opening test data output file: %v", err) - } - defer outFile.Close() - expectedOut, err := io.ReadAll(outFile) - if err != nil { - t.Errorf("error reading test data output file: %v", err) - } + outFile, err := os.Open(fmt.Sprintf("testdata/secret/%s/output", tc.sds)) + if err != nil { + t.Errorf("error opening test data output file: %v", err) + } + defer outFile.Close() + expectedOut, err := io.ReadAll(outFile) + if err != nil { + t.Errorf("error reading test data output file: %v", err) + } - gotOut := &bytes.Buffer{} - cw := &ConfigWriter{Stdout: gotOut} - err = cw.Prime(configDump) - assert.NoError(t, err) - err = cw.PrintSecretSummary() - assert.NoError(t, err) + gotOut := &bytes.Buffer{} + cw := &ConfigWriter{Stdout: gotOut} + err = cw.Prime(configDump) + assert.NoError(t, err) + err = cw.PrintSecretSummary() + assert.NoError(t, err) - assert.Equal(t, string(expectedOut), gotOut.String()) + assert.Equal(t, string(expectedOut), gotOut.String()) + }) + } } diff --git a/istioctl/pkg/writer/envoy/configdump/testdata/secret/config_dump.json b/istioctl/pkg/writer/envoy/configdump/testdata/secret/istio/config_dump.json similarity index 100% rename from istioctl/pkg/writer/envoy/configdump/testdata/secret/config_dump.json rename to istioctl/pkg/writer/envoy/configdump/testdata/secret/istio/config_dump.json diff --git a/istioctl/pkg/writer/envoy/configdump/testdata/secret/output b/istioctl/pkg/writer/envoy/configdump/testdata/secret/istio/output similarity index 100% rename from istioctl/pkg/writer/envoy/configdump/testdata/secret/output rename to istioctl/pkg/writer/envoy/configdump/testdata/secret/istio/output diff --git a/istioctl/pkg/writer/envoy/configdump/testdata/secret/spire/config_dump.json b/istioctl/pkg/writer/envoy/configdump/testdata/secret/spire/config_dump.json new file mode 100644 index 000000000000..dc09ae657763 --- /dev/null +++ b/istioctl/pkg/writer/envoy/configdump/testdata/secret/spire/config_dump.json @@ -0,0 +1,57 @@ +{ + "configs": [ + { + "@type": "type.googleapis.com/envoy.admin.v3.SecretsConfigDump", + "dynamic_active_secrets": [ + { + "name": "default", + "last_updated": "2024-10-25T13:26:36.591Z", + "secret": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "name": "default", + "tls_certificate": { + "certificate_chain": { + "inline_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNSVENDQWVxZ0F3SUJBZ0lSQU0xSkF1U1pGcHNSN0JjZHJSWm9yYnN3Q2dZSUtvWkl6ajBFQXdJd0hqRUwKTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFvVEJsTlFTVVpHUlRBZUZ3MHlOREV3TWpjeU1UUTBNamRhRncweQpOREV3TWpjeU1qUTBNemRhTUVneEN6QUpCZ05WQkFZVEFsVlRNUTR3REFZRFZRUUtFd1ZUVUVsU1JURXBNQ2NHCkExVUVMUk1nTnpJM00yUXlPRFF6WmpreE4yRm1NVGN3T1dGalpqWXhZelk0TUdOak1tTXdXVEFUQmdjcWhrak8KUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVI2TmFlL1BKbnBjbmtSTXZGdDB2LzlMMytVaFpHbHlHTjJvYWNpVUxpTApTejFqb1RWeHFaTGFjVGovdm9EdlE5UmdJZjRTU0swZnRLUytldm1TckhHL280SGVNSUhiTUE0R0ExVWREd0VCCi93UUVBd0lEcURBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUlLd1lCQlFVSEF3SXdEQVlEVlIwVEFRSC8KQkFJd0FEQWRCZ05WSFE0RUZnUVVRMWw0aWZZWkhKZE5PSVJCblVaYnNlc0lnWFl3SHdZRFZSMGpCQmd3Rm9BVQpaZzRKSFJpZDgzd1RPR04wdGdUT0lsUkp1STh3WEFZRFZSMFJCRlV3VTRaUmMzQnBabVpsT2k4dlpXRnpkQzVzCmIyTmhiQzl1Y3k5cGMzUnBieTF6ZVhOMFpXMHZjMkV2Wm1Wa1pYSmhkR2x2YmkxcGJtZHlaWE56TFdkaGRHVjMKWVhrdGMyVnlkbWxqWlMxaFkyTnZkVzUwTUFvR0NDcUdTTTQ5QkFNQ0Ewa0FNRVlDSVFEemx6andPLy9yQXpBYgplcXQwUWF3Q3lITWozOEt5U2liTXJiWXM1Y2lla3dJaEFMY0RIUEFURU5sSjVlZ1VqQVptNWtVLzNLNVBNS09OCkI4b09ndnB2V1RyNgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEa3pDQ0FYdWdBd0lCQWdJUkFQczg1aTVuRDFOOGZBSUZLMmg0Wm1Fd0RRWUpLb1pJaHZjTkFRRUxCUUF3Ck1ERVhNQlVHQTFVRUNnd09iWGt0WTI5dGNHRnVlUzV2Y21jeEZUQVRCZ05WQkFNTURFVmhjM1FnVW05dmRDQkQKUVRBZUZ3MHlOREV3TWpjeU1ERTBNakphRncweU5ERXdNamd5TURFME1qSmFNQjR4Q3pBSkJnTlZCQVlUQWxWVApNUTh3RFFZRFZRUUtFd1pUVUVsR1JrVXdXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CQndOQ0FBUVZWdjI3CjVkcDZYNWxWUEVUaUR6MkpLaTRXekMrR2ZJbzlhY3M5bWdEK0FGeEhqS1AwNGhKc1FxR1cwQk9lVHdncFp3U2MKWDQ3MUk5eUtJRUZBWU83Rm80R0VNSUdCTUE0R0ExVWREd0VCL3dRRUF3SUJCakFQQmdOVkhSTUJBZjhFQlRBRApBUUgvTUIwR0ExVWREZ1FXQkJSbURna2RHSjN6ZkJNNFkzUzJCTTRpVkVtNGp6QWZCZ05WSFNNRUdEQVdnQlRLCmJ6U0pyelBGNmZrOG9iZUxMWFkrMFRKSHh6QWVCZ05WSFJFRUZ6QVZoaE56Y0dsbVptVTZMeTlsWVhOMExteHYKWTJGc01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQ0FRQlpTbGcvbnpJUmhJVDB0aHRUMjNDT3ZvbThyV01QaXQyaQplaFR1b2RPd3Y0VDRuQ2FyY2pMOW1iUVJzNmFUTEtmLzRrV2ZBamNNMFRxSmdjdDNyUEVFTnZxRmkxS09sN010CnlOKytGcWRxbWZ2NnRLMmhmTUduZ2o1dHkxcWNJSXlKRVZlRDRyTTJGWTl6S1VldHpvQ0ZQaFZYejNFRDk0MXQKclpXQmxlU1BNd2xrd1J1S2JiSlpMTHZvYmYyQTR4ck4xeDVRUGxKQmdRd09ZQXpjQzNobE5qRUJIbDFjNjJpMQp4RnJLdXRsR0Uvc0FmNXQ3K3RIUm5pbkdudDNPVmpOQm9Pc29NRTIrejdhT3EvVkd0ckJZR0dWN212T2ozMTBaCmQ3TTZueHpqRUZYU1ljTFk1ZW9sWk9tcm1wR1R1UnRHVUFtL2tuOEdpZlJoVjNDZ3dFdVhkYUgzcTI3R3c1TWYKeUM0V1pVS1NVOTBId010SHBUUHZjTnN0VlhuVmt3Z3FpVlRmY3RqQVdmbE0xU2RTQ3B2YmlPUlltNVpQdVh2NwpoWnBGUGY4cWpxODlsT3pFVXFVL3RhME5qVkkzMDBYcjNYM1JpbDZ2SHF1eGdTbStlTEdaRHozZTV4RmY2Q1FmClFNZVdFZHd3U0oyRTg3bzdZUkNKSzk5ZytFby81ZU1RVVo1dFdoaVVSTG9NOEY3SU1QcjZsTVNWVGRIRnRmUkcKVHdJMlo0SEhHTUVtclp6NmVoMUpvQUZ0RzVscWdNblduNGpLZkVXK2FadmJ2dVYyS21mQ2VsUjRZUlFnUDc2dQpsTHZUZXdIWmd0THQ3cm5zMXRqd3daZ0Z6RExsdkxOSnNEOWx0N1dtMlYvSmpDRldQc0YzY1F0TENhOXJnb01LCnVGSHpGVUNqWnc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + }, + "private_key": { + "inline_bytes": "W3JlZGFjdGVkXQ==" + } + } + } + }, + { + "name": "ROOTCA", + "last_updated": "2024-10-25T13:26:36.586Z", + "secret": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", + "name": "ROOTCA", + "validation_context": { + "trusted_ca": { + }, + "custom_validator_config": { + "name": "envoy.tls.cert_validator.spiffe", + "typed_config": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig", + "trust_domains": [ + { + "name": "east.local", + "trust_bundle": { + "inline_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZNRENDQXhpZ0F3SUJBZ0lVVXB5N3IySTJFZEJYdFJmVS8rTkI1T2dEVURjd0RRWUpLb1pJaHZjTkFRRUwKQlFBd01ERVhNQlVHQTFVRUNnd09iWGt0WTI5dGNHRnVlUzV2Y21jeEZUQVRCZ05WQkFNTURFVmhjM1FnVW05dgpkQ0JEUVRBZUZ3MHlOREV3TWpVeE16SXpNRFZhRncwek5ERXdNak14TXpJek1EVmFNREF4RnpBVkJnTlZCQW9NCkRtMTVMV052YlhCaGJua3ViM0puTVJVd0V3WURWUVFEREF4RllYTjBJRkp2YjNRZ1EwRXdnZ0lpTUEwR0NTcUcKU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ2xRL296OGJqblcxcFdVS1lkWWxxc0V1NjdRRGdhZGpBNQp0YlhFdmVtUWFYdHJNektFVUpiNHlSMkZjaTBRYjR5b0x1bXBld2phZ3Azdll4dUR4TFBQcmtBRUFGSGZpTm5UCmVCRWZuMmRBdW9uTFhLSWtTNHcvZDN1STU3Y1pzRi9YSlEzTWZXb2tXMS9DWTVOdXZRME9pUkRvM3lUWHYzM04KNWRBaG5mcWFCUUMrOWNXbWNpaTM2MVhjM1BrRTZiVWVMS3RTKzArZVhwS0dqUHJOZ3NQdXNrZTdYN0RPVjY3RwpaSTQ0cFBlTlk3T3NnVU5Wc2lLeUNFRnlNenNVQTF1NTAxMXNUTjJLVXhTa252a1lpOHhBeW5aYlJqWU8zVnB2Ck5FaVdHeDVXNmk4MWZ4d00xbFAydmt4NW82S1RPNDErWVRiNjZMaFZVRi9Mam1MeHNhMEp3dnhscm1obDRQcFIKMHA0bjhFc1hCWkZrVksweVlSM2FWV1dXMUZ4bmQ5ZUZKVXgxWjBiM0pYc1hMK3grcEVaOEJ1aFdlSmYyaEVHNQpFRWkycG9UM2hCeHJTSjhxamxrRUpyT2dRV2dwWUFVbmJPZUQ0RHNVNHV2OWZXMXZRcWZlNHdBemJJZnZaNkpmCkpvTjRkdnZ0ZFg4VnhyWFp5S1ZQR2tGTG8vN3lxZFN5RlFsQnVIN2VOamVXVTZXc1pWblo0aEVGZTJPeDBvblIKcjFzc09uV2ZXZjNSQVh2VlFvYzdYdk81czJlT2lJUmhVZUlzWXFhNldCTDRZS2NpZk5sSGkxMThOYjlTWVNaRgorWXdMVEM3RUUvcUF6RXo2bENLRytVcEZ3RG9kWWV6bzBYWE5Ob3JnNVptYUlzcFZ0YXFYaWZDOVVnQTFvL2xtCml3NFd2OXQrbFFJREFRQUJvMEl3UURBZEJnTlZIUTRFRmdRVXltODBpYTh6eGVuNVBLRzNpeTEyUHRFeVI4Y3cKRHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0F1UXdEUVlKS29aSWh2Y05BUUVMQlFBRApnZ0lCQUVJNFMyYWZRcVcwMWlPSEVjcXpCY2JpbWROVk5TMVVON2RwOTNRTXp6ZUlwYTRFQk9yK0NPNEJ1TFhQCjVWdTh0bzNIVU5wL1NSUkJ6YU44cUM2bEdLeko4Zk1FSDNQeVZOSEdLbmFiUUVIU0g0aUROL213MEJNMWR6RDUKMERYN29RaWVidmVqQ0xRMTVGM2tlb2hjTWZ5R2lnLzdZSUNqbXFHcFlHYm5sYlFaUFBkMTRPZ3JFQTQrWGZDRwo2VEF6UTVtVTZJOFpYUm90bklxKzZiU2Q2Y09tVjJianYyVEliUEJlS2tPZkZYZVpOaERKcGIyTFhiVzVyaVR1ClRwM2ZWTFloZmNVbDkxNTgySGd1MXY1MzlzSWtURGZpR0dyMWR0c0RwcmNNSTh1ZVdPYnhTZ0dEL2NXVHVLaFgKRTA0d0RsaUtiQWg0RUlYd3hram1pZ2lyL3BaeDBPVG1iMDNlVzV3WXVTdEhQNWFyZDlKUGNHdHZkVnNaN2ZGWApTRHZnUkRNL0lsazZ5M3YvYy9kSmdHaVUrcVI2NG1taC9FbnZlTHNBZTBwQkRqZ2NyWXNuTUdEdDhjQU1KMU1kClF5RWI4SEdCZEdDMTNSTmQzcVdNK2kxV1pycUU3YXJGR2ZUUnBLSWhxWCtYUTlyek1aNUczWXYzUXhiMGNHeDMKQ0IvV0xUQWExZDEzaTlwUlp1RFBxQ1NBaUQ1L2IwcEVCZHBlUE1OU1hrRjUycDEvODArWEZMWllZZUF3dFU4TgpqR1Q2ZHFyRjJmRlMvUUhYeUFTcjJ0My9oS1NlM2RZZUptSmJnTWQ2ekk4aUl1dmcwM0pqOU1zNSthb3o2YnRhCldPZW5VVFVzS094SEhhZXNzMWI4ZStuKzRRZkM4emxYUy81RWt2TEwrSE90NE5ERwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + } + }, + { + "name": "west.local", + "trust_bundle": { + "inline_bytes": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZNRENDQXhpZ0F3SUJBZ0lVWnlibCt0RkYrTXFhY1I4RlVDbDg3WU9lNDM4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd01ERVhNQlVHQTFVRUNnd09iWGt0WTI5dGNHRnVlUzV2Y21jeEZUQVRCZ05WQkFNTURGZGxjM1FnVW05dgpkQ0JEUVRBZUZ3MHlOREV3TWpVeE16SXpNRFZhRncwek5ERXdNak14TXpJek1EVmFNREF4RnpBVkJnTlZCQW9NCkRtMTVMV052YlhCaGJua3ViM0puTVJVd0V3WURWUVFEREF4WFpYTjBJRkp2YjNRZ1EwRXdnZ0lpTUEwR0NTcUcKU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRRGc0TDFlVkRFbmVBVEZ5eFRSaU9PWUI0RzZzVVorSUoyUwpZdU81U3ZiQXkvY2wwK01TbGJIQnZqNjdhSFE1UWtYL0ZxSHh2K3UrTEhOR3ArY3NkbUlXeXA2aEk5Y0lNVFhRCk0xY01aRkI2YkdRbGdjM1ZWVnFZeGx2d3YyN2tmeHVYdzB2U1lITVZHVkM2d3dMeFlIdjdCVUJRZVVueFF6NGEKTHZUNW5xelpQSU93T1FGc1hJVElTaXlndy8rdVF4aDBiMjR6N2UvNVNkdzBVWnlvc2JrcjNvNFVhZEk0SGx1aApmUkJHK2E4ZXlxekIxYzVORWZuR045TVZFY2hMcFpma0ZEV0xDQ01raTJpTlRyVDVqRXJuQmR3ZUpZRC9JNU9kCkxjZitSWTBicDNwK21vUmFIRUt6Z1V1K21jRFhTVFMzNUdvVHlrZ0Z1aURST1JlbWtvZG4zZENvc0hkRmkxY0wKUnlPYm41Y0dSdmdvMDJscWh2UHJJcmxzdmFXRGNHTEdBem9VaGluNXBDRnJpNTZnSzFldDkwVFQvNEZiNGM0TgovUWcwNjNvT0dBU3Y0TjBRWUMzalVJUG5QTWhheTE3SUVyejZCaDJyZ2VvaDRUOFNXYnRBcStGOTVzejZ6bmp2CnNKZFR5UnZiUGg3Y3llVTk3MEh4a2dkQWtsMUhVczlrenFhWHVDMGdOOEd4NWx4bVBTK05ya01jOTFrVGs0bzcKdk9aUjVNZDdXM0hJQW92aFNaUmRqdzJoN3ljK2h1c1hXRlpnS1laeXY1VmVNWCtqMjQwVHgvQlBxV05sTjZtUAp0RlA3bG9ha3BXZDhOeDhVVWdnWStmYVQ3cS9HN3BhVWQrQXBad1NneUp3MUJOME9Ua28vdThTaVJ5dzhFc2FuCmp2K3VZZ0dHbndJREFRQUJvMEl3UURBZEJnTlZIUTRFRmdRVWhyZ09sd1JsdFd4Mkh0RDhvOWphQ0daY0QzSXcKRHdZRFZSMFRBUUgvQkFVd0F3RUIvekFPQmdOVkhROEJBZjhFQkFNQ0F1UXdEUVlKS29aSWh2Y05BUUVMQlFBRApnZ0lCQU5IbEgxYjl4c1RXTTBDOWRCNjJESWJvazVpV0loR1h3RS9HTFoyemRENVNraHZJY25tdE1XaHRXejZPCjdVVzBBOXk5ODY1eUxzZkRDbEJUWTFsaFlXRC95SWhsV3NVcUNqbXprUHdYb0ZaQjFDMlFZRzZnM2V0cS9CYkEKQVdON01vTjVhSUlvNy9lMmtDSmdFOE9BcE9YVUdZQU4xd3lIbitRaVIvUjFqOXFZaExqeGxmNFZIenBrSHRYcQplVEZBa051MHBqZEFBQzVWeGFtUDN4WHQ0ZlA1emRFakpVeFE1STh4QlBEWXo2UzNuQmtaRW5WZ1htdGk3ZnpaCnZCZ04yTEdlK1hqWjk2U0RRTTVJblpobzhsN0MrWmptVzZ5WkUzdmhwbVc1NDg2Z1pQSDVKcUZlNVoyc2VvNmEKWDhNZWFacHVSOFZyNlRSSno1OVo1WFVNV0plWGtRN3dtbGs4WGN4MGxEZUVVQUpiSnhvOEJsRk1nN05uTklQQwpsK3N1TVE1OThiRTh1ZnkyeWp4Y0tWVTFHSlhFdm9EU29iZGQ4NDVXa3JSQVN2R3lEYlJvcGpIUzArdjBCQ0RFCmpuNUVvSHAzR2E3MHAzdnBlTkRidjdPZ0xQaU90TlpqclpTd29tTlVuRmR6eC8vK0FyTFpMa29sOEIrREE0QmYKZ2xRdjk5c2wyakdHbTh3TVI0K3YxcHlhVGZsUS9vWmt0VXNjRzFDak1nRWxuWVpZYTc5dWJ5cndLR3BKMk4rcgpTUEczWnVBLzY3TXhCbHFtNGNDWjdpdDR1K1lvdDZjZVQrenAvNExSZ2xnQnBzNmVESmJKL0NrRVp2Uy95VFd1CitlOWFpL0NMNmo2aWdkS1k1MDZJOW1nVHZ3L2tzU1pxZDBBRWhCWkFJT2lGOXQrTgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + } + } + ] + } + } + } + } + } + ] + } + ] +} diff --git a/istioctl/pkg/writer/envoy/configdump/testdata/secret/spire/output b/istioctl/pkg/writer/envoy/configdump/testdata/secret/spire/output new file mode 100644 index 000000000000..0c5c5baa95b3 --- /dev/null +++ b/istioctl/pkg/writer/envoy/configdump/testdata/secret/spire/output @@ -0,0 +1,4 @@ +RESOURCE NAME TYPE STATUS VALID CERT SERIAL NUMBER NOT AFTER NOT BEFORE TRUST DOMAIN +default Cert Chain ACTIVE false cd4902e499169b11ec171dad1668adbb 2024-10-27T22:44:37Z 2024-10-27T21:44:27Z east.local +ROOTCA CA ACTIVE true 529cbbaf623611d057b517d4ffe341e4e8035037 2034-10-23T13:23:05Z 2024-10-25T13:23:05Z east.local +ROOTCA CA ACTIVE true 6726e5fad145f8ca9a711f0550297ced839ee37f 2034-10-23T13:23:05Z 2024-10-25T13:23:05Z west.local diff --git a/istioctl/pkg/writer/table/writer.go b/istioctl/pkg/writer/table/writer.go index 30d970989499..00e4ffb46689 100644 --- a/istioctl/pkg/writer/table/writer.go +++ b/istioctl/pkg/writer/table/writer.go @@ -109,13 +109,6 @@ func (c *ColoredTableWriter) Flush() { } } -func max(x, y int) int { - if x < y { - return y - } - return x -} - func getMaxWidths(output [][]Cell) []int { widths := make([]int, len(output[0])) for _, row := range output { diff --git a/licenses/github.com/golang/groupcache/LICENSE b/licenses/github.com/golang/groupcache/LICENSE deleted file mode 100644 index 37ec93a14fdc..000000000000 --- a/licenses/github.com/golang/groupcache/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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. diff --git a/licenses/github.com/imdario/mergo/LICENSE b/licenses/github.com/planetscale/vtprotobuf/LICENSE similarity index 89% rename from licenses/github.com/imdario/mergo/LICENSE rename to licenses/github.com/planetscale/vtprotobuf/LICENSE index 686680298da2..dc61de8465cc 100644 --- a/licenses/github.com/imdario/mergo/LICENSE +++ b/licenses/github.com/planetscale/vtprotobuf/LICENSE @@ -1,5 +1,6 @@ -Copyright (c) 2013 Dario Castañé. All rights reserved. -Copyright (c) 2012 The Go Authors. All rights reserved. +Copyright (c) 2021, PlanetScale Inc. All rights reserved. +Copyright (c) 2013, The GoGo Authors. All rights reserved. +Copyright (c) 2018 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/licenses/sigs.k8s.io/kustomize/kyaml/internal/forked/github.com/qri-io/starlib/util/LICENSE b/licenses/github.com/planetscale/vtprotobuf/generator/pattern/LICENSE similarity index 89% rename from licenses/sigs.k8s.io/kustomize/kyaml/internal/forked/github.com/qri-io/starlib/util/LICENSE rename to licenses/github.com/planetscale/vtprotobuf/generator/pattern/LICENSE index 31f292dce540..2645a8b7790a 100644 --- a/licenses/sigs.k8s.io/kustomize/kyaml/internal/forked/github.com/qri-io/starlib/util/LICENSE +++ b/licenses/github.com/planetscale/vtprotobuf/generator/pattern/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2018 QRI, Inc. +Copyright (c) 2014 Bob Matcuk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/licenses/cel.dev/expr/proto/test/v1/LICENSE b/licenses/go.opentelemetry.io/auto/sdk/LICENSE similarity index 99% rename from licenses/cel.dev/expr/proto/test/v1/LICENSE rename to licenses/go.opentelemetry.io/auto/sdk/LICENSE index d64569567334..261eeb9e9f8b 100644 --- a/licenses/cel.dev/expr/proto/test/v1/LICENSE +++ b/licenses/go.opentelemetry.io/auto/sdk/LICENSE @@ -1,4 +1,3 @@ - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ diff --git a/licenses/go.starlark.net/LICENSE b/licenses/go.starlark.net/LICENSE deleted file mode 100644 index a6609a143720..000000000000 --- a/licenses/go.starlark.net/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -Copyright (c) 2017 The Bazel Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the - distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/licenses/github.com/BurntSushi/toml/internal/toml-test/COPYING b/licenses/k8s.io/kube-openapi/pkg/internal/third_party/govalidator/LICENSE similarity index 88% rename from licenses/github.com/BurntSushi/toml/internal/toml-test/COPYING rename to licenses/k8s.io/kube-openapi/pkg/internal/third_party/govalidator/LICENSE index 93b22020a83d..2f9a31fadf67 100644 --- a/licenses/github.com/BurntSushi/toml/internal/toml-test/COPYING +++ b/licenses/k8s.io/kube-openapi/pkg/internal/third_party/govalidator/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2018 TOML authors +Copyright (c) 2014 Alex Saskevich Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -9,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/manifests/addons/dashboards/istio-extension-dashboard.json b/manifests/addons/dashboards/istio-extension-dashboard.json index 7b0bc27aea5d..9602024a6aec 100644 --- a/manifests/addons/dashboards/istio-extension-dashboard.json +++ b/manifests/addons/dashboards/istio-extension-dashboard.json @@ -809,7 +809,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[1m]))", + "expr": "sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[$__rate_interval]))", "format": "time_series", "hide": false, "intervalFactor": 2, diff --git a/manifests/addons/dashboards/istio-performance-dashboard.json b/manifests/addons/dashboards/istio-performance-dashboard.json index 02b3485cb2d8..d94ff4fed2c0 100644 --- a/manifests/addons/dashboards/istio-performance-dashboard.json +++ b/manifests/addons/dashboards/istio-performance-dashboard.json @@ -182,7 +182,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "(sum(irate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[1m])) / (round(sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[1m])), 0.001)/1000))", + "expr": "(sum(irate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[$__rate_interval])) / (round(sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[$__rate_interval])), 0.001)/1000))", "format": "time_series", "hide": false, "intervalFactor": 1, @@ -194,7 +194,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "(sum(irate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[1m]))/ (round(sum(irate(istio_requests_total[1m])), 0.001)/1000))/ (sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\"}[1m])) >bool 10)", + "expr": "(sum(irate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[$__rate_interval]))/ (round(sum(irate(istio_requests_total[$__rate_interval])), 0.001)/1000))/ (sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\"}[$__rate_interval])) >bool 10)", "format": "time_series", "intervalFactor": 1, "legendFormat": "istio-proxy", @@ -290,7 +290,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(rate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[1m]))", + "expr": "sum(rate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[$__rate_interval]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "istio-ingressgateway", @@ -301,7 +301,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(rate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[1m]))", + "expr": "sum(rate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[$__rate_interval]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "istio-proxy", @@ -530,7 +530,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(irate(istio_response_bytes_sum{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[1m]))", + "expr": "sum(irate(istio_response_bytes_sum{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[$__rate_interval]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "istio-ingressgateway", @@ -541,7 +541,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(irate(istio_response_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[1m])) + sum(irate(istio_request_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[1m]))", + "expr": "sum(irate(istio_response_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[$__rate_interval])) + sum(irate(istio_request_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[$__rate_interval]))", "format": "time_series", "intervalFactor": 1, "legendFormat": "istio-proxy", @@ -883,7 +883,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[1m]))", + "expr": "sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[$__rate_interval]))", "format": "time_series", "hide": false, "intervalFactor": 2, @@ -1301,7 +1301,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[1m]))", + "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[$__rate_interval]))", "format": "time_series", "hide": false, "intervalFactor": 2, @@ -1314,7 +1314,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[1m])) by (container)", + "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[$__rate_interval])) by (container)", "format": "time_series", "hide": false, "intervalFactor": 2, @@ -1327,7 +1327,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "irate(process_cpu_seconds_total{app=\"istiod\"}[1m])", + "expr": "irate(process_cpu_seconds_total{app=\"istiod\"}[$__rate_interval])", "format": "time_series", "hide": false, "intervalFactor": 2, diff --git a/manifests/addons/dashboards/istio-service-dashboard.json b/manifests/addons/dashboards/istio-service-dashboard.json index d8ddfa84040a..3f7e2d3989d0 100644 --- a/manifests/addons/dashboards/istio-service-dashboard.json +++ b/manifests/addons/dashboards/istio-service-dashboard.json @@ -2983,7 +2983,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace), 0.001)", + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[$__rate_interval])) by (destination_workload, destination_workload_namespace), 0.001)", "format": "time_series", "hide": false, "intervalFactor": 1, @@ -2996,7 +2996,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace), 0.001)", + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[$__rate_interval])) by (destination_workload, destination_workload_namespace), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace}}", @@ -3094,7 +3094,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\"mutual_tls\", reporter=\"destination\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace), 0.001)", + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\"mutual_tls\", reporter=\"destination\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[$__rate_interval])) by (destination_workload, destination_workload_namespace), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ destination_workload }}.{{destination_workload_namespace }} (🔐mTLS)", @@ -3106,7 +3106,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=\"destination\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace), 0.001)", + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=\"destination\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[$__rate_interval])) by (destination_workload, destination_workload_namespace), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ destination_workload }}.{{destination_workload_namespace }}", diff --git a/manifests/addons/dashboards/istio-workload-dashboard.json b/manifests/addons/dashboards/istio-workload-dashboard.json index d551de859a23..dee37fe9a179 100644 --- a/manifests/addons/dashboards/istio-workload-dashboard.json +++ b/manifests/addons/dashboards/istio-workload-dashboard.json @@ -420,7 +420,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(irate(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\"}[1m])) + sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\"}[1m]))", + "expr": "sum(irate(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\"}[$__rate_interval])) + sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\"}[$__rate_interval]))", "format": "time_series", "hide": false, "intervalFactor": 1, @@ -500,7 +500,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "sum(irate(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\"}[1m])) + sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\"}[1m]))", + "expr": "sum(irate(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\"}[$__rate_interval])) + sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\"}[$__rate_interval]))", "format": "time_series", "hide": false, "intervalFactor": 1, @@ -1546,7 +1546,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[$__rate_interval])) by (source_workload, source_workload_namespace), 0.001)", "format": "time_series", "hide": false, "intervalFactor": 1, @@ -1559,7 +1559,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[$__rate_interval])) by (source_workload, source_workload_namespace), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}}", @@ -1657,7 +1657,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\"mutual_tls\", reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\"mutual_tls\", reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[$__rate_interval])) by (source_workload, source_workload_namespace), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}} (🔐mTLS)", @@ -1669,7 +1669,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[$__rate_interval])) by (source_workload, source_workload_namespace), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}}", @@ -2715,7 +2715,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_received_bytes_total{connection_security_policy=\"mutual_tls\", reporter=\"source\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service), 0.001)", + "expr": "round(sum(irate(istio_tcp_received_bytes_total{connection_security_policy=\"mutual_tls\", reporter=\"source\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[$__rate_interval])) by (destination_service), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ destination_service }} (🔐mTLS)", @@ -2727,7 +2727,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_received_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=\"source\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service), 0.001)", + "expr": "round(sum(irate(istio_tcp_received_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=\"source\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[$__rate_interval])) by (destination_service), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ destination_service }}", @@ -2825,7 +2825,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_sent_bytes_total{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service), 0.001)", + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[$__rate_interval])) by (destination_service), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ destination_service }} (🔐mTLS)", @@ -2837,7 +2837,7 @@ "type": "prometheus", "uid": "${datasource}" }, - "expr": "round(sum(irate(istio_tcp_sent_bytes_total{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service), 0.001)", + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[$__rate_interval])) by (destination_service), 0.001)", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ destination_service }}", diff --git a/manifests/addons/gen.sh b/manifests/addons/gen.sh index 00476fb59590..73f357d475db 100755 --- a/manifests/addons/gen.sh +++ b/manifests/addons/gen.sh @@ -26,15 +26,15 @@ ADDONS="${WD}/../../samples/addons" DASHBOARDS="${WD}/dashboards" mkdir -p "${ADDONS}" TMP=$(mktemp -d) -LOKI_VERSION=${LOKI_VERSION:-"6.18.0"} -GRAFANA_VERSION=${GRAFANA_VERSION:-"8.5.8"} +LOKI_VERSION=${LOKI_VERSION:-"6.24.0"} +GRAFANA_VERSION=${GRAFANA_VERSION:-"8.6.3"} # Set up kiali { helm3 template kiali-server \ --namespace istio-system \ - --version 2.0.0 \ - --set deployment.image_version=v2.0 \ + --version 2.2.0 \ + --set deployment.image_version=v2.2 \ --include-crds \ kiali-server \ --repo https://kiali.org/helm-charts \ @@ -44,7 +44,7 @@ helm3 template kiali-server \ # Set up prometheus helm3 template prometheus prometheus \ --namespace istio-system \ - --version 25.27.0 \ + --version 26.0.1 \ --repo https://prometheus-community.github.io/helm-charts \ -f "${WD}/values-prometheus.yaml" \ > "${ADDONS}/prometheus.yaml" diff --git a/manifests/charts/README.md b/manifests/charts/README.md index 8858011bd4f6..096c89226631 100644 --- a/manifests/charts/README.md +++ b/manifests/charts/README.md @@ -1,5 +1,21 @@ # Istio Installer +## WARNING: Do not use the files in this directory to install Istio + +This directory contains the helm chart _sources_ which are versioned, built and pushed to following helm +repositories with each Istio release. If you want to make changes to Istio helm charts, you're in the +right place. + +If you want to _install_ Istio with Helm, instead please [follow the Helm installation docs here](https://istio.io/latest/docs/setup/install/helm/). + +Charts in this folder are published to the following Helm repos: + - `https://istio-release.storage.googleapis.com/charts` (charts for official release versions) + - `oci://gcr.io/istio-release/charts/` (charts for official release versions and dev build versions) + +Chart publishing is handled by [release builder](https://github.com/istio/release-builder). + +--- + Note: If making any changes to the charts or values.yaml in this dir, first read [UPDATING-CHARTS.md](UPDATING-CHARTS.md) Istio installer is a modular, 'a-la-carte' installer for Istio. It is based on a diff --git a/manifests/charts/base/files/crd-all.gen.yaml b/manifests/charts/base/files/crd-all.gen.yaml index 9777d4595b03..5360fe804dd9 100644 --- a/manifests/charts/base/files/crd-all.gen.yaml +++ b/manifests/charts/base/files/crd-all.gen.yaml @@ -133,14 +133,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -180,8 +180,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' targetRefs: description: Optional. items: @@ -215,8 +216,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' maxItems: 16 type: array type: @@ -235,10 +237,9 @@ spec: type: string x-kubernetes-validations: - message: url must have schema one of [http, https, file, oci] - rule: 'isURL(self) ? (url(self).getScheme() in ['''', ''http'', - ''https'', ''oci'', ''file'']) : (isURL(''http://'' + self) && - url(''http://'' +self).getScheme() in ['''', ''http'', ''https'', - ''oci'', ''file''])' + rule: |- + isURL(self) ? (url(self).getScheme() in ["", "http", "https", "oci", "file"]) : (isURL("http://" + self) && + url("http://" + self).getScheme() in ["", "http", "https", "oci", "file"]) verificationKey: type: string vmConfig: @@ -272,7 +273,7 @@ spec: type: object x-kubernetes-validations: - message: value may only be set when valueFrom is INLINE - rule: '(has(self.valueFrom) ? self.valueFrom : '''') != ''HOST'' + rule: '(has(self.valueFrom) ? self.valueFrom : "") != "HOST" || !has(self.value)' maxItems: 256 type: array @@ -285,7 +286,8 @@ spec: type: object x-kubernetes-validations: - message: only one of targetRefs or selector can be set - rule: (has(self.selector)?1:0)+(has(self.targetRef)?1:0)+(has(self.targetRefs)?1:0)<=1 + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' status: properties: conditions: @@ -305,6 +307,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -321,8 +329,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -671,9 +677,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, this - is DestinationRule-level and will override mesh - wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -791,7 +795,7 @@ spec: minHealthPercent: description: Outlier detection will be enabled as long as the associated load balancing pool has at least - min_health_percent hosts in healthy mode. + `minHealthPercent` hosts in healthy mode. format: int32 type: integer splitExternalLocalOriginErrors: @@ -1043,9 +1047,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, - this is DestinationRule-level and will override - mesh wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -1167,7 +1169,7 @@ spec: minHealthPercent: description: Outlier detection will be enabled as long as the associated load balancing pool - has at least min_health_percent hosts in healthy + has at least `minHealthPercent` hosts in healthy mode. format: int32 type: integer @@ -1564,8 +1566,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, this is DestinationRule-level - and will override mesh wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -1679,7 +1680,7 @@ spec: type: integer minHealthPercent: description: Outlier detection will be enabled as long as - the associated load balancing pool has at least min_health_percent + the associated load balancing pool has at least `minHealthPercent` hosts in healthy mode. format: int32 type: integer @@ -1926,9 +1927,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, this - is DestinationRule-level and will override mesh - wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -2046,7 +2045,7 @@ spec: minHealthPercent: description: Outlier detection will be enabled as long as the associated load balancing pool has at least - min_health_percent hosts in healthy mode. + `minHealthPercent` hosts in healthy mode. format: int32 type: integer splitExternalLocalOriginErrors: @@ -2217,14 +2216,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -2250,6 +2249,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -2266,8 +2271,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -2588,9 +2591,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, this - is DestinationRule-level and will override mesh - wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -2708,7 +2709,7 @@ spec: minHealthPercent: description: Outlier detection will be enabled as long as the associated load balancing pool has at least - min_health_percent hosts in healthy mode. + `minHealthPercent` hosts in healthy mode. format: int32 type: integer splitExternalLocalOriginErrors: @@ -2960,9 +2961,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, - this is DestinationRule-level and will override - mesh wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -3084,7 +3083,7 @@ spec: minHealthPercent: description: Outlier detection will be enabled as long as the associated load balancing pool - has at least min_health_percent hosts in healthy + has at least `minHealthPercent` hosts in healthy mode. format: int32 type: integer @@ -3481,8 +3480,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, this is DestinationRule-level - and will override mesh wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -3596,7 +3594,7 @@ spec: type: integer minHealthPercent: description: Outlier detection will be enabled as long as - the associated load balancing pool has at least min_health_percent + the associated load balancing pool has at least `minHealthPercent` hosts in healthy mode. format: int32 type: integer @@ -3843,9 +3841,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, this - is DestinationRule-level and will override mesh - wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -3963,7 +3959,7 @@ spec: minHealthPercent: description: Outlier detection will be enabled as long as the associated load balancing pool has at least - min_health_percent hosts in healthy mode. + `minHealthPercent` hosts in healthy mode. format: int32 type: integer splitExternalLocalOriginErrors: @@ -4134,14 +4130,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -4167,6 +4163,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -4183,8 +4185,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -4505,9 +4505,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, this - is DestinationRule-level and will override mesh - wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -4625,7 +4623,7 @@ spec: minHealthPercent: description: Outlier detection will be enabled as long as the associated load balancing pool has at least - min_health_percent hosts in healthy mode. + `minHealthPercent` hosts in healthy mode. format: int32 type: integer splitExternalLocalOriginErrors: @@ -4877,9 +4875,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, - this is DestinationRule-level and will override - mesh wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -5001,7 +4997,7 @@ spec: minHealthPercent: description: Outlier detection will be enabled as long as the associated load balancing pool - has at least min_health_percent hosts in healthy + has at least `minHealthPercent` hosts in healthy mode. format: int32 type: integer @@ -5398,8 +5394,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, this is DestinationRule-level - and will override mesh wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -5513,7 +5508,7 @@ spec: type: integer minHealthPercent: description: Outlier detection will be enabled as long as - the associated load balancing pool has at least min_health_percent + the associated load balancing pool has at least `minHealthPercent` hosts in healthy mode. format: int32 type: integer @@ -5760,9 +5755,7 @@ spec: type: object type: array enabled: - description: enable locality load balancing, this - is DestinationRule-level and will override mesh - wide settings in entirety. + description: Enable locality load balancing. nullable: true type: boolean failover: @@ -5880,7 +5873,7 @@ spec: minHealthPercent: description: Outlier detection will be enabled as long as the associated load balancing pool has at least - min_health_percent hosts in healthy mode. + `minHealthPercent` hosts in healthy mode. format: int32 type: integer splitExternalLocalOriginErrors: @@ -6051,14 +6044,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -6084,6 +6077,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -6100,8 +6099,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -6309,7 +6306,7 @@ spec: additionalProperties: type: string description: Match on the node metadata supplied by - a proxy when connecting to Istio Pilot. + a proxy when connecting to istiod. type: object proxyVersion: description: A regular expression in golang regex format @@ -6445,8 +6442,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' maxItems: 16 type: array workloadSelector: @@ -6459,7 +6457,7 @@ spec: type: string x-kubernetes-validations: - message: wildcard is not supported in selector - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which the configuration should be applied. maxProperties: 256 @@ -6468,7 +6466,8 @@ spec: type: object x-kubernetes-validations: - message: only one of targetRefs or workloadSelector can be set - rule: (has(self.workloadSelector)?1:0)+(has(self.targetRefs)?1:0)<=1 + rule: '(has(self.workloadSelector) ? 1 : 0) + (has(self.targetRefs) + ? 1 : 0) <= 1' status: properties: conditions: @@ -6488,6 +6487,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -6504,8 +6509,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -6743,6 +6746,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -6759,8 +6768,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -6972,6 +6979,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -6988,8 +7001,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -7201,6 +7212,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -7217,8 +7234,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -7318,14 +7333,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -7349,6 +7364,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -7365,8 +7386,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -7480,11 +7499,11 @@ spec: type: string x-kubernetes-validations: - message: UDS must be an absolute path or abstract socket - rule: 'self.startsWith(''unix://'') ? (self.substring(7,8) - == ''/'' || self.substring(7,8) == ''@'') : true' + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) + == "/" || self.substring(7, 8) == "@") : true' - message: UDS may not be a dir - rule: 'self.startsWith(''unix://'') ? !self.endsWith(''/'') - : true' + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : + true' labels: additionalProperties: type: string @@ -7513,7 +7532,7 @@ spec: type: object x-kubernetes-validations: - message: port name must be valid - rule: self.all(key, size(key) < 63 && key.matches('^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$')) + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) serviceAccount: description: The service account associated with the workload if a sidecar is present in the workload. @@ -7529,7 +7548,7 @@ spec: - message: Address is required rule: has(self.address) || has(self.network) - message: UDS may not include ports - rule: '(has(self.address) && self.address.startsWith(''unix://'')) + rule: '(has(self.address) && self.address.startsWith("unix://")) ? !has(self.ports) : true' maxItems: 4096 type: array @@ -7544,7 +7563,7 @@ spec: type: string x-kubernetes-validations: - message: hostname cannot be wildcard - rule: self != '*' + rule: self != "*" maxItems: 256 minItems: 1 type: array @@ -7624,7 +7643,7 @@ spec: type: string x-kubernetes-validations: - message: wildcard is not supported in selector - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which the configuration should be applied. maxProperties: 256 @@ -7635,18 +7654,20 @@ spec: type: object x-kubernetes-validations: - message: only one of WorkloadSelector or Endpoints can be set - rule: (has(self.workloadSelector)?1:0)+(has(self.endpoints)?1:0)<=1 + rule: '(has(self.workloadSelector) ? 1 : 0) + (has(self.endpoints) ? + 1 : 0) <= 1' - message: CIDR addresses are allowed only for NONE/STATIC resolution types - rule: '!(has(self.addresses) && self.addresses.exists(k, k.contains(''/'')) - && (has(self.resolution) && self.resolution != ''STATIC'' && self.resolution - != ''NONE''))' + rule: |- + !(has(self.addresses) && self.addresses.exists(k, k.contains("/")) && has(self.resolution) && + self.resolution != "STATIC" && self.resolution != "NONE") - message: NONE mode cannot set endpoints - rule: '(!has(self.resolution) || self.resolution == ''NONE'') ? !has(self.endpoints) + rule: '(!has(self.resolution) || self.resolution == "NONE") ? !has(self.endpoints) : true' - message: DNS_ROUND_ROBIN mode cannot have multiple endpoints - rule: '(has(self.resolution) && self.resolution == ''DNS_ROUND_ROBIN'') - ? (!has(self.endpoints) || size(self.endpoints) == 1) : true' + rule: |- + (has(self.resolution) && self.resolution == "DNS_ROUND_ROBIN") ? (!has(self.endpoints) || + size(self.endpoints) == 1) : true status: properties: conditions: @@ -7666,6 +7687,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -7682,8 +7709,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -7773,11 +7798,11 @@ spec: type: string x-kubernetes-validations: - message: UDS must be an absolute path or abstract socket - rule: 'self.startsWith(''unix://'') ? (self.substring(7,8) - == ''/'' || self.substring(7,8) == ''@'') : true' + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) + == "/" || self.substring(7, 8) == "@") : true' - message: UDS may not be a dir - rule: 'self.startsWith(''unix://'') ? !self.endsWith(''/'') - : true' + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : + true' labels: additionalProperties: type: string @@ -7806,7 +7831,7 @@ spec: type: object x-kubernetes-validations: - message: port name must be valid - rule: self.all(key, size(key) < 63 && key.matches('^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$')) + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) serviceAccount: description: The service account associated with the workload if a sidecar is present in the workload. @@ -7822,7 +7847,7 @@ spec: - message: Address is required rule: has(self.address) || has(self.network) - message: UDS may not include ports - rule: '(has(self.address) && self.address.startsWith(''unix://'')) + rule: '(has(self.address) && self.address.startsWith("unix://")) ? !has(self.ports) : true' maxItems: 4096 type: array @@ -7837,7 +7862,7 @@ spec: type: string x-kubernetes-validations: - message: hostname cannot be wildcard - rule: self != '*' + rule: self != "*" maxItems: 256 minItems: 1 type: array @@ -7917,7 +7942,7 @@ spec: type: string x-kubernetes-validations: - message: wildcard is not supported in selector - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which the configuration should be applied. maxProperties: 256 @@ -7928,18 +7953,20 @@ spec: type: object x-kubernetes-validations: - message: only one of WorkloadSelector or Endpoints can be set - rule: (has(self.workloadSelector)?1:0)+(has(self.endpoints)?1:0)<=1 + rule: '(has(self.workloadSelector) ? 1 : 0) + (has(self.endpoints) ? + 1 : 0) <= 1' - message: CIDR addresses are allowed only for NONE/STATIC resolution types - rule: '!(has(self.addresses) && self.addresses.exists(k, k.contains(''/'')) - && (has(self.resolution) && self.resolution != ''STATIC'' && self.resolution - != ''NONE''))' + rule: |- + !(has(self.addresses) && self.addresses.exists(k, k.contains("/")) && has(self.resolution) && + self.resolution != "STATIC" && self.resolution != "NONE") - message: NONE mode cannot set endpoints - rule: '(!has(self.resolution) || self.resolution == ''NONE'') ? !has(self.endpoints) + rule: '(!has(self.resolution) || self.resolution == "NONE") ? !has(self.endpoints) : true' - message: DNS_ROUND_ROBIN mode cannot have multiple endpoints - rule: '(has(self.resolution) && self.resolution == ''DNS_ROUND_ROBIN'') - ? (!has(self.endpoints) || size(self.endpoints) == 1) : true' + rule: |- + (has(self.resolution) && self.resolution == "DNS_ROUND_ROBIN") ? (!has(self.endpoints) || + size(self.endpoints) == 1) : true status: properties: conditions: @@ -7959,6 +7986,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -7975,8 +8008,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -8066,11 +8097,11 @@ spec: type: string x-kubernetes-validations: - message: UDS must be an absolute path or abstract socket - rule: 'self.startsWith(''unix://'') ? (self.substring(7,8) - == ''/'' || self.substring(7,8) == ''@'') : true' + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) + == "/" || self.substring(7, 8) == "@") : true' - message: UDS may not be a dir - rule: 'self.startsWith(''unix://'') ? !self.endsWith(''/'') - : true' + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : + true' labels: additionalProperties: type: string @@ -8099,7 +8130,7 @@ spec: type: object x-kubernetes-validations: - message: port name must be valid - rule: self.all(key, size(key) < 63 && key.matches('^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$')) + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) serviceAccount: description: The service account associated with the workload if a sidecar is present in the workload. @@ -8115,7 +8146,7 @@ spec: - message: Address is required rule: has(self.address) || has(self.network) - message: UDS may not include ports - rule: '(has(self.address) && self.address.startsWith(''unix://'')) + rule: '(has(self.address) && self.address.startsWith("unix://")) ? !has(self.ports) : true' maxItems: 4096 type: array @@ -8130,7 +8161,7 @@ spec: type: string x-kubernetes-validations: - message: hostname cannot be wildcard - rule: self != '*' + rule: self != "*" maxItems: 256 minItems: 1 type: array @@ -8210,7 +8241,7 @@ spec: type: string x-kubernetes-validations: - message: wildcard is not supported in selector - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which the configuration should be applied. maxProperties: 256 @@ -8221,18 +8252,20 @@ spec: type: object x-kubernetes-validations: - message: only one of WorkloadSelector or Endpoints can be set - rule: (has(self.workloadSelector)?1:0)+(has(self.endpoints)?1:0)<=1 + rule: '(has(self.workloadSelector) ? 1 : 0) + (has(self.endpoints) ? + 1 : 0) <= 1' - message: CIDR addresses are allowed only for NONE/STATIC resolution types - rule: '!(has(self.addresses) && self.addresses.exists(k, k.contains(''/'')) - && (has(self.resolution) && self.resolution != ''STATIC'' && self.resolution - != ''NONE''))' + rule: |- + !(has(self.addresses) && self.addresses.exists(k, k.contains("/")) && has(self.resolution) && + self.resolution != "STATIC" && self.resolution != "NONE") - message: NONE mode cannot set endpoints - rule: '(!has(self.resolution) || self.resolution == ''NONE'') ? !has(self.endpoints) + rule: '(!has(self.resolution) || self.resolution == "NONE") ? !has(self.endpoints) : true' - message: DNS_ROUND_ROBIN mode cannot have multiple endpoints - rule: '(has(self.resolution) && self.resolution == ''DNS_ROUND_ROBIN'') - ? (!has(self.endpoints) || size(self.endpoints) == 1) : true' + rule: |- + (has(self.resolution) && self.resolution == "DNS_ROUND_ROBIN") ? (!has(self.endpoints) || + size(self.endpoints) == 1) : true status: properties: conditions: @@ -8252,6 +8285,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -8268,8 +8307,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -8790,7 +8827,7 @@ spec: type: string x-kubernetes-validations: - message: wildcard is not supported in selector - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which the configuration should be applied. maxProperties: 256 @@ -8816,6 +8853,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -8832,8 +8875,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -9328,7 +9369,7 @@ spec: type: string x-kubernetes-validations: - message: wildcard is not supported in selector - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which the configuration should be applied. maxProperties: 256 @@ -9354,6 +9395,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -9370,8 +9417,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -9866,7 +9911,7 @@ spec: type: string x-kubernetes-validations: - message: wildcard is not supported in selector - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which the configuration should be applied. maxProperties: 256 @@ -9892,6 +9937,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -9908,8 +9959,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -10954,6 +11003,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -10970,8 +11025,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -11990,6 +12043,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -12006,8 +12065,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -13026,6 +13083,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -13042,8 +13105,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -13137,10 +13198,10 @@ spec: type: string x-kubernetes-validations: - message: UDS must be an absolute path or abstract socket - rule: 'self.startsWith(''unix://'') ? (self.substring(7,8) == ''/'' - || self.substring(7,8) == ''@'') : true' + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == "/" + || self.substring(7, 8) == "@") : true' - message: UDS may not be a dir - rule: 'self.startsWith(''unix://'') ? !self.endsWith(''/'') : true' + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' labels: additionalProperties: type: string @@ -13169,7 +13230,7 @@ spec: type: object x-kubernetes-validations: - message: port name must be valid - rule: self.all(key, size(key) < 63 && key.matches('^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$')) + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) serviceAccount: description: The service account associated with the workload if a sidecar is present in the workload. @@ -13185,8 +13246,8 @@ spec: - message: Address is required rule: has(self.address) || has(self.network) - message: UDS may not include ports - rule: '(has(self.address) && self.address.startsWith(''unix://'')) ? - !has(self.ports) : true' + rule: '(has(self.address) && self.address.startsWith("unix://")) ? !has(self.ports) + : true' status: properties: conditions: @@ -13206,6 +13267,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -13222,8 +13289,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -13293,10 +13358,10 @@ spec: type: string x-kubernetes-validations: - message: UDS must be an absolute path or abstract socket - rule: 'self.startsWith(''unix://'') ? (self.substring(7,8) == ''/'' - || self.substring(7,8) == ''@'') : true' + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == "/" + || self.substring(7, 8) == "@") : true' - message: UDS may not be a dir - rule: 'self.startsWith(''unix://'') ? !self.endsWith(''/'') : true' + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' labels: additionalProperties: type: string @@ -13325,7 +13390,7 @@ spec: type: object x-kubernetes-validations: - message: port name must be valid - rule: self.all(key, size(key) < 63 && key.matches('^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$')) + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) serviceAccount: description: The service account associated with the workload if a sidecar is present in the workload. @@ -13341,8 +13406,8 @@ spec: - message: Address is required rule: has(self.address) || has(self.network) - message: UDS may not include ports - rule: '(has(self.address) && self.address.startsWith(''unix://'')) ? - !has(self.ports) : true' + rule: '(has(self.address) && self.address.startsWith("unix://")) ? !has(self.ports) + : true' status: properties: conditions: @@ -13362,6 +13427,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -13378,8 +13449,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -13449,10 +13518,10 @@ spec: type: string x-kubernetes-validations: - message: UDS must be an absolute path or abstract socket - rule: 'self.startsWith(''unix://'') ? (self.substring(7,8) == ''/'' - || self.substring(7,8) == ''@'') : true' + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == "/" + || self.substring(7, 8) == "@") : true' - message: UDS may not be a dir - rule: 'self.startsWith(''unix://'') ? !self.endsWith(''/'') : true' + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' labels: additionalProperties: type: string @@ -13481,7 +13550,7 @@ spec: type: object x-kubernetes-validations: - message: port name must be valid - rule: self.all(key, size(key) < 63 && key.matches('^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$')) + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) serviceAccount: description: The service account associated with the workload if a sidecar is present in the workload. @@ -13497,8 +13566,8 @@ spec: - message: Address is required rule: has(self.address) || has(self.network) - message: UDS may not include ports - rule: '(has(self.address) && self.address.startsWith(''unix://'')) ? - !has(self.ports) : true' + rule: '(has(self.address) && self.address.startsWith("unix://")) ? !has(self.ports) + : true' status: properties: conditions: @@ -13518,6 +13587,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -13534,8 +13609,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -13644,12 +13717,16 @@ spec: - tcpSocket - required: - exec + - required: + - grpc - required: - httpGet - required: - tcpSocket - required: - exec + - required: + - grpc properties: exec: description: Health is determined by how the command that is executed @@ -13670,6 +13747,21 @@ spec: format: int32 minimum: 0 type: integer + grpc: + description: GRPC call is made and response/error is used to determine + health. + properties: + port: + description: Port on which the endpoint lives. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + service: + type: string + type: object httpGet: description: '`httpGet` is performed to a given endpoint and the status/able to connect determines health.' @@ -13704,7 +13796,7 @@ spec: type: string x-kubernetes-validations: - message: scheme must be one of [HTTP, HTTPS] - rule: self in ['', 'HTTP', 'HTTPS'] + rule: self in ["", "HTTP", "HTTPS"] required: - port type: object @@ -13757,11 +13849,10 @@ spec: type: string x-kubernetes-validations: - message: UDS must be an absolute path or abstract socket - rule: 'self.startsWith(''unix://'') ? (self.substring(7,8) == - ''/'' || self.substring(7,8) == ''@'') : true' + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == + "/" || self.substring(7, 8) == "@") : true' - message: UDS may not be a dir - rule: 'self.startsWith(''unix://'') ? !self.endsWith(''/'') - : true' + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' labels: additionalProperties: type: string @@ -13790,7 +13881,7 @@ spec: type: object x-kubernetes-validations: - message: port name must be valid - rule: self.all(key, size(key) < 63 && key.matches('^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$')) + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) serviceAccount: description: The service account associated with the workload if a sidecar is present in the workload. @@ -13804,7 +13895,7 @@ spec: type: object x-kubernetes-validations: - message: UDS may not include ports - rule: '(has(self.address) && self.address.startsWith(''unix://'')) + rule: '(has(self.address) && self.address.startsWith("unix://")) ? !has(self.ports) : true' required: - template @@ -13828,6 +13919,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -13844,8 +13941,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -13930,12 +14025,16 @@ spec: - tcpSocket - required: - exec + - required: + - grpc - required: - httpGet - required: - tcpSocket - required: - exec + - required: + - grpc properties: exec: description: Health is determined by how the command that is executed @@ -13956,6 +14055,21 @@ spec: format: int32 minimum: 0 type: integer + grpc: + description: GRPC call is made and response/error is used to determine + health. + properties: + port: + description: Port on which the endpoint lives. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + service: + type: string + type: object httpGet: description: '`httpGet` is performed to a given endpoint and the status/able to connect determines health.' @@ -13990,7 +14104,7 @@ spec: type: string x-kubernetes-validations: - message: scheme must be one of [HTTP, HTTPS] - rule: self in ['', 'HTTP', 'HTTPS'] + rule: self in ["", "HTTP", "HTTPS"] required: - port type: object @@ -14043,11 +14157,10 @@ spec: type: string x-kubernetes-validations: - message: UDS must be an absolute path or abstract socket - rule: 'self.startsWith(''unix://'') ? (self.substring(7,8) == - ''/'' || self.substring(7,8) == ''@'') : true' + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == + "/" || self.substring(7, 8) == "@") : true' - message: UDS may not be a dir - rule: 'self.startsWith(''unix://'') ? !self.endsWith(''/'') - : true' + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' labels: additionalProperties: type: string @@ -14076,7 +14189,7 @@ spec: type: object x-kubernetes-validations: - message: port name must be valid - rule: self.all(key, size(key) < 63 && key.matches('^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$')) + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) serviceAccount: description: The service account associated with the workload if a sidecar is present in the workload. @@ -14090,7 +14203,7 @@ spec: type: object x-kubernetes-validations: - message: UDS may not include ports - rule: '(has(self.address) && self.address.startsWith(''unix://'')) + rule: '(has(self.address) && self.address.startsWith("unix://")) ? !has(self.ports) : true' required: - template @@ -14114,6 +14227,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -14130,8 +14249,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -14216,12 +14333,16 @@ spec: - tcpSocket - required: - exec + - required: + - grpc - required: - httpGet - required: - tcpSocket - required: - exec + - required: + - grpc properties: exec: description: Health is determined by how the command that is executed @@ -14242,6 +14363,21 @@ spec: format: int32 minimum: 0 type: integer + grpc: + description: GRPC call is made and response/error is used to determine + health. + properties: + port: + description: Port on which the endpoint lives. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + service: + type: string + type: object httpGet: description: '`httpGet` is performed to a given endpoint and the status/able to connect determines health.' @@ -14276,7 +14412,7 @@ spec: type: string x-kubernetes-validations: - message: scheme must be one of [HTTP, HTTPS] - rule: self in ['', 'HTTP', 'HTTPS'] + rule: self in ["", "HTTP", "HTTPS"] required: - port type: object @@ -14329,11 +14465,10 @@ spec: type: string x-kubernetes-validations: - message: UDS must be an absolute path or abstract socket - rule: 'self.startsWith(''unix://'') ? (self.substring(7,8) == - ''/'' || self.substring(7,8) == ''@'') : true' + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == + "/" || self.substring(7, 8) == "@") : true' - message: UDS may not be a dir - rule: 'self.startsWith(''unix://'') ? !self.endsWith(''/'') - : true' + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' labels: additionalProperties: type: string @@ -14362,7 +14497,7 @@ spec: type: object x-kubernetes-validations: - message: port name must be valid - rule: self.all(key, size(key) < 63 && key.matches('^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$')) + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) serviceAccount: description: The service account associated with the workload if a sidecar is present in the workload. @@ -14376,7 +14511,7 @@ spec: type: object x-kubernetes-validations: - message: UDS may not include ports - rule: '(has(self.address) && self.address.startsWith(''unix://'')) + rule: '(has(self.address) && self.address.startsWith("unix://")) ? !has(self.ports) : true' required: - template @@ -14400,6 +14535,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -14416,8 +14557,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -14678,14 +14817,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -14720,8 +14859,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' targetRefs: description: Optional. items: @@ -14755,14 +14895,16 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' maxItems: 16 type: array type: object x-kubernetes-validations: - message: only one of targetRefs or selector can be set - rule: (has(self.selector)?1:0)+(has(self.targetRef)?1:0)+(has(self.targetRefs)?1:0)<=1 + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' status: properties: conditions: @@ -14782,6 +14924,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -14798,8 +14946,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -15031,14 +15177,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -15073,8 +15219,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' targetRefs: description: Optional. items: @@ -15108,14 +15255,16 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' maxItems: 16 type: array type: object x-kubernetes-validations: - message: only one of targetRefs or selector can be set - rule: (has(self.selector)?1:0)+(has(self.targetRef)?1:0)+(has(self.targetRefs)?1:0)<=1 + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' status: properties: conditions: @@ -15135,6 +15284,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -15151,8 +15306,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -15286,22 +15439,23 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object type: object x-kubernetes-validations: - message: portLevelMtls requires selector - rule: (has(self.selector) && has(self.selector.matchLabels) && self.selector.matchLabels.size() - > 0) || !has(self.portLevelMtls) + rule: |- + has(self.selector) && has(self.selector.matchLabels) && self.selector.matchLabels.size() > 0 || + !has(self.portLevelMtls) status: properties: conditions: @@ -15321,6 +15475,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -15337,8 +15497,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -15445,22 +15603,23 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object type: object x-kubernetes-validations: - message: portLevelMtls requires selector - rule: (has(self.selector) && has(self.selector.matchLabels) && self.selector.matchLabels.size() - > 0) || !has(self.portLevelMtls) + rule: |- + has(self.selector) && has(self.selector.matchLabels) && self.selector.matchLabels.size() > 0 || + !has(self.portLevelMtls) status: properties: conditions: @@ -15480,6 +15639,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -15496,8 +15661,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -15632,7 +15795,7 @@ spec: type: string x-kubernetes-validations: - message: url must have scheme http:// or https:// - rule: url(self).getScheme() in ['http', 'https'] + rule: url(self).getScheme() in ["http", "https"] jwksUri: description: URL of the provider's public key set to validate signature of the JWT. @@ -15641,7 +15804,7 @@ spec: type: string x-kubernetes-validations: - message: url must have scheme http:// or https:// - rule: url(self).getScheme() in ['http', 'https'] + rule: url(self).getScheme() in ["http", "https"] outputClaimToHeaders: description: This field specifies a list of operations to copy the claim to HTTP headers on a successfully verified token. @@ -15678,7 +15841,8 @@ spec: type: object x-kubernetes-validations: - message: only one of jwks or jwksUri can be set - rule: (has(self.jwksUri)?1:0)+(has(self.jwks_uri)?1:0)+(has(self.jwks)?1:0)<=1 + rule: '(has(self.jwksUri) ? 1 : 0) + (has(self.jwks_uri) ? 1 : + 0) + (has(self.jwks) ? 1 : 0) <= 1' maxItems: 4096 type: array selector: @@ -15690,14 +15854,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -15732,8 +15896,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' targetRefs: description: Optional. items: @@ -15767,14 +15932,16 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' maxItems: 16 type: array type: object x-kubernetes-validations: - message: only one of targetRefs or selector can be set - rule: (has(self.selector)?1:0)+(has(self.targetRef)?1:0)+(has(self.targetRefs)?1:0)<=1 + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' status: properties: conditions: @@ -15794,6 +15961,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -15810,8 +15983,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -15919,7 +16090,7 @@ spec: type: string x-kubernetes-validations: - message: url must have scheme http:// or https:// - rule: url(self).getScheme() in ['http', 'https'] + rule: url(self).getScheme() in ["http", "https"] jwksUri: description: URL of the provider's public key set to validate signature of the JWT. @@ -15928,7 +16099,7 @@ spec: type: string x-kubernetes-validations: - message: url must have scheme http:// or https:// - rule: url(self).getScheme() in ['http', 'https'] + rule: url(self).getScheme() in ["http", "https"] outputClaimToHeaders: description: This field specifies a list of operations to copy the claim to HTTP headers on a successfully verified token. @@ -15965,7 +16136,8 @@ spec: type: object x-kubernetes-validations: - message: only one of jwks or jwksUri can be set - rule: (has(self.jwksUri)?1:0)+(has(self.jwks_uri)?1:0)+(has(self.jwks)?1:0)<=1 + rule: '(has(self.jwksUri) ? 1 : 0) + (has(self.jwks_uri) ? 1 : + 0) + (has(self.jwks) ? 1 : 0) <= 1' maxItems: 4096 type: array selector: @@ -15977,14 +16149,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -16019,8 +16191,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' targetRefs: description: Optional. items: @@ -16054,14 +16227,16 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' maxItems: 16 type: array type: object x-kubernetes-validations: - message: only one of targetRefs or selector can be set - rule: (has(self.selector)?1:0)+(has(self.targetRef)?1:0)+(has(self.targetRefs)?1:0)<=1 + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' status: properties: conditions: @@ -16081,6 +16256,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -16097,8 +16278,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -16305,11 +16484,11 @@ spec: type: object x-kubernetes-validations: - message: value must be set when operation is UPSERT - rule: '((has(self.operation) ? self.operation : '''') - == ''UPSERT'') ? self.value != '''' : true' + rule: '((has(self.operation) ? self.operation : "") + == "UPSERT") ? (self.value != "") : true' - message: value must not be set when operation is REMOVE - rule: '((has(self.operation) ? self.operation : '''') - == ''REMOVE'') ? !has(self.value) : true' + rule: '((has(self.operation) ? self.operation : "") + == "REMOVE") ? !has(self.value) : true' description: Optional. type: object type: object @@ -16343,14 +16522,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -16385,8 +16564,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' targetRefs: description: Optional. items: @@ -16420,8 +16600,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' maxItems: 16 type: array tracing: @@ -16494,6 +16675,11 @@ spec: description: Controls span reporting. nullable: true type: boolean + enableIstioTags: + description: Determines whether or not trace spans generated + by Envoy will include Istio specific tags. + nullable: true + type: boolean match: description: Allows tailoring of behavior to specific conditions. properties: @@ -16536,7 +16722,8 @@ spec: type: object x-kubernetes-validations: - message: only one of targetRefs or selector can be set - rule: (has(self.selector)?1:0)+(has(self.targetRef)?1:0)+(has(self.targetRefs)?1:0)<=1 + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' status: properties: conditions: @@ -16556,6 +16743,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -16572,8 +16765,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. @@ -16753,11 +16944,11 @@ spec: type: object x-kubernetes-validations: - message: value must be set when operation is UPSERT - rule: '((has(self.operation) ? self.operation : '''') - == ''UPSERT'') ? self.value != '''' : true' + rule: '((has(self.operation) ? self.operation : "") + == "UPSERT") ? (self.value != "") : true' - message: value must not be set when operation is REMOVE - rule: '((has(self.operation) ? self.operation : '''') - == ''REMOVE'') ? !has(self.value) : true' + rule: '((has(self.operation) ? self.operation : "") + == "REMOVE") ? !has(self.value) : true' description: Optional. type: object type: object @@ -16791,14 +16982,14 @@ spec: type: string x-kubernetes-validations: - message: wildcard not allowed in label value match - rule: '!self.contains(''*'')' + rule: '!self.contains("*")' description: One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. maxProperties: 4096 type: object x-kubernetes-validations: - message: wildcard not allowed in label key match - rule: self.all(key, !key.contains('*')) + rule: self.all(key, !key.contains("*")) - message: key must not be empty rule: self.all(key, key.size() != 0) type: object @@ -16833,8 +17024,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' targetRefs: description: Optional. items: @@ -16868,8 +17060,9 @@ spec: x-kubernetes-validations: - message: Support kinds are core/Service, networking.istio.io/ServiceEntry, gateway.networking.k8s.io/Gateway - rule: '[self.group, self.kind] in [[''core'',''Service''], ['''',''Service''], - [''gateway.networking.k8s.io'',''Gateway''], [''networking.istio.io'',''ServiceEntry'']]' + rule: '[self.group, self.kind] in [["core", "Service"], ["", "Service"], + ["gateway.networking.k8s.io", "Gateway"], ["networking.istio.io", + "ServiceEntry"]]' maxItems: 16 type: array tracing: @@ -16942,6 +17135,11 @@ spec: description: Controls span reporting. nullable: true type: boolean + enableIstioTags: + description: Determines whether or not trace spans generated + by Envoy will include Istio specific tags. + nullable: true + type: boolean match: description: Allows tailoring of behavior to specific conditions. properties: @@ -16984,7 +17182,8 @@ spec: type: object x-kubernetes-validations: - message: only one of targetRefs or selector can be set - rule: (has(self.selector)?1:0)+(has(self.targetRef)?1:0)+(has(self.targetRefs)?1:0)<=1 + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' status: properties: conditions: @@ -17004,6 +17203,12 @@ spec: description: Human-readable message indicating details about last transition. type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true reason: description: Unique, one-word, CamelCase reason for the condition's last transition. @@ -17020,8 +17225,6 @@ spec: anyOf: - type: integer - type: string - description: Resource Generation to which the Reconciled Condition - refers. x-kubernetes-int-or-string: true validationMessages: description: Includes any errors or warnings detected by Istio's analyzers. diff --git a/manifests/charts/base/files/profile-compatibility-version-1.21.yaml b/manifests/charts/base/files/profile-compatibility-version-1.21.yaml deleted file mode 100644 index c8da4d2e14d6..000000000000 --- a/manifests/charts/base/files/profile-compatibility-version-1.21.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# WARNING: DO NOT EDIT, THIS FILE IS A COPY. -# The original version of this file is located at /manifests/helm-profiles directory. -# If you want to make a change in this file, edit the original one and run "make gen". - -pilot: - env: - # 1.22 behavioral changes - ENABLE_ENHANCED_RESOURCE_SCOPING: "false" - ENABLE_RESOLUTION_NONE_TARGET_PORT: "false" - - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - - # 1.24 behavioral changes - ENABLE_INBOUND_RETRY_POLICY: "false" - EXCLUDE_UNSAFE_503_FROM_DEFAULT_RETRY: "false" - PREFER_DESTINATIONRULE_TLS_FOR_EXTERNAL_SERVICES: "false" - ENABLE_ENHANCED_DESTINATIONRULE_MERGE: "false" - PILOT_UNIFIED_SIDECAR_SCOPE: "false" - -meshConfig: - # 1.22 behavioral changes - defaultConfig: - proxyMetadata: - ISTIO_DELTA_XDS: "false" - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - # 1.24 behaviour changes - ENABLE_DEFERRED_STATS_CREATION: "false" - BYPASS_OVERLOAD_MANAGER_FOR_STATIC_LISTENERS: "false" - tracing: - zipkin: - address: zipkin.istio-system:9411 diff --git a/manifests/charts/base/files/profile-compatibility-version-1.24.yaml b/manifests/charts/base/files/profile-compatibility-version-1.24.yaml new file mode 100644 index 000000000000..2704a7d95d6f --- /dev/null +++ b/manifests/charts/base/files/profile-compatibility-version-1.24.yaml @@ -0,0 +1,8 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +pilot: + env: + # 1.24 behavioral changes + PILOT_ENABLE_IP_AUTOALLOCATE: "false" diff --git a/manifests/charts/base/files/profile-demo.yaml b/manifests/charts/base/files/profile-demo.yaml index eadbde17c4e3..d6dc36dd0f74 100644 --- a/manifests/charts/base/files/profile-demo.yaml +++ b/manifests/charts/base/files/profile-demo.yaml @@ -21,6 +21,10 @@ meshConfig: opentelemetry: port: 4317 service: opentelemetry-collector.observability.svc.cluster.local + - name: jaeger + opentelemetry: + port: 4317 + service: jaeger-collector.istio-system.svc.cluster.local cni: resources: diff --git a/manifests/charts/base/files/profile-platform-gke.yaml b/manifests/charts/base/files/profile-platform-gke.yaml new file mode 100644 index 000000000000..1e4cfc15e763 --- /dev/null +++ b/manifests/charts/base/files/profile-platform-gke.yaml @@ -0,0 +1,6 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +cni: + cniBinDir: /home/kubernetes/bin diff --git a/manifests/charts/base/files/profile-platform-k3s.yaml b/manifests/charts/base/files/profile-platform-k3s.yaml index f3f2884aaae6..07820106d9be 100644 --- a/manifests/charts/base/files/profile-platform-k3s.yaml +++ b/manifests/charts/base/files/profile-platform-k3s.yaml @@ -4,4 +4,4 @@ cni: cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.d - cniBinDir: /var/lib/rancher/k3s/data/current/bin/ + cniBinDir: /var/lib/rancher/k3s/data/cni diff --git a/manifests/charts/base/templates/zzz_profile.yaml b/manifests/charts/base/templates/zzz_profile.yaml index 35623047cd31..9c2119b9a44a 100644 --- a/manifests/charts/base/templates/zzz_profile.yaml +++ b/manifests/charts/base/templates/zzz_profile.yaml @@ -24,11 +24,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{- $defaults := $.Values._internal_defaults_do_not_set }} {{- $_ := unset $.Values "_internal_defaults_do_not_set" }} {{- $profile := dict }} -{{- with .Values.profile }} +{{- with (coalesce ($.Values).profile ($.Values.global).profile) }} {{- with $.Files.Get (printf "files/profile-%s.yaml" .)}} {{- $profile = (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown profile" $.Values.profile) }} +{{ fail (cat "unknown profile" .) }} {{- end }} {{- end }} {{- with .Values.compatibilityVersion }} @@ -38,11 +38,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{ fail (cat "unknown compatibility version" $.Values.compatibilityVersion) }} {{- end }} {{- end }} -{{- if ($.Values.global).platform }} -{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" ($.Values.global).platform) }} +{{- with (coalesce ($.Values).platform ($.Values.global).platform) }} +{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" .) }} {{- $ignore := mustMergeOverwrite $profile (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown platform" ($.Values.global).platform) }} +{{ fail (cat "unknown platform" .) }} {{- end }} {{- end }} {{- if $profile }} diff --git a/manifests/charts/base/values.yaml b/manifests/charts/base/values.yaml index 98c9c3645936..d18296f00a78 100644 --- a/manifests/charts/base/values.yaml +++ b/manifests/charts/base/values.yaml @@ -10,11 +10,6 @@ _internal_defaults_do_not_set: # Used to locate istiod. istioNamespace: istio-system - - # Platform where Istio is deployed. Possible values are: "openshift", "gcp". - # An empty value means it is a vanilla Kubernetes distribution, therefore no special - # treatment will be considered. - platform: "" base: # A list of CRDs to exclude. Requires `enableCRDTemplates` to be true. # Example: `excludedCRDs: ["envoyfilters.networking.istio.io"]`. diff --git a/manifests/charts/default/files/profile-compatibility-version-1.21.yaml b/manifests/charts/default/files/profile-compatibility-version-1.21.yaml deleted file mode 100644 index c8da4d2e14d6..000000000000 --- a/manifests/charts/default/files/profile-compatibility-version-1.21.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# WARNING: DO NOT EDIT, THIS FILE IS A COPY. -# The original version of this file is located at /manifests/helm-profiles directory. -# If you want to make a change in this file, edit the original one and run "make gen". - -pilot: - env: - # 1.22 behavioral changes - ENABLE_ENHANCED_RESOURCE_SCOPING: "false" - ENABLE_RESOLUTION_NONE_TARGET_PORT: "false" - - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - - # 1.24 behavioral changes - ENABLE_INBOUND_RETRY_POLICY: "false" - EXCLUDE_UNSAFE_503_FROM_DEFAULT_RETRY: "false" - PREFER_DESTINATIONRULE_TLS_FOR_EXTERNAL_SERVICES: "false" - ENABLE_ENHANCED_DESTINATIONRULE_MERGE: "false" - PILOT_UNIFIED_SIDECAR_SCOPE: "false" - -meshConfig: - # 1.22 behavioral changes - defaultConfig: - proxyMetadata: - ISTIO_DELTA_XDS: "false" - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - # 1.24 behaviour changes - ENABLE_DEFERRED_STATS_CREATION: "false" - BYPASS_OVERLOAD_MANAGER_FOR_STATIC_LISTENERS: "false" - tracing: - zipkin: - address: zipkin.istio-system:9411 diff --git a/manifests/charts/default/files/profile-compatibility-version-1.24.yaml b/manifests/charts/default/files/profile-compatibility-version-1.24.yaml new file mode 100644 index 000000000000..2704a7d95d6f --- /dev/null +++ b/manifests/charts/default/files/profile-compatibility-version-1.24.yaml @@ -0,0 +1,8 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +pilot: + env: + # 1.24 behavioral changes + PILOT_ENABLE_IP_AUTOALLOCATE: "false" diff --git a/manifests/charts/default/files/profile-demo.yaml b/manifests/charts/default/files/profile-demo.yaml index eadbde17c4e3..d6dc36dd0f74 100644 --- a/manifests/charts/default/files/profile-demo.yaml +++ b/manifests/charts/default/files/profile-demo.yaml @@ -21,6 +21,10 @@ meshConfig: opentelemetry: port: 4317 service: opentelemetry-collector.observability.svc.cluster.local + - name: jaeger + opentelemetry: + port: 4317 + service: jaeger-collector.istio-system.svc.cluster.local cni: resources: diff --git a/manifests/charts/default/files/profile-platform-gke.yaml b/manifests/charts/default/files/profile-platform-gke.yaml new file mode 100644 index 000000000000..1e4cfc15e763 --- /dev/null +++ b/manifests/charts/default/files/profile-platform-gke.yaml @@ -0,0 +1,6 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +cni: + cniBinDir: /home/kubernetes/bin diff --git a/manifests/charts/default/files/profile-platform-k3s.yaml b/manifests/charts/default/files/profile-platform-k3s.yaml index f3f2884aaae6..07820106d9be 100644 --- a/manifests/charts/default/files/profile-platform-k3s.yaml +++ b/manifests/charts/default/files/profile-platform-k3s.yaml @@ -4,4 +4,4 @@ cni: cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.d - cniBinDir: /var/lib/rancher/k3s/data/current/bin/ + cniBinDir: /var/lib/rancher/k3s/data/cni diff --git a/manifests/charts/default/templates/zzz_profile.yaml b/manifests/charts/default/templates/zzz_profile.yaml index 35623047cd31..9c2119b9a44a 100644 --- a/manifests/charts/default/templates/zzz_profile.yaml +++ b/manifests/charts/default/templates/zzz_profile.yaml @@ -24,11 +24,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{- $defaults := $.Values._internal_defaults_do_not_set }} {{- $_ := unset $.Values "_internal_defaults_do_not_set" }} {{- $profile := dict }} -{{- with .Values.profile }} +{{- with (coalesce ($.Values).profile ($.Values.global).profile) }} {{- with $.Files.Get (printf "files/profile-%s.yaml" .)}} {{- $profile = (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown profile" $.Values.profile) }} +{{ fail (cat "unknown profile" .) }} {{- end }} {{- end }} {{- with .Values.compatibilityVersion }} @@ -38,11 +38,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{ fail (cat "unknown compatibility version" $.Values.compatibilityVersion) }} {{- end }} {{- end }} -{{- if ($.Values.global).platform }} -{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" ($.Values.global).platform) }} +{{- with (coalesce ($.Values).platform ($.Values.global).platform) }} +{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" .) }} {{- $ignore := mustMergeOverwrite $profile (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown platform" ($.Values.global).platform) }} +{{ fail (cat "unknown platform" .) }} {{- end }} {{- end }} {{- if $profile }} diff --git a/manifests/charts/gateway/files/profile-compatibility-version-1.21.yaml b/manifests/charts/gateway/files/profile-compatibility-version-1.21.yaml deleted file mode 100644 index c8da4d2e14d6..000000000000 --- a/manifests/charts/gateway/files/profile-compatibility-version-1.21.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# WARNING: DO NOT EDIT, THIS FILE IS A COPY. -# The original version of this file is located at /manifests/helm-profiles directory. -# If you want to make a change in this file, edit the original one and run "make gen". - -pilot: - env: - # 1.22 behavioral changes - ENABLE_ENHANCED_RESOURCE_SCOPING: "false" - ENABLE_RESOLUTION_NONE_TARGET_PORT: "false" - - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - - # 1.24 behavioral changes - ENABLE_INBOUND_RETRY_POLICY: "false" - EXCLUDE_UNSAFE_503_FROM_DEFAULT_RETRY: "false" - PREFER_DESTINATIONRULE_TLS_FOR_EXTERNAL_SERVICES: "false" - ENABLE_ENHANCED_DESTINATIONRULE_MERGE: "false" - PILOT_UNIFIED_SIDECAR_SCOPE: "false" - -meshConfig: - # 1.22 behavioral changes - defaultConfig: - proxyMetadata: - ISTIO_DELTA_XDS: "false" - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - # 1.24 behaviour changes - ENABLE_DEFERRED_STATS_CREATION: "false" - BYPASS_OVERLOAD_MANAGER_FOR_STATIC_LISTENERS: "false" - tracing: - zipkin: - address: zipkin.istio-system:9411 diff --git a/manifests/charts/gateway/files/profile-compatibility-version-1.24.yaml b/manifests/charts/gateway/files/profile-compatibility-version-1.24.yaml new file mode 100644 index 000000000000..2704a7d95d6f --- /dev/null +++ b/manifests/charts/gateway/files/profile-compatibility-version-1.24.yaml @@ -0,0 +1,8 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +pilot: + env: + # 1.24 behavioral changes + PILOT_ENABLE_IP_AUTOALLOCATE: "false" diff --git a/manifests/charts/gateway/files/profile-demo.yaml b/manifests/charts/gateway/files/profile-demo.yaml index eadbde17c4e3..d6dc36dd0f74 100644 --- a/manifests/charts/gateway/files/profile-demo.yaml +++ b/manifests/charts/gateway/files/profile-demo.yaml @@ -21,6 +21,10 @@ meshConfig: opentelemetry: port: 4317 service: opentelemetry-collector.observability.svc.cluster.local + - name: jaeger + opentelemetry: + port: 4317 + service: jaeger-collector.istio-system.svc.cluster.local cni: resources: diff --git a/manifests/charts/gateway/files/profile-platform-gke.yaml b/manifests/charts/gateway/files/profile-platform-gke.yaml new file mode 100644 index 000000000000..1e4cfc15e763 --- /dev/null +++ b/manifests/charts/gateway/files/profile-platform-gke.yaml @@ -0,0 +1,6 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +cni: + cniBinDir: /home/kubernetes/bin diff --git a/manifests/charts/gateway/files/profile-platform-k3s.yaml b/manifests/charts/gateway/files/profile-platform-k3s.yaml index f3f2884aaae6..07820106d9be 100644 --- a/manifests/charts/gateway/files/profile-platform-k3s.yaml +++ b/manifests/charts/gateway/files/profile-platform-k3s.yaml @@ -4,4 +4,4 @@ cni: cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.d - cniBinDir: /var/lib/rancher/k3s/data/current/bin/ + cniBinDir: /var/lib/rancher/k3s/data/cni diff --git a/manifests/charts/gateway/templates/deployment.yaml b/manifests/charts/gateway/templates/deployment.yaml index e9bfbbd36eb8..9db59d8b9796 100644 --- a/manifests/charts/gateway/templates/deployment.yaml +++ b/manifests/charts/gateway/templates/deployment.yaml @@ -77,7 +77,7 @@ spec: allowPrivilegeEscalation: false privileged: false readOnlyRootFilesystem: true - {{- if not (eq .Values.platform "openshift") }} + {{- if not (eq (.Values.platform | default "") "openshift") }} runAsUser: 1337 runAsGroup: 1337 {{- end }} diff --git a/manifests/charts/gateway/templates/zzz_profile.yaml b/manifests/charts/gateway/templates/zzz_profile.yaml index 35623047cd31..9c2119b9a44a 100644 --- a/manifests/charts/gateway/templates/zzz_profile.yaml +++ b/manifests/charts/gateway/templates/zzz_profile.yaml @@ -24,11 +24,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{- $defaults := $.Values._internal_defaults_do_not_set }} {{- $_ := unset $.Values "_internal_defaults_do_not_set" }} {{- $profile := dict }} -{{- with .Values.profile }} +{{- with (coalesce ($.Values).profile ($.Values.global).profile) }} {{- with $.Files.Get (printf "files/profile-%s.yaml" .)}} {{- $profile = (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown profile" $.Values.profile) }} +{{ fail (cat "unknown profile" .) }} {{- end }} {{- end }} {{- with .Values.compatibilityVersion }} @@ -38,11 +38,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{ fail (cat "unknown compatibility version" $.Values.compatibilityVersion) }} {{- end }} {{- end }} -{{- if ($.Values.global).platform }} -{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" ($.Values.global).platform) }} +{{- with (coalesce ($.Values).platform ($.Values.global).platform) }} +{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" .) }} {{- $ignore := mustMergeOverwrite $profile (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown platform" ($.Values.global).platform) }} +{{ fail (cat "unknown platform" .) }} {{- end }} {{- end }} {{- if $profile }} diff --git a/manifests/charts/gateways/istio-egress/files/profile-compatibility-version-1.21.yaml b/manifests/charts/gateways/istio-egress/files/profile-compatibility-version-1.21.yaml deleted file mode 100644 index c8da4d2e14d6..000000000000 --- a/manifests/charts/gateways/istio-egress/files/profile-compatibility-version-1.21.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# WARNING: DO NOT EDIT, THIS FILE IS A COPY. -# The original version of this file is located at /manifests/helm-profiles directory. -# If you want to make a change in this file, edit the original one and run "make gen". - -pilot: - env: - # 1.22 behavioral changes - ENABLE_ENHANCED_RESOURCE_SCOPING: "false" - ENABLE_RESOLUTION_NONE_TARGET_PORT: "false" - - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - - # 1.24 behavioral changes - ENABLE_INBOUND_RETRY_POLICY: "false" - EXCLUDE_UNSAFE_503_FROM_DEFAULT_RETRY: "false" - PREFER_DESTINATIONRULE_TLS_FOR_EXTERNAL_SERVICES: "false" - ENABLE_ENHANCED_DESTINATIONRULE_MERGE: "false" - PILOT_UNIFIED_SIDECAR_SCOPE: "false" - -meshConfig: - # 1.22 behavioral changes - defaultConfig: - proxyMetadata: - ISTIO_DELTA_XDS: "false" - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - # 1.24 behaviour changes - ENABLE_DEFERRED_STATS_CREATION: "false" - BYPASS_OVERLOAD_MANAGER_FOR_STATIC_LISTENERS: "false" - tracing: - zipkin: - address: zipkin.istio-system:9411 diff --git a/manifests/charts/gateways/istio-egress/files/profile-compatibility-version-1.24.yaml b/manifests/charts/gateways/istio-egress/files/profile-compatibility-version-1.24.yaml new file mode 100644 index 000000000000..2704a7d95d6f --- /dev/null +++ b/manifests/charts/gateways/istio-egress/files/profile-compatibility-version-1.24.yaml @@ -0,0 +1,8 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +pilot: + env: + # 1.24 behavioral changes + PILOT_ENABLE_IP_AUTOALLOCATE: "false" diff --git a/manifests/charts/gateways/istio-egress/files/profile-demo.yaml b/manifests/charts/gateways/istio-egress/files/profile-demo.yaml index eadbde17c4e3..d6dc36dd0f74 100644 --- a/manifests/charts/gateways/istio-egress/files/profile-demo.yaml +++ b/manifests/charts/gateways/istio-egress/files/profile-demo.yaml @@ -21,6 +21,10 @@ meshConfig: opentelemetry: port: 4317 service: opentelemetry-collector.observability.svc.cluster.local + - name: jaeger + opentelemetry: + port: 4317 + service: jaeger-collector.istio-system.svc.cluster.local cni: resources: diff --git a/manifests/charts/gateways/istio-egress/files/profile-platform-gke.yaml b/manifests/charts/gateways/istio-egress/files/profile-platform-gke.yaml new file mode 100644 index 000000000000..1e4cfc15e763 --- /dev/null +++ b/manifests/charts/gateways/istio-egress/files/profile-platform-gke.yaml @@ -0,0 +1,6 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +cni: + cniBinDir: /home/kubernetes/bin diff --git a/manifests/charts/gateways/istio-egress/files/profile-platform-k3s.yaml b/manifests/charts/gateways/istio-egress/files/profile-platform-k3s.yaml index f3f2884aaae6..07820106d9be 100644 --- a/manifests/charts/gateways/istio-egress/files/profile-platform-k3s.yaml +++ b/manifests/charts/gateways/istio-egress/files/profile-platform-k3s.yaml @@ -4,4 +4,4 @@ cni: cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.d - cniBinDir: /var/lib/rancher/k3s/data/current/bin/ + cniBinDir: /var/lib/rancher/k3s/data/cni diff --git a/manifests/charts/gateways/istio-egress/templates/deployment.yaml b/manifests/charts/gateways/istio-egress/templates/deployment.yaml index 5a889315bc1b..c21e3bbeec70 100644 --- a/manifests/charts/gateways/istio-egress/templates/deployment.yaml +++ b/manifests/charts/gateways/istio-egress/templates/deployment.yaml @@ -57,7 +57,7 @@ spec: spec: {{- if not $gateway.runAsRoot }} securityContext: -{{- if not (eq (coalesce .Values.platform .Values.global.platform) "openshift") }} +{{- if not (eq ((coalesce .Values.platform .Values.global.platform) | default "") "openshift") }} runAsUser: 1337 runAsGroup: 1337 {{- end }} diff --git a/manifests/charts/gateways/istio-egress/templates/zzz_profile.yaml b/manifests/charts/gateways/istio-egress/templates/zzz_profile.yaml index 35623047cd31..9c2119b9a44a 100644 --- a/manifests/charts/gateways/istio-egress/templates/zzz_profile.yaml +++ b/manifests/charts/gateways/istio-egress/templates/zzz_profile.yaml @@ -24,11 +24,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{- $defaults := $.Values._internal_defaults_do_not_set }} {{- $_ := unset $.Values "_internal_defaults_do_not_set" }} {{- $profile := dict }} -{{- with .Values.profile }} +{{- with (coalesce ($.Values).profile ($.Values.global).profile) }} {{- with $.Files.Get (printf "files/profile-%s.yaml" .)}} {{- $profile = (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown profile" $.Values.profile) }} +{{ fail (cat "unknown profile" .) }} {{- end }} {{- end }} {{- with .Values.compatibilityVersion }} @@ -38,11 +38,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{ fail (cat "unknown compatibility version" $.Values.compatibilityVersion) }} {{- end }} {{- end }} -{{- if ($.Values.global).platform }} -{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" ($.Values.global).platform) }} +{{- with (coalesce ($.Values).platform ($.Values.global).platform) }} +{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" .) }} {{- $ignore := mustMergeOverwrite $profile (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown platform" ($.Values.global).platform) }} +{{ fail (cat "unknown platform" .) }} {{- end }} {{- end }} {{- if $profile }} diff --git a/manifests/charts/gateways/istio-ingress/files/profile-compatibility-version-1.21.yaml b/manifests/charts/gateways/istio-ingress/files/profile-compatibility-version-1.21.yaml deleted file mode 100644 index c8da4d2e14d6..000000000000 --- a/manifests/charts/gateways/istio-ingress/files/profile-compatibility-version-1.21.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# WARNING: DO NOT EDIT, THIS FILE IS A COPY. -# The original version of this file is located at /manifests/helm-profiles directory. -# If you want to make a change in this file, edit the original one and run "make gen". - -pilot: - env: - # 1.22 behavioral changes - ENABLE_ENHANCED_RESOURCE_SCOPING: "false" - ENABLE_RESOLUTION_NONE_TARGET_PORT: "false" - - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - - # 1.24 behavioral changes - ENABLE_INBOUND_RETRY_POLICY: "false" - EXCLUDE_UNSAFE_503_FROM_DEFAULT_RETRY: "false" - PREFER_DESTINATIONRULE_TLS_FOR_EXTERNAL_SERVICES: "false" - ENABLE_ENHANCED_DESTINATIONRULE_MERGE: "false" - PILOT_UNIFIED_SIDECAR_SCOPE: "false" - -meshConfig: - # 1.22 behavioral changes - defaultConfig: - proxyMetadata: - ISTIO_DELTA_XDS: "false" - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - # 1.24 behaviour changes - ENABLE_DEFERRED_STATS_CREATION: "false" - BYPASS_OVERLOAD_MANAGER_FOR_STATIC_LISTENERS: "false" - tracing: - zipkin: - address: zipkin.istio-system:9411 diff --git a/manifests/charts/gateways/istio-ingress/files/profile-compatibility-version-1.24.yaml b/manifests/charts/gateways/istio-ingress/files/profile-compatibility-version-1.24.yaml new file mode 100644 index 000000000000..2704a7d95d6f --- /dev/null +++ b/manifests/charts/gateways/istio-ingress/files/profile-compatibility-version-1.24.yaml @@ -0,0 +1,8 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +pilot: + env: + # 1.24 behavioral changes + PILOT_ENABLE_IP_AUTOALLOCATE: "false" diff --git a/manifests/charts/gateways/istio-ingress/files/profile-demo.yaml b/manifests/charts/gateways/istio-ingress/files/profile-demo.yaml index eadbde17c4e3..d6dc36dd0f74 100644 --- a/manifests/charts/gateways/istio-ingress/files/profile-demo.yaml +++ b/manifests/charts/gateways/istio-ingress/files/profile-demo.yaml @@ -21,6 +21,10 @@ meshConfig: opentelemetry: port: 4317 service: opentelemetry-collector.observability.svc.cluster.local + - name: jaeger + opentelemetry: + port: 4317 + service: jaeger-collector.istio-system.svc.cluster.local cni: resources: diff --git a/manifests/charts/gateways/istio-ingress/files/profile-platform-gke.yaml b/manifests/charts/gateways/istio-ingress/files/profile-platform-gke.yaml new file mode 100644 index 000000000000..1e4cfc15e763 --- /dev/null +++ b/manifests/charts/gateways/istio-ingress/files/profile-platform-gke.yaml @@ -0,0 +1,6 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +cni: + cniBinDir: /home/kubernetes/bin diff --git a/manifests/charts/gateways/istio-ingress/files/profile-platform-k3s.yaml b/manifests/charts/gateways/istio-ingress/files/profile-platform-k3s.yaml index f3f2884aaae6..07820106d9be 100644 --- a/manifests/charts/gateways/istio-ingress/files/profile-platform-k3s.yaml +++ b/manifests/charts/gateways/istio-ingress/files/profile-platform-k3s.yaml @@ -4,4 +4,4 @@ cni: cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.d - cniBinDir: /var/lib/rancher/k3s/data/current/bin/ + cniBinDir: /var/lib/rancher/k3s/data/cni diff --git a/manifests/charts/gateways/istio-ingress/templates/deployment.yaml b/manifests/charts/gateways/istio-ingress/templates/deployment.yaml index 7b9205da359e..4472186b14ee 100644 --- a/manifests/charts/gateways/istio-ingress/templates/deployment.yaml +++ b/manifests/charts/gateways/istio-ingress/templates/deployment.yaml @@ -57,7 +57,7 @@ spec: spec: {{- if not $gateway.runAsRoot }} securityContext: -{{- if not (eq (coalesce .Values.platform .Values.global.platform) "openshift") }} +{{- if not (eq ((coalesce .Values.platform .Values.global.platform) | default "") "openshift") }} runAsUser: 1337 runAsGroup: 1337 {{- end }} diff --git a/manifests/charts/gateways/istio-ingress/templates/zzz_profile.yaml b/manifests/charts/gateways/istio-ingress/templates/zzz_profile.yaml index 35623047cd31..9c2119b9a44a 100644 --- a/manifests/charts/gateways/istio-ingress/templates/zzz_profile.yaml +++ b/manifests/charts/gateways/istio-ingress/templates/zzz_profile.yaml @@ -24,11 +24,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{- $defaults := $.Values._internal_defaults_do_not_set }} {{- $_ := unset $.Values "_internal_defaults_do_not_set" }} {{- $profile := dict }} -{{- with .Values.profile }} +{{- with (coalesce ($.Values).profile ($.Values.global).profile) }} {{- with $.Files.Get (printf "files/profile-%s.yaml" .)}} {{- $profile = (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown profile" $.Values.profile) }} +{{ fail (cat "unknown profile" .) }} {{- end }} {{- end }} {{- with .Values.compatibilityVersion }} @@ -38,11 +38,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{ fail (cat "unknown compatibility version" $.Values.compatibilityVersion) }} {{- end }} {{- end }} -{{- if ($.Values.global).platform }} -{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" ($.Values.global).platform) }} +{{- with (coalesce ($.Values).platform ($.Values.global).platform) }} +{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" .) }} {{- $ignore := mustMergeOverwrite $profile (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown platform" ($.Values.global).platform) }} +{{ fail (cat "unknown platform" .) }} {{- end }} {{- end }} {{- if $profile }} diff --git a/manifests/charts/istio-cni/files/profile-compatibility-version-1.21.yaml b/manifests/charts/istio-cni/files/profile-compatibility-version-1.21.yaml deleted file mode 100644 index c8da4d2e14d6..000000000000 --- a/manifests/charts/istio-cni/files/profile-compatibility-version-1.21.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# WARNING: DO NOT EDIT, THIS FILE IS A COPY. -# The original version of this file is located at /manifests/helm-profiles directory. -# If you want to make a change in this file, edit the original one and run "make gen". - -pilot: - env: - # 1.22 behavioral changes - ENABLE_ENHANCED_RESOURCE_SCOPING: "false" - ENABLE_RESOLUTION_NONE_TARGET_PORT: "false" - - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - - # 1.24 behavioral changes - ENABLE_INBOUND_RETRY_POLICY: "false" - EXCLUDE_UNSAFE_503_FROM_DEFAULT_RETRY: "false" - PREFER_DESTINATIONRULE_TLS_FOR_EXTERNAL_SERVICES: "false" - ENABLE_ENHANCED_DESTINATIONRULE_MERGE: "false" - PILOT_UNIFIED_SIDECAR_SCOPE: "false" - -meshConfig: - # 1.22 behavioral changes - defaultConfig: - proxyMetadata: - ISTIO_DELTA_XDS: "false" - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - # 1.24 behaviour changes - ENABLE_DEFERRED_STATS_CREATION: "false" - BYPASS_OVERLOAD_MANAGER_FOR_STATIC_LISTENERS: "false" - tracing: - zipkin: - address: zipkin.istio-system:9411 diff --git a/manifests/charts/istio-cni/files/profile-compatibility-version-1.24.yaml b/manifests/charts/istio-cni/files/profile-compatibility-version-1.24.yaml new file mode 100644 index 000000000000..2704a7d95d6f --- /dev/null +++ b/manifests/charts/istio-cni/files/profile-compatibility-version-1.24.yaml @@ -0,0 +1,8 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +pilot: + env: + # 1.24 behavioral changes + PILOT_ENABLE_IP_AUTOALLOCATE: "false" diff --git a/manifests/charts/istio-cni/files/profile-demo.yaml b/manifests/charts/istio-cni/files/profile-demo.yaml index eadbde17c4e3..d6dc36dd0f74 100644 --- a/manifests/charts/istio-cni/files/profile-demo.yaml +++ b/manifests/charts/istio-cni/files/profile-demo.yaml @@ -21,6 +21,10 @@ meshConfig: opentelemetry: port: 4317 service: opentelemetry-collector.observability.svc.cluster.local + - name: jaeger + opentelemetry: + port: 4317 + service: jaeger-collector.istio-system.svc.cluster.local cni: resources: diff --git a/manifests/charts/istio-cni/files/profile-platform-gke.yaml b/manifests/charts/istio-cni/files/profile-platform-gke.yaml new file mode 100644 index 000000000000..1e4cfc15e763 --- /dev/null +++ b/manifests/charts/istio-cni/files/profile-platform-gke.yaml @@ -0,0 +1,6 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +cni: + cniBinDir: /home/kubernetes/bin diff --git a/manifests/charts/istio-cni/files/profile-platform-k3s.yaml b/manifests/charts/istio-cni/files/profile-platform-k3s.yaml index f3f2884aaae6..07820106d9be 100644 --- a/manifests/charts/istio-cni/files/profile-platform-k3s.yaml +++ b/manifests/charts/istio-cni/files/profile-platform-k3s.yaml @@ -4,4 +4,4 @@ cni: cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.d - cniBinDir: /var/lib/rancher/k3s/data/current/bin/ + cniBinDir: /var/lib/rancher/k3s/data/cni diff --git a/manifests/charts/istio-cni/templates/clusterrole.yaml b/manifests/charts/istio-cni/templates/clusterrole.yaml index 197e20c65a7c..cbddace74a67 100644 --- a/manifests/charts/istio-cni/templates/clusterrole.yaml +++ b/manifests/charts/istio-cni/templates/clusterrole.yaml @@ -14,7 +14,7 @@ rules: - apiGroups: [""] resources: ["pods","nodes","namespaces"] verbs: ["get", "list", "watch"] -{{- if (eq (coalesce .Values.platform .Values.global.platform) "openshift") }} +{{- if (eq ((coalesce .Values.platform .Values.global.platform) | default "") "openshift") }} - apiGroups: ["security.openshift.io"] resources: ["securitycontextconstraints"] resourceNames: ["privileged"] @@ -73,4 +73,8 @@ rules: {{- /* pods/status is less privileged than the full pod, and either can label. So use the lower pods/status */}} resources: ["pods/status"] verbs: ["patch", "update"] +- apiGroups: ["apps"] + resources: ["daemonsets"] + resourceNames: ["{{ template "name" . }}-node"] + verbs: ["get"] {{- end }} diff --git a/manifests/charts/istio-cni/templates/configmap-cni.yaml b/manifests/charts/istio-cni/templates/configmap-cni.yaml index 39a09fb6997f..2c2bfe57f6fe 100644 --- a/manifests/charts/istio-cni/templates/configmap-cni.yaml +++ b/manifests/charts/istio-cni/templates/configmap-cni.yaml @@ -16,6 +16,7 @@ data: AMBIENT_ENABLED: {{ .Values.ambient.enabled | quote }} AMBIENT_DNS_CAPTURE: {{ .Values.ambient.dnsCapture | default "false" | quote }} AMBIENT_IPV6: {{ .Values.ambient.ipv6 | default "false" | quote }} + AMBIENT_RECONCILE_POD_RULES_ON_STARTUP: {{ .Values.ambient.reconcileIptablesOnStartup | default "false" | quote }} {{- if .Values.cniConfFileName }} # K8S < 1.24 doesn't like empty values CNI_CONF_NAME: {{ .Values.cniConfFileName }} # Name of the CNI config file to create. Only override if you know the exact path your CNI requires.. {{- end }} diff --git a/manifests/charts/istio-cni/templates/daemonset.yaml b/manifests/charts/istio-cni/templates/daemonset.yaml index f7d2962e2d64..a8c4ef98b36d 100644 --- a/manifests/charts/istio-cni/templates/daemonset.yaml +++ b/manifests/charts/istio-cni/templates/daemonset.yaml @@ -1,10 +1,13 @@ # This manifest installs the Istio install-cni container, as well # as the Istio CNI plugin and config on # each master and worker node in a Kubernetes cluster. -{{- $defaultBinDir := +# +# $detectedBinDir exists to support a GKE-specific platform override, +# and is deprecated in favor of using the explicit `gke` platform profile. +{{- $detectedBinDir := (.Capabilities.KubeVersion.GitVersion | contains "-gke") | ternary "/home/kubernetes/bin" - "/opt/cni/bin" + .Values.cniBinDir }} kind: DaemonSet apiVersion: apps/v1 @@ -41,12 +44,21 @@ spec: prometheus.io/scrape: 'true' prometheus.io/port: "15014" prometheus.io/path: '/metrics' + # Add AppArmor annotation + # This is required to avoid conflicts with AppArmor profiles which block certain + # privileged pod capabilities. + # Required for Kubernetes 1.29 which does not support setting appArmorProfile in the + # securityContext which is otherwise preferred. + container.apparmor.security.beta.kubernetes.io/install-cni: unconfined # Custom annotations {{- if .Values.podAnnotations }} {{ toYaml .Values.podAnnotations | indent 8 }} {{- end }} spec: - {{if .Values.ambient.enabled }}hostNetwork: true{{ end }} +{{if .Values.ambient.enabled }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet +{{ end }} nodeSelector: kubernetes.io/os: linux # Can be configured to allow for excluding istio-cni from being scheduled on specified nodes @@ -104,13 +116,18 @@ spec: - NET_ADMIN # CAP_NET_RAW is required to allow iptables mutation of the `nat` table - NET_RAW - # CAP_SYS_PTRACE is required for repair mode to describe the pod's network namespace - # in ambient and repair mode. + # CAP_SYS_PTRACE is required for repair and ambient mode to describe + # the pod's network namespace. - SYS_PTRACE # CAP_SYS_ADMIN is required for both ambient and repair, in order to open # network namespaces in `/proc` to obtain descriptors for entering pod network # namespaces. There does not appear to be a more granular capability for this. - SYS_ADMIN + # While we run as a 'root' (UID/GID 0), since we drop all capabilities we lose + # the typical ability to read/write to folders owned by others. + # This can cause problems if the hostPath mounts we use, which we require write access into, + # are owned by non-root. DAC_OVERRIDE bypasses these and gives us write access into any folder. + - DAC_OVERRIDE {{- if .Values.seLinuxOptions }} {{ with (merge .Values.seLinuxOptions (dict "type" "spc_t")) }} seLinuxOptions: @@ -191,7 +208,7 @@ spec: # Used to install CNI. - name: cni-bin-dir hostPath: - path: {{ .Values.cniBinDir | default $defaultBinDir }} + path: {{ $detectedBinDir }} {{- if or .Values.repair.repairPods .Values.ambient.enabled }} - name: cni-host-procfs hostPath: @@ -206,14 +223,14 @@ spec: {{- end }} - name: cni-net-dir hostPath: - path: {{ default "/etc/cni/net.d" .Values.cniConfDir }} + path: {{ .Values.cniConfDir }} # Used for UDS sockets for logging, ambient eventing - name: cni-socket-dir hostPath: path: /var/run/istio-cni - name: cni-netns-dir hostPath: - path: {{ .Values.cniNetnsDir | default "/var/run/netns" }} + path: {{ .Values.cniNetnsDir }} type: DirectoryOrCreate # DirectoryOrCreate instead of Directory for the following reason - CNI may not bind mount this until a non-hostnetwork pod is scheduled on the node, # and we don't want to block CNI agent pod creation on waiting for the first non-hostnetwork pod. # Once the CNI does mount this, it will get populated and we're good. diff --git a/manifests/charts/istio-cni/templates/zzz_profile.yaml b/manifests/charts/istio-cni/templates/zzz_profile.yaml index 35623047cd31..9c2119b9a44a 100644 --- a/manifests/charts/istio-cni/templates/zzz_profile.yaml +++ b/manifests/charts/istio-cni/templates/zzz_profile.yaml @@ -24,11 +24,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{- $defaults := $.Values._internal_defaults_do_not_set }} {{- $_ := unset $.Values "_internal_defaults_do_not_set" }} {{- $profile := dict }} -{{- with .Values.profile }} +{{- with (coalesce ($.Values).profile ($.Values.global).profile) }} {{- with $.Files.Get (printf "files/profile-%s.yaml" .)}} {{- $profile = (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown profile" $.Values.profile) }} +{{ fail (cat "unknown profile" .) }} {{- end }} {{- end }} {{- with .Values.compatibilityVersion }} @@ -38,11 +38,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{ fail (cat "unknown compatibility version" $.Values.compatibilityVersion) }} {{- end }} {{- end }} -{{- if ($.Values.global).platform }} -{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" ($.Values.global).platform) }} +{{- with (coalesce ($.Values).platform ($.Values.global).platform) }} +{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" .) }} {{- $ignore := mustMergeOverwrite $profile (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown platform" ($.Values.global).platform) }} +{{ fail (cat "unknown platform" .) }} {{- end }} {{- end }} {{- if $profile }} diff --git a/manifests/charts/istio-cni/values.yaml b/manifests/charts/istio-cni/values.yaml index 1c2d22f9dca8..6ac1d05e317e 100644 --- a/manifests/charts/istio-cni/values.yaml +++ b/manifests/charts/istio-cni/values.yaml @@ -16,15 +16,13 @@ _internal_defaults_do_not_set: # Example # cniConfFileName: 10-calico.conflist - # CNI bin and conf dir override settings - # defaults: - cniBinDir: "" # Auto-detected based on version; defaults to /opt/cni/bin. + # CNI-and-platform specific path defaults. + # These may need to be set to platform-specific values, consult + # overrides for your platform in `manifests/helm-profiles/platform-*.yaml` + cniBinDir: /opt/cni/bin cniConfDir: /etc/cni/net.d cniConfFileName: "" - # This directory must exist on the node, if it does not, consult your container runtime - # documentation for the appropriate path. - cniNetnsDir: # Defaults to '/var/run/netns', in minikube/docker/others can be '/var/run/docker/netns'. - + cniNetnsDir: "/var/run/netns" excludeNamespaces: - kube-system @@ -53,6 +51,8 @@ _internal_defaults_do_not_set: dnsCapture: false # If enabled, and ambient is enabled, enables ipv6 support ipv6: true + # If enabled, and ambient is enabled, the CNI agent will reconcile incompatible iptables rules and chains at startup. + reconcileIptablesOnStartup: false repair: diff --git a/manifests/charts/istio-control/istio-discovery/files/injection-template.yaml b/manifests/charts/istio-control/istio-discovery/files/injection-template.yaml index 0ef948e6a36f..3b3f69cd9dda 100644 --- a/manifests/charts/istio-control/istio-discovery/files/injection-template.yaml +++ b/manifests/charts/istio-control/istio-discovery/files/injection-template.yaml @@ -52,7 +52,7 @@ metadata: sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} + traffic.sidecar.istio.io/includeInboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}", traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", @@ -61,6 +61,7 @@ metadata: traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", {{- end }} {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} + {{ with index .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces` }}istio.io/reroute-virtual-interfaces: "{{.}}",{{ end }} {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} {{- end }} } @@ -113,6 +114,10 @@ spec: {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - "-k" - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" + {{ end -}} + {{ if (isset .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces`) -}} + - "-k" + - "{{ index .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces` }}" {{ end -}} {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - "-c" @@ -293,9 +298,9 @@ spec: - name: ISTIO_META_NETWORK value: "{{ .Values.global.network }}" {{- end }} - {{- if .DeploymentMeta.Name }} + {{- with (index .ObjectMeta.Labels `service.istio.io/workload-name` | default .DeploymentMeta.Name) }} - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" + value: "{{ . }}" {{ end }} {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - name: ISTIO_META_OWNER diff --git a/manifests/charts/istio-control/istio-discovery/files/profile-compatibility-version-1.21.yaml b/manifests/charts/istio-control/istio-discovery/files/profile-compatibility-version-1.21.yaml deleted file mode 100644 index c8da4d2e14d6..000000000000 --- a/manifests/charts/istio-control/istio-discovery/files/profile-compatibility-version-1.21.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# WARNING: DO NOT EDIT, THIS FILE IS A COPY. -# The original version of this file is located at /manifests/helm-profiles directory. -# If you want to make a change in this file, edit the original one and run "make gen". - -pilot: - env: - # 1.22 behavioral changes - ENABLE_ENHANCED_RESOURCE_SCOPING: "false" - ENABLE_RESOLUTION_NONE_TARGET_PORT: "false" - - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - - # 1.24 behavioral changes - ENABLE_INBOUND_RETRY_POLICY: "false" - EXCLUDE_UNSAFE_503_FROM_DEFAULT_RETRY: "false" - PREFER_DESTINATIONRULE_TLS_FOR_EXTERNAL_SERVICES: "false" - ENABLE_ENHANCED_DESTINATIONRULE_MERGE: "false" - PILOT_UNIFIED_SIDECAR_SCOPE: "false" - -meshConfig: - # 1.22 behavioral changes - defaultConfig: - proxyMetadata: - ISTIO_DELTA_XDS: "false" - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - # 1.24 behaviour changes - ENABLE_DEFERRED_STATS_CREATION: "false" - BYPASS_OVERLOAD_MANAGER_FOR_STATIC_LISTENERS: "false" - tracing: - zipkin: - address: zipkin.istio-system:9411 diff --git a/manifests/charts/istio-control/istio-discovery/files/profile-compatibility-version-1.24.yaml b/manifests/charts/istio-control/istio-discovery/files/profile-compatibility-version-1.24.yaml new file mode 100644 index 000000000000..2704a7d95d6f --- /dev/null +++ b/manifests/charts/istio-control/istio-discovery/files/profile-compatibility-version-1.24.yaml @@ -0,0 +1,8 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +pilot: + env: + # 1.24 behavioral changes + PILOT_ENABLE_IP_AUTOALLOCATE: "false" diff --git a/manifests/charts/istio-control/istio-discovery/files/profile-demo.yaml b/manifests/charts/istio-control/istio-discovery/files/profile-demo.yaml index eadbde17c4e3..d6dc36dd0f74 100644 --- a/manifests/charts/istio-control/istio-discovery/files/profile-demo.yaml +++ b/manifests/charts/istio-control/istio-discovery/files/profile-demo.yaml @@ -21,6 +21,10 @@ meshConfig: opentelemetry: port: 4317 service: opentelemetry-collector.observability.svc.cluster.local + - name: jaeger + opentelemetry: + port: 4317 + service: jaeger-collector.istio-system.svc.cluster.local cni: resources: diff --git a/manifests/charts/istio-control/istio-discovery/files/profile-platform-gke.yaml b/manifests/charts/istio-control/istio-discovery/files/profile-platform-gke.yaml new file mode 100644 index 000000000000..1e4cfc15e763 --- /dev/null +++ b/manifests/charts/istio-control/istio-discovery/files/profile-platform-gke.yaml @@ -0,0 +1,6 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +cni: + cniBinDir: /home/kubernetes/bin diff --git a/manifests/charts/istio-control/istio-discovery/files/profile-platform-k3s.yaml b/manifests/charts/istio-control/istio-discovery/files/profile-platform-k3s.yaml index f3f2884aaae6..07820106d9be 100644 --- a/manifests/charts/istio-control/istio-discovery/files/profile-platform-k3s.yaml +++ b/manifests/charts/istio-control/istio-discovery/files/profile-platform-k3s.yaml @@ -4,4 +4,4 @@ cni: cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.d - cniBinDir: /var/lib/rancher/k3s/data/current/bin/ + cniBinDir: /var/lib/rancher/k3s/data/cni diff --git a/manifests/charts/istio-control/istio-discovery/files/waypoint.yaml b/manifests/charts/istio-control/istio-discovery/files/waypoint.yaml index bbe47674b90b..2600e98e2114 100644 --- a/manifests/charts/istio-control/istio-discovery/files/waypoint.yaml +++ b/manifests/charts/istio-control/istio-discovery/files/waypoint.yaml @@ -120,6 +120,9 @@ spec: {{- if .Values.global.logAsJson }} - --log_as_json {{- end }} + {{- if .Values.global.proxy.outlierLogPath }} + - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} + {{- end}} env: - name: ISTIO_META_SERVICE_ACCOUNT valueFrom: @@ -198,6 +201,10 @@ spec: - name: ISTIO_META_MESH_ID value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} {{- if .Values.global.waypoint.resources }} resources: {{- toYaml .Values.global.waypoint.resources | nindent 10 }} diff --git a/manifests/charts/istio-control/istio-discovery/templates/serviceaccount.yaml b/manifests/charts/istio-control/istio-discovery/templates/serviceaccount.yaml index 22b841e872fc..a673a4d0781a 100644 --- a/manifests/charts/istio-control/istio-discovery/templates/serviceaccount.yaml +++ b/manifests/charts/istio-control/istio-discovery/templates/serviceaccount.yaml @@ -18,7 +18,7 @@ metadata: {{- include "istio.labels" . | nindent 4 }} {{- if .Values.serviceAccountAnnotations }} annotations: -{{- toYaml .Values.serviceAccountAnnotations | indent 4 }} +{{- toYaml .Values.serviceAccountAnnotations | nindent 4 }} {{- end }} {{- end }} --- diff --git a/manifests/charts/istio-control/istio-discovery/templates/zzz_profile.yaml b/manifests/charts/istio-control/istio-discovery/templates/zzz_profile.yaml index 35623047cd31..9c2119b9a44a 100644 --- a/manifests/charts/istio-control/istio-discovery/templates/zzz_profile.yaml +++ b/manifests/charts/istio-control/istio-discovery/templates/zzz_profile.yaml @@ -24,11 +24,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{- $defaults := $.Values._internal_defaults_do_not_set }} {{- $_ := unset $.Values "_internal_defaults_do_not_set" }} {{- $profile := dict }} -{{- with .Values.profile }} +{{- with (coalesce ($.Values).profile ($.Values.global).profile) }} {{- with $.Files.Get (printf "files/profile-%s.yaml" .)}} {{- $profile = (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown profile" $.Values.profile) }} +{{ fail (cat "unknown profile" .) }} {{- end }} {{- end }} {{- with .Values.compatibilityVersion }} @@ -38,11 +38,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{ fail (cat "unknown compatibility version" $.Values.compatibilityVersion) }} {{- end }} {{- end }} -{{- if ($.Values.global).platform }} -{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" ($.Values.global).platform) }} +{{- with (coalesce ($.Values).platform ($.Values.global).platform) }} +{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" .) }} {{- $ignore := mustMergeOverwrite $profile (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown platform" ($.Values.global).platform) }} +{{ fail (cat "unknown platform" .) }} {{- end }} {{- end }} {{- if $profile }} diff --git a/manifests/charts/ztunnel/files/profile-compatibility-version-1.21.yaml b/manifests/charts/ztunnel/files/profile-compatibility-version-1.21.yaml deleted file mode 100644 index c8da4d2e14d6..000000000000 --- a/manifests/charts/ztunnel/files/profile-compatibility-version-1.21.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# WARNING: DO NOT EDIT, THIS FILE IS A COPY. -# The original version of this file is located at /manifests/helm-profiles directory. -# If you want to make a change in this file, edit the original one and run "make gen". - -pilot: - env: - # 1.22 behavioral changes - ENABLE_ENHANCED_RESOURCE_SCOPING: "false" - ENABLE_RESOLUTION_NONE_TARGET_PORT: "false" - - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - - # 1.24 behavioral changes - ENABLE_INBOUND_RETRY_POLICY: "false" - EXCLUDE_UNSAFE_503_FROM_DEFAULT_RETRY: "false" - PREFER_DESTINATIONRULE_TLS_FOR_EXTERNAL_SERVICES: "false" - ENABLE_ENHANCED_DESTINATIONRULE_MERGE: "false" - PILOT_UNIFIED_SIDECAR_SCOPE: "false" - -meshConfig: - # 1.22 behavioral changes - defaultConfig: - proxyMetadata: - ISTIO_DELTA_XDS: "false" - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - # 1.24 behaviour changes - ENABLE_DEFERRED_STATS_CREATION: "false" - BYPASS_OVERLOAD_MANAGER_FOR_STATIC_LISTENERS: "false" - tracing: - zipkin: - address: zipkin.istio-system:9411 diff --git a/manifests/charts/ztunnel/files/profile-compatibility-version-1.24.yaml b/manifests/charts/ztunnel/files/profile-compatibility-version-1.24.yaml new file mode 100644 index 000000000000..2704a7d95d6f --- /dev/null +++ b/manifests/charts/ztunnel/files/profile-compatibility-version-1.24.yaml @@ -0,0 +1,8 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +pilot: + env: + # 1.24 behavioral changes + PILOT_ENABLE_IP_AUTOALLOCATE: "false" diff --git a/manifests/charts/ztunnel/files/profile-demo.yaml b/manifests/charts/ztunnel/files/profile-demo.yaml index eadbde17c4e3..d6dc36dd0f74 100644 --- a/manifests/charts/ztunnel/files/profile-demo.yaml +++ b/manifests/charts/ztunnel/files/profile-demo.yaml @@ -21,6 +21,10 @@ meshConfig: opentelemetry: port: 4317 service: opentelemetry-collector.observability.svc.cluster.local + - name: jaeger + opentelemetry: + port: 4317 + service: jaeger-collector.istio-system.svc.cluster.local cni: resources: diff --git a/manifests/charts/ztunnel/files/profile-platform-gke.yaml b/manifests/charts/ztunnel/files/profile-platform-gke.yaml new file mode 100644 index 000000000000..1e4cfc15e763 --- /dev/null +++ b/manifests/charts/ztunnel/files/profile-platform-gke.yaml @@ -0,0 +1,6 @@ +# WARNING: DO NOT EDIT, THIS FILE IS A COPY. +# The original version of this file is located at /manifests/helm-profiles directory. +# If you want to make a change in this file, edit the original one and run "make gen". + +cni: + cniBinDir: /home/kubernetes/bin diff --git a/manifests/charts/ztunnel/files/profile-platform-k3s.yaml b/manifests/charts/ztunnel/files/profile-platform-k3s.yaml index f3f2884aaae6..07820106d9be 100644 --- a/manifests/charts/ztunnel/files/profile-platform-k3s.yaml +++ b/manifests/charts/ztunnel/files/profile-platform-k3s.yaml @@ -4,4 +4,4 @@ cni: cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.d - cniBinDir: /var/lib/rancher/k3s/data/current/bin/ + cniBinDir: /var/lib/rancher/k3s/data/cni diff --git a/manifests/charts/ztunnel/templates/_helpers.tpl b/manifests/charts/ztunnel/templates/_helpers.tpl new file mode 100644 index 000000000000..82740e441626 --- /dev/null +++ b/manifests/charts/ztunnel/templates/_helpers.tpl @@ -0,0 +1 @@ +{{ define "ztunnel.release-name" }}{{ .Values.resourceName| default .Release.Name }}{{ end }} diff --git a/manifests/charts/ztunnel/templates/daemonset.yaml b/manifests/charts/ztunnel/templates/daemonset.yaml index c6e2daf48ab2..bfb74280d237 100644 --- a/manifests/charts/ztunnel/templates/daemonset.yaml +++ b/manifests/charts/ztunnel/templates/daemonset.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: DaemonSet metadata: - name: ztunnel + name: {{ include "ztunnel.release-name" . }} namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/name: ztunnel diff --git a/manifests/charts/ztunnel/templates/rbac.yaml b/manifests/charts/ztunnel/templates/rbac.yaml index a9ea6fb6ad2b..3b90cf5af4d6 100644 --- a/manifests/charts/ztunnel/templates/rbac.yaml +++ b/manifests/charts/ztunnel/templates/rbac.yaml @@ -7,7 +7,7 @@ imagePullSecrets: {{- end }} {{- end }} metadata: - name: ztunnel + name: {{ include "ztunnel.release-name" . }} namespace: {{ .Release.Namespace }} labels: app.kubernetes.io/name: ztunnel @@ -21,14 +21,14 @@ metadata: {{- .Values.annotations | toYaml | nindent 4 }} {{- end }} --- -{{- if (eq .Values.platform "openshift") }} +{{- if (eq (.Values.platform | default "") "openshift") }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: ztunnel + name: {{ include "ztunnel.release-name" . }} labels: app: ztunnel - release: {{ .Release.Name }} + release: {{ include "ztunnel.release-name" . }} install.operator.istio.io/owning-resource: {{ .Values.ownerName | default "unknown" }} app.kubernetes.io/name: ztunnel {{- include "istio.labels" . | nindent 4}} @@ -48,10 +48,10 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: ztunnel + name: {{ include "ztunnel.release-name" . }} labels: app: ztunnel - release: {{ .Release.Name }} + release: {{ include "ztunnel.release-name" . }} install.operator.istio.io/owning-resource: {{ .Values.ownerName | default "unknown" }} app.kubernetes.io/name: ztunnel {{- include "istio.labels" . | nindent 4}} @@ -65,10 +65,10 @@ metadata: roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: ztunnel + name: {{ include "ztunnel.release-name" . }} subjects: - kind: ServiceAccount - name: ztunnel + name: {{ include "ztunnel.release-name" . }} namespace: {{ .Release.Namespace }} {{- end }} --- diff --git a/manifests/charts/ztunnel/templates/zzz_profile.yaml b/manifests/charts/ztunnel/templates/zzz_profile.yaml index 72d3adc53113..ded66c5fdf7b 100644 --- a/manifests/charts/ztunnel/templates/zzz_profile.yaml +++ b/manifests/charts/ztunnel/templates/zzz_profile.yaml @@ -24,11 +24,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{- $defaults := $.Values._internal_defaults_do_not_set }} {{- $_ := unset $.Values "_internal_defaults_do_not_set" }} {{- $profile := dict }} -{{- with .Values.profile }} +{{- with (coalesce ($.Values).profile ($.Values.global).profile) }} {{- with $.Files.Get (printf "files/profile-%s.yaml" .)}} {{- $profile = (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown profile" $.Values.profile) }} +{{ fail (cat "unknown profile" .) }} {{- end }} {{- end }} {{- with .Values.compatibilityVersion }} @@ -38,11 +38,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{ fail (cat "unknown compatibility version" $.Values.compatibilityVersion) }} {{- end }} {{- end }} -{{- if ($.Values.global).platform }} -{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" ($.Values.global).platform) }} +{{- with (coalesce ($.Values).platform ($.Values.global).platform) }} +{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" .) }} {{- $ignore := mustMergeOverwrite $profile (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown platform" ($.Values.global).platform) }} +{{ fail (cat "unknown platform" .) }} {{- end }} {{- end }} {{- if $profile }} diff --git a/manifests/charts/ztunnel/values.yaml b/manifests/charts/ztunnel/values.yaml index b47eba0ec836..ab41dfd05273 100644 --- a/manifests/charts/ztunnel/values.yaml +++ b/manifests/charts/ztunnel/values.yaml @@ -12,6 +12,10 @@ _internal_defaults_do_not_set: # If Image contains a "/", it will replace the entire `image` in the pod. image: ztunnel + # resourceName, if set, will override the naming of resources. If not set, will default to the release name. + # It is recommended to not set this; this is primarily for backwards compatibility. + resourceName: "" + # Labels to apply to all top level resources labels: {} # Annotations to apply to all top level resources diff --git a/manifests/helm-profiles/compatibility-version-1.21.yaml b/manifests/helm-profiles/compatibility-version-1.21.yaml deleted file mode 100644 index d42fadbc2919..000000000000 --- a/manifests/helm-profiles/compatibility-version-1.21.yaml +++ /dev/null @@ -1,29 +0,0 @@ -pilot: - env: - # 1.22 behavioral changes - ENABLE_ENHANCED_RESOURCE_SCOPING: "false" - ENABLE_RESOLUTION_NONE_TARGET_PORT: "false" - - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - - # 1.24 behavioral changes - ENABLE_INBOUND_RETRY_POLICY: "false" - EXCLUDE_UNSAFE_503_FROM_DEFAULT_RETRY: "false" - PREFER_DESTINATIONRULE_TLS_FOR_EXTERNAL_SERVICES: "false" - ENABLE_ENHANCED_DESTINATIONRULE_MERGE: "false" - PILOT_UNIFIED_SIDECAR_SCOPE: "false" - -meshConfig: - # 1.22 behavioral changes - defaultConfig: - proxyMetadata: - ISTIO_DELTA_XDS: "false" - # 1.23 behavioral changes - ENABLE_DELIMITED_STATS_TAG_REGEX: "false" - # 1.24 behaviour changes - ENABLE_DEFERRED_STATS_CREATION: "false" - BYPASS_OVERLOAD_MANAGER_FOR_STATIC_LISTENERS: "false" - tracing: - zipkin: - address: zipkin.istio-system:9411 diff --git a/manifests/helm-profiles/compatibility-version-1.24.yaml b/manifests/helm-profiles/compatibility-version-1.24.yaml new file mode 100644 index 000000000000..db1a67e64bf8 --- /dev/null +++ b/manifests/helm-profiles/compatibility-version-1.24.yaml @@ -0,0 +1,4 @@ +pilot: + env: + # 1.24 behavioral changes + PILOT_ENABLE_IP_AUTOALLOCATE: "false" diff --git a/manifests/helm-profiles/demo.yaml b/manifests/helm-profiles/demo.yaml index 88f5116972aa..a3e5a692f9ed 100644 --- a/manifests/helm-profiles/demo.yaml +++ b/manifests/helm-profiles/demo.yaml @@ -17,6 +17,10 @@ meshConfig: opentelemetry: port: 4317 service: opentelemetry-collector.observability.svc.cluster.local + - name: jaeger + opentelemetry: + port: 4317 + service: jaeger-collector.istio-system.svc.cluster.local cni: resources: diff --git a/manifests/helm-profiles/platform-gke.yaml b/manifests/helm-profiles/platform-gke.yaml new file mode 100644 index 000000000000..6daf336ebd96 --- /dev/null +++ b/manifests/helm-profiles/platform-gke.yaml @@ -0,0 +1,2 @@ +cni: + cniBinDir: /home/kubernetes/bin diff --git a/manifests/helm-profiles/platform-k3s.yaml b/manifests/helm-profiles/platform-k3s.yaml index f47d42cce2f4..119ead83e885 100644 --- a/manifests/helm-profiles/platform-k3s.yaml +++ b/manifests/helm-profiles/platform-k3s.yaml @@ -1,3 +1,3 @@ cni: cniConfDir: /var/lib/rancher/k3s/agent/etc/cni/net.d - cniBinDir: /var/lib/rancher/k3s/data/current/bin/ + cniBinDir: /var/lib/rancher/k3s/data/cni diff --git a/manifests/profiles/default.yaml b/manifests/profiles/default.yaml index 75ad17fdd837..cf749dfa4933 100644 --- a/manifests/profiles/default.yaml +++ b/manifests/profiles/default.yaml @@ -30,3 +30,5 @@ spec: gateways: istio-ingressgateway: {} istio-egressgateway: {} + ztunnel: + resourceName: ztunnel diff --git a/manifests/sample-charts/ambient/values.yaml b/manifests/sample-charts/ambient/values.yaml index 24dd24624b27..c7df0953ef9a 100644 --- a/manifests/sample-charts/ambient/values.yaml +++ b/manifests/sample-charts/ambient/values.yaml @@ -9,6 +9,7 @@ istiod: # Overrides for the `ztunnel` dep ztunnel: profile: ambient + resourceName: ztunnel # Overrides for the `cni` dep cni: diff --git a/manifests/zzz_profile.yaml b/manifests/zzz_profile.yaml index a92ae92a04cb..dfb9ad2975e2 100644 --- a/manifests/zzz_profile.yaml +++ b/manifests/zzz_profile.yaml @@ -24,11 +24,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{- $defaults := $.Values._internal_defaults_do_not_set }} {{- $_ := unset $.Values "_internal_defaults_do_not_set" }} {{- $profile := dict }} -{{- with .Values.profile }} +{{- with (coalesce ($.Values).profile ($.Values.global).profile) }} {{- with $.Files.Get (printf "files/profile-%s.yaml" .)}} {{- $profile = (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown profile" $.Values.profile) }} +{{ fail (cat "unknown profile" .) }} {{- end }} {{- end }} {{- with .Values.compatibilityVersion }} @@ -38,11 +38,11 @@ Finally, we can set all of that under .Values so the chart behaves without aware {{ fail (cat "unknown compatibility version" $.Values.compatibilityVersion) }} {{- end }} {{- end }} -{{- if ($.Values.global).platform }} -{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" ($.Values.global).platform) }} +{{- with (coalesce ($.Values).platform ($.Values.global).platform) }} +{{- with $.Files.Get (printf "files/profile-platform-%s.yaml" .) }} {{- $ignore := mustMergeOverwrite $profile (. | fromYaml) }} {{- else }} -{{ fail (cat "unknown platform" ($.Values.global).platform) }} +{{ fail (cat "unknown platform" .) }} {{- end }} {{- end }} {{- if $profile }} diff --git a/operator/cmd/mesh/manifest-generate_test.go b/operator/cmd/mesh/manifest-generate_test.go index cc220572683d..64e983e17a51 100644 --- a/operator/cmd/mesh/manifest-generate_test.go +++ b/operator/cmd/mesh/manifest-generate_test.go @@ -517,8 +517,9 @@ func TestManifestGeneratePilot(t *testing.T) { fileSelect: []string{"templates/deployment.yaml", "templates/autoscale.yaml"}, }, { - desc: "pilot_override_kubernetes", - diffSelect: "Deployment:*:istiod, Service:*:istiod,MutatingWebhookConfiguration:*:istio-sidecar-injector,ServiceAccount:*:istio-reader-service-account", + desc: "pilot_override_kubernetes", + // nolint: lll + diffSelect: "Deployment:*:istiod, Service:*:istiod,PodDisruptionBudget:*:istiod,MutatingWebhookConfiguration:*:istio-sidecar-injector,ServiceAccount:*:istio-reader-service-account", fileSelect: []string{ "templates/deployment.yaml", "templates/mutatingwebhook.yaml", "templates/service.yaml", "templates/reader-serviceaccount.yaml", @@ -817,9 +818,20 @@ func TestLDFlags(t *testing.T) { assert.Equal(t, vals.GetPathString("spec.tag"), version.DockerInfo.Tag) } +// TestManifestGenerateStructure makes some basic assertions about the structure of GeneratedManifests output. +// This is to ensure that we only generate a single ManifestSet per component-type (in this case ingress gateways). +// prevent an `istioctl install` regression of https://github.com/istio/istio/issues/53875 +func TestManifestGenerateStructure(t *testing.T) { + multiGatewayFile := filepath.Join(testDataDir, "input/gateways.yaml") + sets, _, err := render.GenerateManifest([]string{multiGatewayFile}, []string{}, false, nil, nil) + assert.NoError(t, err) + assert.Equal(t, len(sets), 1) // if this produces more than 1 ManifestSet it will cause a deadlock during install + gateways := sets[0].Manifests + assert.Equal(t, len(gateways), 21) // 7 kube resources * 3 gateways +} + func runTestGroup(t *testing.T, tests testGroup) { for _, tt := range tests { - tt := tt t.Run(tt.desc, func(t *testing.T) { t.Parallel() inPath := filepath.Join(testDataDir, "input", tt.desc+".yaml") diff --git a/operator/cmd/mesh/testdata/manifest-generate/input/pilot_override_kubernetes.yaml b/operator/cmd/mesh/testdata/manifest-generate/input/pilot_override_kubernetes.yaml index a657f69f3fb9..a319379bd9a2 100644 --- a/operator/cmd/mesh/testdata/manifest-generate/input/pilot_override_kubernetes.yaml +++ b/operator/cmd/mesh/testdata/manifest-generate/input/pilot_override_kubernetes.yaml @@ -23,6 +23,8 @@ spec: enabled: true namespace: istio-control k8s: + podDisruptionBudget: + maxUnavailable: 1 resources: requests: cpu: 123m diff --git a/operator/cmd/mesh/testdata/manifest-generate/output/pilot_override_kubernetes.golden.yaml b/operator/cmd/mesh/testdata/manifest-generate/output/pilot_override_kubernetes.golden.yaml index 2cdbf82fc52a..b3a63bd8073b 100644 --- a/operator/cmd/mesh/testdata/manifest-generate/output/pilot_override_kubernetes.golden.yaml +++ b/operator/cmd/mesh/testdata/manifest-generate/output/pilot_override_kubernetes.golden.yaml @@ -316,6 +316,26 @@ spec: optional: true name: istio-csr-ca-configmap --- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + labels: + app: istiod + install.operator.istio.io/owning-resource: unknown + istio: pilot + istio.io/rev: default + operator.istio.io/component: Pilot + release: istio + name: istiod + namespace: istio-control +spec: + maxUnavailable: 1 + minAvailable: null + selector: + matchLabels: + app: istiod + istio: pilot +--- apiVersion: v1 kind: Service metadata: diff --git a/operator/pkg/apis/validation/validation.go b/operator/pkg/apis/validation/validation.go index dac464679c1a..0cbf4294fa75 100644 --- a/operator/pkg/apis/validation/validation.go +++ b/operator/pkg/apis/validation/validation.go @@ -28,6 +28,8 @@ import ( "github.com/google/go-containerregistry/pkg/name" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/yaml" @@ -88,27 +90,41 @@ func environmentalDetection(client kube.Client, iop *apis.IstioOperator) (Warnin func detectCniIncompatibility(client kube.Client, cniEnabled bool, ztunnelEnabled bool) util.Errors { var errs util.Errors - cilium, err := client.Kube().CoreV1().ConfigMaps("kube-system").Get(context.Background(), "cilium-config", metav1.GetOptions{}) - if err != nil { - // Ignore errors, user may not be running Cilium at all - return nil + calicoResource := schema.GroupVersionResource{Group: "projectcalico.org", Version: "v3", Resource: "felixconfigurations"} + calico, err := client.Dynamic().Resource(calicoResource).Get(context.Background(), "default", metav1.GetOptions{}) + if err == nil { + bpfConnectTimeLoadBalancing, found, _ := unstructured.NestedString(calico.Object, "spec", "bpfConnectTimeLoadBalancing") + if found && bpfConnectTimeLoadBalancing != "Disabled" { + // Need to disable Calico connect-time load balancing since it send traffic directly to the backend pod IP + // nolint: lll + errs = util.AppendErr(errs, fmt.Errorf("detected Calico CNI with 'bpfConnectTimeLoadBalancing=%s'; this must be set to 'bpfConnectTimeLoadBalancing=Disabled' in the Calico configuration", bpfConnectTimeLoadBalancing)) + } + bpfConnectTimeLoadBalancingEnabled, found, _ := unstructured.NestedBool(calico.Object, "spec", "bpfConnectTimeLoadBalancingEnabled") + if found && bpfConnectTimeLoadBalancingEnabled { + // Same behavior as BpfconnectTimeLoadBalancing + // nolint: lll + errs = util.AppendErr(errs, fmt.Errorf("detected Calico CNI with 'bpfConnectTimeLoadBalancingEnabled=true'; this must be set to 'bpfConnectTimeLoadBalancingEnabled=false' in the Calico configuration")) + } } - if cniEnabled && cilium.Data["cni-exclusive"] == "true" { - // Without this, Cilium will constantly overwrite our CNI config. - errs = util.AppendErr(errs, - fmt.Errorf("detected Cilium CNI with 'cni-exclusive=true'; this must be set to 'cni-exclusive=false' in the Cilium configuration")) - } - if ztunnelEnabled && cilium.Data["enable-bpf-masquerade"] == "true" { - // See https://github.com/istio/istio/issues/52208 - errs = util.AppendErr(errs, - fmt.Errorf("detected Cilium CNI with 'enable-bpf-masquerade=true'; this must be set to 'false' when using ambient mode")) - } - bpfLbSocket := cilium.Data["bpf-lb-sock"] == "true" // Unset implies 'false', so this check is ok - bpfLbHostnsOnly := cilium.Data["bpf-lb-sock-hostns-only"] == "true" // Unset implies 'false', so this check is ok - if bpfLbSocket && !bpfLbHostnsOnly { - // See https://github.com/istio/istio/issues/27619 - errs = util.AppendErr(errs, - errors.New("detected Cilium CNI with 'bpf-lb-sock=true'; this requires 'bpf-lb-sock-hostns-only=true' to be set")) + cilium, err := client.Kube().CoreV1().ConfigMaps("kube-system").Get(context.Background(), "cilium-config", metav1.GetOptions{}) + if err == nil { + if cniEnabled && cilium.Data["cni-exclusive"] == "true" { + // Without this, Cilium will constantly overwrite our CNI config. + errs = util.AppendErr(errs, + fmt.Errorf("detected Cilium CNI with 'cni-exclusive=true'; this must be set to 'cni-exclusive=false' in the Cilium configuration")) + } + if ztunnelEnabled && cilium.Data["enable-bpf-masquerade"] == "true" { + // See https://github.com/istio/istio/issues/52208 + errs = util.AppendErr(errs, + fmt.Errorf("detected Cilium CNI with 'enable-bpf-masquerade=true'; this must be set to 'false' when using ambient mode")) + } + bpfLbSocket := cilium.Data["bpf-lb-sock"] == "true" // Unset implies 'false', so this check is ok + bpfLbHostnsOnly := cilium.Data["bpf-lb-sock-hostns-only"] == "true" // Unset implies 'false', so this check is ok + if bpfLbSocket && !bpfLbHostnsOnly { + // See https://github.com/istio/istio/issues/27619 + errs = util.AppendErr(errs, + errors.New("detected Cilium CNI with 'bpf-lb-sock=true'; this requires 'bpf-lb-sock-hostns-only=true' to be set")) + } } return errs } diff --git a/operator/pkg/apis/validation/validation_test.go b/operator/pkg/apis/validation/validation_test.go index 331380d775aa..b4fbffa60676 100644 --- a/operator/pkg/apis/validation/validation_test.go +++ b/operator/pkg/apis/validation/validation_test.go @@ -15,14 +15,21 @@ package validation_test import ( + "context" "errors" "fmt" "testing" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "istio.io/istio/operator/pkg/apis" "istio.io/istio/operator/pkg/apis/validation" "istio.io/istio/operator/pkg/util" "istio.io/istio/operator/pkg/values" + "istio.io/istio/pkg/kube" "istio.io/istio/pkg/test/util/assert" ) @@ -358,6 +365,88 @@ cni: } } +// nolint: lll +func TestDetectCniIncompatibility(t *testing.T) { + tests := []struct { + desc string + ioYamlStr string + calicoConfig *unstructured.Unstructured + ciliumConfig *v1.ConfigMap + wantWarnings util.Errors + }{ + { + desc: "Calico bpfConnectTimeLoadBalancing TCP", + calicoConfig: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "projectcalico.org/v3", + "kind": "FelixConfiguration", + "metadata": map[string]interface{}{ + "name": "default", + }, + "spec": map[string]interface{}{ + "bpfConnectTimeLoadBalancing": "TCP", + }, + }, + }, + + wantWarnings: makeErrors([]string{`detected Calico CNI with 'bpfConnectTimeLoadBalancing=TCP'; this must be set to 'bpfConnectTimeLoadBalancing=Disabled' in the Calico configuration`}), + }, + { + desc: "Calico bpfConnectTimeLoadBalancingEnabled true", + calicoConfig: &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "projectcalico.org/v3", + "kind": "FelixConfiguration", + "metadata": map[string]interface{}{ + "name": "default", + }, + "spec": map[string]interface{}{ + "bpfConnectTimeLoadBalancingEnabled": true, + }, + }, + }, + + wantWarnings: makeErrors([]string{`detected Calico CNI with 'bpfConnectTimeLoadBalancingEnabled=true'; this must be set to 'bpfConnectTimeLoadBalancingEnabled=false' in the Calico configuration`}), + }, + { + desc: "Cilium enable-bpf-masquerade true", + ioYamlStr: ` +spec: + components: + ztunnel: + enabled: true +`, + ciliumConfig: &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{Namespace: "kube-system", Name: "cilium-config"}, + Data: map[string]string{ + "enable-bpf-masquerade": "true", + }, + }, + wantWarnings: makeErrors([]string{`detected Cilium CNI with 'enable-bpf-masquerade=true'; this must be set to 'false' when using ambient mode`}), + }, + } + + calicoResource := schema.GroupVersionResource{Group: "projectcalico.org", Version: "v3", Resource: "felixconfigurations"} + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + m, err := values.MapFromYaml([]byte(tt.ioYamlStr)) + assert.NoError(t, err) + + client := kube.NewFakeClient() + if tt.calicoConfig != nil { + client.Dynamic().Resource(calicoResource).Create(context.Background(), tt.calicoConfig, metav1.CreateOptions{}) + } + if tt.ciliumConfig != nil { + client.Kube().CoreV1().ConfigMaps("kube-system").Create(context.Background(), tt.ciliumConfig, metav1.CreateOptions{}) + } + warnings, _ := validation.ParseAndValidateIstioOperator(m, client) + if gotWarnings, wantWarnings := warnings, tt.wantWarnings; !util.EqualErrors(gotWarnings, wantWarnings) { + t.Errorf("CheckValues(%s): gotWarnings:%s, wantWarnings:%s", tt.desc, gotWarnings, wantWarnings) + } + }) + } +} + func makeErrors(estr []string) util.Errors { var errs util.Errors for _, s := range estr { diff --git a/operator/pkg/apis/values_types.pb.go b/operator/pkg/apis/values_types.pb.go index 29076ecac481..165c4fccc367 100644 --- a/operator/pkg/apis/values_types.pb.go +++ b/operator/pkg/apis/values_types.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc (unknown) // source: pkg/apis/values_types.proto diff --git a/operator/pkg/helm/helm.go b/operator/pkg/helm/helm.go index da4b37c705f1..222855743f3e 100644 --- a/operator/pkg/helm/helm.go +++ b/operator/pkg/helm/helm.go @@ -46,7 +46,7 @@ func Render(namespace string, directory string, iop values.Map, kubernetesVersio vals, _ := iop.GetPathMap("spec.values") installPackagePath := iop.GetPathString("spec.installPackagePath") f := manifests.BuiltinOrDir(installPackagePath) - path := filepath.Join("charts", directory) + path := pathJoin("charts", directory) chrt, err := loadChart(f, path) if err != nil { return nil, nil, fmt.Errorf("load chart: %v", err) diff --git a/operator/pkg/helm/path.go b/operator/pkg/helm/path.go new file mode 100644 index 000000000000..90253d8a25a7 --- /dev/null +++ b/operator/pkg/helm/path.go @@ -0,0 +1,25 @@ +//go:build !windows + +// Copyright Istio Authors +// +// Licensed 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 helm + +import ( + "path/filepath" +) + +func pathJoin(elem ...string) string { + return filepath.Join(elem...) +} diff --git a/operator/pkg/helm/path_windows.go b/operator/pkg/helm/path_windows.go new file mode 100644 index 000000000000..72ea7bd66905 --- /dev/null +++ b/operator/pkg/helm/path_windows.go @@ -0,0 +1,25 @@ +//go:build windows + +// Copyright Istio Authors +// +// Licensed 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 helm + +import "strings" + +func pathJoin(elem ...string) string { + elems := make([]string, 0, len(elem)) + elems = append(elems, elem...) + return strings.Join(elems, "/") +} diff --git a/tools/istio-iptables/pkg/capture/util.go b/operator/pkg/helm/path_windows_test.go similarity index 59% rename from tools/istio-iptables/pkg/capture/util.go rename to operator/pkg/helm/path_windows_test.go index 513d5d5353e5..5aecbbb4b93c 100644 --- a/tools/istio-iptables/pkg/capture/util.go +++ b/operator/pkg/helm/path_windows_test.go @@ -1,3 +1,5 @@ +//go:build windows + // Copyright Istio Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,20 +14,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -package capture +package helm + +import ( + "testing" -func CombineMatchers(values []string, matcher func(value string) []string) []string { - matchers := make([][]string, 0, len(values)) - for _, value := range values { - matchers = append(matchers, matcher(value)) + "github.com/stretchr/testify/require" +) + +func TestPathJoin(t *testing.T) { + cases := []struct { + input []string + expected string + }{ + { + input: []string{"a", "b", "c"}, + expected: "a/b/c", + }, } - return Flatten(matchers...) -} -func Flatten(lists ...[]string) []string { - var result []string - for _, list := range lists { - result = append(result, list...) + for _, c := range cases { + actual := pathJoin(c.input...) + require.Equal(t, c.expected, actual) } - return result } diff --git a/operator/pkg/install/install.go b/operator/pkg/install/install.go index 8328cab0e1a7..86e1e57ff35e 100644 --- a/operator/pkg/install/install.go +++ b/operator/pkg/install/install.go @@ -114,7 +114,6 @@ func (i Installer) install(manifests []manifest.ManifestSet) error { })...) dependencyWaitCh := dependenciesChannels() for _, mf := range manifests { - mf := mf c := mf.Component ms := mf.Manifests disabledComponents.Delete(c) diff --git a/operator/pkg/render/manifest.go b/operator/pkg/render/manifest.go index c3513f9cafb3..8153590302b8 100644 --- a/operator/pkg/render/manifest.go +++ b/operator/pkg/render/manifest.go @@ -65,7 +65,7 @@ func GenerateManifest(files []string, setFlags []string, force bool, client kube } // Render each component - var allManifests []manifest.ManifestSet + allManifests := map[component.Name]manifest.ManifestSet{} var chartWarnings util.Errors for _, comp := range component.AllComponents { specs, err := comp.Get(merged) @@ -86,10 +86,16 @@ func GenerateManifest(files []string, setFlags []string, force bool, client kube if err != nil { return nil, nil, fmt.Errorf("post processing: %v", err) } - allManifests = append(allManifests, manifest.ManifestSet{ - Component: comp.UserFacingName, - Manifests: finalized, - }) + manifests, found := allManifests[comp.UserFacingName] + if found { + manifests.Manifests = append(manifests.Manifests, finalized...) + allManifests[comp.UserFacingName] = manifests + } else { + allManifests[comp.UserFacingName] = manifest.ManifestSet{ + Component: comp.UserFacingName, + Manifests: finalized, + } + } } } @@ -99,7 +105,14 @@ func GenerateManifest(files []string, setFlags []string, force bool, client kube logger.LogAndErrorf("%s %v", "❗", w) } } - return allManifests, merged, nil + + values := make([]manifest.ManifestSet, 0, len(allManifests)) + + for _, v := range allManifests { + values = append(values, v) + } + + return values, merged, nil } type MigrationResult struct { diff --git a/operator/pkg/render/postprocess.go b/operator/pkg/render/postprocess.go index 691cb636d80d..1f6555e08e3e 100644 --- a/operator/pkg/render/postprocess.go +++ b/operator/pkg/render/postprocess.go @@ -31,6 +31,11 @@ import ( "istio.io/istio/operator/pkg/values" ) +type patchContext struct { + Patch string + PostProcess func([]byte) ([]byte, error) +} + // postProcess applies any manifest manipulation to be done after Helm chart rendering. func postProcess(comp component.Component, spec apis.GatewayComponentSpec, manifests []manifest.Manifest, vals values.Map) ([]manifest.Manifest, error) { if spec.Kubernetes == nil { @@ -38,8 +43,9 @@ func postProcess(comp component.Component, spec apis.GatewayComponentSpec, manif return manifests, nil } type Patch struct { - Kind, Name string - Patch string + Kind, Name string + Patch string + PostProcess func([]byte) ([]byte, error) } rn := comp.ResourceName if spec.Name != "" { @@ -67,10 +73,15 @@ func postProcess(comp component.Component, spec apis.GatewayComponentSpec, manif Name: rn, Patch: fmt.Sprintf(`{"spec":{"template":{"spec":{"containers":[{"name":%q, "imagePullPolicy": %%s}]}}}}`, comp.ContainerName), }, - "nodeSelector": {Kind: rt, Name: rn, Patch: `{"spec":{"template":{"spec":{"nodeSelector":%s}}}}`}, - "podDisruptionBudget": {Kind: "PodDisruptionBudget", Name: rn, Patch: `{"spec":%s}`}, - "podAnnotations": {Kind: rt, Name: rn, Patch: `{"spec":{"template":{"metadata":{"annotations":%s}}}}`}, - "priorityClassName": {Kind: rt, Name: rn, Patch: `{"spec":{"template":{"spec":{"priorityClassName":%s}}}}`}, + "nodeSelector": {Kind: rt, Name: rn, Patch: `{"spec":{"template":{"spec":{"nodeSelector":%s}}}}`}, + "podDisruptionBudget": { + Kind: "PodDisruptionBudget", + Name: rn, + Patch: `{"spec":%s}`, + PostProcess: postProcessPodDisruptionBudget, + }, + "podAnnotations": {Kind: rt, Name: rn, Patch: `{"spec":{"template":{"metadata":{"annotations":%s}}}}`}, + "priorityClassName": {Kind: rt, Name: rn, Patch: `{"spec":{"template":{"spec":{"priorityClassName":%s}}}}`}, "readinessProbe": { Kind: rt, Name: rn, @@ -89,7 +100,7 @@ func postProcess(comp component.Component, spec apis.GatewayComponentSpec, manif "securityContext": {Kind: rt, Name: rn, Patch: `{"spec":{"template":{"spec":{"securityContext":%s}}}}`}, } // needPatching builds a map of manifest index -> patch. This ensures we only do the full round-tripping once per object. - needPatching := map[int][]string{} + needPatching := map[int][]patchContext{} for field, k := range patches { if field == "service" && comp.IsGateway() { // Hack: https://github.com/kubernetes/kubernetes/issues/103544 means strategy merge is ~broken for service ports. @@ -111,7 +122,7 @@ func postProcess(comp component.Component, spec apis.GatewayComponentSpec, manif // Find which manifests need the patch for idx, m := range manifests { if k.Kind == m.GetKind() && k.Name == m.GetName() { - needPatching[idx] = append(needPatching[idx], patch) + needPatching[idx] = append(needPatching[idx], patchContext{Patch: patch, PostProcess: k.PostProcess}) } } } @@ -131,10 +142,16 @@ func postProcess(comp component.Component, spec apis.GatewayComponentSpec, manif // Apply all the patches for _, patch := range patches { - newBytes, err := strategicpatch.StrategicMergePatch(baseJSON, []byte(patch), typed) + newBytes, err := strategicpatch.StrategicMergePatch(baseJSON, []byte(patch.Patch), typed) if err != nil { return nil, fmt.Errorf("patch: %v", err) } + if patch.PostProcess != nil { + newBytes, err = patch.PostProcess(newBytes) + if err != nil { + return nil, fmt.Errorf("patch post process: %v", err) + } + } baseJSON = newBytes } // Rebuild our manifest @@ -168,6 +185,24 @@ func postProcess(comp component.Component, spec apis.GatewayComponentSpec, manif return manifests, nil } +// PDB does not allow both minAvailable and maxUnavailable to be set on the same object, but the strategic merge patch +// configuration does not account for this. Since Istio defaults `minAvailable`, this would otherwise prevent users from +// setting maxUnavailable. +func postProcessPodDisruptionBudget(bytes []byte) ([]byte, error) { + v, err := values.MapFromJSON(bytes) + if err != nil { + return nil, err + } + _, hasMax := v.GetPath("spec.maxUnavailable") + _, hasMin := v.GetPath("spec.minAvailable") + if hasMax && hasMin { + if err := v.SetPath("spec.minAvailable", nil); err != nil { + return nil, err + } + } + return []byte(v.JSON()), nil +} + // applyPatches applies the given patches against the given object. It returns the resulting patched YAML if successful, // or a list of errors otherwise. func applyPatches(base manifest.Manifest, patches []apis.Patch) (manifest.Manifest, error) { diff --git a/operator/version/version.go b/operator/version/version.go index f28cd483d416..2f70a2ef536b 100644 --- a/operator/version/version.go +++ b/operator/version/version.go @@ -23,9 +23,9 @@ import ( const ( // OperatorCodeBaseVersion is the version string from the code base. - OperatorCodeBaseVersion = "1.24.0" + OperatorCodeBaseVersion = "1.25.0" OperatorEOLYear = 2025 - OperatorEOLMonth = time.July + OperatorEOLMonth = time.October ) var ( diff --git a/pilot/cmd/pilot-agent/app/cmd.go b/pilot/cmd/pilot-agent/app/cmd.go index aa1eebb3e586..90a19e6c80f5 100644 --- a/pilot/cmd/pilot-agent/app/cmd.go +++ b/pilot/cmd/pilot-agent/app/cmd.go @@ -42,7 +42,6 @@ import ( "istio.io/istio/pkg/util/protomarshal" "istio.io/istio/pkg/util/sets" "istio.io/istio/pkg/version" - cleaniptables "istio.io/istio/tools/istio-clean-iptables/pkg/cmd" iptables "istio.io/istio/tools/istio-iptables/pkg/cmd" iptableslog "istio.io/istio/tools/istio-iptables/pkg/log" ) @@ -81,7 +80,6 @@ func NewRootCommand(sds istioagent.SDSServiceFactory) *cobra.Command { rootCmd.AddCommand(waitCmd) rootCmd.AddCommand(version.CobraCommand()) rootCmd.AddCommand(iptables.GetCommand(loggingOptions)) - rootCmd.AddCommand(cleaniptables.GetCommand(loggingOptions)) rootCmd.AddCommand(collateral.CobraCommand(rootCmd, collateral.Metadata{ Title: "Istio Pilot Agent", diff --git a/pilot/cmd/pilot-agent/status/server.go b/pilot/cmd/pilot-agent/status/server.go index 721a0204c49c..9d3464af085e 100644 --- a/pilot/cmd/pilot-agent/status/server.go +++ b/pilot/cmd/pilot-agent/status/server.go @@ -87,7 +87,7 @@ var ( var PrometheusScrapingConfig = env.Register("ISTIO_PROMETHEUS_ANNOTATIONS", "", "") var ( - appProberPattern = regexp.MustCompile(`^/app-health/[^/]+/(livez|readyz|startupz)$`) + appProberPattern = regexp.MustCompile(`^/(app-health|app-lifecycle)/[^/]+/(livez|readyz|startupz|prestopz|poststartz)$`) EnableHTTP2Probing = env.Register("ISTIO_ENABLE_HTTP2_PROBING", true, "If enabled, HTTP2 probes will be enabled for HTTPS probes, following Kubernetes").Get() @@ -350,13 +350,15 @@ func validateAppKubeProber(path string, prober *Prober) error { // FormatProberURL returns a set of HTTP URLs that pilot agent will serve to take over Kubernetes // app probers. -func FormatProberURL(container string) (string, string, string) { +func FormatProberURL(container string) (string, string, string, string, string) { return fmt.Sprintf("/app-health/%v/readyz", container), fmt.Sprintf("/app-health/%v/livez", container), - fmt.Sprintf("/app-health/%v/startupz", container) + fmt.Sprintf("/app-health/%v/startupz", container), + fmt.Sprintf("/app-lifecycle/%v/prestopz", container), + fmt.Sprintf("/app-lifecycle/%v/poststartz", container) } -// Run opens a the status port and begins accepting probes. +// Run opens the status port and begins accepting probes. func (s *Server) Run(ctx context.Context) { log.Infof("Opening status port %d", s.statusPort) @@ -372,6 +374,7 @@ func (s *Server) Run(ctx context.Context) { mux.HandleFunc(quitPath, s.handleQuit) mux.HandleFunc(drainPath, s.handleDrain) mux.HandleFunc("/app-health/", s.handleAppProbe) + mux.HandleFunc("/app-lifecycle/", s.handleAppProbe) if s.enableProfiling { // Add the handler for pprof. diff --git a/pilot/cmd/pilot-agent/status/server_test.go b/pilot/cmd/pilot-agent/status/server_test.go index 7d188920ada9..b3bc177daa7d 100644 --- a/pilot/cmd/pilot-agent/status/server_test.go +++ b/pilot/cmd/pilot-agent/status/server_test.go @@ -780,6 +780,19 @@ func TestAppProbe(t *testing.T) { }, statusCode: http.StatusOK, }, + { + name: "http-prestopz-path", + probePath: "app-lifecycle/hello-world/prestopz", + config: KubeAppProbers{ + "/app-lifecycle/hello-world/prestopz": &Prober{ + HTTPGet: &apimirror.HTTPGetAction{ + Path: "hello/texas", + Port: apimirror.IntOrString{IntVal: int32(appPort)}, + }, + }, + }, + statusCode: http.StatusOK, + }, { name: "http-livez-path", probePath: "app-health/hello-world/livez", diff --git a/pilot/pkg/autoregistration/controller.go b/pilot/pkg/autoregistration/controller.go index 35747afbd817..4789748894c9 100644 --- a/pilot/pkg/autoregistration/controller.go +++ b/pilot/pkg/autoregistration/controller.go @@ -530,7 +530,6 @@ func (c *Controller) periodicWorkloadEntryCleanup(stopCh <-chan struct{}) { case <-ticker.C: wles := c.store.List(gvk.WorkloadEntry, metav1.NamespaceAll) for _, wle := range wles { - wle := wle if c.shouldCleanupEntry(wle) { c.cleanupQueue.Push(func() error { c.cleanupEntry(wle, true) diff --git a/pilot/pkg/autoregistration/controller_test.go b/pilot/pkg/autoregistration/controller_test.go index 133f3c676a80..abc600ec6433 100644 --- a/pilot/pkg/autoregistration/controller_test.go +++ b/pilot/pkg/autoregistration/controller_test.go @@ -162,7 +162,7 @@ var ( } ) -func TestNonAutoregisteredWorkloads(t *testing.T) { +func TestNonAutoRegisteredWorkloads(t *testing.T) { store := memory.NewController(memory.Make(collections.All)) c := NewController(store, "", time.Duration(math.MaxInt64)) createOrFail(t, store, wgA) @@ -177,7 +177,6 @@ func TestNonAutoregisteredWorkloads(t *testing.T) { } for name, tc := range cases { - tc := tc t.Run(name, func(t *testing.T) { c.OnConnect(makeConn(tc, time.Now())) items := store.List(gvk.WorkloadEntry, model.NamespaceAll) diff --git a/pilot/pkg/bootstrap/monitoring.go b/pilot/pkg/bootstrap/monitoring.go index f12f216e3bbe..a29223e053a9 100644 --- a/pilot/pkg/bootstrap/monitoring.go +++ b/pilot/pkg/bootstrap/monitoring.go @@ -53,15 +53,7 @@ var ( ) ) -func init() { - pilotVersion.With(versionTag.Value(version.Info.String())).Record(1) -} - -func addMonitor(mux *http.ServeMux) error { - exporter, err := monitoring.RegisterPrometheusExporter(nil, nil) - if err != nil { - return fmt.Errorf("could not set up prometheus exporter: %v", err) - } +func addMonitor(exporter http.Handler, mux *http.ServeMux) { mux.Handle(metricsPath, metricsMiddleware(exporter)) mux.HandleFunc(versionPath, func(out http.ResponseWriter, req *http.Request) { @@ -69,8 +61,6 @@ func addMonitor(mux *http.ServeMux) error { log.Errorf("Unable to write version string: %v", err) } }) - - return nil } func metricsMiddleware(handler http.Handler) http.Handler { @@ -86,7 +76,7 @@ func metricsMiddleware(handler http.Handler) http.Handler { // Deprecated: we shouldn't have 2 http ports. Will be removed after code using // this port is removed. -func startMonitor(addr string, mux *http.ServeMux) (*monitor, error) { +func startMonitor(exporter http.Handler, addr string, mux *http.ServeMux) (*monitor, error) { m := &monitor{} // get the network stuff setup @@ -102,9 +92,7 @@ func startMonitor(addr string, mux *http.ServeMux) (*monitor, error) { // for pilot. a full design / implementation of self-monitoring and reporting // is coming. that design will include proper coverage of statusz/healthz type // functionality, in addition to how pilot reports its own metrics. - if err := addMonitor(mux); err != nil { - return nil, fmt.Errorf("could not establish self-monitoring: %v", err) - } + addMonitor(exporter, mux) if addr != "" { m.monitoringServer = &http.Server{ Addr: listener.Addr().String(), @@ -115,6 +103,7 @@ func startMonitor(addr string, mux *http.ServeMux) (*monitor, error) { } version.Info.RecordComponentBuildTag("pilot") + pilotVersion.With(versionTag.Value(version.Info.String())).Record(1) if addr != "" { go func() { @@ -135,7 +124,7 @@ func (m *monitor) Close() error { // initMonitor initializes the configuration for the pilot monitoring server. func (s *Server) initMonitor(addr string) error { // nolint: unparam s.addStartFunc("monitoring", func(stop <-chan struct{}) error { - monitor, err := startMonitor(addr, s.monitoringMux) + monitor, err := startMonitor(s.metricsExporter, addr, s.monitoringMux) if err != nil { return err } diff --git a/pilot/pkg/bootstrap/server.go b/pilot/pkg/bootstrap/server.go index 5cba38cc198c..12676e48cddf 100644 --- a/pilot/pkg/bootstrap/server.go +++ b/pilot/pkg/bootstrap/server.go @@ -73,6 +73,7 @@ import ( "istio.io/istio/pkg/kube/multicluster" "istio.io/istio/pkg/kube/namespace" "istio.io/istio/pkg/log" + "istio.io/istio/pkg/monitoring" "istio.io/istio/pkg/network" "istio.io/istio/pkg/security" "istio.io/istio/pkg/spiffe" @@ -128,6 +129,8 @@ type Server struct { // internalDebugMux is a mux for *internal* calls to the debug interface. That is, authentication is disabled. internalDebugMux *http.ServeMux + metricsExporter http.Handler + // httpMux listens on the httpAddr (8080). // If a Gateway is used in front and https is off it is also multiplexing // the rest of the features if their port is empty. @@ -228,6 +231,10 @@ func NewServer(args *PilotArgs, initFuncs ...func(*Server)) (*Server, error) { }) e.ServiceDiscovery = ac + exporter, err := monitoring.RegisterPrometheusExporter(nil, nil) + if err != nil { + return nil, fmt.Errorf("could not set up prometheus exporter: %v", err) + } s := &Server{ clusterID: getClusterID(args), environment: e, @@ -241,6 +248,7 @@ func NewServer(args *PilotArgs, initFuncs ...func(*Server)) (*Server, error) { internalStop: make(chan struct{}), istiodCertBundleWatcher: keycertbundle.NewWatcher(), webhookInfo: &webhookInfo{}, + metricsExporter: exporter, } // Apply custom initialization functions. diff --git a/pilot/pkg/bootstrap/servicecontroller.go b/pilot/pkg/bootstrap/servicecontroller.go index 0b5eda25d291..9f8ecc8a1cdc 100644 --- a/pilot/pkg/bootstrap/servicecontroller.go +++ b/pilot/pkg/bootstrap/servicecontroller.go @@ -80,11 +80,8 @@ func (s *Server) initKubeRegistry(args *PilotArgs) (err error) { args.RegistryOptions.KubeOptions.MeshServiceController = s.ServiceController() // pass namespace to k8s service registry kubecontroller.NewMulticluster(args.PodName, - s.kubeClient.Kube(), - args.RegistryOptions.ClusterRegistriesNamespace, args.RegistryOptions.KubeOptions, s.serviceEntryController, - s.configController, s.istiodCertBundleWatcher, args.Revision, s.shouldStartNsController(), diff --git a/pilot/pkg/config/kube/crdclient/client.go b/pilot/pkg/config/kube/crdclient/client.go index c61d1526765e..fce4bc177e26 100644 --- a/pilot/pkg/config/kube/crdclient/client.go +++ b/pilot/pkg/config/kube/crdclient/client.go @@ -361,7 +361,7 @@ func (cl *Client) addCRD(name string) { var namespaceFilter kubetypes.DynamicObjectFilter if !s.IsClusterScoped() { - namespaceFilter = kube.FilterIfEnhancedFilteringEnabled(cl.client) + namespaceFilter = cl.client.ObjectFilter() } filter := kubetypes.Filter{ ObjectFilter: composeFilters(namespaceFilter, cl.inRevision, extraFilter), diff --git a/pilot/pkg/config/kube/gateway/conditions.go b/pilot/pkg/config/kube/gateway/conditions.go index 906ab33b0d6a..30f850937c9a 100644 --- a/pilot/pkg/config/kube/gateway/conditions.go +++ b/pilot/pkg/config/kube/gateway/conditions.go @@ -337,7 +337,7 @@ func generateSupportedKinds(l k8s.Listener) ([]k8s.RouteGroupKind, bool) { } else { supported = []k8s.RouteGroupKind{{Group: (*k8s.Group)(ptr.Of(gvk.TCPRoute.Group)), Kind: k8s.Kind(gvk.TCPRoute.Kind)}} } - // UDP route note support + // UDP route not support } if l.AllowedRoutes != nil && len(l.AllowedRoutes.Kinds) > 0 { // We need to filter down to only ones we actually support diff --git a/pilot/pkg/config/kube/gateway/conversion.go b/pilot/pkg/config/kube/gateway/conversion.go index a9dc37268230..34faba6be654 100644 --- a/pilot/pkg/config/kube/gateway/conversion.go +++ b/pilot/pkg/config/kube/gateway/conversion.go @@ -1616,7 +1616,7 @@ func createMirrorFilter(ctx configContext, filter *k8s.HTTPRequestMirrorFilter, } var percent *istio.Percent if f := filter.Fraction; f != nil { - percent = &istio.Percent{Value: float64(f.Numerator) / float64(ptr.OrDefault(f.Denominator, int32(100)))} + percent = &istio.Percent{Value: (100 * float64(f.Numerator)) / float64(ptr.OrDefault(f.Denominator, int32(100)))} } else if p := filter.Percent; p != nil { percent = &istio.Percent{Value: float64(*p)} } @@ -2048,7 +2048,6 @@ func convertGateways(r configContext) ([]config.Config, map[parentKey][]*parentI namespaceLabelReferences := sets.New[string]() classes := getGatewayClasses(r.GatewayResources) for _, obj := range r.Gateway { - obj := obj kgw := obj.Spec.(*k8s.GatewaySpec) controllerName, f := classes[string(kgw.GatewayClassName)] if !f { @@ -2075,7 +2074,6 @@ func convertGateways(r configContext) ([]config.Config, map[parentKey][]*parentI continue } for i, l := range kgw.Listeners { - i := i namespaceLabelReferences.InsertAll(getNamespaceLabelReferences(l.AllowedRoutes)...) server, programmed := buildListener(r, obj, l, i, controllerName) @@ -2461,15 +2459,13 @@ func buildListener(r configContext, obj config.Config, l k8s.Listener, listenerI ok = false } hostnames := buildHostnameMatch(obj.Namespace, r.GatewayResources, l) - server := &istio.Server{ - Port: &istio.Port{ - // Name is required. We only have one server per Gateway, so we can just name them all the same - Name: "default", - Number: uint32(l.Port), - Protocol: listenerProtocolToIstio(l.Protocol), - }, - Hosts: hostnames, - Tls: tls, + protocol, perr := listenerProtocolToIstio(controllerName, l.Protocol) + if perr != nil { + listenerConditions[string(k8s.ListenerConditionAccepted)].error = &ConfigError{ + Reason: string(k8s.ListenerReasonUnsupportedProtocol), + Message: perr.Error(), + } + ok = false } if controllerName == constants.ManagedGatewayMeshController { if unexpectedWaypointListener(l) { @@ -2479,14 +2475,53 @@ func buildListener(r configContext, obj config.Config, l k8s.Listener, listenerI } } } + server := &istio.Server{ + Port: &istio.Port{ + // Name is required. We only have one server per Gateway, so we can just name them all the same + Name: "default", + Number: uint32(l.Port), + Protocol: protocol, + }, + Hosts: hostnames, + Tls: tls, + } reportListenerCondition(listenerIndex, l, obj, listenerConditions) return server, ok } -func listenerProtocolToIstio(protocol k8s.ProtocolType) string { - // Currently, all gateway-api protocols are valid Istio protocols. - return string(protocol) +var supportedProtocols = sets.New( + k8s.HTTPProtocolType, + k8s.HTTPSProtocolType, + k8s.TLSProtocolType, + k8s.TCPProtocolType, + k8s.ProtocolType(protocol.HBONE)) + +func listenerProtocolToIstio(name k8s.GatewayController, p k8s.ProtocolType) (string, error) { + switch p { + // Standard protocol types + case k8s.HTTPProtocolType: + return string(p), nil + case k8s.HTTPSProtocolType: + return string(p), nil + case k8s.TLSProtocolType, k8s.TCPProtocolType: + if !features.EnableAlphaGatewayAPI { + return "", fmt.Errorf("protocol %q is supported, but only when %v=true is configured", p, features.EnableAlphaGatewayAPIName) + } + return string(p), nil + // Our own custom types + case k8s.ProtocolType(protocol.HBONE): + if name != constants.ManagedGatewayMeshController { + return "", fmt.Errorf("protocol %q is only supported for waypoint proxies", p) + } + return string(p), nil + } + up := k8s.ProtocolType(strings.ToUpper(string(p))) + if supportedProtocols.Contains(up) { + return "", fmt.Errorf("protocol %q is unsupported. hint: %q (uppercase) may be supported", p, up) + } + // Note: the k8s.UDPProtocolType is explicitly left to hit this path + return "", fmt.Errorf("protocol %q is unsupported", p) } func buildTLS(ctx configContext, tls *k8s.GatewayTLSConfig, gw config.Config, isAutoPassthrough bool) (*istio.ServerTLSSettings, *ConfigError) { diff --git a/pilot/pkg/config/kube/gateway/deploymentcontroller.go b/pilot/pkg/config/kube/gateway/deploymentcontroller.go index 2c82f361a0f8..535c42a13d47 100644 --- a/pilot/pkg/config/kube/gateway/deploymentcontroller.go +++ b/pilot/pkg/config/kube/gateway/deploymentcontroller.go @@ -182,7 +182,7 @@ func getClassInfos() map[gateway.GatewayController]classInfo { func NewDeploymentController(client kube.Client, clusterID cluster.ID, env *model.Environment, webhookConfig func() inject.WebhookConfig, injectionHandler func(fn func()), tw revisions.TagWatcher, revision string, ) *DeploymentController { - filter := kclient.Filter{ObjectFilter: kube.FilterIfEnhancedFilteringEnabled(client)} + filter := kclient.Filter{ObjectFilter: client.ObjectFilter()} gateways := kclient.NewFiltered[*gateway.Gateway](client, filter) gatewayClasses := kclient.New[*gateway.GatewayClass](client) dc := &DeploymentController{ @@ -573,10 +573,7 @@ func (d *DeploymentController) apply(controller string, yml string) error { if err != nil { return err } - j, err := json.Marshal(us.Object) - if err != nil { - return err - } + canManage, resourceVersion := d.canManage(gvr, us.GetName(), us.GetNamespace()) if !canManage { log.Debugf("skipping %v/%v/%v, already managed", gvr, us.GetName(), us.GetNamespace()) @@ -585,6 +582,21 @@ func (d *DeploymentController) apply(controller string, yml string) error { // Ensure our canManage assertion is not stale us.SetResourceVersion(resourceVersion) + // Because in 1.24 we removed old label "istio.io/gateway-name", in order to not mutate the deployment.spec.Selector during upgrade. + // we always use the old `selector` value + if gvr.Resource == "deployments" { + deployment := d.deployments.Get(us.GetName(), us.GetNamespace()) + if deployment != nil && deployment.Spec.Selector.MatchLabels["istio.io/gateway-name"] != "" { + us.Object["spec"].(map[string]any)["selector"] = deployment.Spec.Selector + // nolint lll + us.Object["spec"].(map[string]any)["template"].(map[string]any)["metadata"].(map[string]any)["labels"].(map[string]any)["istio.io/gateway-name"] = deployment.Spec.Template.ObjectMeta.Labels["istio.io/gateway-name"] + } + } + + j, err := json.Marshal(us.Object) + if err != nil { + return err + } log.Debugf("applying %v", string(j)) if err := d.patcher(gvr, us.GetName(), us.GetNamespace(), j); err != nil { return fmt.Errorf("patch %v/%v/%v: %v", us.GroupVersionKind(), us.GetNamespace(), us.GetName(), err) diff --git a/pilot/pkg/config/kube/gateway/deploymentcontroller_test.go b/pilot/pkg/config/kube/gateway/deploymentcontroller_test.go index ad71752d7013..3054785e6f15 100644 --- a/pilot/pkg/config/kube/gateway/deploymentcontroller_test.go +++ b/pilot/pkg/config/kube/gateway/deploymentcontroller_test.go @@ -23,6 +23,7 @@ import ( "time" "go.uber.org/atomic" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -72,6 +73,39 @@ func TestConfigureIstioGateway(t *testing.T) { ControllerName: k8s.GatewayController(features.ManagedGatewayController), }, } + upgradeDeployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-upgrade", + Namespace: "default", + Labels: map[string]string{ + "gateway.istio.io/managed": "istio.io-mesh-controller", + "istio.io/gateway-name": "test-upgrade", + }, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "gateway.networking.k8s.io/gateway-name": "test-upgrade", + "istio.io/gateway-name": "test-upgrade", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "gateway.istio.io/managed": "istio.io-mesh-controller", + "gateway.networking.k8s.io/gateway-name": "test-upgrade", + "istio.io/gateway-name": "test-upgrade", + "istio.io/dataplane-mode": "none", + "service.istio.io/canonical-name": "test-upgrade", + "service.istio.io/canonical-revision": "latest", + "sidecar.istio.io/inject": "false", + "topology.istio.io/network": "network-1", + }, + }, + }, + }, + } + defaultObjects := []runtime.Object{defaultNamespace} store := model.NewFakeStore() if _, err := store.Create(config.Config{ @@ -340,6 +374,28 @@ func TestConfigureIstioGateway(t *testing.T) { }, objects: defaultObjects, }, + { + name: "istio-upgrade-to-1.24", + gw: k8sbeta.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-upgrade", + Namespace: "default", + }, + Spec: k8s.GatewaySpec{ + GatewayClassName: constants.WaypointGatewayClassName, + Listeners: []k8s.Listener{{ + Name: "mesh", + Port: k8s.PortNumber(15008), + Protocol: "ALL", + }}, + }, + }, + objects: defaultObjects, + values: `global: + hub: test + tag: test + network: network-1`, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -349,6 +405,7 @@ func TestConfigureIstioGateway(t *testing.T) { client.Kube().Discovery().(*fakediscovery.FakeDiscovery).FakedServerVersion = &kubeVersion.Info{Major: "1", Minor: "28"} kclient.NewWriteClient[*k8sbeta.GatewayClass](client).Create(customClass) kclient.NewWriteClient[*k8sbeta.Gateway](client).Create(tt.gw.DeepCopy()) + kclient.NewWriteClient[*appsv1.Deployment](client).Create(upgradeDeployment) stop := test.NewStop(t) env := model.NewEnvironment() env.PushContext().ProxyConfigs = tt.pcs diff --git a/pilot/pkg/config/kube/gateway/testdata/deployment/istio-upgrade-to-1.24.yaml b/pilot/pkg/config/kube/gateway/testdata/deployment/istio-upgrade-to-1.24.yaml new file mode 100644 index 000000000000..c9cd8e60dba0 --- /dev/null +++ b/pilot/pkg/config/kube/gateway/testdata/deployment/istio-upgrade-to-1.24.yaml @@ -0,0 +1,256 @@ +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + annotations: + gateway.istio.io/controller-version: "5" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: {} + labels: + gateway.istio.io/managed: istio.io-mesh-controller + gateway.networking.k8s.io/gateway-name: test-upgrade + topology.istio.io/network: network-1 + name: test-upgrade + namespace: default + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: test-upgrade + uid: "" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: {} + labels: + gateway.istio.io/managed: istio.io-mesh-controller + gateway.networking.k8s.io/gateway-name: test-upgrade + topology.istio.io/network: network-1 + name: test-upgrade + namespace: default + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: test-upgrade + uid: "" +spec: + selector: + matchLabels: + gateway.networking.k8s.io/gateway-name: test-upgrade + istio.io/gateway-name: test-upgrade + template: + metadata: + annotations: + istio.io/rev: default + prometheus.io/path: /stats/prometheus + prometheus.io/port: "15020" + prometheus.io/scrape: "true" + labels: + gateway.istio.io/managed: istio.io-mesh-controller + gateway.networking.k8s.io/gateway-name: test-upgrade + istio.io/dataplane-mode: none + istio.io/gateway-name: test-upgrade + service.istio.io/canonical-name: test-upgrade + service.istio.io/canonical-revision: latest + sidecar.istio.io/inject: "false" + topology.istio.io/network: network-1 + spec: + containers: + - args: + - proxy + - waypoint + - --domain + - $(POD_NAMESPACE).svc. + - --serviceCluster + - test-upgrade.$(POD_NAMESPACE) + - --proxyLogLevel + - + - --proxyComponentLogLevel + - + - --log_output_level + - + env: + - name: ISTIO_META_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: PILOT_CERT_PROVIDER + value: + - name: CA_ADDR + value: istiod-..svc:15012 + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {} + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: ISTIO_META_CLUSTER_ID + value: Kubernetes + - name: ISTIO_META_NETWORK + value: network-1 + - name: ISTIO_META_INTERCEPTION_MODE + value: REDIRECT + - name: ISTIO_META_WORKLOAD_NAME + value: test-upgrade + - name: ISTIO_META_OWNER + value: kubernetes://apis/apps/v1/namespaces/default/deployments/test-upgrade + - name: ISTIO_META_MESH_ID + value: cluster.local + - name: TRUST_DOMAIN + value: cluster.local + image: test/proxyv2:test + name: istio-proxy + ports: + - containerPort: 15020 + name: metrics + protocol: TCP + - containerPort: 15021 + name: status-port + protocol: TCP + - containerPort: 15090 + name: http-envoy-prom + protocol: TCP + readinessProbe: + failureThreshold: 4 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 0 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 1 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsGroup: 1337 + runAsNonRoot: true + runAsUser: 1337 + startupProbe: + failureThreshold: 30 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 1 + periodSeconds: 1 + successThreshold: 1 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /var/run/secrets/workload-spiffe-uds + name: workload-socket + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + - mountPath: /var/lib/istio/data + name: istio-data + - mountPath: /etc/istio/proxy + name: istio-envoy + - mountPath: /var/run/secrets/tokens + name: istio-token + - mountPath: /etc/istio/pod + name: istio-podinfo + serviceAccountName: test-upgrade + terminationGracePeriodSeconds: 2 + volumes: + - emptyDir: {} + name: workload-socket + - emptyDir: + medium: Memory + name: istio-envoy + - emptyDir: + medium: Memory + name: go-proxy-envoy + - emptyDir: {} + name: istio-data + - emptyDir: {} + name: go-proxy-data + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.labels + path: labels + - fieldRef: + fieldPath: metadata.annotations + path: annotations + name: istio-podinfo + - name: istio-token + projected: + sources: + - serviceAccountToken: + audience: istio-ca + expirationSeconds: 43200 + path: istio-token + - configMap: + name: istio-ca-root-cert + name: istiod-ca-cert +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + networking.istio.io/traffic-distribution: PreferClose + labels: + gateway.istio.io/managed: istio.io-mesh-controller + gateway.networking.k8s.io/gateway-name: test-upgrade + topology.istio.io/network: network-1 + name: test-upgrade + namespace: default + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: test-upgrade + uid: "" +spec: + ipFamilyPolicy: PreferDualStack + ports: + - appProtocol: tcp + name: status-port + port: 15021 + protocol: TCP + - appProtocol: all + name: mesh + port: 15008 + protocol: TCP + selector: + gateway.networking.k8s.io/gateway-name: test-upgrade + type: ClusterIP +--- diff --git a/pilot/pkg/config/kube/gateway/testdata/deployment/waypoint-no-network-label.yaml b/pilot/pkg/config/kube/gateway/testdata/deployment/waypoint-no-network-label.yaml index dda2b3b7bb7a..5129eb15ae17 100644 --- a/pilot/pkg/config/kube/gateway/testdata/deployment/waypoint-no-network-label.yaml +++ b/pilot/pkg/config/kube/gateway/testdata/deployment/waypoint-no-network-label.yaml @@ -129,6 +129,8 @@ spec: value: kubernetes://apis/apps/v1/namespaces/default/deployments/namespace - name: ISTIO_META_MESH_ID value: cluster.local + - name: TRUST_DOMAIN + value: cluster.local image: test/proxyv2:test name: istio-proxy ports: diff --git a/pilot/pkg/config/kube/gateway/testdata/deployment/waypoint.yaml b/pilot/pkg/config/kube/gateway/testdata/deployment/waypoint.yaml index dda2b3b7bb7a..5129eb15ae17 100644 --- a/pilot/pkg/config/kube/gateway/testdata/deployment/waypoint.yaml +++ b/pilot/pkg/config/kube/gateway/testdata/deployment/waypoint.yaml @@ -129,6 +129,8 @@ spec: value: kubernetes://apis/apps/v1/namespaces/default/deployments/namespace - name: ISTIO_META_MESH_ID value: cluster.local + - name: TRUST_DOMAIN + value: cluster.local image: test/proxyv2:test name: istio-proxy ports: diff --git a/pilot/pkg/config/kube/gateway/testdata/http.yaml.golden b/pilot/pkg/config/kube/gateway/testdata/http.yaml.golden index 431d43035e01..8c647223598d 100644 --- a/pilot/pkg/config/kube/gateway/testdata/http.yaml.golden +++ b/pilot/pkg/config/kube/gateway/testdata/http.yaml.golden @@ -239,7 +239,7 @@ spec: port: number: 80 percentage: - value: 0.5 + value: 50 - destination: host: httpbin-second.default.svc.domain.suffix port: diff --git a/pilot/pkg/config/kube/gateway/testdata/invalid.status.yaml.golden b/pilot/pkg/config/kube/gateway/testdata/invalid.status.yaml.golden index 52fb6aa512b1..bfabb20ff57f 100644 --- a/pilot/pkg/config/kube/gateway/testdata/invalid.status.yaml.golden +++ b/pilot/pkg/config/kube/gateway/testdata/invalid.status.yaml.golden @@ -345,6 +345,144 @@ status: kind: GRPCRoute --- apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + creationTimestamp: null + name: udp-protocol + namespace: istio-system +spec: null +status: + conditions: + - lastTransitionTime: fake + message: Resource accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: fake + message: 'Failed to assign to any requested addresses: hostname "udp-protocol-istio.istio-system.svc.domain.suffix" + not found' + reason: AddressNotUsable + status: "False" + type: Programmed + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: fake + message: protocol "UDP" is unsupported + reason: UnsupportedProtocol + status: "False" + type: Accepted + - lastTransitionTime: fake + message: No errors found + reason: NoConflicts + status: "False" + type: Conflicted + - lastTransitionTime: fake + message: No errors found + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: fake + message: No errors found + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: udp + supportedKinds: [] +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + creationTimestamp: null + name: unknown-protocol + namespace: istio-system +spec: null +status: + conditions: + - lastTransitionTime: fake + message: Resource accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: fake + message: 'Failed to assign to any requested addresses: hostname "unknown-protocol-istio.istio-system.svc.domain.suffix" + not found' + reason: AddressNotUsable + status: "False" + type: Programmed + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: fake + message: protocol "unknown" is unsupported + reason: UnsupportedProtocol + status: "False" + type: Accepted + - lastTransitionTime: fake + message: No errors found + reason: NoConflicts + status: "False" + type: Conflicted + - lastTransitionTime: fake + message: No errors found + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: fake + message: No errors found + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: unknown + supportedKinds: [] +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + creationTimestamp: null + name: protocol-lower-case + namespace: istio-system +spec: null +status: + conditions: + - lastTransitionTime: fake + message: Resource accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: fake + message: 'Failed to assign to any requested addresses: hostname "protocol-lower-case-istio.istio-system.svc.domain.suffix" + not found' + reason: AddressNotUsable + status: "False" + type: Programmed + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: fake + message: 'protocol "http" is unsupported. hint: "HTTP" (uppercase) may be supported' + reason: UnsupportedProtocol + status: "False" + type: Accepted + - lastTransitionTime: fake + message: No errors found + reason: NoConflicts + status: "False" + type: Conflicted + - lastTransitionTime: fake + message: No errors found + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: fake + message: No errors found + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: [] +--- +apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: creationTimestamp: null diff --git a/pilot/pkg/config/kube/gateway/testdata/invalid.yaml b/pilot/pkg/config/kube/gateway/testdata/invalid.yaml index 93df901db805..c2f3591ee803 100644 --- a/pilot/pkg/config/kube/gateway/testdata/invalid.yaml +++ b/pilot/pkg/config/kube/gateway/testdata/invalid.yaml @@ -137,6 +137,42 @@ spec: kind: Secret --- apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: udp-protocol + namespace: istio-system +spec: + gatewayClassName: istio + listeners: + - name: udp + port: 1234 + protocol: UDP +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: unknown-protocol + namespace: istio-system +spec: + gatewayClassName: istio + listeners: + - name: unknown + port: 1234 + protocol: unknown +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: protocol-lower-case + namespace: istio-system +spec: + gatewayClassName: istio + listeners: + - name: http + port: 1234 + protocol: http +--- +apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: invalid-backendRef-kind diff --git a/pilot/pkg/controllers/ipallocate/ipallocate_test.go b/pilot/pkg/controllers/ipallocate/ipallocate_test.go index c4e821f1c7ed..7dff8019e29f 100644 --- a/pilot/pkg/controllers/ipallocate/ipallocate_test.go +++ b/pilot/pkg/controllers/ipallocate/ipallocate_test.go @@ -27,7 +27,6 @@ import ( "istio.io/api/networking/v1alpha3" networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1" "istio.io/istio/pilot/pkg/controllers/ipallocate" - "istio.io/istio/pilot/pkg/features" autoallocate "istio.io/istio/pilot/pkg/networking/serviceentry" "istio.io/istio/pkg/config/schema/gvr" kubelib "istio.io/istio/pkg/kube" @@ -61,7 +60,6 @@ type ipAllocateTestRig struct { func setupIPAllocateTest(t *testing.T) (*ipallocate.IPAllocator, ipAllocateTestRig) { t.Helper() - features.EnableIPAutoallocate = true s := test.NewStop(t) c := kubelib.NewFakeClient() clienttest.MakeCRD(t, c, gvr.ServiceEntry) diff --git a/pilot/pkg/controllers/untaint/nodeuntainter.go b/pilot/pkg/controllers/untaint/nodeuntainter.go index 33da17e3e9b6..4a149e967d5b 100644 --- a/pilot/pkg/controllers/untaint/nodeuntainter.go +++ b/pilot/pkg/controllers/untaint/nodeuntainter.go @@ -84,7 +84,7 @@ func (n *NodeUntainter) setup(stop <-chan struct{}) { nodes := krt.WrapClient[*v1.Node](n.nodesClient) pods := krt.WrapClient[*v1.Pod](n.podsClient) - readyCniPods := krt.NewCollection(pods, func(ctx krt.HandlerContext, p *v1.Pod) *v1.Pod { + readyCniPods := krt.NewCollection(pods, func(ctx krt.HandlerContext, p *v1.Pod) **v1.Pod { log.Debugf("cniPods event: %s", p.Name) if p.Namespace != n.ourNs { return nil @@ -96,12 +96,12 @@ func (n *NodeUntainter) setup(stop <-chan struct{}) { return nil } log.Debugf("pod %s on node %s ready!", p.Name, p.Spec.NodeName) - return p + return &p }, krt.WithStop(stop)) // these are all the nodes that have a ready cni pod. if the cni pod is ready, // it means we are ok scheduling pods to it. - readyCniNodes := krt.NewCollection(readyCniPods, func(ctx krt.HandlerContext, p v1.Pod) *v1.Node { + readyCniNodes := krt.NewCollection(readyCniPods, func(ctx krt.HandlerContext, p *v1.Pod) **v1.Node { pnode := krt.FetchOne(ctx, nodes, krt.FilterKey(p.Spec.NodeName)) if pnode == nil { return nil @@ -110,7 +110,7 @@ func (n *NodeUntainter) setup(stop <-chan struct{}) { if !hasTaint(node) { return nil } - return node + return &node }, krt.WithStop(stop)) n.queue = controllers.NewQueue("untaint nodes", @@ -118,13 +118,13 @@ func (n *NodeUntainter) setup(stop <-chan struct{}) { controllers.WithMaxAttempts(5)) // remove the taints from readyCniNodes - readyCniNodes.Register(func(o krt.Event[v1.Node]) { + readyCniNodes.Register(func(o krt.Event[*v1.Node]) { if o.Event == controllers.EventDelete { return } if o.New != nil { - log.Debugf("adding node to queue event: %s", o.New.Name) - n.queue.AddObject(o.New) + log.Debugf("adding node to queue event: %s", (*o.New).Name) + n.queue.AddObject(*o.New) } }) } diff --git a/pilot/pkg/credentials/kube/secrets.go b/pilot/pkg/credentials/kube/secrets.go index 3c31234a22a4..70bd09c858f8 100644 --- a/pilot/pkg/credentials/kube/secrets.go +++ b/pilot/pkg/credentials/kube/secrets.go @@ -89,11 +89,10 @@ func NewCredentialsController(kc kube.Client, handlers []func(name string, names fields.OneTermNotEqualSelector("type", string(v1.SecretTypeServiceAccountToken))).String() secrets := kclient.NewFiltered[*v1.Secret](kc, kclient.Filter{ FieldSelector: fieldSelector, - ObjectFilter: kube.FilterIfEnhancedFilteringEnabled(kc), + ObjectFilter: kc.ObjectFilter(), }) for _, h := range handlers { - h := h // register handler before informer starts secrets.AddEventHandler(controllers.ObjectHandler(func(o controllers.Object) { h(o.GetName(), o.GetNamespace()) diff --git a/pilot/pkg/features/experimental.go b/pilot/pkg/features/experimental.go index b09f3fac8efc..ef5180bd9fd0 100644 --- a/pilot/pkg/features/experimental.go +++ b/pilot/pkg/features/experimental.go @@ -133,7 +133,8 @@ var ( "If this is set to true, support for Kubernetes gateway-api (github.com/kubernetes-sigs/gateway-api) will "+ " be enabled. In addition to this being enabled, the gateway-api CRDs need to be installed.").Get() - EnableAlphaGatewayAPI = env.Register("PILOT_ENABLE_ALPHA_GATEWAY_API", false, + EnableAlphaGatewayAPIName = "PILOT_ENABLE_ALPHA_GATEWAY_API" + EnableAlphaGatewayAPI = env.Register(EnableAlphaGatewayAPIName, false, "If this is set to true, support for alpha APIs in the Kubernetes gateway-api (github.com/kubernetes-sigs/gateway-api) will "+ " be enabled. In addition to this being enabled, the gateway-api CRDs need to be installed.").Get() @@ -147,8 +148,8 @@ var ( "If this is set to true, istiod will create and manage its default GatewayClasses").Get() DeltaXds = env.Register("ISTIO_DELTA_XDS", true, - "If enabled, pilot will only send the delta configs as opposed to the state of the world on a "+ - "Resource Request. This feature uses the delta xds api, but does not currently send the actual deltas.").Get() + "If enabled, pilot will only send the delta configs as opposed to the state of the world configuration on a Resource Request. "+ + "While this feature uses the delta xds api, it may still occasionally send unchanged configurations instead of just the actual deltas.").Get() EnableQUICListeners = env.Register("PILOT_ENABLE_QUIC_LISTENERS", false, "If true, QUIC listeners will be generated wherever there are listeners terminating TLS on gateways "+ @@ -160,10 +161,6 @@ var ( EnableHCMInternalNetworks = env.Register("ENABLE_HCM_INTERNAL_NETWORKS", false, "If enable, endpoints defined in mesh networks will be configured as internal addresses in Http Connection Manager").Get() - EnableEnhancedResourceScoping = env.Register("ENABLE_ENHANCED_RESOURCE_SCOPING", true, - "If enabled, meshConfig.discoverySelectors will limit the CustomResource configurations(like Gateway,VirtualService,DestinationRule,Ingress, etc)"+ - "that can be processed by pilot. This will also restrict the root-ca certificate distribution.").Get() - EnableLeaderElection = env.Register("ENABLE_LEADER_ELECTION", true, "If enabled (default), starts a leader election client and gains leadership before executing controllers. "+ "If false, it assumes that only one instance of istiod is running and skips leader election.").Get() @@ -181,9 +178,6 @@ var ( EnableNativeSidecars = env.Register("ENABLE_NATIVE_SIDECARS", false, "If set, used Kubernetes native Sidecar container support. Requires SidecarContainer feature flag.") - PassthroughTargetPort = env.Register("ENABLE_RESOLUTION_NONE_TARGET_PORT", true, - "If enabled, targetPort will be supported for resolution=NONE ServiceEntry").Get() - Enable100ContinueHeaders = env.Register("ENABLE_100_CONTINUE_HEADERS", true, "If enabled, istiod will proxy 100-continue headers as is").Get() diff --git a/pilot/pkg/features/pilot.go b/pilot/pkg/features/pilot.go index 0e87481ccde6..688340f37bbc 100644 --- a/pilot/pkg/features/pilot.go +++ b/pilot/pkg/features/pilot.go @@ -65,7 +65,26 @@ var ( ClusterName = env.Register("CLUSTER_ID", constants.DefaultClusterName, "Defines the cluster and service registry that this Istiod instance belongs to").Get() - DNSJitterDurationEnv = env.Register("ENVOY_DNS_JITTER_DURATION", 100*time.Millisecond, "Jitter added to periodic DNS resolution").Get() + // This value defaults to 0 which is interpreted as infinity and causes Envoys to get "stuck" to dead dns pods + // (https://github.com/istio/istio/issues/53577). + // However, setting this value too high will rate limit the number of DNS requests we can make by using up all + // available local udp ports. + // Generally, the max dns query rate is + // + // (# local dns ports) * (udp_max_queries) / (query duration) + // + // The longest a query can take should be 5s, the Envoy default timeout. + // We underestimate the number of local dns ports to 10,000 (default is ~15,000, but some might be in use). + // Setting udp_max_queries to 100 gives us at least 10,000 * 100 / 5 = 200,000 requests / second, which is + // hopefully enough for any cluster. + PilotDNSCaresUDPMaxQueries = env.Register("PILOT_DNS_CARES_UDP_MAX_QUERIES", uint32(100), + "Sets the `udp_max_queries` option in Envoy for the Cares DNS resolver. "+ + "Defaults to 0, an unlimited number of queries. "+ + "See `extensions.network.dns_resolver.cares.v3.CaresDnsResolverConfig` in "+ + "https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/network/dns_resolver/cares/v3/cares_dns_resolver.proto "+ + "and `ARES_OPT_UDP_MAX_QUERIES` in https://c-ares.org/docs/ares_init.html").Get() + + PilotDNSJitterDurationEnv = env.Register("PILOT_DNS_JITTER_DURATION", 100*time.Millisecond, "Jitter added to periodic DNS resolution").Get() ExternalIstiod = env.Register("EXTERNAL_ISTIOD", false, "If this is set to true, one Istiod will control remote clusters including CA.").Get() @@ -139,7 +158,7 @@ var ( EnableIPAutoallocate = env.Register( "PILOT_ENABLE_IP_AUTOALLOCATE", - false, + true, "If enabled, pilot will start a controller that assigns IP addresses to ServiceEntry which do not have a user-supplied IP. "+ "This, when combined with DNS capture allows for tcp routing of traffic sent to the ServiceEntry.").Get() diff --git a/pilot/pkg/grpc/grpc.go b/pilot/pkg/grpc/grpc.go index b54340c42e04..404fa4ed4fcc 100644 --- a/pilot/pkg/grpc/grpc.go +++ b/pilot/pkg/grpc/grpc.go @@ -137,5 +137,5 @@ func GRPCErrorType(err error) ErrorType { return ExpectedError } - return ExpectedError + return UnexpectedError } diff --git a/pilot/pkg/leaderelection/k8sleaderelection/leaderelection.go b/pilot/pkg/leaderelection/k8sleaderelection/leaderelection.go index 2a58e0fa528a..f4a98482c738 100644 --- a/pilot/pkg/leaderelection/k8sleaderelection/leaderelection.go +++ b/pilot/pkg/leaderelection/k8sleaderelection/leaderelection.go @@ -289,9 +289,10 @@ func (le *LeaderElector) renew(ctx context.Context) { wait.Until(func() { timeoutCtx, timeoutCancel := context.WithTimeout(ctx, le.config.RenewDeadline) defer timeoutCancel() - err := wait.PollImmediateUntil(le.config.RetryPeriod, func() (bool, error) { - return le.tryAcquireOrRenew(timeoutCtx), nil - }, timeoutCtx.Done()) + + err := wait.PollUntilContextCancel(timeoutCtx, le.config.RetryPeriod, true, func(ctx context.Context) (bool, error) { + return le.tryAcquireOrRenew(ctx), nil + }) le.maybeReportTransition() desc := le.config.Lock.Describe() diff --git a/pilot/pkg/leaderelection/leaderelection.go b/pilot/pkg/leaderelection/leaderelection.go index 313a18f0153a..92e84d1dc4b4 100644 --- a/pilot/pkg/leaderelection/leaderelection.go +++ b/pilot/pkg/leaderelection/leaderelection.go @@ -162,7 +162,7 @@ func (l *LeaderElection) create() (*k8sleaderelection.LeaderElector, error) { Key: key, }, } - if l.perRevision { + if l.perRevision || l.useLeaseLock { lock = &k8sresourcelock.LeaseLock{ LeaseMeta: metav1.ObjectMeta{Namespace: l.namespace, Name: l.electionID}, Client: l.client.CoordinationV1(), @@ -248,6 +248,10 @@ func newLeaderElection(namespace, name, electionID, revision string, perRevision if features.EnableLeaderElection { watcher = revisions.NewDefaultWatcher(client, revision) } + // Default revision for consistency. Note that on Kubernetes, there is ~always a revision set. + if revision == "" { + revision = "default" + } if name == "" { hn, _ := os.Hostname() name = fmt.Sprintf("unknown-%s", hn) diff --git a/pilot/pkg/model/authentication.go b/pilot/pkg/model/authentication.go index 7507b52f3f8e..c87e0c942c2e 100644 --- a/pilot/pkg/model/authentication.go +++ b/pilot/pkg/model/authentication.go @@ -25,6 +25,7 @@ import ( "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/schema/gvk" "istio.io/istio/pkg/config/schema/kind" + "istio.io/istio/pkg/slices" ) // MutualTLSMode is the mutual TLS mode specified by authentication policy. @@ -230,15 +231,11 @@ func getConfigsForWorkload(rootNamespace string, configsByNamespace map[string][ workloadLabels := selectionOpts.WorkloadLabels namespace := selectionOpts.WorkloadNamespace configs := make([]*config.Config, 0) - var lookupInNamespaces []string - if namespace != rootNamespace { - // Only check the root namespace if the (workload) namespace is not already the root namespace - // to avoid double inclusion. - lookupInNamespaces = []string{namespace, rootNamespace} - } else { - lookupInNamespaces = []string{namespace} + lookupInNamespaces := []string{namespace, rootNamespace} + for _, svc := range selectionOpts.Services { + lookupInNamespaces = append(lookupInNamespaces, svc.Namespace) } - for _, ns := range lookupInNamespaces { + for _, ns := range slices.FilterDuplicates(lookupInNamespaces) { if nsConfig, ok := configsByNamespace[ns]; ok { for idx := range nsConfig { cfg := &nsConfig[idx] diff --git a/pilot/pkg/model/authentication_test.go b/pilot/pkg/model/authentication_test.go index b8a4eb4a99b5..ff5f883d377e 100644 --- a/pilot/pkg/model/authentication_test.go +++ b/pilot/pkg/model/authentication_test.go @@ -26,11 +26,13 @@ import ( selectorpb "istio.io/api/type/v1beta1" "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model/test" + "istio.io/istio/pilot/pkg/serviceregistry/provider" "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/mesh" "istio.io/istio/pkg/config/schema/gvk" pkgtest "istio.io/istio/pkg/test" + "istio.io/istio/pkg/test/util/assert" ) const ( @@ -46,6 +48,7 @@ func TestGetPoliciesForWorkload(t *testing.T) { name string workloadNamespace string workloadLabels labels.Instance + WithService *Service wantRequestAuthn []*config.Config wantPeerAuthn []*config.Config wantNamespaceMutualTLS MutualTLSMode @@ -581,20 +584,111 @@ func TestGetPoliciesForWorkload(t *testing.T) { }, wantNamespaceMutualTLS: MTLSStrict, }, + { + name: "Service targetRef bar namespace", + workloadNamespace: "bar", + workloadLabels: labels.Instance{ + label.IoK8sNetworkingGatewayGatewayName.Name: "my-waypoint", + }, + isWaypoint: true, + WithService: &Service{ + Attributes: ServiceAttributes{ + ServiceRegistry: provider.Kubernetes, + Name: "target-service-bar", + Namespace: "bar", + }, + }, + wantRequestAuthn: []*config.Config{ + { + Meta: config.Meta{ + GroupVersionKind: gvk.RequestAuthentication, + Name: "with-targetref-service", + Namespace: "bar", + }, + Spec: &securityBeta.RequestAuthentication{ + TargetRef: &selectorpb.PolicyTargetReference{ + Group: gvk.Service.Group, + Kind: gvk.Service.Kind, + Name: "target-service-bar", + }, + }, + }, + }, + wantPeerAuthn: []*config.Config{ + { + Meta: config.Meta{ + GroupVersionKind: gvk.PeerAuthentication, + CreationTimestamp: baseTimestamp, + Name: "default", + Namespace: "istio-config", + }, + Spec: &securityBeta.PeerAuthentication{ + Mtls: &securityBeta.PeerAuthentication_MutualTLS{ + Mode: securityBeta.PeerAuthentication_MutualTLS_UNSET, + }, + }, + }, + }, + wantNamespaceMutualTLS: MTLSPermissive, + }, + { + name: "Service targetRef cross namespace", + workloadNamespace: "gateway", + workloadLabels: labels.Instance{ + label.IoK8sNetworkingGatewayGatewayName.Name: "my-waypoint", + }, + isWaypoint: true, + WithService: &Service{ + Attributes: ServiceAttributes{ + ServiceRegistry: provider.Kubernetes, + Name: "target-service-bar", + Namespace: "bar", + }, + }, + wantRequestAuthn: []*config.Config{ + { + Meta: config.Meta{ + GroupVersionKind: gvk.RequestAuthentication, + Name: "with-targetref-service", + Namespace: "bar", + }, + Spec: &securityBeta.RequestAuthentication{ + TargetRef: &selectorpb.PolicyTargetReference{ + Group: gvk.Service.Group, + Kind: gvk.Service.Kind, + Name: "target-service-bar", + }, + }, + }, + }, + wantPeerAuthn: []*config.Config{ + { + Meta: config.Meta{ + GroupVersionKind: gvk.PeerAuthentication, + CreationTimestamp: baseTimestamp, + Name: "default", + Namespace: "istio-config", + }, + Spec: &securityBeta.PeerAuthentication{ + Mtls: &securityBeta.PeerAuthentication_MutualTLS{ + Mode: securityBeta.PeerAuthentication_MutualTLS_UNSET, + }, + }, + }, + }, + wantNamespaceMutualTLS: MTLSPermissive, + }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { matcher := PolicyMatcherFor(tc.workloadNamespace, tc.workloadLabels, tc.isWaypoint) - if got := policies.GetJwtPoliciesForWorkload(matcher); !reflect.DeepEqual(tc.wantRequestAuthn, got) { - t.Fatalf("want %+v\n, but got %+v\n", printConfigs(tc.wantRequestAuthn), printConfigs(got)) - } - if got := policies.GetPeerAuthenticationsForWorkload(matcher); !reflect.DeepEqual(tc.wantPeerAuthn, got) { - t.Fatalf("want %+v\n, but got %+v\n", printConfigs(tc.wantPeerAuthn), printConfigs(got)) - } - if got := policies.GetNamespaceMutualTLSMode(tc.workloadNamespace); got != tc.wantNamespaceMutualTLS { - t.Fatalf("want %s\n, but got %s\n", tc.wantNamespaceMutualTLS, got) + if tc.WithService != nil { + matcher = matcher.WithService(tc.WithService) } + assert.Equal(t, policies.GetJwtPoliciesForWorkload(matcher), tc.wantRequestAuthn) + assert.Equal(t, policies.GetPeerAuthenticationsForWorkload(matcher), tc.wantPeerAuthn) + assert.Equal(t, policies.GetNamespaceMutualTLSMode(tc.workloadNamespace), tc.wantNamespaceMutualTLS) }) } } @@ -1101,15 +1195,9 @@ func TestGetPoliciesForGatewayPolicyAttachmentOnly(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { matcher := PolicyMatcherFor(tc.workloadNamespace, tc.workloadLabels, tc.isWaypoint) - if got := policies.GetJwtPoliciesForWorkload(matcher); !reflect.DeepEqual(tc.wantRequestAuthn, got) { - t.Fatalf("want %+v\n, but got %+v\n", printConfigs(tc.wantRequestAuthn), printConfigs(got)) - } - if got := policies.GetPeerAuthenticationsForWorkload(matcher); !reflect.DeepEqual(tc.wantPeerAuthn, got) { - t.Fatalf("want %+v\n, but got %+v\n", printConfigs(tc.wantPeerAuthn), printConfigs(got)) - } - if got := policies.GetNamespaceMutualTLSMode(tc.workloadNamespace); got != tc.wantNamespaceMutualTLS { - t.Fatalf("want %s\n, but got %s\n", tc.wantNamespaceMutualTLS, got) - } + assert.Equal(t, policies.GetJwtPoliciesForWorkload(matcher), tc.wantRequestAuthn) + assert.Equal(t, policies.GetPeerAuthenticationsForWorkload(matcher), tc.wantPeerAuthn) + assert.Equal(t, policies.GetNamespaceMutualTLSMode(tc.workloadNamespace), tc.wantNamespaceMutualTLS) }) } } @@ -1395,7 +1483,8 @@ func TestGetPoliciesForWorkloadWithJwksResolver(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { matcher := PolicyMatcherFor(tc.workloadNamespace, tc.workloadLabels, tc.isWaypoint) - if got := policies.GetJwtPoliciesForWorkload(matcher); !reflect.DeepEqual(tc.wantRequestAuthn, got) { + got := policies.GetJwtPoliciesForWorkload(matcher) + if !reflect.DeepEqual(tc.wantRequestAuthn, got) { t.Fatalf("want %+v\n, but got %+v\n", printConfigs(tc.wantRequestAuthn), printConfigs(got)) } }) @@ -1495,6 +1584,12 @@ func createTestConfigs(withMeshPeerAuthn bool) []*config.Config { Kind: gvk.KubernetesGateway.Kind, Name: "my-gateway", }), + createTestRequestAuthenticationResource("with-targetref-service", "bar", nil, + &selectorpb.PolicyTargetReference{ + Group: gvk.Service.Group, + Kind: gvk.Service.Kind, + Name: "target-service-bar", + }), createTestPeerAuthenticationResource("global-peer-with-selector", rootNamespace, baseTimestamp, &selectorpb.WorkloadSelector{ MatchLabels: map[string]string{ "app": "httpbin", diff --git a/pilot/pkg/model/authorization.go b/pilot/pkg/model/authorization.go index 02bd3ab4fc20..9b83028e0ecf 100644 --- a/pilot/pkg/model/authorization.go +++ b/pilot/pkg/model/authorization.go @@ -19,6 +19,7 @@ import ( authpb "istio.io/api/security/v1beta1" "istio.io/istio/pkg/config/schema/gvk" + "istio.io/istio/pkg/slices" ) type AuthorizationPolicy struct { @@ -86,22 +87,19 @@ func (policy *AuthorizationPolicies) ListAuthorizationPolicies(selectionOpts Wor return configs } - rootNamespace := policy.RootNamespace - wlNamespace := selectionOpts.WorkloadNamespace - svcNamespace := selectionOpts.ServiceNamespace - var lookupInNamespaces []string - - if svcNamespace != "" { - lookupInNamespaces = []string{svcNamespace} - } else if wlNamespace != rootNamespace { - // Only check the root namespace if the (workload) namespace is not already the root namespace - // to avoid double inclusion. - lookupInNamespaces = []string{rootNamespace, wlNamespace} - } else { - lookupInNamespaces = []string{wlNamespace} + if len(selectionOpts.Services) > 1 { + // Currently, listing multiple services is unnecessary. + // To simplify, this function allows at most one service. + // The restriction can be lifted if future needs arise. + panic("ListAuthorizationPolicies expects at most 1 service in WorkloadPolicyMatcher") } - for _, ns := range lookupInNamespaces { + lookupInNamespaces := []string{policy.RootNamespace, selectionOpts.WorkloadNamespace} + for _, svc := range selectionOpts.Services { + lookupInNamespaces = append(lookupInNamespaces, svc.Namespace) + } + + for _, ns := range slices.FilterDuplicates(lookupInNamespaces) { for _, config := range policy.NamespaceToPolicies[ns] { spec := config.Spec diff --git a/pilot/pkg/model/authorization_test.go b/pilot/pkg/model/authorization_test.go index 87b52bd0006f..18bb17b502a9 100644 --- a/pilot/pkg/model/authorization_test.go +++ b/pilot/pkg/model/authorization_test.go @@ -408,10 +408,10 @@ func TestAuthorizationPolicies_ListAuthorizationPolicies(t *testing.T) { { name: "waypoint service attached", selectionOpts: WorkloadPolicyMatcher{ - IsWaypoint: true, - Service: "foo-svc", - ServiceNamespace: "foo", - ServiceRegistry: provider.Kubernetes, + IsWaypoint: true, + Services: []ServiceInfoForPolicyMatcher{ + {Name: "foo-svc", Namespace: "foo", Registry: provider.Kubernetes}, + }, WorkloadNamespace: "foo", WorkloadLabels: labels.Instance{ label.IoK8sNetworkingGatewayGatewayName.Name: "foo-waypoint", diff --git a/pilot/pkg/model/config.go b/pilot/pkg/model/config.go index 2a975cf7bb02..003b2ff50844 100644 --- a/pilot/pkg/model/config.go +++ b/pilot/pkg/model/config.go @@ -94,19 +94,6 @@ func ConfigNamesOfKind(configs sets.Set[ConfigKey], kind kind.Kind) sets.String return ret } -// ConfigNameOfKind extracts config names of the specified kind. -func ConfigNameOfKind(configs map[ConfigKey]struct{}, kind kind.Kind) sets.String { - ret := sets.New[string]() - - for conf := range configs { - if conf.Kind == kind { - ret.Insert(conf.Name) - } - } - - return ret -} - // ConfigStore describes a set of platform agnostic APIs that must be supported // by the underlying platform to store and retrieve Istio configuration. // diff --git a/pilot/pkg/model/context.go b/pilot/pkg/model/context.go index 8f9bfdd5b0f4..ced2ad65c4cb 100644 --- a/pilot/pkg/model/context.go +++ b/pilot/pkg/model/context.go @@ -523,7 +523,7 @@ func compareVersion(ov, nv int) int { return 1 } -func (node *Proxy) VersionGreaterAndEqual(inv *IstioVersion) bool { +func (node *Proxy) VersionGreaterOrEqual(inv *IstioVersion) bool { if inv == nil { return true } diff --git a/pilot/pkg/model/endpointshards.go b/pilot/pkg/model/endpointshards.go index e473bf4d77e2..2392c67056ab 100644 --- a/pilot/pkg/model/endpointshards.go +++ b/pilot/pkg/model/endpointshards.go @@ -273,6 +273,7 @@ func (e *EndpointIndex) UpdateServiceEndpoints( hostname string, namespace string, istioEndpoints []*IstioEndpoint, + logPushType bool, ) PushType { if len(istioEndpoints) == 0 { // Should delete the service EndpointShards when endpoints become zero to prevent memory leak, @@ -280,7 +281,11 @@ func (e *EndpointIndex) UpdateServiceEndpoints( // unnecessary full push which can become a real problem if a pod is in crashloop and thus endpoints // flip flopping between 1 and 0. e.DeleteServiceShard(shard, hostname, namespace, true) - log.Infof("Incremental push, service %s at shard %v has no endpoints", hostname, shard) + if logPushType { + log.Infof("Incremental push, service %s at shard %v has no endpoints", hostname, shard) + } else { + log.Infof("Cache Update, Service %s at shard %v has no endpoints", hostname, shard) + } return IncrementalPush } @@ -289,7 +294,11 @@ func (e *EndpointIndex) UpdateServiceEndpoints( ep, created := e.GetOrCreateEndpointShard(hostname, namespace) // If we create a new endpoint shard, that means we have not seen the service earlier. We should do a full push. if created { - log.Infof("Full push, new service %s/%s", namespace, hostname) + if logPushType { + log.Infof("Full push, new service %s/%s", namespace, hostname) + } else { + log.Infof("Cache Update, new service %s/%s", namespace, hostname) + } pushType = FullPush } @@ -311,7 +320,11 @@ func (e *EndpointIndex) UpdateServiceEndpoints( // For existing endpoints, we need to do full push if service accounts change. if saUpdated && pushType != FullPush { // Avoid extra logging if already a full push - log.Infof("Full push, service accounts changed, %v", hostname) + if logPushType { + log.Infof("Full push, service accounts changed, %v", hostname) + } else { + log.Infof("Cache Update, service accounts changed, %v", hostname) + } pushType = FullPush } @@ -403,46 +416,3 @@ func updateShardServiceAccount(shards *EndpointShards, serviceName string) bool return false } - -// EndpointIndexUpdater is an updater that will keep an EndpointIndex in sync. This is intended for tests only. -type EndpointIndexUpdater struct { - Index *EndpointIndex - // Optional; if set, we will trigger ConfigUpdates in response to EDS updates as appropriate - ConfigUpdateFunc func(req *PushRequest) -} - -var _ XDSUpdater = &EndpointIndexUpdater{} - -func NewEndpointIndexUpdater(ei *EndpointIndex) *EndpointIndexUpdater { - return &EndpointIndexUpdater{Index: ei} -} - -func (f *EndpointIndexUpdater) ConfigUpdate(*PushRequest) {} - -func (f *EndpointIndexUpdater) EDSUpdate(shard ShardKey, serviceName string, namespace string, eps []*IstioEndpoint) { - pushType := f.Index.UpdateServiceEndpoints(shard, serviceName, namespace, eps) - if f.ConfigUpdateFunc != nil && (pushType == IncrementalPush || pushType == FullPush) { - // Trigger a push - f.ConfigUpdateFunc(&PushRequest{ - Full: pushType == FullPush, - ConfigsUpdated: sets.New(ConfigKey{Kind: kind.ServiceEntry, Name: serviceName, Namespace: namespace}), - Reason: NewReasonStats(EndpointUpdate), - }) - } -} - -func (f *EndpointIndexUpdater) EDSCacheUpdate(shard ShardKey, serviceName string, namespace string, eps []*IstioEndpoint) { - f.Index.UpdateServiceEndpoints(shard, serviceName, namespace, eps) -} - -func (f *EndpointIndexUpdater) SvcUpdate(shard ShardKey, hostname string, namespace string, event Event) { - if event == EventDelete { - f.Index.DeleteServiceShard(shard, hostname, namespace, false) - } -} - -func (f *EndpointIndexUpdater) ProxyUpdate(_ cluster.ID, _ string) {} - -func (f *EndpointIndexUpdater) RemoveShard(shardKey ShardKey) { - f.Index.DeleteShard(shardKey) -} diff --git a/pilot/pkg/model/endpointshards_test.go b/pilot/pkg/model/endpointshards_test.go index 18546640deb7..9c5b2fef70cb 100644 --- a/pilot/pkg/model/endpointshards_test.go +++ b/pilot/pkg/model/endpointshards_test.go @@ -180,7 +180,7 @@ func TestUpdateServiceEndpoints(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - endpoints.UpdateServiceEndpoints(tc.shardKey, tc.hostname, tc.namespace, tc.endpoints) + endpoints.UpdateServiceEndpoints(tc.shardKey, tc.hostname, tc.namespace, tc.endpoints, true) eps, _ := endpoints.ShardsForService(tc.hostname, tc.namespace) assert.Equal(t, len(eps.Shards[tc.shardKey]), tc.expect) }) diff --git a/pilot/pkg/model/extensions.go b/pilot/pkg/model/extensions.go index 6fa9be15d0ae..0bd0200dbe35 100644 --- a/pilot/pkg/model/extensions.go +++ b/pilot/pkg/model/extensions.go @@ -159,6 +159,7 @@ func (p *WasmPluginWrapper) buildPluginConfig() *wasmextensions.PluginConfig { datasource := buildDataSource(u, plugin) resourceName := p.Namespace + "." + p.Name + // nolint: staticcheck // FailOpen deprecated return &wasmextensions.PluginConfig{ Name: resourceName, RootId: plugin.PluginName, @@ -173,7 +174,15 @@ type WasmPluginListenerInfo struct { Class istionetworking.ListenerClass // Service that WasmPlugins can attach to via targetRefs (optional) - Service *Service + Services []*Service +} + +func (listenerInfo WasmPluginListenerInfo) WithService(service *Service) WasmPluginListenerInfo { + if service == nil { + return listenerInfo + } + listenerInfo.Services = append(listenerInfo.Services, service) + return listenerInfo } // If anyListener is used as a listener info, diff --git a/pilot/pkg/model/extensions_test.go b/pilot/pkg/model/extensions_test.go index 77e70523a7ee..ff1e80a003d3 100644 --- a/pilot/pkg/model/extensions_test.go +++ b/pilot/pkg/model/extensions_test.go @@ -275,6 +275,8 @@ func TestFailStrategy(t *testing.T) { if out == nil { t.Fatal("filter can not be nil") } + + // nolint: staticcheck // FailOpen deprecated if got := filter.Config.FailOpen; got != tc.out { t.Errorf("got %t, want %t", got, tc.out) } diff --git a/pilot/pkg/model/fake_endpointshards.go b/pilot/pkg/model/fake_endpointshards.go new file mode 100644 index 000000000000..0554e54da8f2 --- /dev/null +++ b/pilot/pkg/model/fake_endpointshards.go @@ -0,0 +1,64 @@ +// Copyright Istio Authors +// +// Licensed 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 model + +import ( + "istio.io/istio/pkg/cluster" + "istio.io/istio/pkg/config/schema/kind" + "istio.io/istio/pkg/util/sets" +) + +// FakeEndpointIndexUpdater is an updater that will keep an EndpointIndex in sync. This is intended for tests only. +type FakeEndpointIndexUpdater struct { + Index *EndpointIndex + // Optional; if set, we will trigger ConfigUpdates in response to EDS updates as appropriate + ConfigUpdateFunc func(req *PushRequest) +} + +var _ XDSUpdater = &FakeEndpointIndexUpdater{} + +func NewEndpointIndexUpdater(ei *EndpointIndex) *FakeEndpointIndexUpdater { + return &FakeEndpointIndexUpdater{Index: ei} +} + +func (f *FakeEndpointIndexUpdater) ConfigUpdate(*PushRequest) {} + +func (f *FakeEndpointIndexUpdater) EDSUpdate(shard ShardKey, serviceName string, namespace string, eps []*IstioEndpoint) { + pushType := f.Index.UpdateServiceEndpoints(shard, serviceName, namespace, eps, true) + if f.ConfigUpdateFunc != nil && (pushType == IncrementalPush || pushType == FullPush) { + // Trigger a push + f.ConfigUpdateFunc(&PushRequest{ + Full: pushType == FullPush, + ConfigsUpdated: sets.New(ConfigKey{Kind: kind.ServiceEntry, Name: serviceName, Namespace: namespace}), + Reason: NewReasonStats(EndpointUpdate), + }) + } +} + +func (f *FakeEndpointIndexUpdater) EDSCacheUpdate(shard ShardKey, serviceName string, namespace string, eps []*IstioEndpoint) { + f.Index.UpdateServiceEndpoints(shard, serviceName, namespace, eps, false) +} + +func (f *FakeEndpointIndexUpdater) SvcUpdate(shard ShardKey, hostname string, namespace string, event Event) { + if event == EventDelete { + f.Index.DeleteServiceShard(shard, hostname, namespace, false) + } +} + +func (f *FakeEndpointIndexUpdater) ProxyUpdate(_ cluster.ID, _ string) {} + +func (f *FakeEndpointIndexUpdater) RemoveShard(shardKey ShardKey) { + f.Index.DeleteShard(shardKey) +} diff --git a/pilot/pkg/model/policyattachment.go b/pilot/pkg/model/policyattachment.go index d02ec4d16979..ebd749ad6eb7 100644 --- a/pilot/pkg/model/policyattachment.go +++ b/pilot/pkg/model/policyattachment.go @@ -42,9 +42,13 @@ type WorkloadPolicyMatcher struct { WorkloadNamespace string WorkloadLabels labels.Instance IsWaypoint bool - Service string - ServiceNamespace string - ServiceRegistry provider.ID + Services []ServiceInfoForPolicyMatcher +} + +type ServiceInfoForPolicyMatcher struct { + Name string + Namespace string + Registry provider.ID } func PolicyMatcherFor(workloadNamespace string, labels labels.Instance, isWaypoint bool) WorkloadPolicyMatcher { @@ -68,9 +72,23 @@ func (p WorkloadPolicyMatcher) WithService(service *Service) WorkloadPolicyMatch return p } - p.Service = ptr.NonEmptyOrDefault(service.Attributes.ObjectName, service.Attributes.Name) - p.ServiceNamespace = service.Attributes.Namespace - p.ServiceRegistry = service.Attributes.ServiceRegistry + p.Services = append(p.Services, ServiceInfoForPolicyMatcher{ + Name: ptr.NonEmptyOrDefault(service.Attributes.ObjectName, service.Attributes.Name), + Namespace: service.Attributes.Namespace, + Registry: service.Attributes.ServiceRegistry, + }) + return p +} + +// WithServices marks multiple services as part of the selection criteria. This is used when we want to +// find **all** policies attached to a specific proxy instance, rather than scoped to a specific service. +// This is useful when using ECDS, for example, where we might have: +// * Each unique service creates a listener, and applies a policy selected by `WithService` pointing to ECDS +// * All policies are found, by `WithServices`, and returned in ECDS. +func (p WorkloadPolicyMatcher) WithServices(services []*Service) WorkloadPolicyMatcher { + for _, svc := range services { + p = p.WithService(svc) + } return p } @@ -124,25 +142,34 @@ func (p WorkloadPolicyMatcher) ShouldAttachPolicy(kind config.GroupVersionKind, target := targetRef.GetName() // Service attached - if p.IsWaypoint && - matchesGroupKind(targetRef, gvk.Service) && - target == p.Service && - policyName.Namespace == p.ServiceNamespace && - p.ServiceRegistry == provider.Kubernetes { - return true + if p.IsWaypoint && matchesGroupKind(targetRef, gvk.Service) { + for _, svc := range p.Services { + if target == svc.Name && + policyName.Namespace == svc.Namespace && + svc.Registry == provider.Kubernetes { + return true + } + } } // ServiceEntry attached - if p.IsWaypoint && - matchesGroupKind(targetRef, gvk.ServiceEntry) && - target == p.Service && - policyName.Namespace == p.ServiceNamespace && - p.ServiceRegistry == provider.External { - return true + if p.IsWaypoint && matchesGroupKind(targetRef, gvk.ServiceEntry) { + for _, svc := range p.Services { + if target == svc.Name && + policyName.Namespace == svc.Namespace && + svc.Registry == provider.External { + return true + } + } } // Namespace does not match + if p.WorkloadNamespace != policyName.Namespace { + // Policy is not in the same namespace + continue + } if !(targetRef.GetNamespace() == "" || targetRef.GetNamespace() == p.WorkloadNamespace) { + // Policy references a different namespace (which is unsupported; it will never match anything) continue } diff --git a/pilot/pkg/model/policyattachment_test.go b/pilot/pkg/model/policyattachment_test.go index 17c29bc610ea..5b66985f0424 100644 --- a/pilot/pkg/model/policyattachment_test.go +++ b/pilot/pkg/model/policyattachment_test.go @@ -92,10 +92,8 @@ func TestPolicyMatcher(t *testing.T) { "app": "my-app", label.IoK8sNetworkingGatewayGatewayName.Name: "sample-waypoint", }, - IsWaypoint: true, - Service: "sample-svc", - ServiceNamespace: "default", - ServiceRegistry: provider.Kubernetes, + IsWaypoint: true, + Services: []ServiceInfoForPolicyMatcher{{Name: "sample-svc", Namespace: "default", Registry: provider.Kubernetes}}, } serviceEntryTarget := WorkloadPolicyMatcher{ WorkloadNamespace: "default", @@ -103,10 +101,8 @@ func TestPolicyMatcher(t *testing.T) { "app": "my-app", label.IoK8sNetworkingGatewayGatewayName.Name: "sample-waypoint", }, - IsWaypoint: true, - ServiceNamespace: "default", - Service: "sample-svc-entry", - ServiceRegistry: provider.External, + IsWaypoint: true, + Services: []ServiceInfoForPolicyMatcher{{Name: "sample-svc-entry", Namespace: "default", Registry: provider.External}}, } tests := []struct { name string @@ -304,6 +300,46 @@ func TestPolicyMatcher(t *testing.T) { enableSelectorPolicies: false, expected: false, }, + { + name: "gateway attached policy with service", + selection: serviceTarget, + policy: &mockPolicyTargetGetter{ + targetRefs: []*v1beta1.PolicyTargetReference{waypointTargetRef}, + }, + enableSelectorPolicies: false, + expected: true, + }, + { + name: "gateway attached policy with multi-service", + // selection: serviceTarget, + selection: func() WorkloadPolicyMatcher { + base := serviceTarget + base.Services = append(base.Services, ServiceInfoForPolicyMatcher{Name: "sample-svc-1", Namespace: "default", Registry: provider.Kubernetes}) + return base + }(), + policy: &mockPolicyTargetGetter{ + targetRefs: []*v1beta1.PolicyTargetReference{waypointTargetRef}, + }, + enableSelectorPolicies: false, + expected: true, + }, + { + name: "gateway attached policy with cross-namespace service", + selection: func() WorkloadPolicyMatcher { + base := serviceTarget + // Waypoint is in 'waypoint' + base.WorkloadNamespace = "waypoint" + // Policy and service are in default + base.Services = []ServiceInfoForPolicyMatcher{{Name: "sample-svc", Namespace: "default", Registry: provider.Kubernetes}} + return base + }(), + // Policy points to a waypoint.. but its in the wrong namespace + policy: &mockPolicyTargetGetter{ + targetRefs: []*v1beta1.PolicyTargetReference{waypointTargetRef}, + }, + enableSelectorPolicies: false, + expected: false, + }, } for _, tt := range tests { diff --git a/pilot/pkg/model/proxy_view_test.go b/pilot/pkg/model/proxy_view_test.go index 448e1d28ff47..8fb1bfcf1b13 100644 --- a/pilot/pkg/model/proxy_view_test.go +++ b/pilot/pkg/model/proxy_view_test.go @@ -56,7 +56,6 @@ func TestProxyView(t *testing.T) { } for _, c := range cases { - c := c t.Run(c.name, func(t *testing.T) { g := NewWithT(t) diff --git a/pilot/pkg/model/push_context.go b/pilot/pkg/model/push_context.go index 71dc346f491d..7e8d571cf918 100644 --- a/pilot/pkg/model/push_context.go +++ b/pilot/pkg/model/push_context.go @@ -2109,8 +2109,23 @@ func (ps *PushContext) initWasmPlugins(env *Environment) { } // WasmPlugins return the WasmPluginWrappers of a proxy. +// For most proxy types, we include only the root namespace and same-namespace objects. +// However, waypoints allow cross-namespace access based on attached Service objects. +// In this case, include all referenced services in the selection criteria func (ps *PushContext) WasmPlugins(proxy *Proxy) map[extensions.PluginPhase][]*WasmPluginWrapper { - return ps.WasmPluginsByListenerInfo(proxy, anyListener, WasmPluginTypeAny) + listenerInfo := WasmPluginListenerInfo{} + if proxy.IsWaypointProxy() { + servicesInfo := ps.ServicesForWaypoint(WaypointKeyForProxy(proxy)) + for i := range servicesInfo { + svc, exist := ps.ServiceIndex.HostnameAndNamespace[host.Name(servicesInfo[i].Hostname)][servicesInfo[i].Namespace] + if !exist { + log.Warnf("cannot find waypoint service in serviceindex, namespace/hostname: %s/%s", servicesInfo[i].Namespace, servicesInfo[i].Hostname) + continue + } + listenerInfo = listenerInfo.WithService(svc) + } + } + return ps.WasmPluginsByListenerInfo(proxy, listenerInfo, WasmPluginTypeAny) } func (ps *PushContext) WasmPluginsByName(proxy *Proxy, names []types.NamespacedName) []*WasmPluginWrapper { @@ -2138,19 +2153,13 @@ func (ps *PushContext) WasmPluginsByListenerInfo(proxy *Proxy, info WasmPluginLi return nil } - var lookupInNamespaces []string matchedPlugins := make(map[extensions.PluginPhase][]*WasmPluginWrapper) - - if proxy.ConfigNamespace != ps.Mesh.RootNamespace { - // Only check the root namespace if the (workload) namespace is not already the root namespace - // to avoid double inclusion. - lookupInNamespaces = []string{proxy.ConfigNamespace, ps.Mesh.RootNamespace} - } else { - lookupInNamespaces = []string{proxy.ConfigNamespace} + lookupInNamespaces := []string{proxy.ConfigNamespace, ps.Mesh.RootNamespace} + for i := range info.Services { + lookupInNamespaces = append(lookupInNamespaces, info.Services[i].NamespacedName().Namespace) } - - selectionOpts := PolicyMatcherForProxy(proxy).WithService(info.Service) - for _, ns := range lookupInNamespaces { + selectionOpts := PolicyMatcherForProxy(proxy).WithServices(info.Services) + for _, ns := range slices.FilterDuplicates(lookupInNamespaces) { if wasmPlugins, ok := ps.wasmPluginsByNamespace[ns]; ok { for _, plugin := range wasmPlugins { if plugin.MatchListener(selectionOpts, info) && plugin.MatchType(pluginType) { diff --git a/pilot/pkg/model/service.go b/pilot/pkg/model/service.go index bcc86b0fa40d..6151be34e830 100644 --- a/pilot/pkg/model/service.go +++ b/pilot/pkg/model/service.go @@ -887,15 +887,34 @@ type AmbientIndexes interface { type WaypointKey struct { Namespace string Hostnames []string + + Network string + Addresses []string } // WaypointKeyForProxy builds a key from a proxy to lookup func WaypointKeyForProxy(node *Proxy) WaypointKey { key := WaypointKey{ Namespace: node.ConfigNamespace, + Network: node.Metadata.Network.String(), } for _, svct := range node.ServiceTargets { key.Hostnames = append(key.Hostnames, svct.Service.Hostname.String()) + + ips := svct.Service.ClusterVIPs.GetAddressesFor(node.GetClusterID()) + // if we find autoAllocated addresses then ips should contain constants.UnspecifiedIP which should not be used + foundAutoAllocated := false + if svct.Service.AutoAllocatedIPv4Address != "" { + key.Addresses = append(key.Addresses, svct.Service.AutoAllocatedIPv4Address) + foundAutoAllocated = true + } + if svct.Service.AutoAllocatedIPv6Address != "" { + key.Addresses = append(key.Addresses, svct.Service.AutoAllocatedIPv6Address) + foundAutoAllocated = true + } + if !foundAutoAllocated { + key.Addresses = append(key.Addresses, ips...) + } } return key } @@ -1011,37 +1030,53 @@ const ( WaypointAccepted ConditionType = "WaypointAccepted" ) -type ConditionSet = map[ConditionType][]Condition +type ConditionSet = map[ConditionType]*Condition type Condition struct { - Reason string - Message string - Status bool + ObservedGeneration int64 + Reason string + Message string + Status bool +} + +func (c *Condition) Equals(v *Condition) bool { + return c.ObservedGeneration == v.ObservedGeneration && + c.Reason == v.Reason && + c.Message == v.Message && + c.Status == v.Status } func (i ServiceInfo) GetConditions() ConditionSet { - set := map[ConditionType][]Condition{ + set := ConditionSet{ // Write all conditions here, then override if we want them set. // This ensures we can properly prune the condition if its no longer needed (such as if there is no waypoint attached at all). WaypointBound: nil, } + if i.Waypoint.ResourceName != "" { - set[WaypointBound] = []Condition{ - { - Status: true, - Reason: "WaypointAccepted", - Message: fmt.Sprintf("Successfully attached to waypoint %v", i.Waypoint.ResourceName), - }, + buildMsg := strings.Builder{} + buildMsg.WriteString("Successfully attached to waypoint ") + buildMsg.WriteString(i.Waypoint.ResourceName) + + if i.Waypoint.IngressUseWaypoint { + buildMsg.WriteString(". Ingress traffic will traverse the waypoint") + } else if i.Waypoint.IngressLabelPresent { + buildMsg.WriteString(". Ingress traffic is not using the waypoint, set the istio.io/ingress-use-waypoint label to true if desired.") + } + + set[WaypointBound] = &Condition{ + Status: true, + Reason: string(WaypointAccepted), + Message: buildMsg.String(), } } else if i.Waypoint.Error != nil { - set[WaypointBound] = []Condition{ - { - Status: false, - Reason: i.Waypoint.Error.Reason, - Message: i.Waypoint.Error.Message, - }, + set[WaypointBound] = &Condition{ + Status: false, + Reason: i.Waypoint.Error.Reason, + Message: i.Waypoint.Error.Message, } } + return set } @@ -1050,6 +1085,8 @@ type WaypointBindingStatus struct { ResourceName string // IngressUseWaypoint specifies whether ingress gateways should use the waypoint for this service. IngressUseWaypoint bool + // IngressLabelPresent specifies whether the istio.io/ingress-use-waypoint label is set on the service. + IngressLabelPresent bool // Error represents some error Error *StatusMessage } @@ -1059,6 +1096,10 @@ type StatusMessage struct { Message string } +func (i WaypointBindingStatus) Equals(other WaypointBindingStatus) bool { + return i.ResourceName == other.ResourceName && i.IngressUseWaypoint == other.IngressUseWaypoint && ptr.Equal(i.Error, other.Error) +} + func (i ServiceInfo) NamespacedName() types.NamespacedName { return types.NamespacedName{Name: i.Name, Namespace: i.Namespace} } @@ -1068,7 +1109,7 @@ func (i ServiceInfo) Equals(other ServiceInfo) bool { maps.Equal(i.LabelSelector.Labels, other.LabelSelector.Labels) && maps.Equal(i.PortNames, other.PortNames) && i.Source == other.Source && - i.Waypoint == other.Waypoint + i.Waypoint.Equals(other.Waypoint) } func (i ServiceInfo) ResourceName() string { @@ -1134,7 +1175,7 @@ func (i WaypointPolicyStatus) GetStatusTarget() TypedObject { func (i WaypointPolicyStatus) GetConditions() ConditionSet { set := make(ConditionSet, 1) - set[WaypointAccepted] = []Condition{flattenConditions(i.Conditions)} + set[WaypointAccepted] = flattenConditions(i.Conditions) return set } @@ -1144,7 +1185,7 @@ func (i WaypointPolicyStatus) GetConditions() ConditionSet { // flattenConditions is a work around for the uncertain future of Ancestor in gtwapi which exists at the moment. // It is intended to take many conditions which have ancestors and condense them into a single condition so we can // retain detail in the codebase to be prepared when a canonical representation is accepted upstream. -func flattenConditions(conditions []PolicyBindingStatus) Condition { +func flattenConditions(conditions []PolicyBindingStatus) *Condition { status := false reason := WaypointPolicyReasonInvalid unboundAncestors := []string{} @@ -1153,13 +1194,15 @@ func flattenConditions(conditions []PolicyBindingStatus) Condition { // flatten causes a loss of some information and there is only 1 condition so no need to flatten if len(conditions) == 1 { c := conditions[0] - return Condition{ - Reason: c.Status.Reason, - Message: c.Status.Message, - Status: c.Bound, + return &Condition{ + ObservedGeneration: c.ObservedGeneration, + Reason: c.Status.Reason, + Message: c.Status.Message, + Status: c.Bound, } } + var highestObservedGeneration int64 for _, c := range conditions { if c.Bound { // if anything was true we consider the overall bind to be true @@ -1167,6 +1210,10 @@ func flattenConditions(conditions []PolicyBindingStatus) Condition { } else { unboundAncestors = append(unboundAncestors, c.Ancestor) } + + if c.ObservedGeneration > highestObservedGeneration { + highestObservedGeneration = c.ObservedGeneration + } } someUnbound := len(unboundAncestors) > 0 @@ -1183,7 +1230,8 @@ func flattenConditions(conditions []PolicyBindingStatus) Condition { message = fmt.Sprintf("Invalid targetRefs: %s", strings.Join(unboundAncestors, ", ")) } - return Condition{ + return &Condition{ + highestObservedGeneration, reason, message, status, @@ -1198,15 +1246,17 @@ func (i WaypointPolicyStatus) ResourceName() string { // end impl ResourceNamer type PolicyBindingStatus struct { - Ancestor string - Status *StatusMessage - Bound bool + ObservedGeneration int64 + Ancestor string + Status *StatusMessage + Bound bool } func (i PolicyBindingStatus) Equals(other PolicyBindingStatus) bool { return ptr.Equal(i.Status, other.Status) && i.Bound == other.Bound && - i.Ancestor == other.Ancestor + i.Ancestor == other.Ancestor && + i.ObservedGeneration == other.ObservedGeneration } type WorkloadAuthorization struct { @@ -1227,21 +1277,19 @@ func (i WorkloadAuthorization) GetConditions() ConditionSet { set := make(ConditionSet, 1) if i.Binding.Status != nil { - set[ZtunnelAccepted] = []Condition{ - { - Reason: i.Binding.Status.Reason, - Message: i.Binding.Status.Message, - Status: i.Binding.Bound, - }, + set[ZtunnelAccepted] = &Condition{ + ObservedGeneration: i.Binding.ObservedGeneration, + Reason: i.Binding.Status.Reason, + Message: i.Binding.Status.Message, + Status: i.Binding.Bound, } } else { message := "attached to ztunnel" - set[ZtunnelAccepted] = []Condition{ - { - Reason: "Accepted", - Message: message, - Status: i.Binding.Bound, - }, + set[ZtunnelAccepted] = &Condition{ + ObservedGeneration: i.Binding.ObservedGeneration, + Reason: "Accepted", + Message: message, + Status: i.Binding.Bound, } } diff --git a/pilot/pkg/model/sidecar.go b/pilot/pkg/model/sidecar.go index 83d3309e5101..5f1ed6a06522 100644 --- a/pilot/pkg/model/sidecar.go +++ b/pilot/pkg/model/sidecar.go @@ -500,29 +500,28 @@ func convertIstioListenerToWrapper(ps *PushContext, configNamespace string, hostsByNamespace := make(map[string]hostClassification) for _, h := range istioListener.Hosts { - parts := strings.SplitN(h, "/", 2) - if len(parts) < 2 { + if strings.Count(h, "/") != 1 { log.Errorf("Illegal host in sidecar resource: %s, host must be of form namespace/dnsName", h) continue } - if parts[0] == currentNamespace { - parts[0] = configNamespace + ns, name, _ := strings.Cut(h, "/") + if ns == currentNamespace { + ns = configNamespace } - ns := parts[0] - hName := host.Name(parts[1]) - if _, exists := hostsByNamespace[ns]; !exists { - hostsByNamespace[ns] = hostClassification{exactHosts: sets.New[host.Name](), allHosts: make([]host.Name, 0)} + hName := host.Name(name) + hc, exists := hostsByNamespace[ns] + if !exists { + hc = hostClassification{exactHosts: sets.New[host.Name](), allHosts: make([]host.Name, 0)} } // exact hosts are saved separately for map lookup if !hName.IsWildCarded() { - hostsByNamespace[ns].exactHosts.Insert(hName) + hc.exactHosts.Insert(hName) } // allHosts contains the exact hosts and wildcard hosts, // since SelectVirtualServices will use `Matches` semantic matching. - hc := hostsByNamespace[ns] hc.allHosts = append(hc.allHosts, hName) hostsByNamespace[ns] = hc } @@ -705,7 +704,6 @@ func (sc *SidecarScope) Services() []*Service { func (sc *SidecarScope) SetDestinationRulesForTesting(configs []config.Config) { sc.destinationRulesByNames = make(map[types.NamespacedName]*config.Config) for _, c := range configs { - c := c sc.destinationRulesByNames[types.NamespacedName{Name: c.Name, Namespace: c.Namespace}] = &c } } diff --git a/pilot/pkg/model/telemetry.go b/pilot/pkg/model/telemetry.go index 2e8c1f829d59..1f23d8e86089 100644 --- a/pilot/pkg/model/telemetry.go +++ b/pilot/pkg/model/telemetry.go @@ -204,6 +204,7 @@ type TracingSpec struct { RandomSamplingPercentage *float64 CustomTags map[string]*tpb.Tracing_CustomTag UseRequestIDForTraceSampling bool + EnableIstioTags bool } type LoggingConfig struct { @@ -238,7 +239,7 @@ func workloadMode(class networking.ListenerClass) tpb.WorkloadMode { // If nil or empty configuration is returned, access logs are not configured via Telemetry and should use fallback mechanisms. // If access logging is explicitly disabled, a configuration with disabled set to true is returned. func (t *Telemetries) AccessLogging(push *PushContext, proxy *Proxy, class networking.ListenerClass, svc *Service) []LoggingConfig { - ct := t.applicableTelemetries(proxy, nil) + ct := t.applicableTelemetries(proxy, svc) if len(ct.Logging) == 0 && len(t.meshConfig.GetDefaultProviders().GetAccessLogging()) == 0 { // No Telemetry API configured, fall back to legacy mesh config setting return nil @@ -269,7 +270,7 @@ func (t *Telemetries) AccessLogging(push *PushContext, proxy *Proxy, class netwo Disabled: v.Disabled, } - al := telemetryAccessLog(push, fp) + al := telemetryAccessLog(push, proxy, fp) if al == nil { // stackdriver will be handled in HTTPFilters/TCPFilters continue @@ -296,8 +297,8 @@ func (t *Telemetries) Tracing(proxy *Proxy, svc *Service) *TracingConfig { return nil } - clientSpec := TracingSpec{UseRequestIDForTraceSampling: true} - serverSpec := TracingSpec{UseRequestIDForTraceSampling: true} + clientSpec := TracingSpec{UseRequestIDForTraceSampling: true, EnableIstioTags: true} + serverSpec := TracingSpec{UseRequestIDForTraceSampling: true, EnableIstioTags: true} if hasDefaultProvider { // todo: what do we want to do with more than one default provider? @@ -353,6 +354,11 @@ func (t *Telemetries) Tracing(proxy *Proxy, svc *Service) *TracingConfig { spec.UseRequestIDForTraceSampling = m.UseRequestIdForTraceSampling.Value } } + if m.EnableIstioTags != nil { + for _, spec := range specs { + spec.EnableIstioTags = m.EnableIstioTags.Value + } + } } // If no provider is configured (and retrieved) for the tracing specs, diff --git a/pilot/pkg/model/telemetry_logging.go b/pilot/pkg/model/telemetry_logging.go index c19c3c357914..2fc9153e2ef6 100644 --- a/pilot/pkg/model/telemetry_logging.go +++ b/pilot/pkg/model/telemetry_logging.go @@ -97,7 +97,7 @@ var ( "request_id": {Kind: &structpb.Value_StringValue{StringValue: "%REQ(X-REQUEST-ID)%"}}, "authority": {Kind: &structpb.Value_StringValue{StringValue: "%REQ(:AUTHORITY)%"}}, "upstream_host": {Kind: &structpb.Value_StringValue{StringValue: "%UPSTREAM_HOST%"}}, - "upstream_cluster": {Kind: &structpb.Value_StringValue{StringValue: "%UPSTREAM_CLUSTER%"}}, + "upstream_cluster": {Kind: &structpb.Value_StringValue{StringValue: "%UPSTREAM_CLUSTER_RAW%"}}, "upstream_local_address": {Kind: &structpb.Value_StringValue{StringValue: "%UPSTREAM_LOCAL_ADDRESS%"}}, "downstream_local_address": {Kind: &structpb.Value_StringValue{StringValue: "%DOWNSTREAM_LOCAL_ADDRESS%"}}, "downstream_remote_address": {Kind: &structpb.Value_StringValue{StringValue: "%DOWNSTREAM_REMOTE_ADDRESS%"}}, @@ -110,6 +110,8 @@ var ( // We need to propagate these as part of access log service stream // Logging them by default on the console may be an issue as the base64 encoded string is bound to be a big one. // But end users can certainly configure it on their own via the meshConfig using the %FILTER_STATE% macro. + // Related to https://github.com/istio/proxy/pull/5825, start from 1.24, Istio use new filter state key. + envoyStateToLog = []string{"upstream_peer", "downstream_peer"} envoyWasmStateToLog = []string{"wasm.upstream_peer", "wasm.upstream_peer_id", "wasm.downstream_peer", "wasm.downstream_peer_id"} // reqWithoutQueryFormatter configures additional formatters needed for some of the format strings like "REQ_WITHOUT_QUERY" @@ -138,7 +140,7 @@ var ( // STOP. DO NOT UPDATE THIS WITHOUT UPDATING telemetryAccessLog. const telemetryAccessLogHandled = 14 -func telemetryAccessLog(push *PushContext, fp *meshconfig.MeshConfig_ExtensionProvider) *accesslog.AccessLog { +func telemetryAccessLog(push *PushContext, proxy *Proxy, fp *meshconfig.MeshConfig_ExtensionProvider) *accesslog.AccessLog { var al *accesslog.AccessLog switch prov := fp.Provider.(type) { case *meshconfig.MeshConfig_ExtensionProvider_EnvoyFileAccessLog: @@ -149,11 +151,11 @@ func telemetryAccessLog(push *PushContext, fp *meshconfig.MeshConfig_ExtensionPr al = fileAccessLogFromTelemetry(prov.EnvoyFileAccessLog) } case *meshconfig.MeshConfig_ExtensionProvider_EnvoyHttpAls: - al = httpGrpcAccessLogFromTelemetry(push, prov.EnvoyHttpAls) + al = httpGrpcAccessLogFromTelemetry(push, proxy, prov.EnvoyHttpAls) case *meshconfig.MeshConfig_ExtensionProvider_EnvoyTcpAls: - al = tcpGrpcAccessLogFromTelemetry(push, prov.EnvoyTcpAls) + al = tcpGrpcAccessLogFromTelemetry(push, proxy, prov.EnvoyTcpAls) case *meshconfig.MeshConfig_ExtensionProvider_EnvoyOtelAls: - al = openTelemetryLog(push, prov.EnvoyOtelAls) + al = openTelemetryLog(push, proxy, prov.EnvoyOtelAls) case *meshconfig.MeshConfig_ExtensionProvider_EnvoyExtAuthzHttp, *meshconfig.MeshConfig_ExtensionProvider_EnvoyExtAuthzGrpc, *meshconfig.MeshConfig_ExtensionProvider_Zipkin, @@ -172,13 +174,23 @@ func telemetryAccessLog(push *PushContext, fp *meshconfig.MeshConfig_ExtensionPr return al } -func tcpGrpcAccessLogFromTelemetry(push *PushContext, prov *meshconfig.MeshConfig_ExtensionProvider_EnvoyTcpGrpcV3LogProvider) *accesslog.AccessLog { +func filterStateObjectsToLog(proxy *Proxy) []string { + if proxy.VersionGreaterOrEqual(&IstioVersion{Major: 1, Minor: 24, Patch: 0}) { + return envoyStateToLog + } + + return envoyWasmStateToLog +} + +func tcpGrpcAccessLogFromTelemetry(push *PushContext, proxy *Proxy, + prov *meshconfig.MeshConfig_ExtensionProvider_EnvoyTcpGrpcV3LogProvider, +) *accesslog.AccessLog { logName := TCPEnvoyAccessLogFriendlyName if prov != nil && prov.LogName != "" { logName = prov.LogName } - filterObjects := envoyWasmStateToLog + filterObjects := filterStateObjectsToLog(proxy) if len(prov.FilterStateObjectsToLog) != 0 { filterObjects = prov.FilterStateObjectsToLog } @@ -332,13 +344,15 @@ func accessLogTextFormatters(text string) []*core.TypedExtensionConfig { return formatters } -func httpGrpcAccessLogFromTelemetry(push *PushContext, prov *meshconfig.MeshConfig_ExtensionProvider_EnvoyHttpGrpcV3LogProvider) *accesslog.AccessLog { +func httpGrpcAccessLogFromTelemetry(push *PushContext, proxy *Proxy, + prov *meshconfig.MeshConfig_ExtensionProvider_EnvoyHttpGrpcV3LogProvider, +) *accesslog.AccessLog { logName := HTTPEnvoyAccessLogFriendlyName if prov != nil && prov.LogName != "" { logName = prov.LogName } - filterObjects := envoyWasmStateToLog + filterObjects := filterStateObjectsToLog(proxy) if len(prov.FilterStateObjectsToLog) != 0 { filterObjects = prov.FilterStateObjectsToLog } @@ -443,7 +457,7 @@ func FileAccessLogFromMeshConfig(path string, mesh *meshconfig.MeshConfig) *acce return al } -func openTelemetryLog(pushCtx *PushContext, +func openTelemetryLog(pushCtx *PushContext, proxy *Proxy, provider *meshconfig.MeshConfig_ExtensionProvider_EnvoyOpenTelemetryLogProvider, ) *accesslog.AccessLog { hostname, cluster, err := clusterLookupFn(pushCtx, provider.Service, int(provider.Port)) @@ -468,7 +482,7 @@ func openTelemetryLog(pushCtx *PushContext, labels = provider.LogFormat.Labels } - cfg := buildOpenTelemetryAccessLogConfig(logName, hostname, cluster, f, labels) + cfg := buildOpenTelemetryAccessLogConfig(proxy, logName, hostname, cluster, f, labels) return &accesslog.AccessLog{ Name: OtelEnvoyALSName, @@ -476,7 +490,9 @@ func openTelemetryLog(pushCtx *PushContext, } } -func buildOpenTelemetryAccessLogConfig(logName, hostname, clusterName, format string, labels *structpb.Struct) *otelaccesslog.OpenTelemetryAccessLogConfig { +func buildOpenTelemetryAccessLogConfig(proxy *Proxy, + logName, hostname, clusterName, format string, labels *structpb.Struct, +) *otelaccesslog.OpenTelemetryAccessLogConfig { cfg := &otelaccesslog.OpenTelemetryAccessLogConfig{ CommonConfig: &grpcaccesslog.CommonGrpcAccessLogConfig{ LogName: logName, @@ -489,7 +505,7 @@ func buildOpenTelemetryAccessLogConfig(logName, hostname, clusterName, format st }, }, TransportApiVersion: core.ApiVersion_V3, - FilterStateObjectsToLog: envoyWasmStateToLog, + FilterStateObjectsToLog: filterStateObjectsToLog(proxy), }, DisableBuiltinLabels: true, } diff --git a/pilot/pkg/model/telemetry_logging_test.go b/pilot/pkg/model/telemetry_logging_test.go index f831d3951544..c04380941c76 100644 --- a/pilot/pkg/model/telemetry_logging_test.go +++ b/pilot/pkg/model/telemetry_logging_test.go @@ -959,6 +959,13 @@ func TestAccessLoggingCache(t *testing.T) { } func TestBuildOpenTelemetryAccessLogConfig(t *testing.T) { + sidecar := &Proxy{ + ConfigNamespace: "default", + Labels: map[string]string{"app": "test"}, + Metadata: &NodeMetadata{}, + IstioVersion: &IstioVersion{Major: 1, Minor: 23}, + } + fakeCluster := "outbound|55680||otel-collector.monitoring.svc.cluster.local" fakeAuthority := "otel-collector.monitoring.svc.cluster.local" for _, tc := range []struct { @@ -1042,7 +1049,7 @@ func TestBuildOpenTelemetryAccessLogConfig(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - got := buildOpenTelemetryAccessLogConfig(tc.logName, tc.hostname, tc.clusterName, tc.body, tc.labels) + got := buildOpenTelemetryAccessLogConfig(sidecar, tc.logName, tc.hostname, tc.clusterName, tc.body, tc.labels) assert.Equal(t, tc.expected, got) }) } @@ -1430,6 +1437,13 @@ func TestTelemetryAccessLog(t *testing.T) { }, } + sidecar := &Proxy{ + ConfigNamespace: "default", + Labels: map[string]string{"app": "test"}, + Metadata: &NodeMetadata{}, + IstioVersion: &IstioVersion{Major: 1, Minor: 23}, + } + for _, tc := range []struct { name string ctx *PushContext @@ -1597,7 +1611,7 @@ func TestTelemetryAccessLog(t *testing.T) { } push.Mesh = tc.meshConfig - got := telemetryAccessLog(push, tc.fp) + got := telemetryAccessLog(push, sidecar, tc.fp) if got == nil { t.Fatal("get nil accesslog") } @@ -1912,3 +1926,36 @@ func TestAccessLogFormatters(t *testing.T) { }) } } + +func TestFilterStateObjectsToLog(t *testing.T) { + cases := []struct { + proxy *Proxy + expected []string + }{ + { + proxy: &Proxy{ + IstioVersion: &IstioVersion{Major: 1, Minor: 23}, + }, + expected: []string{"wasm.upstream_peer", "wasm.upstream_peer_id", "wasm.downstream_peer", "wasm.downstream_peer_id"}, + }, + { + proxy: &Proxy{ + IstioVersion: &IstioVersion{Major: 1, Minor: 24}, + }, + expected: []string{"upstream_peer", "downstream_peer"}, + }, + { + proxy: &Proxy{ + IstioVersion: &IstioVersion{Major: 1, Minor: 25}, + }, + expected: []string{"upstream_peer", "downstream_peer"}, + }, + } + + for _, tc := range cases { + t.Run("", func(t *testing.T) { + got := filterStateObjectsToLog(tc.proxy) + assert.Equal(t, tc.expected, got) + }) + } +} diff --git a/pilot/pkg/model/telemetry_test.go b/pilot/pkg/model/telemetry_test.go index d2e4d00203bd..e441a29dbf19 100644 --- a/pilot/pkg/model/telemetry_test.go +++ b/pilot/pkg/model/telemetry_test.go @@ -234,11 +234,13 @@ func newTracingConfig(providerName string, disabled bool) *TracingConfig { Provider: &meshconfig.MeshConfig_ExtensionProvider{Name: providerName}, Disabled: disabled, UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, ServerSpec: TracingSpec{ Provider: &meshconfig.MeshConfig_ExtensionProvider{Name: providerName}, Disabled: disabled, UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, } } @@ -295,6 +297,7 @@ func TestTracing(t *testing.T) { "bar": {}, }, UseRequestIdForTraceSampling: &wrappers.BoolValue{Value: false}, + EnableIstioTags: &wrappers.BoolValue{Value: false}, }, }, } @@ -307,6 +310,7 @@ func TestTracing(t *testing.T) { "baz": {}, }, UseRequestIdForTraceSampling: &wrappers.BoolValue{Value: true}, + EnableIstioTags: &wrappers.BoolValue{Value: true}, }, }, } @@ -426,8 +430,8 @@ func TestTracing(t *testing.T) { sidecar, []string{"envoy"}, &TracingConfig{ - ClientSpec: TracingSpec{Disabled: true, UseRequestIDForTraceSampling: true}, - ServerSpec: TracingSpec{Disabled: true, UseRequestIDForTraceSampling: true}, + ClientSpec: TracingSpec{Disabled: true, UseRequestIDForTraceSampling: true, EnableIstioTags: true}, + ServerSpec: TracingSpec{Disabled: true, UseRequestIDForTraceSampling: true, EnableIstioTags: true}, }, }, { @@ -452,6 +456,7 @@ func TestTracing(t *testing.T) { "bar": {}, }, UseRequestIDForTraceSampling: false, + EnableIstioTags: false, }, }, }, @@ -468,6 +473,7 @@ func TestTracing(t *testing.T) { "baz": {}, }, UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, ServerSpec: TracingSpec{ Provider: &meshconfig.MeshConfig_ExtensionProvider{Name: "envoy"}, CustomTags: map[string]*tpb.Tracing_CustomTag{ @@ -475,6 +481,7 @@ func TestTracing(t *testing.T) { "baz": {}, }, UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, }, }, @@ -495,6 +502,7 @@ func TestTracing(t *testing.T) { "baz": {}, }, UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, ServerSpec: TracingSpec{ Provider: &meshconfig.MeshConfig_ExtensionProvider{Name: "envoy"}, @@ -504,6 +512,7 @@ func TestTracing(t *testing.T) { "baz": {}, }, UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, }, }, @@ -522,10 +531,12 @@ func TestTracing(t *testing.T) { }, RandomSamplingPercentage: ptr.Of(99.9), UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, ServerSpec: TracingSpec{ Provider: &meshconfig.MeshConfig_ExtensionProvider{Name: "envoy"}, UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, }, }, @@ -538,11 +549,13 @@ func TestTracing(t *testing.T) { ClientSpec: TracingSpec{ Provider: &meshconfig.MeshConfig_ExtensionProvider{Name: "envoy"}, UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, ServerSpec: TracingSpec{ Provider: &meshconfig.MeshConfig_ExtensionProvider{Name: "envoy"}, Disabled: true, UseRequestIDForTraceSampling: true, + EnableIstioTags: true, }, }, }, diff --git a/pilot/pkg/networking/core/accesslog.go b/pilot/pkg/networking/core/accesslog.go index b068a1fb2ef6..96baf8fbbf4f 100644 --- a/pilot/pkg/networking/core/accesslog.go +++ b/pilot/pkg/networking/core/accesslog.go @@ -49,7 +49,8 @@ var ( // We need to propagate these as part of access log service stream // Logging them by default on the console may be an issue as the base64 encoded string is bound to be a big one. // But end users can certainly configure it on their own via the meshConfig using the %FILTER_STATE% macro. - envoyWasmStateToLog = []string{"wasm.upstream_peer", "wasm.upstream_peer_id", "wasm.downstream_peer", "wasm.downstream_peer_id"} + envoyWasmStateToLog = []string{"upstream_peer", "downstream_peer", // start from 1.24.0 + "wasm.upstream_peer", "wasm.upstream_peer_id", "wasm.downstream_peer", "wasm.downstream_peer_id"} // accessLogBuilder is used to set accessLog to filters accessLogBuilder = newAccessLogBuilder() diff --git a/pilot/pkg/networking/core/accesslog_test.go b/pilot/pkg/networking/core/accesslog_test.go index bb9feb00f7b9..c753dc0f57c8 100644 --- a/pilot/pkg/networking/core/accesslog_test.go +++ b/pilot/pkg/networking/core/accesslog_test.go @@ -98,7 +98,6 @@ func TestListenerAccessLog(t *testing.T) { wantFormat: model.EnvoyTextLogFormat, }, } { - tc := tc t.Run(tc.name, func(t *testing.T) { accessLogBuilder.reset() // Update MeshConfig diff --git a/pilot/pkg/networking/core/cluster_builder.go b/pilot/pkg/networking/core/cluster_builder.go index f88d35f4ab0d..bd14dd5c70a8 100644 --- a/pilot/pkg/networking/core/cluster_builder.go +++ b/pilot/pkg/networking/core/cluster_builder.go @@ -22,6 +22,7 @@ import ( cluster "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" endpoint "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" + cares "github.com/envoyproxy/go-control-plane/envoy/extensions/network/dns_resolver/cares/v3" http "github.com/envoyproxy/go-control-plane/envoy/extensions/upstreams/http/v3" discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" anypb "google.golang.org/protobuf/types/known/anypb" @@ -43,7 +44,6 @@ import ( "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/log" "istio.io/istio/pkg/security" - "istio.io/istio/pkg/util/protomarshal" "istio.io/istio/pkg/util/sets" ) @@ -301,7 +301,6 @@ func (cb *ClusterBuilder) buildCluster(name string, discoveryType cluster.Cluste switch discoveryType { case cluster.Cluster_STRICT_DNS, cluster.Cluster_LOGICAL_DNS: - c.DnsJitter = durationpb.New(features.DNSJitterDurationEnv) if networkutil.AllIPv4(cb.proxyIPAddresses) { // IPv4 only c.DnsLookupFamily = cluster.Cluster_V4_ONLY @@ -324,7 +323,20 @@ func (cb *ClusterBuilder) buildCluster(name string, discoveryType cluster.Cluste c.DnsLookupFamily = cluster.Cluster_V4_ONLY } } - c.DnsRefreshRate = protomarshal.ShallowClone(cb.req.Push.Mesh.DnsRefreshRate) + dnsResolverConfig, err := anypb.New(&cares.CaresDnsResolverConfig{ + UdpMaxQueries: wrappers.UInt32(features.PilotDNSCaresUDPMaxQueries), + }) + if err != nil { + log.Warnf("Could not create typed_dns_cluster_config for %s: %s. Using default configuration.", name, err) + } else { + c.TypedDnsResolverConfig = &core.TypedExtensionConfig{ + Name: "envoy.network.dns_resolver.cares", + TypedConfig: dnsResolverConfig, + } + } + // 0 disables jitter. + c.DnsJitter = durationpb.New(features.PilotDNSJitterDurationEnv) + c.DnsRefreshRate = cb.req.Push.Mesh.DnsRefreshRate c.RespectDnsTtl = true // we want to run all the STATIC parts as well to build the load assignment fallthrough @@ -340,13 +352,11 @@ func (cb *ClusterBuilder) buildCluster(name string, discoveryType cluster.Cluste Endpoints: localityLbEndpoints, } case cluster.Cluster_ORIGINAL_DST: - if features.PassthroughTargetPort { - if override, f := service.Attributes.PassthroughTargetPorts[uint32(port.Port)]; f { - c.LbConfig = &cluster.Cluster_OriginalDstLbConfig_{ - OriginalDstLbConfig: &cluster.Cluster_OriginalDstLbConfig{ - UpstreamPortOverride: wrappers.UInt32(override), - }, - } + if override, f := service.Attributes.PassthroughTargetPorts[uint32(port.Port)]; f { + c.LbConfig = &cluster.Cluster_OriginalDstLbConfig_{ + OriginalDstLbConfig: &cluster.Cluster_OriginalDstLbConfig{ + UpstreamPortOverride: wrappers.UInt32(override), + }, } } } @@ -515,7 +525,7 @@ func (cb *ClusterBuilder) buildBlackHoleCluster() *cluster.Cluster { c := &cluster.Cluster{ Name: util.BlackHoleCluster, ClusterDiscoveryType: &cluster.Cluster_Type{Type: cluster.Cluster_STATIC}, - ConnectTimeout: protomarshal.ShallowClone(cb.req.Push.Mesh.ConnectTimeout), + ConnectTimeout: cb.req.Push.Mesh.ConnectTimeout, LbPolicy: cluster.Cluster_ROUND_ROBIN, } c.AltStatName = util.DelimitedStatsPrefix(util.BlackHoleCluster) @@ -528,7 +538,7 @@ func (cb *ClusterBuilder) buildDefaultPassthroughCluster() *cluster.Cluster { cluster := &cluster.Cluster{ Name: util.PassthroughCluster, ClusterDiscoveryType: &cluster.Cluster_Type{Type: cluster.Cluster_ORIGINAL_DST}, - ConnectTimeout: protomarshal.ShallowClone(cb.req.Push.Mesh.ConnectTimeout), + ConnectTimeout: cb.req.Push.Mesh.ConnectTimeout, LbPolicy: cluster.Cluster_CLUSTER_PROVIDED, TypedExtensionProtocolOptions: map[string]*anypb.Any{ v3.HttpProtocolOptionsType: passthroughHttpProtocolOptions, @@ -735,7 +745,7 @@ func (cb *ClusterBuilder) buildExternalSDSCluster(addr string) *cluster.Cluster c := &cluster.Cluster{ Name: security.SDSExternalClusterName, ClusterDiscoveryType: &cluster.Cluster_Type{Type: cluster.Cluster_STATIC}, - ConnectTimeout: protomarshal.ShallowClone(cb.req.Push.Mesh.ConnectTimeout), + ConnectTimeout: cb.req.Push.Mesh.ConnectTimeout, LoadAssignment: &endpoint.ClusterLoadAssignment{ ClusterName: security.SDSExternalClusterName, Endpoints: []*endpoint.LocalityLbEndpoints{ diff --git a/pilot/pkg/networking/core/cluster_builder_test.go b/pilot/pkg/networking/core/cluster_builder_test.go index aa4b57f6b92e..0959389a6ef9 100644 --- a/pilot/pkg/networking/core/cluster_builder_test.go +++ b/pilot/pkg/networking/core/cluster_builder_test.go @@ -27,6 +27,7 @@ import ( cluster "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" endpoint "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" + cares "github.com/envoyproxy/go-control-plane/envoy/extensions/network/dns_resolver/cares/v3" tls "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" http "github.com/envoyproxy/go-control-plane/envoy/extensions/upstreams/http/v3" "github.com/google/go-cmp/cmp" @@ -1311,6 +1312,85 @@ func TestBuildDefaultCluster(t *testing.T) { } } +func TestClusterDnsConfig(t *testing.T) { + servicePort := &model.Port{ + Name: "default", + Port: 8080, + Protocol: protocol.HTTP, + } + + endpoints := []*endpoint.LocalityLbEndpoints{ + { + Locality: &core.Locality{ + Region: "region1", + Zone: "zone1", + SubZone: "subzone1", + }, + LbEndpoints: []*endpoint.LbEndpoint{}, + LoadBalancingWeight: &wrappers.UInt32Value{ + Value: 1, + }, + Priority: 0, + }, + } + + cases := []struct { + name string + udpMaxQueries uint32 + dnsJitter time.Duration + proxy *model.Proxy + }{ + { + name: "Dual stack proxy", + udpMaxQueries: 99, + dnsJitter: 0 * time.Millisecond, + proxy: &dualStackProxy, + }, + { + name: "IPv4 proxy", + udpMaxQueries: 0, + dnsJitter: 1 * time.Millisecond, + proxy: getProxy(), + }, + { + name: "IPv6 proxy", + udpMaxQueries: 1, + dnsJitter: 5 * time.Millisecond, + proxy: getIPv6Proxy(), + }, + } + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + test.SetForTest(t, &features.PilotDNSCaresUDPMaxQueries, tt.udpMaxQueries) + test.SetForTest(t, &features.PilotDNSJitterDurationEnv, tt.dnsJitter) + mesh := testMesh() + cg := NewConfigGenTest(t, TestOptions{MeshConfig: mesh}) + cb := NewClusterBuilder(cg.SetupProxy(tt.proxy), &model.PushRequest{Push: cg.PushContext()}, nil) + service := &model.Service{ + Ports: model.PortList{ + servicePort, + }, + Hostname: "host", + MeshExternal: false, + Attributes: model.ServiceAttributes{Name: "svc", Namespace: "default"}, + } + defaultCluster := cb.buildCluster("my-cluster", cluster.Cluster_STRICT_DNS, endpoints, model.TrafficDirectionOutbound, servicePort, service, nil, "") + c := defaultCluster.build() + + dnsConfig := new(cares.CaresDnsResolverConfig) + if err := c.TypedDnsResolverConfig.TypedConfig.UnmarshalTo(dnsConfig); err != nil { + t.Errorf("Unexpected TypedDnsResolverConfig type, expected cares dns resolver, got: %v", c.TypedDnsResolverConfig.TypedConfig.TypeUrl) + } + if dnsConfig.UdpMaxQueries.Value != tt.udpMaxQueries { + t.Errorf("Unexpected UdpMaxQueries, expected : %v, got: %v", tt.udpMaxQueries, dnsConfig.UdpMaxQueries.Value) + } + if c.DnsJitter.AsDuration() != tt.dnsJitter { + t.Errorf("Unexpected dnsJitter, expected : %v, got: %v", tt.dnsJitter, c.DnsJitter.AsDuration()) + } + }) + } +} + func TestClusterDnsLookupFamily(t *testing.T) { servicePort := &model.Port{ Name: "default", @@ -1410,9 +1490,6 @@ func TestClusterDnsLookupFamily(t *testing.T) { if c.DnsLookupFamily != tt.expectedFamily { t.Errorf("Unexpected DnsLookupFamily, got: %v, want: %v", c.DnsLookupFamily, tt.expectedFamily) } - if c.DnsJitter.AsDuration() <= 0 { - t.Errorf("Unexpected DnsJitter, got: %v, want: positive", c.DnsJitter.AsDuration()) - } }) } } @@ -2474,6 +2551,18 @@ func TestShouldH2Upgrade(t *testing.T) { }, upgrade: false, }, + { + name: "mesh upgrade - dr useClientProtocol", + clusterName: "bar", + port: &model.Port{Protocol: protocol.HTTP}, + mesh: &meshconfig.MeshConfig{H2UpgradePolicy: meshconfig.MeshConfig_UPGRADE}, + connectionPool: &networking.ConnectionPoolSettings{ + Http: &networking.ConnectionPoolSettings_HTTPSettings{ + UseClientProtocol: true, + }, + }, + upgrade: false, + }, { name: "non-http", clusterName: "bar", diff --git a/pilot/pkg/networking/core/cluster_traffic_policy.go b/pilot/pkg/networking/core/cluster_traffic_policy.go index 28c391e95cbe..46d789e8a0a7 100644 --- a/pilot/pkg/networking/core/cluster_traffic_policy.go +++ b/pilot/pkg/networking/core/cluster_traffic_policy.go @@ -197,6 +197,12 @@ func shouldH2Upgrade(clusterName string, port *model.Port, mesh *meshconfig.Mesh // Upgrade if tls.GetMode() == networking.TLSSettings_ISTIO_MUTUAL if connectionPool != nil && connectionPool.Http != nil { override := connectionPool.Http.H2UpgradePolicy + // If useClientProtocol is set, do not upgrade + if connectionPool.Http.UseClientProtocol { + log.Debugf("Not upgrading cluster because useClientProtocol is set: %v (%v %v)", + clusterName, mesh.H2UpgradePolicy, override) + return false + } // If user wants an upgrade at destination rule/port level that means he is sure that // it is a Http port - upgrade in such case. This is useful incase protocol sniffing is // enabled and user wants to upgrade/preserve http protocol from client. diff --git a/pilot/pkg/networking/core/gateway.go b/pilot/pkg/networking/core/gateway.go index cc0ee28c7b61..9a74dd0f6412 100644 --- a/pilot/pkg/networking/core/gateway.go +++ b/pilot/pkg/networking/core/gateway.go @@ -503,6 +503,7 @@ func (configgen *ConfigGeneratorImpl) buildGatewayHTTPRouteConfig(node *model.Pr if !server.GetTls().GetHttpsRedirect() { continue } + hostname = strings.ToLower(hostname) if vHost, exists := vHostDedupMap[host.Name(hostname)]; exists { vHost.RequireTls = route.VirtualHost_ALL continue diff --git a/pilot/pkg/networking/core/gateway_test.go b/pilot/pkg/networking/core/gateway_test.go index ae1feb14cc05..0a830f5ac6db 100644 --- a/pilot/pkg/networking/core/gateway_test.go +++ b/pilot/pkg/networking/core/gateway_test.go @@ -2156,7 +2156,7 @@ func TestGatewayHTTPRouteConfig(t *testing.T) { Selector: map[string]string{"istio": "ingressgateway"}, Servers: []*networking.Server{ { - Hosts: []string{"example.org"}, + Hosts: []string{"Example.org"}, Port: &networking.Port{Name: "http", Number: 80, Protocol: "HTTP"}, Tls: &networking.ServerTLSSettings{HttpsRedirect: true}, }, diff --git a/pilot/pkg/networking/core/httproute.go b/pilot/pkg/networking/core/httproute.go index b5f16df0a160..90b89106be74 100644 --- a/pilot/pkg/networking/core/httproute.go +++ b/pilot/pkg/networking/core/httproute.go @@ -775,13 +775,6 @@ func mergeAllVirtualHosts(vHostPortMap map[int][]*route.VirtualHost) []*route.Vi return virtualHosts } -func min(a, b int) int { - if a < b { - return a - } - return b -} - // getUniqueAndSharedDNSDomain computes the unique and shared DNS suffix from a FQDN service name and // the proxy's local domain with namespace. This is especially useful in Kubernetes environments, where // a two services can have same name in different namespaces (e.g., foo.ns1.svc.cluster.local, diff --git a/pilot/pkg/networking/core/httproute_test.go b/pilot/pkg/networking/core/httproute_test.go index 1b595f9cd704..3036e26e997d 100644 --- a/pilot/pkg/networking/core/httproute_test.go +++ b/pilot/pkg/networking/core/httproute_test.go @@ -369,7 +369,6 @@ func TestGenerateVirtualHostDomains(t *testing.T) { } for _, c := range cases { - c := c t.Run(c.name, func(t *testing.T) { test.SetForTest[bool](t, &features.EnableDualStack, c.enableDualStack) testFn(t, c.service, c.port, c.node, c.want) diff --git a/pilot/pkg/networking/core/listener.go b/pilot/pkg/networking/core/listener.go index d1b6eb526c23..4528f74ba62c 100644 --- a/pilot/pkg/networking/core/listener.go +++ b/pilot/pkg/networking/core/listener.go @@ -585,15 +585,7 @@ func buildListenerFromEntry(builder *ListenerBuilder, le *outboundListenerEntry, } } - // We add a TLS inspector when http inspector is needed for outbound only. This - // is because if we ever set ALPN in the match without - // transport_protocol=raw_buffer, Envoy will automatically inject a tls - // inspector: https://github.com/envoyproxy/envoy/issues/13601. This leads to - // excessive logging and loss of control over the config. For inbound this is not - // needed, since we are explicitly setting transport protocol in every single - // match. We can do this for outbound as well, at which point this could be - // removed, but have not yet - if needTLSInspector || needHTTPInspector { + if needTLSInspector { l.ListenerFilters = append(l.ListenerFilters, xdsfilters.TLSInspector) } diff --git a/pilot/pkg/networking/core/listener_test.go b/pilot/pkg/networking/core/listener_test.go index 2caf0990fe59..f6133a7d8ec7 100644 --- a/pilot/pkg/networking/core/listener_test.go +++ b/pilot/pkg/networking/core/listener_test.go @@ -1810,7 +1810,7 @@ func testOutboundListenerConflict(t *testing.T, services ...*model.Service) { } verifyHTTPFilterChainMatch(t, listeners[0].FilterChains[0]) - verifyListenerFilters(t, listeners[0].ListenerFilters) + verifyHTTPListenerFilters(t, listeners[0].ListenerFilters) if listeners[0].ListenerFiltersTimeout.GetSeconds() != 5 { t.Fatalf("expected timeout 5s, found ListenerFiltersTimeout %v", @@ -1836,7 +1836,7 @@ func testOutboundListenerConflict(t *testing.T, services ...*model.Service) { http := getHTTPFilterChain(t, listeners[0]) verifyHTTPFilterChainMatch(t, http) - verifyListenerFilters(t, listeners[0].ListenerFilters) + verifyHTTPListenerFilters(t, listeners[0].ListenerFilters) if listeners[0].ListenerFiltersTimeout == nil { t.Fatalf("expected timeout, found ContinueOnListenerFiltersTimeout %v, ListenerFiltersTimeout %v", @@ -2093,13 +2093,12 @@ func testInboundListenerConfigWithoutService(t *testing.T, proxy *model.Proxy) { verifyFilterChainMatch(t, l) } -func verifyListenerFilters(t *testing.T, lfilters []*listener.ListenerFilter) { +func verifyHTTPListenerFilters(t *testing.T, lfilters []*listener.ListenerFilter) { t.Helper() - if len(lfilters) != 2 { - t.Fatalf("expected %d listener filter, found %d", 2, len(lfilters)) + if len(lfilters) != 1 { + t.Fatalf("expected %d listener filter, found %d", 1, len(lfilters)) } - if lfilters[0].Name != wellknown.TLSInspector || - lfilters[1].Name != wellknown.HTTPInspector { + if lfilters[0].Name != wellknown.HTTPInspector { t.Fatalf("expected listener filters not found, got %v", lfilters) } } @@ -2208,7 +2207,7 @@ func testOutboundListenerConfigWithSidecar(t *testing.T, services ...*model.Serv } verifyHTTPFilterChainMatch(t, l.FilterChains[0]) - verifyListenerFilters(t, l.ListenerFilters) + verifyHTTPListenerFilters(t, l.ListenerFilters) if l := findListenerByPort(listeners, 3306); !isMysqlListener(l) { t.Fatalf("expected MySQL listener on port 3306, found %v", l) @@ -2231,7 +2230,7 @@ func testOutboundListenerConfigWithSidecar(t *testing.T, services ...*model.Serv } verifyHTTPFilterChainMatch(t, l.FilterChains[0]) - verifyListenerFilters(t, l.ListenerFilters) + verifyHTTPListenerFilters(t, l.ListenerFilters) } } @@ -2340,15 +2339,16 @@ func TestHttpProxyListener(t *testing.T) { m.ProxyHttpPort = 15007 listeners := buildListeners(t, TestOptions{MeshConfig: m}, nil) httpProxy := xdstest.ExtractListener("127.0.0.1_15007", listeners) - t.Log(xdstest.Dump(t, httpProxy)) f := httpProxy.FilterChains[0].Filters[0] cfg, _ := conversion.MessageToStruct(f.GetTypedConfig()) if httpProxy.Address.GetSocketAddress().GetPortValue() != 15007 { + t.Log(xdstest.Dump(t, httpProxy)) t.Fatalf("expected http proxy is not listening on %d, but on port %d", 15007, httpProxy.Address.GetSocketAddress().GetPortValue()) } if !strings.HasPrefix(cfg.Fields["stat_prefix"].GetStringValue(), "outbound_") { + t.Log(xdstest.Dump(t, httpProxy)) t.Fatalf("expected http proxy stat prefix to have outbound, %s", cfg.Fields["stat_prefix"].GetStringValue()) } } @@ -2761,7 +2761,7 @@ func TestOutboundListenerConfig_TCPFailThrough(t *testing.T) { verifyHTTPFilterChainMatch(t, l.FilterChains[0]) verifyPassThroughTCPFilterChain(t, l.DefaultFilterChain) - verifyListenerFilters(t, l.ListenerFilters) + verifyHTTPListenerFilters(t, l.ListenerFilters) } func verifyPassThroughTCPFilterChain(t *testing.T, fc *listener.FilterChain) { diff --git a/pilot/pkg/networking/core/listener_waypoint.go b/pilot/pkg/networking/core/listener_waypoint.go index 61dcb9d05092..3a697e4b8c5f 100644 --- a/pilot/pkg/networking/core/listener_waypoint.go +++ b/pilot/pkg/networking/core/listener_waypoint.go @@ -17,6 +17,7 @@ package core import ( "fmt" "net/netip" + "regexp" "strconv" "time" @@ -28,6 +29,7 @@ import ( hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" tcp "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3" tls "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" + envoymatcher "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" any "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/durationpb" wrappers "google.golang.org/protobuf/types/known/wrapperspb" @@ -465,10 +467,10 @@ func (lb *ListenerBuilder) buildWaypointHTTPFilters(svc *model.Service) (pre []* // TODO: consider dedicated listener class for waypoint filters cls := istionetworking.ListenerClassSidecarInbound - wasm := lb.push.WasmPluginsByListenerInfo(lb.node, model.WasmPluginListenerInfo{ - Class: cls, - Service: svc, - }, model.WasmPluginTypeHTTP) + wasm := lb.push.WasmPluginsByListenerInfo(lb.node, + model.WasmPluginListenerInfo{Class: cls}.WithService(svc), + model.WasmPluginTypeHTTP, + ) // TODO: how to deal with ext-authz? It will be in the ordering twice // TODO policies here will need to be different per-chain (service attached) pre = append(pre, authzCustomBuilder.BuildHTTP(cls)...) @@ -624,8 +626,9 @@ func (lb *ListenerBuilder) translateWaypointRoute( match *networking.HTTPMatchRequest, listenPort int, ) *route.Route { + gatewaySemantics := model.UseGatewaySemantics(virtualService) // When building routes, it's okay if the target cluster cannot be - // resolved Traffic to such clusters will blackhole. + // resolved. Traffic to such clusters will blackhole. // Match by the destination port specified in the match condition if match != nil && match.Port != 0 && match.Port != uint32(listenPort) { @@ -657,7 +660,7 @@ func (lb *ListenerBuilder) translateWaypointRoute( } else if in.DirectResponse != nil { istio_route.ApplyDirectResponse(out, in.DirectResponse) } else { - lb.waypointRouteDestination(out, in, authority, listenPort) + lb.waypointRouteDestination(out, in, authority, listenPort, gatewaySemantics) } out.Decorator = &route.Decorator{ @@ -676,7 +679,13 @@ func (lb *ListenerBuilder) translateWaypointRoute( return out } -func (lb *ListenerBuilder) waypointRouteDestination(out *route.Route, in *networking.HTTPRoute, authority string, listenerPort int) { +func (lb *ListenerBuilder) waypointRouteDestination( + out *route.Route, + in *networking.HTTPRoute, + authority string, + listenerPort int, + gatewaySemantics bool, +) { policy := in.Retries if policy == nil { // No VS policy set, use mesh defaults @@ -692,13 +701,39 @@ func (lb *ListenerBuilder) waypointRouteDestination(out *route.Route, in *networ action.Timeout = in.Timeout } // Use deprecated value for now as the replacement MaxStreamDuration has some regressions. + // TODO: check and see if the replacement has been fixed. // nolint: staticcheck action.MaxGrpcTimeout = action.Timeout + if gatewaySemantics { + // return 500 for invalid backends + // https://github.com/kubernetes-sigs/gateway-api/blob/cea484e38e078a2c1997d8c7a62f410a1540f519/apis/v1beta1/httproute_types.go#L204 + action.ClusterNotFoundResponseCode = route.RouteAction_INTERNAL_SERVER_ERROR + } out.Action = &route.Route_Route{Route: action} if in.Rewrite != nil { - action.PrefixRewrite = in.Rewrite.GetUri() + if regexRewrite := in.Rewrite.GetUriRegexRewrite(); regexRewrite != nil { + action.RegexRewrite = &envoymatcher.RegexMatchAndSubstitute{ + Pattern: &envoymatcher.RegexMatcher{ + Regex: regexRewrite.Match, + }, + Substitution: regexRewrite.Rewrite, + } + } else if uri := in.Rewrite.GetUri(); uri != "" { + if gatewaySemantics && uri == "/" { + // remove the prefix + action.RegexRewrite = &envoymatcher.RegexMatchAndSubstitute{ + Pattern: &envoymatcher.RegexMatcher{ + Regex: fmt.Sprintf(`^%s(/?)(.*)`, regexp.QuoteMeta(out.Match.GetPathSeparatedPrefix())), + }, + // hold `/` in case the entire path is removed + Substitution: `/\2`, + } + } else { + action.PrefixRewrite = uri + } + } if in.Rewrite.GetAuthority() != "" { authority = in.Rewrite.GetAuthority() } @@ -785,9 +820,13 @@ func (lb *ListenerBuilder) waypointRouteDestination(out *route.Route, in *networ } } -// getWaypointDestinationCluster generates a cluster name for the route, or error if no cluster -// can be found. Called by translateRule to determine if +// getWaypointDestinationCluster generates a cluster name for the route. If the destination is invalid +// or cannot be found, "UnknownService" is returned. func (lb *ListenerBuilder) getWaypointDestinationCluster(destination *networking.Destination, service *model.Service, listenerPort int) string { + if len(destination.GetHost()) == 0 { + // only happens when the gateway-api BackendRef is invalid + return "UnknownService" + } dir, port := model.TrafficDirectionInboundVIP, listenerPort if destination.GetPort() != nil { @@ -822,10 +861,14 @@ func (lb *ListenerBuilder) getWaypointDestinationCluster(destination *networking // portToSubset helps translate a port to the waypoint subset to use func portToSubset(service *model.Service, port int, destination *networking.Destination) string { - p, ok := service.Ports.GetByPort(port) + var p *model.Port + var ok bool + if service != nil { + p, ok = service.Ports.GetByPort(port) + } if !ok { // Port is unknown. - if destination.Subset != "" { + if destination != nil && destination.Subset != "" { return "http/" + destination.Subset } return "http" diff --git a/pilot/pkg/networking/core/networkfilter.go b/pilot/pkg/networking/core/networkfilter.go index 99929d56aecc..b055c76a55a7 100644 --- a/pilot/pkg/networking/core/networkfilter.go +++ b/pilot/pkg/networking/core/networkfilter.go @@ -116,11 +116,10 @@ func (lb *ListenerBuilder) buildCompleteNetworkFilters( } var filters []*listener.Filter - wasm := lb.push.WasmPluginsByListenerInfo(lb.node, model.WasmPluginListenerInfo{ - Port: port, - Class: class, - Service: policySvc, - }, model.WasmPluginTypeNetwork) + wasm := lb.push.WasmPluginsByListenerInfo( + lb.node, model.WasmPluginListenerInfo{Port: port, Class: class}.WithService(policySvc), + model.WasmPluginTypeNetwork, + ) // Metadata exchange goes first, so RBAC failures, etc can access the state. See https://github.com/istio/istio/issues/41066 if features.MetadataExchange && includeMx { diff --git a/pilot/pkg/networking/core/route/route.go b/pilot/pkg/networking/core/route/route.go index 4778bbf3ff90..31cb3da24a28 100644 --- a/pilot/pkg/networking/core/route/route.go +++ b/pilot/pkg/networking/core/route/route.go @@ -329,8 +329,8 @@ func buildSidecarVirtualHostForService(svc *model.Service, } } -// GetDestinationCluster generates a cluster name for the route, or error if no cluster -// can be found. Called by translateRule to determine if +// GetDestinationCluster generates a cluster name for the route. If the destination is invalid +// or cannot be found, "UnknownService" is returned. func GetDestinationCluster(destination *networking.Destination, service *model.Service, listenerPort int) string { if len(destination.GetHost()) == 0 { // only happens when the gateway-api BackendRef is invalid @@ -790,7 +790,12 @@ func ApplyRedirect(out *route.Route, redirect *networking.HTTPRedirect, port int action.Redirect.ResponseCode = route.RedirectAction_PERMANENT_REDIRECT default: log.Warnf("Redirect Code %d is not yet supported", redirect.RedirectCode) - action = nil + // Can't just set action to nil here because the proto marshaller will still see + // the Route_Redirect type of the variable and assume that the value is set + // (and panic because it's not). What we need to do is set out.Action directly to + // (a typeless) nil so that type assertions to Route_Redirect will fail. + out.Action = nil + return } out.Action = action @@ -1181,11 +1186,8 @@ func TranslateCORSPolicy(proxy *model.Proxy, in *networking.CorsPolicy) *cors.Co // CORS filter is enabled by default out := cors.CorsPolicy{} - // Start from Envoy 1.30(istio 1.22), cors filter will not forward preflight requests to upstream by default. - // Istio start support this feature from 1.23. - if proxy.VersionGreaterAndEqual(&model.IstioVersion{Major: 1, Minor: 23, Patch: -1}) { - out.ForwardNotMatchingPreflights = forwardNotMatchingPreflights(in) - } + + out.ForwardNotMatchingPreflights = forwardNotMatchingPreflights(in) // nolint: staticcheck if in.AllowOrigins != nil { diff --git a/pilot/pkg/networking/core/route/route_internal_test.go b/pilot/pkg/networking/core/route/route_internal_test.go index 84094ac64fb5..40895e164649 100644 --- a/pilot/pkg/networking/core/route/route_internal_test.go +++ b/pilot/pkg/networking/core/route/route_internal_test.go @@ -165,13 +165,7 @@ func TestIsCatchAllRoute(t *testing.T) { } func TestTranslateCORSPolicyForwardNotMatchingPreflights(t *testing.T) { - node := &model.Proxy{ - IstioVersion: &model.IstioVersion{ - Major: 1, - Minor: 23, - Patch: 0, - }, - } + node := &model.Proxy{} corsPolicy := &networking.CorsPolicy{ AllowOrigins: []*networking.StringMatch{ {MatchType: &networking.StringMatch_Exact{Exact: "exact"}}, @@ -206,13 +200,7 @@ func TestTranslateCORSPolicyForwardNotMatchingPreflights(t *testing.T) { } func TestTranslateCORSPolicy(t *testing.T) { - node := &model.Proxy{ - IstioVersion: &model.IstioVersion{ - Major: 1, - Minor: 21, - Patch: 0, - }, - } + node := &model.Proxy{} corsPolicy := &networking.CorsPolicy{ AllowOrigins: []*networking.StringMatch{ {MatchType: &networking.StringMatch_Exact{Exact: "exact"}}, @@ -232,6 +220,7 @@ func TestTranslateCORSPolicy(t *testing.T) { }, }, }, + ForwardNotMatchingPreflights: wrapperspb.Bool(true), FilterEnabled: &core.RuntimeFractionalPercent{ DefaultValue: &xdstype.FractionalPercent{ Numerator: 100, diff --git a/pilot/pkg/networking/core/route/route_test.go b/pilot/pkg/networking/core/route/route_test.go index a42c5d0ece81..055bc40cb89e 100644 --- a/pilot/pkg/networking/core/route/route_test.go +++ b/pilot/pkg/networking/core/route/route_test.go @@ -933,6 +933,19 @@ func TestBuildHTTPRoutes(t *testing.T) { g.Expect(redirectAction.Redirect.ResponseCode).To(Equal(envoyroute.RedirectAction_PERMANENT_REDIRECT)) }) + t.Run("for invalid redirect code", func(t *testing.T) { + g := NewWithT(t) + cg := core.NewConfigGenTest(t, core.TestOptions{}) + + routes, err := route.BuildHTTPRoutesForVirtualService(node(cg), virtualServiceWithInvalidRedirect, serviceRegistry, + nil, 8080, gatewayNames, route.RouteOptions{}) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(len(routes)).To(Equal(1)) + + _, ok := routes[0].Action.(*envoyroute.Route_Redirect) + g.Expect(ok).To(BeFalse()) + }) + t.Run("for path prefix redirect", func(t *testing.T) { g := NewWithT(t) cg := core.NewConfigGenTest(t, core.TestOptions{}) @@ -1862,6 +1875,26 @@ var virtualServiceWithRedirect = config.Config{ }, } +var virtualServiceWithInvalidRedirect = config.Config{ + Meta: config.Meta{ + GroupVersionKind: gvk.VirtualService, + Name: "acme", + }, + Spec: &networking.VirtualService{ + Hosts: []string{}, + Gateways: []string{"some-gateway"}, + Http: []*networking.HTTPRoute{ + { + Redirect: &networking.HTTPRedirect{ + Uri: "example.org", + Authority: "some-authority.default.svc.cluster.local", + RedirectCode: 317, + }, + }, + }, + }, +} + var virtualServiceWithRedirectPathPrefix = config.Config{ Meta: config.Meta{ GroupVersionKind: gvk.VirtualService, diff --git a/pilot/pkg/networking/core/serviceentry_simulation_test.go b/pilot/pkg/networking/core/serviceentry_simulation_test.go index 7a9219b973a8..afd6fe165f47 100644 --- a/pilot/pkg/networking/core/serviceentry_simulation_test.go +++ b/pilot/pkg/networking/core/serviceentry_simulation_test.go @@ -16,9 +16,11 @@ package core_test import ( "testing" + "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/simulation" "istio.io/istio/pilot/test/xds" + "istio.io/istio/pkg/test" "istio.io/istio/pkg/test/util/tmpl" ) @@ -206,13 +208,69 @@ func TestServiceEntry(t *testing.T) { }, }, }, + { + // Regression test for https://github.com/istio/istio/issues/52847 + name: "partial overlap of IP", + config: tmpl.MustEvaluate(`apiVersion: networking.istio.io/v1 +kind: ServiceEntry +metadata: + name: se1 +spec: + hosts: + - blah1.somedomain + addresses: {{ . |toJson }} + ports: + - number: 9999 + name: port-9999 + protocol: TCP`, []string{"1.1.1.1"}) + "\n---\n" + tmpl.MustEvaluate(`apiVersion: networking.istio.io/v1 +kind: ServiceEntry +metadata: + name: se2 +spec: + hosts: + - blah2.somedomain + addresses: {{ . |toJson }} + ports: + - number: 9999 + name: port-9999 + protocol: TCP`, []string{"2.2.2.2", "1.1.1.1"}), + kubeConfig: "", + calls: []simulation.Expect{ + { + Name: "unique IP", + Call: simulation.Call{ + Port: 9999, + // Matches both, but more closely matches blah2, but SNI is blah1 + Address: "2.2.2.2", + }, + Result: simulation.Result{ + Error: nil, + ListenerMatched: "2.2.2.2_9999", + ClusterMatched: "outbound|9999||blah2.somedomain", + }, + }, + { + Name: "shared IP", + Call: simulation.Call{ + Port: 9999, + // Matches both, but more closely matches blah2, but SNI is blah1 + Address: "1.1.1.1", + }, + Result: simulation.Result{ + Error: nil, + ListenerMatched: "1.1.1.1_9999", + ClusterMatched: "outbound|9999||blah1.somedomain", + }, + }, + }, + }, } for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { proxy := &model.Proxy{ Labels: map[string]string{"app": "foo"}, - Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "foo"}}, + Metadata: &model.NodeMetadata{Labels: map[string]string{"app": "foo"}, ClusterID: "Kubernetes"}, IPAddresses: []string{"127.0.0.1", "1234::1234"}, } proxy.DiscoverIPMode() @@ -256,6 +314,9 @@ spec: ` func TestServiceEntryDuplicatedHostname(t *testing.T) { + // Only the old IP auto-allocator has this functionality + // TODO(https://github.com/istio/istio/issues/53676): implement this in the new one, and test both + test.SetForTest(t, &features.EnableIPAutoallocate, false) cases := []simulationTest{ { name: "service entries with reused hosts should have auto allocated the same IP address", diff --git a/pilot/pkg/networking/core/sidecar_simulation_test.go b/pilot/pkg/networking/core/sidecar_simulation_test.go index f426e1fe1413..64990a46e9f0 100644 --- a/pilot/pkg/networking/core/sidecar_simulation_test.go +++ b/pilot/pkg/networking/core/sidecar_simulation_test.go @@ -2608,7 +2608,6 @@ spec: for _, variant := range []string{"httproute", "virtualservice"} { t.Run(variant, func(t *testing.T) { for _, tt := range cases { - tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() // feature flags and parallel tests don't mix cfg := knownServices diff --git a/pilot/pkg/networking/core/tracing.go b/pilot/pkg/networking/core/tracing.go index 954769d1f880..5e5328e46221 100644 --- a/pilot/pkg/networking/core/tracing.go +++ b/pilot/pkg/networking/core/tracing.go @@ -83,7 +83,7 @@ func configureTracingFromTelemetry( // use the prior configuration bits of sampling and custom tags h.Tracing = &hcm.HttpConnectionManager_Tracing{} configureSampling(h.Tracing, proxyConfigSamplingValue(proxyCfg)) - configureCustomTags(h.Tracing, map[string]*telemetrypb.Tracing_CustomTag{}, proxyCfg, proxy) + configureCustomTags(nil, h.Tracing, map[string]*telemetrypb.Tracing_CustomTag{}, proxyCfg, proxy) if proxyCfg.GetTracing().GetMaxPathTagLength() != 0 { h.Tracing.MaxPathTagLength = wrapperspb.UInt32(proxyCfg.GetTracing().MaxPathTagLength) } @@ -130,7 +130,7 @@ func configureTracingFromTelemetry( } configureSampling(h.Tracing, sampling) - configureCustomTags(h.Tracing, spec.CustomTags, proxyCfg, proxy) + configureCustomTags(&spec, h.Tracing, spec.CustomTags, proxyCfg, proxy) // if there is configured max tag length somewhere, fallback to it. if h.GetTracing().GetMaxPathTagLength() == nil && proxyCfg.GetTracing().GetMaxPathTagLength() != 0 { @@ -597,10 +597,22 @@ func proxyConfigSamplingValue(config *meshconfig.ProxyConfig) float64 { return sampling } -func configureCustomTags(hcmTracing *hcm.HttpConnectionManager_Tracing, +func configureCustomTags(spec *model.TracingSpec, hcmTracing *hcm.HttpConnectionManager_Tracing, providerTags map[string]*telemetrypb.Tracing_CustomTag, proxyCfg *meshconfig.ProxyConfig, node *model.Proxy, ) { - tags := append(buildServiceTags(node.Metadata, node.Labels), optionalPolicyTags...) + var tags []*tracing.CustomTag + if spec == nil { + // Fallback to legacy mesh config. + enableIstioTags := true + if proxyCfg.GetTracing().GetEnableIstioTags() != nil { + enableIstioTags = proxyCfg.GetTracing().GetEnableIstioTags().GetValue() + } + if enableIstioTags { + tags = append(buildServiceTags(node.Metadata, node.Labels), optionalPolicyTags...) + } + } else if spec.EnableIstioTags { + tags = append(buildServiceTags(node.Metadata, node.Labels), optionalPolicyTags...) + } if len(providerTags) == 0 { tags = append(tags, buildCustomTagsFromProxyConfig(proxyCfg.GetTracing().GetCustomTags())...) diff --git a/pilot/pkg/networking/core/tracing_test.go b/pilot/pkg/networking/core/tracing_test.go index 9988e77669e6..19567d342551 100644 --- a/pilot/pkg/networking/core/tracing_test.go +++ b/pilot/pkg/networking/core/tracing_test.go @@ -77,10 +77,12 @@ func TestConfigureTracing(t *testing.T) { name: "default providers", inSpec: &model.TracingConfig{ ClientSpec: model.TracingSpec{ - Disabled: true, + Disabled: true, + EnableIstioTags: true, }, ServerSpec: model.TracingSpec{ - Provider: fakeZipkin(), + Provider: fakeZipkin(), + EnableIstioTags: true, }, }, opts: fakeOptsWithDefaultProviders(), @@ -95,11 +97,18 @@ func TestConfigureTracing(t *testing.T) { }, { name: "only telemetry api (no provider)", - inSpec: fakeTracingSpecNoProvider(99.999, false, true), + inSpec: fakeTracingSpecNoProvider(99.999, false, true, true), opts: fakeOptsOnlyZipkinTelemetryAPI(), want: fakeTracingConfigNoProvider(99.999, 0, append(defaultTracingTags(), fakeEnvTag)), wantReqIDExtCtx: &defaultUUIDExtensionCtx, }, + { + name: "only telemetry api (no provider) and disabled istio tags", + inSpec: fakeTracingSpecNoProvider(99.999, false, true, false), + opts: fakeOptsOnlyZipkinTelemetryAPI(), + want: fakeTracingConfigNoProvider(99.999, 0, append([]*tracing.CustomTag{}, fakeEnvTag)), + wantReqIDExtCtx: &defaultUUIDExtensionCtx, + }, { name: "only telemetry api (no provider) with nil custom tag", inSpec: fakeTracingSpecNoProviderWithNilCustomTag(99.999, false, true), @@ -110,7 +119,7 @@ func TestConfigureTracing(t *testing.T) { }, { name: "only telemetry api (with provider)", - inSpec: fakeTracingSpec(fakeZipkin(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeZipkin(), 99.999, false, true, true), opts: fakeOptsOnlyZipkinTelemetryAPI(), want: fakeTracingConfig(fakeZipkinProvider(clusterName, authority, DefaultZipkinEndpoint, true), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), @@ -118,7 +127,7 @@ func TestConfigureTracing(t *testing.T) { }, { name: "zipkin enable 64bit trace id", - inSpec: fakeTracingSpec(fakeZipkinEnable64bitTraceID(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeZipkinEnable64bitTraceID(), 99.999, false, true, true), opts: fakeOptsOnlyZipkinTelemetryAPI(), want: fakeTracingConfig(fakeZipkinProvider(clusterName, authority, DefaultZipkinEndpoint, false), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), @@ -126,21 +135,21 @@ func TestConfigureTracing(t *testing.T) { }, { name: "both tracing enabled (no provider)", - inSpec: fakeTracingSpecNoProvider(99.999, false, true), + inSpec: fakeTracingSpecNoProvider(99.999, false, true, true), opts: fakeOptsMeshAndTelemetryAPI(true /* enable tracing */), want: fakeTracingConfigNoProvider(99.999, 13, append(defaultTracingTags(), fakeEnvTag)), wantReqIDExtCtx: &defaultUUIDExtensionCtx, }, { name: "both tracing disabled (no provider)", - inSpec: fakeTracingSpecNoProvider(99.999, false, true), + inSpec: fakeTracingSpecNoProvider(99.999, false, true, true), opts: fakeOptsMeshAndTelemetryAPI(false /* no enable tracing */), want: fakeTracingConfigNoProvider(99.999, 13, append(defaultTracingTags(), fakeEnvTag)), wantReqIDExtCtx: &defaultUUIDExtensionCtx, }, { name: "both tracing enabled (with provider)", - inSpec: fakeTracingSpec(fakeZipkin(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeZipkin(), 99.999, false, true, true), opts: fakeOptsMeshAndTelemetryAPI(true /* enable tracing */), want: fakeTracingConfig(fakeZipkinProvider(clusterName, authority, DefaultZipkinEndpoint, true), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), @@ -148,7 +157,7 @@ func TestConfigureTracing(t *testing.T) { }, { name: "both tracing disabled (with provider)", - inSpec: fakeTracingSpec(fakeZipkin(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeZipkin(), 99.999, false, true, true), opts: fakeOptsMeshAndTelemetryAPI(false /* no enable tracing */), want: fakeTracingConfig(fakeZipkinProvider(clusterName, authority, DefaultZipkinEndpoint, true), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), @@ -157,7 +166,7 @@ func TestConfigureTracing(t *testing.T) { }, { name: "basic config (with datadog provider)", - inSpec: fakeTracingSpec(fakeDatadog(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeDatadog(), 99.999, false, true, true), opts: fakeOptsOnlyDatadogTelemetryAPI(), want: fakeTracingConfig(fakeDatadogProvider("fake-cluster", "testhost", clusterName), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), @@ -165,14 +174,14 @@ func TestConfigureTracing(t *testing.T) { }, { name: "basic config (with skywalking provider)", - inSpec: fakeTracingSpec(fakeSkywalking(), 99.999, false, false), + inSpec: fakeTracingSpec(fakeSkywalking(), 99.999, false, false, true), opts: fakeOptsOnlySkywalkingTelemetryAPI(), want: fakeTracingConfigForSkywalking(fakeSkywalkingProvider(clusterName, authority), 99.999, 0, append(defaultTracingTags(), fakeEnvTag)), wantReqIDExtCtx: &requestidextension.UUIDRequestIDExtensionContext{UseRequestIDForTraceSampling: false}, }, { name: "basic config (with opentelemetry provider via grpc)", - inSpec: fakeTracingSpec(fakeOpenTelemetryGrpc(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeOpenTelemetryGrpc(), 99.999, false, true, true), opts: fakeOptsOnlyOpenTelemetryGrpcTelemetryAPI(), want: fakeTracingConfig(fakeOpenTelemetryGrpcProvider(clusterName, authority), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), @@ -180,14 +189,14 @@ func TestConfigureTracing(t *testing.T) { }, { name: "basic config (with opentelemetry provider via http)", - inSpec: fakeTracingSpec(fakeOpenTelemetryHTTP(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeOpenTelemetryHTTP(), 99.999, false, true, true), opts: fakeOptsOnlyOpenTelemetryHTTPTelemetryAPI(), want: fakeTracingConfig(fakeOpenTelemetryHTTPProvider(clusterName, authority), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), wantReqIDExtCtx: &defaultUUIDExtensionCtx, }, { name: "basic config (with opentelemetry provider with resource detectors)", - inSpec: fakeTracingSpec(fakeOpenTelemetryResourceDetectors(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeOpenTelemetryResourceDetectors(), 99.999, false, true, true), opts: fakeOptsOnlyOpenTelemetryResourceDetectorsTelemetryAPI(), want: fakeTracingConfig( fakeOpenTelemetryResourceDetectorsProvider(clusterName, authority), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), @@ -210,14 +219,14 @@ func TestConfigureTracing(t *testing.T) { }, { name: "invalid provider", - inSpec: fakeTracingSpec(fakePrometheus(), 99.999, false, true), + inSpec: fakeTracingSpec(fakePrometheus(), 99.999, false, true, true), opts: fakeOptsMeshAndTelemetryAPI(true /* enable tracing */), want: nil, wantReqIDExtCtx: nil, }, { name: "basic config (with opentelemetry provider via grpc with initial metadata)", - inSpec: fakeTracingSpec(fakeOpenTelemetryGrpcWithInitialMetadata(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeOpenTelemetryGrpcWithInitialMetadata(), 99.999, false, true, true), opts: fakeOptsOnlyOpenTelemetryGrpcWithInitialMetadataTelemetryAPI(), want: fakeTracingConfig(fakeOpenTelemetryGrpcWithInitialMetadataProvider(clusterName, authority), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), @@ -225,7 +234,7 @@ func TestConfigureTracing(t *testing.T) { }, { name: "only telemetry api (with provider)", - inSpec: fakeTracingSpec(fakeZipkinWithEndpoint(), 99.999, false, true), + inSpec: fakeTracingSpec(fakeZipkinWithEndpoint(), 99.999, false, true, true), opts: fakeOptsZipkinTelemetryWithEndpoint(), want: fakeTracingConfig(fakeZipkinProvider(clusterName, authority, "/custom/path/api/v2/spans", true), 99.999, 256, append(defaultTracingTags(), fakeEnvTag)), @@ -294,8 +303,8 @@ func TestConfigureDynatraceSampler(t *testing.T) { // Use a different value for RandomSamplingPercentage to ensure it is changed to 100% // when a custom sampler is used for the OTel tracing provider inSpec := &model.TracingConfig{ - ClientSpec: tracingSpec(httpProvider, 50, false, false), - ServerSpec: tracingSpec(httpProvider, 50, false, false), + ClientSpec: tracingSpec(httpProvider, 50, false, false, true), + ServerSpec: tracingSpec(httpProvider, 50, false, false, true), } opts := fakeOptsOnlyOpenTelemetryHTTPTelemetryAPI() @@ -420,8 +429,8 @@ func TestConfigureDynatraceSamplerWithCustomHttp(t *testing.T) { // Use a different value for RandomSamplingPercentage to ensure it is changed to 100% // when a custom sampler is used for the OTel tracing provider inSpec := &model.TracingConfig{ - ClientSpec: tracingSpec(httpProvider, 50, false, false), - ServerSpec: tracingSpec(httpProvider, 50, false, false), + ClientSpec: tracingSpec(httpProvider, 50, false, false, true), + ServerSpec: tracingSpec(httpProvider, 50, false, false, true), } opts := fakeOptsOnlyOpenTelemetryHTTPTelemetryAPI() @@ -1057,8 +1066,9 @@ func fakeInboundOptsOnlySkywalkingTelemetryAPI() gatewayListenerOpts { return opts } -func fakeTracingSpecNoProvider(sampling float64, disableReporting bool, useRequestIDForTraceSampling bool) *model.TracingConfig { - return fakeTracingSpec(nil, sampling, disableReporting, useRequestIDForTraceSampling) +// nolint: unparam +func fakeTracingSpecNoProvider(sampling float64, disableReporting bool, useRequestIDForTraceSampling bool, enableIstiotags bool) *model.TracingConfig { + return fakeTracingSpec(nil, sampling, disableReporting, useRequestIDForTraceSampling, enableIstiotags) } func fakeTracingSpecNoProviderWithNilCustomTag(sampling float64, disableReporting bool, useRequestIDForTraceSampling bool) *model.TracingConfig { @@ -1067,10 +1077,11 @@ func fakeTracingSpecNoProviderWithNilCustomTag(sampling float64, disableReportin func fakeTracingSpec(provider *meshconfig.MeshConfig_ExtensionProvider, sampling float64, disableReporting bool, useRequestIDForTraceSampling bool, + enableIstioTags bool, ) *model.TracingConfig { t := &model.TracingConfig{ - ClientSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling), - ServerSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling), + ClientSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling, enableIstioTags), + ServerSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling, enableIstioTags), } return t } @@ -1079,7 +1090,7 @@ func fakeClientOnlyTracingSpec(provider *meshconfig.MeshConfig_ExtensionProvider useRequestIDForTraceSampling bool, ) *model.TracingConfig { t := &model.TracingConfig{ - ClientSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling), + ClientSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling, true), ServerSpec: model.TracingSpec{ Disabled: true, }, @@ -1094,13 +1105,14 @@ func fakeServerOnlyTracingSpec(provider *meshconfig.MeshConfig_ExtensionProvider ClientSpec: model.TracingSpec{ Disabled: true, }, - ServerSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling), + ServerSpec: tracingSpec(provider, sampling, disableReporting, useRequestIDForTraceSampling, true), } return t } func tracingSpec(provider *meshconfig.MeshConfig_ExtensionProvider, sampling float64, disableReporting bool, useRequestIDForTraceSampling bool, + enableIstioTags bool, ) model.TracingSpec { return model.TracingSpec{ Provider: provider, @@ -1116,6 +1128,7 @@ func tracingSpec(provider *meshconfig.MeshConfig_ExtensionProvider, sampling flo }, }, UseRequestIDForTraceSampling: useRequestIDForTraceSampling, + EnableIstioTags: enableIstioTags, } } @@ -1131,6 +1144,7 @@ func fakeTracingSpecWithNilCustomTag(provider *meshconfig.MeshConfig_ExtensionPr "test": nil, }, UseRequestIDForTraceSampling: useRequestIDForTraceSampling, + EnableIstioTags: true, }, ServerSpec: model.TracingSpec{ Provider: provider, @@ -1140,6 +1154,7 @@ func fakeTracingSpecWithNilCustomTag(provider *meshconfig.MeshConfig_ExtensionPr "test": nil, }, UseRequestIDForTraceSampling: useRequestIDForTraceSampling, + EnableIstioTags: true, }, } return t diff --git a/pilot/pkg/networking/util/util.go b/pilot/pkg/networking/util/util.go index 27aa8ed2825d..430bfcb23a4d 100644 --- a/pilot/pkg/networking/util/util.go +++ b/pilot/pkg/networking/util/util.go @@ -885,7 +885,7 @@ func ShallowCopyTrafficPolicy(original *networking.TrafficPolicy) *networking.Tr } func VersionGreaterOrEqual124(proxy *model.Proxy) bool { - return proxy.VersionGreaterAndEqual(&model.IstioVersion{Major: 1, Minor: 24, Patch: -1}) + return proxy.VersionGreaterOrEqual(&model.IstioVersion{Major: 1, Minor: 24, Patch: -1}) } func DelimitedStatsPrefix(statPrefix string) string { diff --git a/pilot/pkg/server/instance_test.go b/pilot/pkg/server/instance_test.go index b1674606cb54..8918c9d639cb 100644 --- a/pilot/pkg/server/instance_test.go +++ b/pilot/pkg/server/instance_test.go @@ -88,7 +88,6 @@ func TestRunComponentsAfterStart(t *testing.T) { }, } for _, c := range cases { - c := c t.Run(c.name, func(t *testing.T) { g := NewWithT(t) diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex.go b/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex.go index 0673a6502a92..b09c5c7870b6 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex.go @@ -17,6 +17,7 @@ package ambient import ( "net/netip" "strings" + "sync/atomic" v1 "k8s.io/api/core/v1" discovery "k8s.io/api/discovery/v1" @@ -45,6 +46,7 @@ import ( "istio.io/istio/pkg/log" "istio.io/istio/pkg/maps" "istio.io/istio/pkg/network" + "istio.io/istio/pkg/ptr" "istio.io/istio/pkg/slices" "istio.io/istio/pkg/util/sets" "istio.io/istio/pkg/workloadapi" @@ -75,9 +77,10 @@ func (n NamespaceHostname) String() string { type workloadsCollection struct { krt.Collection[model.WorkloadInfo] - ByAddress krt.Index[networkAddress, model.WorkloadInfo] - ByServiceKey krt.Index[string, model.WorkloadInfo] - ByOwningWaypoint krt.Index[NamespaceHostname, model.WorkloadInfo] + ByAddress krt.Index[networkAddress, model.WorkloadInfo] + ByServiceKey krt.Index[string, model.WorkloadInfo] + ByOwningWaypointHostname krt.Index[NamespaceHostname, model.WorkloadInfo] + ByOwningWaypointIP krt.Index[networkAddress, model.WorkloadInfo] } type waypointsCollection struct { @@ -86,8 +89,9 @@ type waypointsCollection struct { type servicesCollection struct { krt.Collection[model.ServiceInfo] - ByAddress krt.Index[networkAddress, model.ServiceInfo] - ByOwningWaypoint krt.Index[NamespaceHostname, model.ServiceInfo] + ByAddress krt.Index[networkAddress, model.ServiceInfo] + ByOwningWaypointHostname krt.Index[NamespaceHostname, model.ServiceInfo] + ByOwningWaypointIP krt.Index[networkAddress, model.ServiceInfo] } // index maintains an index of ambient WorkloadInfo objects by various keys. @@ -99,6 +103,7 @@ type index struct { authorizationPolicies krt.Collection[model.WorkloadAuthorization] networkUpdateTrigger *krt.RecomputeTrigger + networkGateways *atomic.Pointer[map[network.ID][]model.NetworkGateway] statusQueue *statusqueue.StatusQueue @@ -108,8 +113,17 @@ type index struct { XDSUpdater model.XDSUpdater // Network provides a way to lookup which network a given workload is running on Network LookupNetwork - // LookupNetworkGateways provides a function to lookup all the known network gateways in the system. - LookupNetworkGateways LookupNetworkGateways + // LookupNetworkGatewaysExpensive provides a function to lookup all the known network gateways in the system. + // This is generally called infrequently and cached in networkGateways. + LookupNetworkGatewaysExpensive LookupNetworkGateways + Flags FeatureFlags + + stop chan struct{} +} + +type FeatureFlags struct { + DefaultAllowFromWaypoint bool + EnableK8SServiceSelectWorkloadEntries bool } type Options struct { @@ -123,70 +137,91 @@ type Options struct { LookupNetwork LookupNetwork LookupNetworkGateways LookupNetworkGateways StatusNotifier *activenotifier.ActiveNotifier + Flags FeatureFlags + + Debugger *krt.DebugHandler +} + +// KrtOptions is a small wrapper around KRT options to make it easy to provide a common set of options to all collections +// without excessive duplication. +type KrtOptions struct { + stop chan struct{} + debugger *krt.DebugHandler +} + +func (k KrtOptions) WithName(n string) []krt.CollectionOption { + return []krt.CollectionOption{krt.WithDebugging(k.debugger), krt.WithStop(k.stop), krt.WithName(n)} } func New(options Options) Index { a := &index{ - networkUpdateTrigger: krt.NewRecomputeTrigger(false), - - SystemNamespace: options.SystemNamespace, - DomainSuffix: options.DomainSuffix, - ClusterID: options.ClusterID, - XDSUpdater: options.XDSUpdater, - Network: options.LookupNetwork, - LookupNetworkGateways: options.LookupNetworkGateways, + networkUpdateTrigger: krt.NewRecomputeTrigger(false, krt.WithName("NetworkTrigger")), + networkGateways: new(atomic.Pointer[map[network.ID][]model.NetworkGateway]), + + SystemNamespace: options.SystemNamespace, + DomainSuffix: options.DomainSuffix, + ClusterID: options.ClusterID, + XDSUpdater: options.XDSUpdater, + Network: options.LookupNetwork, + LookupNetworkGatewaysExpensive: options.LookupNetworkGateways, + Flags: options.Flags, + stop: make(chan struct{}), } filter := kclient.Filter{ ObjectFilter: options.Client.ObjectFilter(), } - ConfigMaps := krt.NewInformerFiltered[*v1.ConfigMap](options.Client, filter, krt.WithName("ConfigMaps")) + opts := KrtOptions{ + stop: a.stop, + debugger: options.Debugger, + } + ConfigMaps := krt.NewInformerFiltered[*v1.ConfigMap](options.Client, filter, opts.WithName("ConfigMaps")...) authzPolicies := kclient.NewDelayedInformer[*securityclient.AuthorizationPolicy](options.Client, gvr.AuthorizationPolicy, kubetypes.StandardInformer, filter) - AuthzPolicies := krt.WrapClient[*securityclient.AuthorizationPolicy](authzPolicies, krt.WithName("AuthorizationPolicies")) + AuthzPolicies := krt.WrapClient[*securityclient.AuthorizationPolicy](authzPolicies, opts.WithName("AuthorizationPolicies")...) peerAuths := kclient.NewDelayedInformer[*securityclient.PeerAuthentication](options.Client, gvr.PeerAuthentication, kubetypes.StandardInformer, filter) - PeerAuths := krt.WrapClient[*securityclient.PeerAuthentication](peerAuths, krt.WithName("PeerAuthentications")) + PeerAuths := krt.WrapClient[*securityclient.PeerAuthentication](peerAuths, opts.WithName("PeerAuthentications")...) serviceEntries := kclient.NewDelayedInformer[*networkingclient.ServiceEntry](options.Client, gvr.ServiceEntry, kubetypes.StandardInformer, filter) - ServiceEntries := krt.WrapClient[*networkingclient.ServiceEntry](serviceEntries, krt.WithName("ServiceEntries")) + ServiceEntries := krt.WrapClient[*networkingclient.ServiceEntry](serviceEntries, opts.WithName("ServiceEntries")...) workloadEntries := kclient.NewDelayedInformer[*networkingclient.WorkloadEntry](options.Client, gvr.WorkloadEntry, kubetypes.StandardInformer, filter) - WorkloadEntries := krt.WrapClient[*networkingclient.WorkloadEntry](workloadEntries, krt.WithName("WorkloadEntries")) + WorkloadEntries := krt.WrapClient[*networkingclient.WorkloadEntry](workloadEntries, opts.WithName("WorkloadEntries")...) gatewayClient := kclient.NewDelayedInformer[*v1beta1.Gateway](options.Client, gvr.KubernetesGateway, kubetypes.StandardInformer, filter) - Gateways := krt.WrapClient[*v1beta1.Gateway](gatewayClient, krt.WithName("Gateways")) + Gateways := krt.WrapClient[*v1beta1.Gateway](gatewayClient, opts.WithName("Gateways")...) gatewayClassClient := kclient.NewDelayedInformer[*v1beta1.GatewayClass](options.Client, gvr.GatewayClass, kubetypes.StandardInformer, filter) - GatewayClasses := krt.WrapClient[*v1beta1.GatewayClass](gatewayClassClient, krt.WithName("GatewayClasses")) + GatewayClasses := krt.WrapClient[*v1beta1.GatewayClass](gatewayClassClient, opts.WithName("GatewayClasses")...) servicesClient := kclient.NewFiltered[*v1.Service](options.Client, filter) - Services := krt.WrapClient[*v1.Service](servicesClient, krt.WithName("Services")) + Services := krt.WrapClient[*v1.Service](servicesClient, opts.WithName("Services")...) Nodes := krt.NewInformerFiltered[*v1.Node](options.Client, kclient.Filter{ ObjectFilter: options.Client.ObjectFilter(), ObjectTransform: kubeclient.StripNodeUnusedFields, - }, krt.WithName("Nodes")) + }, opts.WithName("Nodes")...) Pods := krt.NewInformerFiltered[*v1.Pod](options.Client, kclient.Filter{ ObjectFilter: options.Client.ObjectFilter(), ObjectTransform: kubeclient.StripPodUnusedFields, - }, krt.WithName("Pods")) + }, opts.WithName("Pods")...) // TODO: Should this go ahead and transform the full ns into some intermediary with just the details we care about? - Namespaces := krt.NewInformer[*v1.Namespace](options.Client, krt.WithName("Namespaces")) + Namespaces := krt.NewInformer[*v1.Namespace](options.Client, opts.WithName("Namespaces")...) EndpointSlices := krt.NewInformerFiltered[*discovery.EndpointSlice](options.Client, kclient.Filter{ ObjectFilter: options.Client.ObjectFilter(), - }, krt.WithName("EndpointSlices")) + }, opts.WithName("EndpointSlices")...) - MeshConfig := MeshConfigCollection(ConfigMaps, options) - Waypoints := a.WaypointsCollection(Gateways, GatewayClasses, Pods) + MeshConfig := MeshConfigCollection(ConfigMaps, options, opts) + Waypoints := a.WaypointsCollection(Gateways, GatewayClasses, Pods, opts) // AllPolicies includes peer-authentication converted policies - AuthorizationPolicies, AllPolicies := PolicyCollections(AuthzPolicies, PeerAuths, MeshConfig, Waypoints) + AuthorizationPolicies, AllPolicies := PolicyCollections(AuthzPolicies, PeerAuths, MeshConfig, Waypoints, opts, a.Flags) AllPolicies.RegisterBatch(PushXds(a.XDSUpdater, func(i model.WorkloadAuthorization) model.ConfigKey { if i.Authorization == nil { @@ -199,7 +234,7 @@ func New(options Options) Index { servicesWriter := kclient.NewWriteClient[*v1.Service](options.Client) // these are workloadapi-style services combined from kube services and service entries - WorkloadServices := a.ServicesCollection(Services, ServiceEntries, Waypoints, Namespaces) + WorkloadServices := a.ServicesCollection(Services, ServiceEntries, Waypoints, Namespaces, opts) WaypointPolicyStatus := WaypointPolicyStatusCollection( AuthzPolicies, @@ -207,30 +242,34 @@ func New(options Options) Index { Services, ServiceEntries, Namespaces, + opts, ) authorizationPoliciesWriter := kclient.NewWriteClient[*securityclient.AuthorizationPolicy](options.Client) if features.EnableAmbientStatus { statusQueue := statusqueue.NewQueue(options.StatusNotifier) - statusqueue.Register(statusQueue, "istio-ambient-service", WorkloadServices, func(info model.ServiceInfo) (kclient.Patcher, []string) { - // Since we have 1 collection for multiple types, we need to split these out - if info.Source.Kind == kind.ServiceEntry { - return kclient.ToPatcher(serviceEntriesWriter), getConditions(info.Source.NamespacedName, serviceEntries) - } - return kclient.ToPatcher(servicesWriter), getConditions(info.Source.NamespacedName, servicesClient) - }) - statusqueue.Register(statusQueue, "istio-ambient-ztunnel-policy", AuthorizationPolicies, func(pol model.WorkloadAuthorization) (kclient.Patcher, []string) { - return kclient.ToPatcher(authorizationPoliciesWriter), getConditions(pol.Source.NamespacedName, authzPolicies) - }) - statusqueue.Register(statusQueue, "istio-ambient-waypoint-policy", WaypointPolicyStatus, func(pol model.WaypointPolicyStatus) (kclient.Patcher, []string) { - return kclient.ToPatcher(authorizationPoliciesWriter), getConditions(pol.Source.NamespacedName, authzPolicies) - }) + statusqueue.Register(statusQueue, "istio-ambient-service", WorkloadServices, + func(info model.ServiceInfo) (kclient.Patcher, map[string]model.Condition) { + // Since we have 1 collection for multiple types, we need to split these out + if info.Source.Kind == kind.ServiceEntry { + return kclient.ToPatcher(serviceEntriesWriter), getConditions(info.Source.NamespacedName, serviceEntries) + } + return kclient.ToPatcher(servicesWriter), getConditions(info.Source.NamespacedName, servicesClient) + }) + statusqueue.Register(statusQueue, "istio-ambient-ztunnel-policy", AuthorizationPolicies, + func(pol model.WorkloadAuthorization) (kclient.Patcher, map[string]model.Condition) { + return kclient.ToPatcher(authorizationPoliciesWriter), getConditions(pol.Source.NamespacedName, authzPolicies) + }) + statusqueue.Register(statusQueue, "istio-ambient-waypoint-policy", WaypointPolicyStatus, + func(pol model.WaypointPolicyStatus) (kclient.Patcher, map[string]model.Condition) { + return kclient.ToPatcher(authorizationPoliciesWriter), getConditions(pol.Source.NamespacedName, authzPolicies) + }) a.statusQueue = statusQueue } ServiceAddressIndex := krt.NewIndex[networkAddress, model.ServiceInfo](WorkloadServices, networkAddressFromService) - ServiceInfosByOwningWaypoint := krt.NewIndex(WorkloadServices, func(s model.ServiceInfo) []NamespaceHostname { + ServiceInfosByOwningWaypointHostname := krt.NewIndex(WorkloadServices, func(s model.ServiceInfo) []NamespaceHostname { // Filter out waypoint services if s.Labels[label.GatewayManaged.Name] == constants.ManagedGatewayMeshControllerLabel { return nil @@ -249,6 +288,27 @@ func New(options Options) Index { Hostname: waypointAddress.Hostname, }} }) + ServiceInfosByOwningWaypointIP := krt.NewIndex(WorkloadServices, func(s model.ServiceInfo) []networkAddress { + // Filter out waypoint services + if s.Labels[label.GatewayManaged.Name] == constants.ManagedGatewayMeshControllerLabel { + return nil + } + waypoint := s.Service.Waypoint + if waypoint == nil { + return nil + } + waypointAddress := waypoint.GetAddress() + if waypointAddress == nil { + return nil + } + netip, _ := netip.AddrFromSlice(waypointAddress.Address) + netaddr := networkAddress{ + network: waypointAddress.Network, + ip: netip.String(), + } + + return []networkAddress{netaddr} + }) WorkloadServices.RegisterBatch(krt.BatchedEventFilter( func(a model.ServiceInfo) *workloadapi.Service { // Only trigger push if the XDS object changed; the rest is just for computation of others @@ -270,13 +330,14 @@ func New(options Options) Index { ServiceEntries, EndpointSlices, Namespaces, + opts, ) WorkloadAddressIndex := krt.NewIndex[networkAddress, model.WorkloadInfo](Workloads, networkAddressFromWorkload) WorkloadServiceIndex := krt.NewIndex[string, model.WorkloadInfo](Workloads, func(o model.WorkloadInfo) []string { return maps.Keys(o.Services) }) - WorkloadWaypointIndex := krt.NewIndex(Workloads, func(w model.WorkloadInfo) []NamespaceHostname { + WorkloadWaypointIndexHostname := krt.NewIndex(Workloads, func(w model.WorkloadInfo) []NamespaceHostname { // Filter out waypoints. if w.Labels[label.GatewayManaged.Name] == constants.ManagedGatewayMeshControllerLabel { return nil @@ -295,6 +356,28 @@ func New(options Options) Index { Hostname: waypointAddress.Hostname, }} }) + WorkloadWaypointIndexIP := krt.NewIndex(Workloads, func(w model.WorkloadInfo) []networkAddress { + // Filter out waypoints. + if w.Labels[label.GatewayManaged.Name] == constants.ManagedGatewayMeshControllerLabel { + return nil + } + waypoint := w.Waypoint + if waypoint == nil { + return nil + } + + waypointAddress := waypoint.GetAddress() + if waypointAddress == nil { + return nil + } + netip, _ := netip.AddrFromSlice(waypointAddress.Address) + netaddr := networkAddress{ + network: waypointAddress.Network, + ip: netip.String(), + } + + return []networkAddress{netaddr} + }) Workloads.RegisterBatch(krt.BatchedEventFilter( func(a model.WorkloadInfo) *workloadapi.Workload { // Only trigger push if the XDS object changed; the rest is just for computation of others @@ -311,19 +394,22 @@ func New(options Options) Index { WorkloadServiceIndex, WorkloadServices, ServiceAddressIndex, + opts, ) } a.workloads = workloadsCollection{ - Collection: Workloads, - ByAddress: WorkloadAddressIndex, - ByServiceKey: WorkloadServiceIndex, - ByOwningWaypoint: WorkloadWaypointIndex, + Collection: Workloads, + ByAddress: WorkloadAddressIndex, + ByServiceKey: WorkloadServiceIndex, + ByOwningWaypointHostname: WorkloadWaypointIndexHostname, + ByOwningWaypointIP: WorkloadWaypointIndexIP, } a.services = servicesCollection{ - Collection: WorkloadServices, - ByAddress: ServiceAddressIndex, - ByOwningWaypoint: ServiceInfosByOwningWaypoint, + Collection: WorkloadServices, + ByAddress: ServiceAddressIndex, + ByOwningWaypointHostname: ServiceInfosByOwningWaypointHostname, + ByOwningWaypointIP: ServiceInfosByOwningWaypointIP, } a.waypoints = waypointsCollection{ Collection: Waypoints, @@ -333,28 +419,56 @@ func New(options Options) Index { return a } -func getConditions[T controllers.ComparableObject](name types.NamespacedName, i kclient.Informer[T]) []string { +func getConditions[T controllers.ComparableObject](name types.NamespacedName, i kclient.Informer[T]) map[string]model.Condition { o := i.Get(name.Name, name.Namespace) if controllers.IsNil(o) { return nil } switch t := any(o).(type) { case *v1.Service: - return slices.Map(t.Status.Conditions, func(c metav1.Condition) string { return c.Type }) + return translateKubernetesCondition(t.Status.Conditions) case *networkingclient.ServiceEntry: - return slices.Map(t.Status.Conditions, (*v1alpha1.IstioCondition).GetType) + return translateIstioCondition(t.Status.Conditions) case *securityclient.AuthorizationPolicy: - return slices.Map(t.Status.Conditions, (*v1alpha1.IstioCondition).GetType) + return translateIstioCondition(t.Status.Conditions) default: log.Fatalf("unknown type %T; cannot write status", o) } return nil } +func translateIstioCondition(conds []*v1alpha1.IstioCondition) map[string]model.Condition { + res := make(map[string]model.Condition, len(conds)) + for _, cond := range conds { + c := model.Condition{ + ObservedGeneration: cond.ObservedGeneration, + Reason: cond.Reason, + Message: cond.Message, + Status: cond.Status == string(metav1.ConditionTrue), + } + res[cond.Type] = c + } + return res +} + +func translateKubernetesCondition(conds []metav1.Condition) map[string]model.Condition { + res := make(map[string]model.Condition, len(conds)) + for _, cond := range conds { + c := model.Condition{ + ObservedGeneration: cond.ObservedGeneration, + Reason: cond.Reason, + Message: cond.Message, + Status: cond.Status == metav1.ConditionTrue, + } + res[cond.Type] = c + } + return res +} + // Lookup finds all addresses associated with a given key. Many different key formats are supported; see inline comments. func (a *index) Lookup(key string) []model.AddressInfo { // 1. Workload UID - if w := a.workloads.GetKey(krt.Key[model.WorkloadInfo](key)); w != nil { + if w := a.workloads.GetKey(key); w != nil { return []model.AddressInfo{workloadToAddressInfo(w.Workload)} } @@ -383,7 +497,7 @@ func (a *index) Lookup(key string) []model.AddressInfo { func (a *index) lookupService(key string) *model.ServiceInfo { // 1. namespace/hostname format - s := a.services.GetKey(krt.Key[model.ServiceInfo](key)) + s := a.services.GetKey(key) if s != nil { return s } @@ -462,26 +576,60 @@ func (a *index) AddressInformation(addresses sets.String) ([]model.AddressInfo, } func (a *index) ServicesForWaypoint(key model.WaypointKey) []model.ServiceInfo { - var out []model.ServiceInfo + out := map[string]model.ServiceInfo{} for _, host := range key.Hostnames { - out = append(out, a.services.ByOwningWaypoint.Lookup(NamespaceHostname{ + for _, res := range a.services.ByOwningWaypointHostname.Lookup(NamespaceHostname{ Namespace: key.Namespace, Hostname: host, - })...) + }) { + name := res.ResourceName() + if _, f := out[name]; !f { + out[name] = res + } + } } - return out + + for _, addr := range key.Addresses { + for _, res := range a.services.ByOwningWaypointIP.Lookup(networkAddress{ + network: key.Network, + ip: addr, + }) { + name := res.ResourceName() + if _, f := out[name]; !f { + out[name] = res + } + } + } + // Response is unsorted; it is up to the caller to sort + return maps.Values(out) } func (a *index) WorkloadsForWaypoint(key model.WaypointKey) []model.WorkloadInfo { - var out []model.WorkloadInfo + out := map[string]model.WorkloadInfo{} for _, host := range key.Hostnames { - out = append(out, a.workloads.ByOwningWaypoint.Lookup(NamespaceHostname{ + for _, res := range a.workloads.ByOwningWaypointHostname.Lookup(NamespaceHostname{ Namespace: key.Namespace, Hostname: host, - })...) + }) { + name := res.ResourceName() + if _, f := out[name]; !f { + out[name] = res + } + } + } + + for _, addr := range key.Addresses { + for _, res := range a.workloads.ByOwningWaypointIP.Lookup(networkAddress{ + network: key.Network, + ip: addr, + }) { + name := res.ResourceName() + if _, f := out[name]; !f { + out[name] = res + } + } } - out = model.SortWorkloadsByCreationTime(out) - return out + return model.SortWorkloadsByCreationTime(maps.Values(out)) } func (a *index) AdditionalPodSubscriptions( @@ -525,9 +673,36 @@ func (a *index) AdditionalPodSubscriptions( } func (a *index) SyncAll() { + // Reload NetworkGateways, which is expensive to compute each time + raw := a.LookupNetworkGatewaysExpensive() + grouped := slices.Group(raw, func(t model.NetworkGateway) network.ID { + return t.Network + }) + a.networkGateways.Store(ptr.Of(grouped)) a.networkUpdateTrigger.TriggerRecomputation() } +func (a *index) LookupNetworkGateway(id network.ID) []model.NetworkGateway { + n := a.networkGateways.Load() + if n == nil { + return nil + } + return (*n)[id] +} + +func (a *index) LookupAllNetworkGateway() []model.NetworkGateway { + // Since computing the network set is expensive we cache it. Look it up now + n := a.networkGateways.Load() + if n == nil { + return nil + } + res := make([]model.NetworkGateway, 0, len(*n)) + for _, v := range *n { + res = append(res, v...) + } + return res +} + func (a *index) NetworksSynced() { a.networkUpdateTrigger.MarkSynced() } @@ -539,6 +714,8 @@ func (a *index) Run(stop <-chan struct{}) { a.statusQueue.Run(stop) }() } + <-stop + close(a.stop) } func (a *index) HasSynced() bool { diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_serviceentry_test.go b/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_serviceentry_test.go index 6a42ff1f842f..601683b57a14 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_serviceentry_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_serviceentry_test.go @@ -22,7 +22,6 @@ import ( "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/test" "istio.io/istio/pkg/test/util/assert" "istio.io/istio/pkg/workloadapi" ) @@ -332,8 +331,10 @@ func TestAmbientIndex_ServiceEntry(t *testing.T) { } func TestAmbientIndex_ServiceEntry_DisableK8SServiceSelectWorkloadEntries(t *testing.T) { - test.SetForTest(t, &features.EnableK8SServiceSelectWorkloadEntries, false) - s := newAmbientTestServer(t, testC, testNW) + s := newAmbientTestServerWithFlags(t, testC, testNW, FeatureFlags{ + DefaultAllowFromWaypoint: features.DefaultAllowFromWaypoint, + EnableK8SServiceSelectWorkloadEntries: false, + }) s.addPods(t, "140.140.0.10", "pod1", "sa1", map[string]string{"app": "a"}, nil, true, corev1.PodRunning) s.assertEvent(t, s.podXdsName("pod1")) diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_test.go b/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_test.go index 85bdf93bc6ff..519e1673e409 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_test.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" k8sv1 "sigs.k8s.io/gateway-api/apis/v1" k8sbeta "sigs.k8s.io/gateway-api/apis/v1beta1" + "sigs.k8s.io/yaml" "istio.io/api/annotation" "istio.io/api/label" @@ -595,19 +596,93 @@ func TestAmbientIndex_WaypointInboundBinding(t *testing.T) { }, }) s.addWaypoint(t, "1.2.3.4", "proxy-sandwich", constants.AllTraffic, true) - // TODO needing this check seems suspicious. We should really wait for up to 2 pod events. assert.EventuallyEqual(t, func() int { return len(s.waypoints.List()) }, 1) s.addPods(t, "10.0.0.1", "proxy-sandwich-instance", "", map[string]string{label.IoK8sNetworkingGatewayGatewayName.Name: "proxy-sandwich"}, nil, true, corev1.PodRunning) s.assertEvent(t, s.podXdsName("proxy-sandwich-instance")) - appTunnel := s.lookup(s.podXdsName("proxy-sandwich-instance"))[0].GetWorkload().GetApplicationTunnel() - assert.Equal(t, appTunnel, &workloadapi.ApplicationTunnel{ + // We may get 1 or 2 events, depending on ordering, so wait. + assert.EventuallyEqual(t, func() *workloadapi.ApplicationTunnel { + return s.lookup(s.podXdsName("proxy-sandwich-instance"))[0].GetWorkload().GetApplicationTunnel() + }, &workloadapi.ApplicationTunnel{ Protocol: workloadapi.ApplicationTunnel_PROXY, Port: 15088, }) } +func TestAmbientIndex_ServicesForWaypoint(t *testing.T) { + wpKey := model.WaypointKey{ + Namespace: testNS, + Hostnames: []string{fmt.Sprintf("%s.%s.svc.company.com", "wp", testNS)}, + Addresses: []string{"10.0.0.1"}, + Network: testNW, + } + t.Run("hostname", func(t *testing.T) { + s := newAmbientTestServer(t, testC, testNW) + s.addService(t, "svc1", + map[string]string{label.IoIstioUseWaypoint.Name: "wp"}, + map[string]string{}, + []int32{80}, map[string]string{"app": "app1"}, "11.0.0.1") + s.assertEvent(s.t, s.svcXdsName("svc1")) + + s.addWaypointSpecificAddress(t, "", s.hostnameForService("wp"), "wp", constants.AllTraffic, true) + s.addService(t, "wp", + map[string]string{}, + map[string]string{}, + []int32{80}, map[string]string{"app": "waypoint"}, "10.0.0.2") + s.assertEvent(s.t, s.svcXdsName("svc1")) + + svc1Host := ptr.ToList(s.services.GetKey(fmt.Sprintf("%s/%s", testNS, s.hostnameForService("svc1")))) + assert.Equal(t, len(svc1Host), 1) + assert.EventuallyEqual(t, func() []model.ServiceInfo { + return s.ServicesForWaypoint(wpKey) + }, svc1Host) + }) + t.Run("ip", func(t *testing.T) { + s := newAmbientTestServer(t, testC, testNW) + + s.addService(t, "svc1", + map[string]string{label.IoIstioUseWaypoint.Name: "wp"}, + map[string]string{}, + []int32{80}, map[string]string{"app": "app1"}, "11.0.0.1") + s.assertEvent(s.t, s.svcXdsName("svc1")) + + s.addWaypointSpecificAddress(t, "10.0.0.1", "", "wp", constants.AllTraffic, true) + s.addService(t, "wp", + map[string]string{}, + map[string]string{}, + []int32{80}, map[string]string{"app": "waypoint"}, "10.0.0.1") + s.assertEvent(s.t, s.svcXdsName("svc1")) + + svc1Host := ptr.ToList(s.services.GetKey(fmt.Sprintf("%s/%s", testNS, s.hostnameForService("svc1")))) + assert.Equal(t, len(svc1Host), 1) + assert.EventuallyEqual(t, func() []model.ServiceInfo { + return s.ServicesForWaypoint(wpKey) + }, svc1Host) + }) + t.Run("mixed", func(t *testing.T) { + s := newAmbientTestServer(t, testC, testNW) + s.addService(t, "svc1", + map[string]string{label.IoIstioUseWaypoint.Name: "wp"}, + map[string]string{}, + []int32{80}, map[string]string{"app": "app1"}, "11.0.0.1") + s.assertEvent(s.t, s.svcXdsName("svc1")) + + s.addWaypointSpecificAddress(t, "10.0.0.1", s.hostnameForService("wp"), "wp", constants.AllTraffic, true) + s.addService(t, "wp", + map[string]string{}, + map[string]string{}, + []int32{80}, map[string]string{"app": "waypoint"}, "10.0.0.1") + s.assertEvent(s.t, s.svcXdsName("svc1")) + + svc1Host := ptr.ToList(s.services.GetKey(fmt.Sprintf("%s/%s", testNS, s.hostnameForService("svc1")))) + assert.Equal(t, len(svc1Host), 1) + assert.EventuallyEqual(t, func() []model.ServiceInfo { + return s.ServicesForWaypoint(wpKey) + }, svc1Host) + }) +} + // define constants for the different types of XDS events which occur during policy unit tests const ( xdsConvertedPeerAuthSelector = "converted_peer_authentication_selector" @@ -875,10 +950,10 @@ func TestAmbientIndex_Policy(t *testing.T) { } }) s.assertEvent(t, s.podXdsName("pod1"), s.podXdsName("pod2"), xdsConvertedPeerAuthSelector) // Matching pods receive an event - // The policy should still be added since the effective policy is STRICT + // There should be no static strict policy because the permissive override should have the strict part in-line assert.Equal(t, s.lookup(s.addrXdsName("127.0.0.1"))[0].Address.GetWorkload().AuthorizationPolicies, - []string{fmt.Sprintf("istio-system/%s", staticStrictPolicyName), fmt.Sprintf("ns1/%s", model.GetAmbientPolicyConfigName(model.ConfigKey{ + []string{fmt.Sprintf("ns1/%s", model.GetAmbientPolicyConfigName(model.ConfigKey{ Kind: kind.PeerAuthentication, Name: selectorPolicyName, Namespace: "ns1", @@ -1079,14 +1154,16 @@ func TestAmbientIndex_Policy(t *testing.T) { func TestDefaultAllowWaypointPolicy(t *testing.T) { // while the Waypoint is in testNS, the policies live in the Pods' namespaces policyName := "ns1/istio_allow_waypoint_" + testNS + "_" + "waypoint-ns" - test.SetForTest(t, &features.DefaultAllowFromWaypoint, true) - s := newAmbientTestServer(t, testC, testNW) + s := newAmbientTestServerWithFlags(t, testC, testNW, FeatureFlags{ + DefaultAllowFromWaypoint: true, + EnableK8SServiceSelectWorkloadEntries: features.EnableK8SServiceSelectWorkloadEntries, + }) setupPolicyTest(t, s) t.Run("policy with service accounts", func(t *testing.T) { assert.EventuallyEqual(t, func() []string { - waypointPolicy := s.authorizationPolicies.GetKey(krt.Key[model.WorkloadAuthorization](policyName)) + waypointPolicy := s.authorizationPolicies.GetKey(policyName) if waypointPolicy == nil { return nil } @@ -1184,15 +1261,88 @@ func TestRBACConvert(t *testing.T) { }, Spec: *((pol[0].Spec).(*auth.AuthorizationPolicy)), //nolint: govet }) - case gvk.PeerAuthentication: - o = convertPeerAuthentication(systemNS, &clientsecurityv1beta1.PeerAuthentication{ - TypeMeta: metav1.TypeMeta{}, - ObjectMeta: metav1.ObjectMeta{ - Name: pol[0].Name, - Namespace: pol[0].Namespace, - }, - Spec: *((pol[0].Spec).(*auth.PeerAuthentication)), //nolint: govet - }) + case gvk.PeerAuthentication: // we assume all crds in the same file are of the same type + var rootCfg, nsCfg, workloadCfg *config.Config + if len(pol) > 1 { + for _, p := range pol { + switch p.Namespace { + case systemNS: + if p.Spec.(*auth.PeerAuthentication).GetSelector() != nil { + t.Fatalf("unexpected selector in mesh-level policy %v", p) + } + if rootCfg == nil || p.GetCreationTimestamp().Before(rootCfg.GetCreationTimestamp()) { + rootCfg = ptr.Of(p) + } + default: + spec := p.Spec.(*auth.PeerAuthentication) + if spec.GetSelector() != nil && workloadCfg != nil && workloadCfg.Spec.(*auth.PeerAuthentication).GetSelector() != nil { + t.Fatalf("multiple workload-level policies %v and %v", p, workloadCfg) + } + + if spec.GetSelector() != nil { + // Workload policy + workloadCfg = ptr.Of(p) + } else if nsCfg == nil || p.GetCreationTimestamp().Before(nsCfg.GetCreationTimestamp()) { + // Namespace policy + nsCfg = ptr.Of(p) + } + } + } + } + + // Simple case + if len(pol) == 1 { + o = convertPeerAuthentication(systemNS, &clientsecurityv1beta1.PeerAuthentication{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: pol[0].Name, + Namespace: pol[0].Namespace, + }, + Spec: *((pol[0].Spec).(*auth.PeerAuthentication)), //nolint: govet + }, nil, nil) + } else { + var workloadPA, nsPA, rootPA *clientsecurityv1beta1.PeerAuthentication + if workloadCfg != nil { + workloadPA = &clientsecurityv1beta1.PeerAuthentication{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: workloadCfg.Name, + Namespace: workloadCfg.Namespace, + }, + Spec: *((workloadCfg.Spec).(*auth.PeerAuthentication)), //nolint: govet + } + } + if nsCfg != nil { + nsPA = &clientsecurityv1beta1.PeerAuthentication{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: nsCfg.Name, + Namespace: nsCfg.Namespace, + }, + Spec: *((nsCfg.Spec).(*auth.PeerAuthentication)), //nolint: govet + } + } + + if rootCfg != nil { + rootPA = &clientsecurityv1beta1.PeerAuthentication{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: rootCfg.Name, + Namespace: rootCfg.Namespace, + }, + Spec: *((rootCfg.Spec).(*auth.PeerAuthentication)), //nolint: govet + } + } + + if workloadPA == nil { + // We have a namespace policy and a root policy; send the NS policy as the workload policy + // It won't get far anyway since this convert function returns nil for non-workload policies + workloadPA = nsPA + nsPA = nil + } + + o = convertPeerAuthentication(systemNS, workloadPA, nsPA, rootPA) + } default: t.Fatalf("unknown kind %v", pol[0].GroupVersionKind) } @@ -1472,6 +1622,13 @@ type ambientTestServer struct { } func newAmbientTestServer(t *testing.T, clusterID cluster.ID, networkID network.ID) *ambientTestServer { + return newAmbientTestServerWithFlags(t, clusterID, networkID, FeatureFlags{ + DefaultAllowFromWaypoint: features.DefaultAllowFromWaypoint, + EnableK8SServiceSelectWorkloadEntries: features.EnableK8SServiceSelectWorkloadEntries, + }) +} + +func newAmbientTestServerWithFlags(t *testing.T, clusterID cluster.ID, networkID network.ID, flags FeatureFlags) *ambientTestServer { up := xdsfake.NewFakeXDS() up.SplitEvents = true cl := kubeclient.NewFakeClient() @@ -1486,6 +1643,7 @@ func newAmbientTestServer(t *testing.T, clusterID cluster.ID, networkID network. } { clienttest.MakeCRD(t, cl, crd) } + debugger := &krt.DebugHandler{} idx := New(Options{ Client: cl, SystemNamespace: systemNS, @@ -1499,19 +1657,13 @@ func newAmbientTestServer(t *testing.T, clusterID cluster.ID, networkID network. return nil }, StatusNotifier: activenotifier.New(true), + Debugger: debugger, + Flags: flags, }) idx.NetworksSynced() cl.RunAndWait(test.NewStop(t)) - t.Cleanup(func() { - if t.Failed() { - idx := idx.(*index) - krt.Dump(idx.authorizationPolicies) - krt.Dump(idx.workloads.Collection) - krt.Dump(idx.services.Collection) - krt.Dump(idx.waypoints.Collection) - } - }) + dumpOnFailure(t, debugger) a := &ambientTestServer{ t: t, clusterID: clusterID, @@ -1551,6 +1703,15 @@ func newAmbientTestServer(t *testing.T, clusterID cluster.ID, networkID network. return a } +func dumpOnFailure(t *testing.T, debugger *krt.DebugHandler) { + t.Cleanup(func() { + if t.Failed() { + b, _ := yaml.Marshal(debugger) + t.Log(string(b)) + } + }) +} + func (s *ambientTestServer) addWaypoint(t *testing.T, ip, name, trafficType string, ready bool) { s.addWaypointSpecificAddress(t, ip, fmt.Sprintf("%s.%s.svc.%s", name, testNS, s.DomainSuffix), name, trafficType, ready) } diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_workloadentry_test.go b/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_workloadentry_test.go index bf5ed4f4dbaa..9c649a3c0d34 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_workloadentry_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/ambientindex_workloadentry_test.go @@ -25,7 +25,6 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pkg/config/constants" "istio.io/istio/pkg/config/schema/gvk" - "istio.io/istio/pkg/test" "istio.io/istio/pkg/test/util/assert" "istio.io/istio/pkg/workloadapi" ) @@ -346,8 +345,10 @@ func TestAmbientIndex_InlinedWorkloadEntries(t *testing.T) { } func TestAmbientIndex_WorkloadEntries_DisableK8SServiceSelectWorkloadEntries(t *testing.T) { - test.SetForTest(t, &features.EnableK8SServiceSelectWorkloadEntries, false) - s := newAmbientTestServer(t, testC, testNW) + s := newAmbientTestServerWithFlags(t, testC, testNW, FeatureFlags{ + DefaultAllowFromWaypoint: features.DefaultAllowFromWaypoint, + EnableK8SServiceSelectWorkloadEntries: false, + }) s.addWorkloadEntries(t, "127.0.0.1", "name1", "sa1", map[string]string{"app": "a"}) s.assertEvent(t, s.wleXdsName("name1")) diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/authorization.go b/pilot/pkg/serviceregistry/kube/controller/ambient/authorization.go index 1536d16747dc..0f0f633b02a4 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/authorization.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/authorization.go @@ -62,8 +62,18 @@ func (a *index) Policies(requested sets.Set[model.ConfigKey]) []model.WorkloadAu return res } +func getOldestPeerAuthn(policies []*securityclient.PeerAuthentication) *securityclient.PeerAuthentication { + var oldest *securityclient.PeerAuthentication + for _, pol := range policies { + if oldest == nil || pol.CreationTimestamp.Before(&oldest.CreationTimestamp) { + oldest = pol + } + } + return oldest +} + // convertedSelectorPeerAuthentications returns a list of keys corresponding to one or both of: -// [static STRICT policy, port-level STRICT policy] based on the effective PeerAuthentication policy +// [static STRICT policy, port-level (potentially merged) STRICT policy] based on the effective PeerAuthentication policy func convertedSelectorPeerAuthentications(rootNamespace string, configs []*securityclient.PeerAuthentication) []string { var meshCfg, namespaceCfg, workloadCfg *securityclient.PeerAuthentication for _, cfg := range configs { @@ -98,9 +108,7 @@ func convertedSelectorPeerAuthentications(rootNamespace string, configs []*secur // Process in mesh, namespace, workload order to resolve inheritance (UNSET) if meshCfg != nil { - if !isMtlsModeUnset(meshCfg.Spec.Mtls) { - isEffectiveStrictPolicy = isMtlsModeStrict(meshCfg.Spec.Mtls) - } + isEffectiveStrictPolicy = isMtlsModeStrict(meshCfg.Spec.Mtls) } if namespaceCfg != nil { @@ -115,12 +123,10 @@ func convertedSelectorPeerAuthentications(rootNamespace string, configs []*secur workloadSpec := &workloadCfg.Spec - // Regardless of if we have port-level overrides, if the workload policy is STRICT, then we need to reference our static STRICT policy if isMtlsModeStrict(workloadSpec.Mtls) { isEffectiveStrictPolicy = true } - // Regardless of if we have port-level overrides, if the workload policy is PERMISSIVE or DISABLE, then we shouldn't send our static STRICT policy if isMtlsModePermissive(workloadSpec.Mtls) || isMtlsModeDisable(workloadSpec.Mtls) { isEffectiveStrictPolicy = false } @@ -180,6 +186,8 @@ func convertedSelectorPeerAuthentications(rootNamespace string, configs []*secur Kind: kind.PeerAuthentication, Namespace: workloadCfg.Namespace, }) + // We DON'T want to send the static STRICT policy since the merged form of this policy will include the default STRICT mode + isEffectiveStrictPolicy = false } } else { // Permissive mesh or namespace policy @@ -221,15 +229,9 @@ func effectivePeerAuthenticationKeys(rootNamespace string, isEffectiveStringPoli return sets.SortedList(res) } -// convertPeerAuthentication converts a PeerAuthentication to an L4 authorization policy (i.e. security.Authorization) iff -// 1. the PeerAuthentication has a workload selector -// 2. The PeerAuthentication is NOT in the root namespace -// 3. There is a portLevelMtls policy (technically implied by 1) -// 4. If the top-level mode is PERMISSIVE or DISABLE, there is at least one portLevelMtls policy with mode STRICT -// -// STRICT policies that don't have portLevelMtls will be -// handled when the Workload xDS resource is pushed (a static STRICT-equivalent policy will always be pushed) -func convertPeerAuthentication(rootNamespace string, cfg *securityclient.PeerAuthentication) *security.Authorization { +// convertPeerAuthentication converts a PeerAuthentication to an L4 authorization policy (i.e. security.Authorization) +// taking into account the top level policies (and merging if necessary) +func convertPeerAuthentication(rootNamespace string, cfg, nsCfg, rootCfg *securityclient.PeerAuthentication) *security.Authorization { pa := &cfg.Spec mode := pa.GetMtls().GetMode() @@ -278,7 +280,7 @@ func convertPeerAuthentication(rootNamespace string, cfg *securityclient.PeerAut }, }, }) - case portMtlsMode == v1beta1.PeerAuthentication_MutualTLS_PERMISSIVE: + case portMtlsMode == v1beta1.PeerAuthentication_MutualTLS_PERMISSIVE, portMtlsMode == v1beta1.PeerAuthentication_MutualTLS_DISABLE: // Check top-level mode if mode == v1beta1.PeerAuthentication_MutualTLS_PERMISSIVE || mode == v1beta1.PeerAuthentication_MutualTLS_DISABLE { // we don't care; log and continue @@ -286,24 +288,16 @@ func convertPeerAuthentication(rootNamespace string, cfg *securityclient.PeerAut port, portMtlsMode, cfg.Namespace, cfg.Name, mode) continue } - foundNonStrictPortmTLS = true - // If the top level policy is STRICT, we need to add a rule for the port that exempts it from the deny policy - rules = append(rules, &security.Rules{ - Matches: []*security.Match{ - { - NotDestinationPorts: []uint32{port}, // if the incoming connection does not match this port, deny (notice there's no principals requirement) - }, - }, - }) - case portMtlsMode == v1beta1.PeerAuthentication_MutualTLS_DISABLE: - // Check top-level mode - if mode == v1beta1.PeerAuthentication_MutualTLS_PERMISSIVE || mode == v1beta1.PeerAuthentication_MutualTLS_DISABLE { + if mode == v1beta1.PeerAuthentication_MutualTLS_UNSET && ((nsCfg != nil && !isMtlsModeStrict(nsCfg.Spec.Mtls)) || + (nsCfg == nil && rootCfg != nil && !isMtlsModeStrict(rootCfg.Spec.Mtls)) || + (nsCfg == nil && rootCfg == nil)) { // we don't care; log and continue - log.Debugf("skipping port %s/%s for PeerAuthentication %s/%s for ambient since the parent mTLS mode is %s", - port, portMtlsMode, cfg.Namespace, cfg.Name, mode) + log.Debugf("skipping port %s/%s for PeerAuthentication %s/%s for ambient since it's not STRICT and the effective policy is not STRICT", + port, portMtlsMode, cfg.Namespace, cfg.Name) continue } + foundNonStrictPortmTLS = true // If the top level policy is STRICT, we need to add a rule for the port that exempts it from the deny policy @@ -342,6 +336,31 @@ func convertPeerAuthentication(rootNamespace string, cfg *securityclient.PeerAut Groups: []*security.Group{{Rules: rules}}, } + // We only need to merge if the effective policy is STRICT, the workload policy's mode is unstrict, and we have a non-strict port level policy + var shouldMergeStrict bool + // Merge if there's a STRICT root policy and the namespace policy is nil, UNSET or STRICT + if rootCfg != nil && isMtlsModeStrict(rootCfg.Spec.Mtls) && (nsCfg == nil || isMtlsModeUnset(nsCfg.Spec.Mtls) || isMtlsModeStrict(nsCfg.Spec.Mtls)) { + shouldMergeStrict = true + } else if nsCfg != nil && isMtlsModeStrict(nsCfg.Spec.Mtls) { // Merge if there's a STRICT namespace policy + shouldMergeStrict = true + } + + // If the effective policy (namespace or mesh) is STRICT and we have a non-strict port level policy, + // we need to merge that strictness into the workload policy so that the static strict policy + if shouldMergeStrict && foundNonStrictPortmTLS { + opol.Groups[0].Rules = append(opol.Groups[0].Rules, &security.Rules{ + Matches: []*security.Match{ + { + NotPrincipals: []*security.StringMatch{ + { + MatchType: &security.StringMatch_Presence{}, + }, + }, + }, + }, + }) + } + return opol } @@ -410,10 +429,13 @@ func convertAuthorizationPolicy(rootns string, obj *securityclient.Authorization } const ( - httpRuleFmt string = "ztunnel does not support HTTP rules (%s require HTTP parsing), in ambient mode you must use waypoint proxy to enforce HTTP rules. %s" + httpRuleFmt string = "ztunnel does not support HTTP attributes (found: %s). " + + "In ambient mode you must use a waypoint proxy to enforce HTTP rules. %s" - httpDenyRuleBoilerplate string = "Deny rules with HTTP attributes will be enforced without their HTTP components. This is more restrictive than intended." - httpAllowRuleBoilerplate string = "Allow rules with HTTP attributes will be empty and never match. This is more restrictive than requested." + httpDenyRuleBoilerplate string = "DENY policy with HTTP attributes is enforced without the HTTP rules. " + + "This will be more restrictive than requested." + httpAllowRuleBoilerplate string = "Within an ALLOW policy, rules matching HTTP attributes are omitted. " + + "This will be more restrictive than requested." ) func httpOperations(op *v1beta1.Operation) []string { diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/authorization_test.go b/pilot/pkg/serviceregistry/kube/controller/ambient/authorization_test.go index 027c18beb17e..2b1d7a48131e 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/authorization_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/authorization_test.go @@ -198,9 +198,10 @@ func TestConvertAuthorizationPolicyStatus(t *testing.T) { }, expectStatusMessage: &model.StatusMessage{ Reason: "UnsupportedValue", - Message: "ztunnel does not support HTTP rules (methods, request.auth.presenter, requestPrincipals require HTTP parsing), in ambient" + - " mode you must use waypoint proxy to enforce HTTP rules. Allow rules with HTTP attributes will be empty and never match." + - " This is more restrictive than requested.", + Message: "ztunnel does not support HTTP attributes (found: methods, request.auth.presenter, requestPrincipals). " + + "In ambient mode you must use a waypoint proxy to enforce HTTP rules. " + + "Within an ALLOW policy, rules matching HTTP attributes are omitted. " + + "This will be more restrictive than requested.", }, }, } @@ -257,7 +258,7 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { } }) - wpsCollection := WaypointPolicyStatusCollection(authzPolCol, waypointCol, svcCol, seCol, nsCol) + wpsCollection := WaypointPolicyStatusCollection(authzPolCol, waypointCol, svcCol, seCol, nsCol, KrtOptions{}) c.RunAndWait(ctx.Done()) _, err := clientNs.Create(&v1.Namespace{ @@ -292,16 +293,18 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { serviceEntries: []networkingclient.ServiceEntry{ { ObjectMeta: metav1.ObjectMeta{ - Name: "working-se", - Namespace: testNS, + Name: "working-se", + Namespace: testNS, + Generation: 1, }, Spec: v1alpha3.ServiceEntry{}, }, }, policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "working-se-pol", - Namespace: testNS, + Name: "working-se-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -322,7 +325,48 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAccepted, Message: "bound to " + testNS + "/waypoint", }, - Bound: true, + Bound: true, + ObservedGeneration: 1, + }, + }, + }, + { + testName: "single-bind-success-serviceentry-targetRef", + serviceEntries: []networkingclient.ServiceEntry{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "working-se-tr", + Namespace: testNS, + Generation: 1, + }, + Spec: v1alpha3.ServiceEntry{}, + }, + }, + policy: securityclient.AuthorizationPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "working-se-pol-tr", + Namespace: testNS, + Generation: 1, + }, + Spec: v1beta1.AuthorizationPolicy{ + TargetRef: &apiv1beta1.PolicyTargetReference{ + Group: gvk.ServiceEntry.Group, + Kind: gvk.ServiceEntry.Kind, + Name: "working-se-tr", + }, + Rules: []*v1beta1.Rule{}, + Action: 0, + }, + }, + expect: []model.PolicyBindingStatus{ + { + Ancestor: "ServiceEntry.networking.istio.io:ns1/working-se-tr", + Status: &model.StatusMessage{ + Reason: model.WaypointPolicyReasonAccepted, + Message: "bound to " + testNS + "/waypoint", + }, + Bound: true, + ObservedGeneration: 1, }, }, }, @@ -336,14 +380,16 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Labels: map[string]string{ label.IoIstioUseWaypoint.Name: "none", }, + Generation: 1, }, Spec: v1alpha3.ServiceEntry{}, }, }, policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "no-waypoint-se-pol", - Namespace: testNS, + Name: "no-waypoint-se-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -364,7 +410,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAncestorNotBound, Message: gvk.ServiceEntry.Kind + " " + testNS + "/no-waypoint-se is not bound to a waypoint", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, }, }, @@ -373,8 +420,9 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { serviceEntries: []networkingclient.ServiceEntry{}, policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "missing-se-pol", - Namespace: testNS, + Name: "missing-se-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -395,7 +443,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonTargetNotFound, Message: gvk.ServiceEntry.Kind + " " + testNS + "/missing-se was not found", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, }, }, @@ -404,23 +453,26 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { serviceEntries: []networkingclient.ServiceEntry{ { ObjectMeta: metav1.ObjectMeta{ - Name: "multi-working-se-1", - Namespace: testNS, + Name: "multi-working-se-1", + Namespace: testNS, + Generation: 1, }, Spec: v1alpha3.ServiceEntry{}, }, { ObjectMeta: metav1.ObjectMeta{ - Name: "multi-working-se-2", - Namespace: testNS, + Name: "multi-working-se-2", + Namespace: testNS, + Generation: 1, }, Spec: v1alpha3.ServiceEntry{}, }, }, policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "multi-working-se-pol", - Namespace: testNS, + Name: "multi-working-se-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -446,7 +498,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAccepted, Message: "bound to " + testNS + "/waypoint", }, - Bound: true, + Bound: true, + ObservedGeneration: 1, }, { Ancestor: "ServiceEntry.networking.istio.io:ns1/multi-working-se-2", @@ -454,7 +507,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAccepted, Message: "bound to " + testNS + "/waypoint", }, - Bound: true, + Bound: true, + ObservedGeneration: 1, }, }, }, @@ -468,21 +522,24 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Labels: map[string]string{ label.IoIstioUseWaypoint.Name: "none", }, + Generation: 1, }, Spec: v1alpha3.ServiceEntry{}, }, { ObjectMeta: metav1.ObjectMeta{ - Name: "multi-partial-bound-se-1", - Namespace: testNS, + Name: "multi-partial-bound-se-1", + Namespace: testNS, + Generation: 1, }, Spec: v1alpha3.ServiceEntry{}, }, }, policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "multi-partial-se-pol", - Namespace: testNS, + Name: "multi-partial-se-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -513,7 +570,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAncestorNotBound, Message: gvk.ServiceEntry.Kind + " " + testNS + "/multi-partial-no-waypoint-se-1 is not bound to a waypoint", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, { Ancestor: "ServiceEntry.networking.istio.io:ns1/multi-partial-bound-se-1", @@ -521,7 +579,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAccepted, Message: "bound to " + testNS + "/waypoint", }, - Bound: true, + Bound: true, + ObservedGeneration: 1, }, { Ancestor: "ServiceEntry.networking.istio.io:ns1/multi-partial-missing-se-1", @@ -529,7 +588,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonTargetNotFound, Message: gvk.ServiceEntry.Kind + " " + testNS + "/multi-partial-missing-se-1 was not found", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, }, }, @@ -538,16 +598,18 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { services: []v1.Service{ { ObjectMeta: metav1.ObjectMeta{ - Name: "working-service", - Namespace: testNS, + Name: "working-service", + Namespace: testNS, + Generation: 1, }, Spec: v1.ServiceSpec{}, }, }, policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "working-service-pol", - Namespace: testNS, + Name: "working-service-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -568,7 +630,48 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAccepted, Message: "bound to " + testNS + "/waypoint", }, - Bound: true, + Bound: true, + ObservedGeneration: 1, + }, + }, + }, + { + testName: "single-bind-success-service-targetRef", + services: []v1.Service{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "working-service-tr", + Namespace: testNS, + Generation: 1, + }, + Spec: v1.ServiceSpec{}, + }, + }, + policy: securityclient.AuthorizationPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "working-service-pol-tr", + Namespace: testNS, + Generation: 1, + }, + Spec: v1beta1.AuthorizationPolicy{ + TargetRef: &apiv1beta1.PolicyTargetReference{ + Group: gvk.Service.Group, + Kind: gvk.Service.Kind, + Name: "working-service-tr", + }, + Rules: []*v1beta1.Rule{}, + Action: 0, + }, + }, + expect: []model.PolicyBindingStatus{ + { + Ancestor: "Service.core:ns1/working-service-tr", + Status: &model.StatusMessage{ + Reason: model.WaypointPolicyReasonAccepted, + Message: "bound to " + testNS + "/waypoint", + }, + Bound: true, + ObservedGeneration: 1, }, }, }, @@ -582,14 +685,16 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Labels: map[string]string{ label.IoIstioUseWaypoint.Name: "none", }, + Generation: 1, }, Spec: v1.ServiceSpec{}, }, }, policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "no-waypoint-service-pol", - Namespace: testNS, + Name: "no-waypoint-service-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -610,7 +715,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAncestorNotBound, Message: "Service " + testNS + "/no-waypoint-service is not bound to a waypoint", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, }, }, @@ -618,8 +724,9 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { testName: "single-bind-no-service", policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "no-service-pol", - Namespace: testNS, + Name: "no-service-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -640,7 +747,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonTargetNotFound, Message: "Service " + testNS + "/no-service was not found", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, }, }, @@ -648,8 +756,41 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { testName: "single-bind-success-gateway", policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "single-gateway-pol", - Namespace: testNS, + Name: "single-gateway-pol", + Namespace: testNS, + Generation: 1, + }, + Spec: v1beta1.AuthorizationPolicy{ + TargetRefs: []*apiv1beta1.PolicyTargetReference{ + { + Group: gvk.KubernetesGateway.Group, + Kind: gvk.KubernetesGateway.Kind, + Name: "waypoint", + }, + }, + Rules: []*v1beta1.Rule{}, + Action: 0, + }, + }, + expect: []model.PolicyBindingStatus{ + { + Ancestor: "Gateway.gateway.networking.k8s.io:ns1/waypoint", + Status: &model.StatusMessage{ + Reason: model.WaypointPolicyReasonAccepted, + Message: "bound to " + testNS + "/waypoint", + }, + Bound: true, + ObservedGeneration: 1, + }, + }, + }, + { + testName: "single-bind-success-gateway-targetRef", + policy: securityclient.AuthorizationPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "single-gateway-pol-tr", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -670,7 +811,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAccepted, Message: "bound to " + testNS + "/waypoint", }, - Bound: true, + Bound: true, + ObservedGeneration: 1, }, }, }, @@ -678,8 +820,9 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { testName: "single-bind-no-gateway", policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "single-no-gateway-pol", - Namespace: testNS, + Name: "single-no-gateway-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -700,7 +843,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonTargetNotFound, Message: "not bound", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, }, }, @@ -708,8 +852,9 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { testName: "multi-bind-partial-all-resources", policy: securityclient.AuthorizationPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "multi-partial-all-pol", - Namespace: testNS, + Name: "multi-partial-all-pol", + Namespace: testNS, + Generation: 1, }, Spec: v1beta1.AuthorizationPolicy{ TargetRefs: []*apiv1beta1.PolicyTargetReference{ @@ -765,7 +910,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAccepted, Message: "bound to " + testNS + "/waypoint", }, - Bound: true, + Bound: true, + ObservedGeneration: 1, }, { Ancestor: "ServiceEntry.networking.istio.io:ns1/no-waypoint-se", @@ -773,7 +919,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAncestorNotBound, Message: gvk.ServiceEntry.Kind + " " + testNS + "/no-waypoint-se is not bound to a waypoint", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, { Ancestor: "ServiceEntry.networking.istio.io:ns1/missing-se", @@ -781,7 +928,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonTargetNotFound, Message: gvk.ServiceEntry.Kind + " " + testNS + "/missing-se was not found", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, { Ancestor: "Service.core:ns1/working-service", @@ -789,7 +937,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAccepted, Message: "bound to " + testNS + "/waypoint", }, - Bound: true, + Bound: true, + ObservedGeneration: 1, }, { Ancestor: "Service.core:ns1/no-waypoint-service", @@ -797,7 +946,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAncestorNotBound, Message: "Service " + testNS + "/no-waypoint-service is not bound to a waypoint", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, { Ancestor: "Service.core:ns1/no-service", @@ -805,7 +955,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonTargetNotFound, Message: "Service " + testNS + "/no-service was not found", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, { Ancestor: "Gateway.gateway.networking.k8s.io:ns1/waypoint", @@ -813,7 +964,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonAccepted, Message: "bound to " + testNS + "/waypoint", }, - Bound: true, + Bound: true, + ObservedGeneration: 1, }, { Ancestor: "Gateway.gateway.networking.k8s.io:ns1/not-a-waypoint", @@ -821,7 +973,8 @@ func TestWaypointPolicyStatusCollection(t *testing.T) { Reason: model.WaypointPolicyReasonTargetNotFound, Message: "not bound", }, - Bound: false, + Bound: false, + ObservedGeneration: 1, }, }, }, @@ -866,5 +1019,5 @@ type TestWaypointPolicyStatusCollectionTestCase struct { } func getStatus[T any](col krt.Collection[T], name, namespace string) *T { - return col.GetKey(krt.Key[T](namespace + "/" + name)) + return col.GetKey(namespace + "/" + name) } diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/meshconfig.go b/pilot/pkg/serviceregistry/kube/controller/ambient/meshconfig.go index 14bdb3c3ae28..4169b2320cb3 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/meshconfig.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/meshconfig.go @@ -31,11 +31,11 @@ type MeshConfig struct { *meshapi.MeshConfig } -func (m MeshConfig) ResourceName() string { return " " } +func (m MeshConfig) ResourceName() string { return "MeshConfig" } func (m MeshConfig) Equals(other MeshConfig) bool { return proto.Equal(m.MeshConfig, other.MeshConfig) } -func MeshConfigCollection(configMaps krt.Collection[*v1.ConfigMap], options Options) krt.Singleton[MeshConfig] { +func MeshConfigCollection(configMaps krt.Collection[*v1.ConfigMap], options Options, opts KrtOptions) krt.Singleton[MeshConfig] { cmName := "istio" if options.Revision != "" && options.Revision != "default" { cmName = cmName + "-" + options.Revision @@ -60,7 +60,7 @@ func MeshConfigCollection(configMaps krt.Collection[*v1.ConfigMap], options Opti meshCfg = n } return &MeshConfig{meshCfg} - }, krt.WithName("MeshConfig"), + }, opts.WithName("MeshConfig")..., ) } diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/policies.go b/pilot/pkg/serviceregistry/kube/controller/ambient/policies.go index 15bee7e599a6..0709ae4e6df7 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/policies.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/policies.go @@ -23,24 +23,26 @@ import ( networkingclient "istio.io/client-go/pkg/apis/networking/v1" securityclient "istio.io/client-go/pkg/apis/security/v1" - "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" "istio.io/istio/pkg/config/schema/gvk" "istio.io/istio/pkg/kube/krt" + "istio.io/istio/pkg/log" "istio.io/istio/pkg/slices" "istio.io/istio/pkg/spiffe" "istio.io/istio/pkg/workloadapi/security" ) -func WaypointPolicyStatusCollection(authzPolicies krt.Collection[*securityclient.AuthorizationPolicy], +func WaypointPolicyStatusCollection( + authzPolicies krt.Collection[*securityclient.AuthorizationPolicy], waypoints krt.Collection[Waypoint], services krt.Collection[*corev1.Service], serviceEntries krt.Collection[*networkingclient.ServiceEntry], namespaces krt.Collection[*corev1.Namespace], + opts KrtOptions, ) krt.Collection[model.WaypointPolicyStatus] { return krt.NewCollection(authzPolicies, func(ctx krt.HandlerContext, i *securityclient.AuthorizationPolicy) *model.WaypointPolicyStatus { - targetRefs := i.Spec.GetTargetRefs() + targetRefs := model.GetTargetRefs(&i.Spec) if len(targetRefs) == 0 { return nil // targetRef is required for binding to waypoint } @@ -104,6 +106,7 @@ func WaypointPolicyStatusCollection(authzPolicies krt.Collection[*securityclient targetGroup = "core" } conditions = append(conditions, model.PolicyBindingStatus{ + ObservedGeneration: i.GetGeneration(), Status: &model.StatusMessage{ Reason: reason, Message: message, @@ -117,7 +120,7 @@ func WaypointPolicyStatusCollection(authzPolicies krt.Collection[*securityclient Source: MakeSource(i), Conditions: conditions, } - }, krt.WithName("WaypointPolicyStatuses")) + }, opts.WithName("WaypointPolicyStatuses")...) } func PolicyCollections( @@ -125,6 +128,8 @@ func PolicyCollections( peerAuths krt.Collection[*securityclient.PeerAuthentication], meshConfig krt.Singleton[MeshConfig], waypoints krt.Collection[Waypoint], + opts KrtOptions, + flags FeatureFlags, ) (krt.Collection[model.WorkloadAuthorization], krt.Collection[model.WorkloadAuthorization]) { AuthzDerivedPolicies := krt.NewCollection(authzPolicies, func(ctx krt.HandlerContext, i *securityclient.AuthorizationPolicy) *model.WorkloadAuthorization { meshCfg := krt.FetchOne(ctx, meshConfig.AsCollection()) @@ -138,16 +143,67 @@ func PolicyCollections( LabelSelector: model.NewSelector(i.Spec.GetSelector().GetMatchLabels()), Source: MakeSource(i), Binding: model.PolicyBindingStatus{ - Ancestor: string(model.Ztunnel), - Status: status, - Bound: pol != nil, + ObservedGeneration: i.GetGeneration(), + Ancestor: string(model.Ztunnel), + Status: status, + Bound: pol != nil, }, } - }, krt.WithName("AuthzDerivedPolicies")) + }, opts.WithName("AuthzDerivedPolicies")...) + + PeerAuthByNamespace := krt.NewIndex(peerAuths, func(p *securityclient.PeerAuthentication) []string { + if p.Spec.GetSelector() == nil { + return []string{p.GetNamespace()} + } + return nil + }) + // Our derived PeerAuthentication policies are the effective (i.e. potentially merged) set of policies we will send down to ztunnel + // A policy is sent iff (if and only if): + // 1. the PeerAuthentication has a workload selector + // 2. The PeerAuthentication is NOT in the root namespace + // 3. There is a portLevelMtls policy (technically implied by 1) + // 4. If the top-level mode is PERMISSIVE or DISABLE, there is at least one portLevelMtls policy with mode STRICT + // + // STRICT policies that don't have portLevelMtls will be + // handled when the Workload xDS resource is pushed (a static STRICT-equivalent policy will always be pushed) + // + // As a corollary, if the effective top-level policy is STRICT, the workload policy.mode is UNSET + // and the portLevelMtls policy.mode is STRICT, we will merge the portLevelMtls policy with our static strict policy + // (which basically just looks like setting the workload policy.mode to STRICT). This is because our precedence order for policy + // requires that traffic matching *any* DENY policy is blocked, so attaching 2 polciies (the static strict policy + an exception) + // does not work (the traffic will be blocked despite the exception) PeerAuthDerivedPolicies := krt.NewCollection(peerAuths, func(ctx krt.HandlerContext, i *securityclient.PeerAuthentication) *model.WorkloadAuthorization { meshCfg := krt.FetchOne(ctx, meshConfig.AsCollection()) - pol := convertPeerAuthentication(meshCfg.GetRootNamespace(), i) + // violates case #1, #2, or #3 + if i.Namespace == meshCfg.GetRootNamespace() || i.Spec.GetSelector() == nil || len(i.Spec.PortLevelMtls) == 0 { + log.Debugf("skipping PeerAuthentication %s/%s for ambient since it isn't a workload policy with port level mTLS", i.Namespace, i.Name) + return nil + } + + var nsPol, rootPol *securityclient.PeerAuthentication + nsPols := PeerAuthByNamespace.Lookup(i.GetNamespace()) + rootPols := PeerAuthByNamespace.Lookup(meshCfg.GetRootNamespace()) + + switch len(nsPols) { + case 0: + nsPol = nil + case 1: + nsPol = nsPols[0] + default: + nsPol = getOldestPeerAuthn(nsPols) + } + + switch len(rootPols) { + case 0: + rootPol = nil + case 1: + rootPol = rootPols[0] + default: + rootPol = getOldestPeerAuthn(rootPols) + } + + pol := convertPeerAuthentication(meshCfg.GetRootNamespace(), i, nsPol, rootPol) if pol == nil { return nil } @@ -155,11 +211,11 @@ func PolicyCollections( Authorization: pol, LabelSelector: model.NewSelector(i.Spec.GetSelector().GetMatchLabels()), } - }, krt.WithName("PeerAuthDerivedPolicies")) + }, opts.WithName("PeerAuthDerivedPolicies")...) ImplicitWaypointPolicies := krt.NewCollection(waypoints, func(ctx krt.HandlerContext, waypoint Waypoint) *model.WorkloadAuthorization { - return implicitWaypointPolicy(ctx, meshConfig, waypoint) - }, krt.WithName("DefaultAllowFromWaypointPolicies")) + return implicitWaypointPolicy(flags, ctx, meshConfig, waypoint) + }, opts.WithName("DefaultAllowFromWaypointPolicies")...) DefaultPolicy := krt.NewSingleton[model.WorkloadAuthorization](func(ctx krt.HandlerContext) *model.WorkloadAuthorization { if len(krt.Fetch(ctx, peerAuths)) == 0 { @@ -193,34 +249,40 @@ func PolicyCollections( }, }, } - }, krt.WithName("DefaultPolicy")) + }, opts.WithName("DefaultPolicy")...) // Policies contains all of the policies we will send down to clients + // No need to add withDebug on join since it is trivial Policies := krt.JoinCollection([]krt.Collection[model.WorkloadAuthorization]{ AuthzDerivedPolicies, PeerAuthDerivedPolicies, DefaultPolicy.AsCollection(), ImplicitWaypointPolicies, - }, krt.WithName("Policies")) + }, opts.WithName("Policies")...) return AuthzDerivedPolicies, Policies } -func implicitWaypointPolicyName(waypoint *Waypoint) string { - if !features.DefaultAllowFromWaypoint || waypoint == nil || len(waypoint.ServiceAccounts) == 0 { +func implicitWaypointPolicyName(flags FeatureFlags, waypoint *Waypoint) string { + if !flags.DefaultAllowFromWaypoint || waypoint == nil || len(waypoint.ServiceAccounts) == 0 { return "" } // use '_' character since those are illegal in k8s names return "istio_allow_waypoint_" + waypoint.Namespace + "_" + waypoint.Name } -func implicitWaypointPolicy(ctx krt.HandlerContext, MeshConfig krt.Singleton[MeshConfig], waypoint Waypoint) *model.WorkloadAuthorization { - if !features.DefaultAllowFromWaypoint || len(waypoint.ServiceAccounts) == 0 { +func implicitWaypointPolicy( + flags FeatureFlags, + ctx krt.HandlerContext, + MeshConfig krt.Singleton[MeshConfig], + waypoint Waypoint, +) *model.WorkloadAuthorization { + if !flags.DefaultAllowFromWaypoint || len(waypoint.ServiceAccounts) == 0 { return nil } meshCfg := krt.FetchOne(ctx, MeshConfig.AsCollection()) return &model.WorkloadAuthorization{ Authorization: &security.Authorization{ - Name: implicitWaypointPolicyName(&waypoint), + Name: implicitWaypointPolicyName(flags, &waypoint), Namespace: waypoint.Namespace, // note: we don't actually use label selection; the names have an internally well-known format // workload generation will append a reference to this diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/services.go b/pilot/pkg/serviceregistry/kube/controller/ambient/services.go index 153170e4d69c..577a1964e29a 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/services.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/services.go @@ -43,10 +43,13 @@ func (a *index) ServicesCollection( serviceEntries krt.Collection[*networkingclient.ServiceEntry], waypoints krt.Collection[Waypoint], namespaces krt.Collection[*v1.Namespace], + opts KrtOptions, ) krt.Collection[model.ServiceInfo] { - ServicesInfo := krt.NewCollection(services, a.serviceServiceBuilder(waypoints, namespaces), krt.WithName("ServicesInfo")) - ServiceEntriesInfo := krt.NewManyCollection(serviceEntries, a.serviceEntryServiceBuilder(waypoints, namespaces), krt.WithName("ServiceEntriesInfo")) - WorkloadServices := krt.JoinCollection([]krt.Collection[model.ServiceInfo]{ServicesInfo, ServiceEntriesInfo}, krt.WithName("WorkloadServices")) + ServicesInfo := krt.NewCollection(services, a.serviceServiceBuilder(waypoints, namespaces), + opts.WithName("ServicesInfo")...) + ServiceEntriesInfo := krt.NewManyCollection(serviceEntries, a.serviceEntryServiceBuilder(waypoints, namespaces), + opts.WithName("ServiceEntriesInfo")...) + WorkloadServices := krt.JoinCollection([]krt.Collection[model.ServiceInfo]{ServicesInfo, ServiceEntriesInfo}, opts.WithName("WorkloadService")...) return WorkloadServices } @@ -55,6 +58,14 @@ func (a *index) serviceServiceBuilder( namespaces krt.Collection[*v1.Namespace], ) krt.TransformationSingle[*v1.Service, model.ServiceInfo] { return func(ctx krt.HandlerContext, s *v1.Service) *model.ServiceInfo { + if s.Spec.Type == v1.ServiceTypeExternalName { + // ExternalName services are not implemented by ambient (but will still work). + // The DNS requests will forward to the upstream DNS server, then Ztunnel can handle the request based on the target + // hostname. + // In theory we could add support for native 'DNS alias' into Ztunnel's DNS proxy. This would give the same behavior + // but let the DNS proxy handle it instead of forwarding upstream. However, at this time we do not do so. + return nil + } portNames := map[int32]model.ServicePortName{} for _, p := range s.Spec.Ports { portNames[p.Port] = model.ServicePortName{ @@ -66,7 +77,12 @@ func (a *index) serviceServiceBuilder( waypoint, wperr := fetchWaypointForService(ctx, waypoints, namespaces, s.ObjectMeta) if waypoint != nil { waypointStatus.ResourceName = waypoint.ResourceName() - waypointStatus.IngressUseWaypoint = s.Labels["istio.io/ingress-use-waypoint"] == "true" + + // TODO: add this label to the istio api labels so we have constants to use + if val, ok := s.Labels["istio.io/ingress-use-waypoint"]; ok { + waypointStatus.IngressLabelPresent = true + waypointStatus.IngressUseWaypoint = strings.EqualFold(val, "true") + } } waypointStatus.Error = wperr diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/services_test.go b/pilot/pkg/serviceregistry/kube/controller/ambient/services_test.go index e2d514394ecf..f8410e22ec26 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/services_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/services_test.go @@ -27,7 +27,6 @@ import ( "istio.io/api/label" networking "istio.io/api/networking/v1alpha3" networkingclient "istio.io/client-go/pkg/apis/networking/v1" - "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" "istio.io/istio/pkg/config/constants" "istio.io/istio/pkg/kube/krt" @@ -440,7 +439,6 @@ func TestServiceEntryServices(t *testing.T) { } for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { - features.EnableIPAutoallocate = true mock := krttest.NewMock(t, tt.inputs) a := newAmbientUnitTest() builder := a.serviceEntryServiceBuilder( @@ -502,6 +500,21 @@ func TestServiceServices(t *testing.T) { }}, }, }, + { + name: "external name", + inputs: []any{}, + svc: &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "ns", + }, + Spec: v1.ServiceSpec{ + Type: v1.ServiceTypeExternalName, + ExternalName: "example.com", + }, + }, + result: nil, + }, { name: "target ports", inputs: []any{}, @@ -759,7 +772,141 @@ func TestServiceServices(t *testing.T) { krttest.GetMockCollection[*v1.Namespace](mock), ) res := builder(krt.TestingDummyContext{}, tt.svc) - assert.Equal(t, res.Service, tt.result) + if res == nil { + assert.Equal(t, nil, tt.result) + } else { + assert.Equal(t, res.Service, tt.result) + } + }) + } +} + +func TestServiceConditions(t *testing.T) { + waypointAddr := &workloadapi.GatewayAddress{ + Destination: &workloadapi.GatewayAddress_Hostname{ + Hostname: &workloadapi.NamespacedHostname{ + Namespace: "ns", + Hostname: "hostname.example", + }, + }, + // TODO: look up the HBONE port instead of hardcoding it + HboneMtlsPort: 15008, + } + + waypoint := Waypoint{ + Named: krt.Named{ + Name: "waypoint", + Namespace: "waypoint-ns", + }, + TrafficType: constants.AllTraffic, + Address: waypointAddr, + AllowedRoutes: WaypointSelector{ + FromNamespaces: gatewayv1.NamespacesFromSelector, + Selector: labels.ValidatedSetSelector(map[string]string{v1.LabelMetadataName: "ns"}), + }, + } + + ns := &v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ns", + Labels: map[string]string{ + v1.LabelMetadataName: "ns", + }, + }, + } + + makeServiceWithLabels := func(labels map[string]string) *v1.Service { + return &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "ns", + Labels: labels, + }, + Spec: v1.ServiceSpec{ + ClusterIP: "1.2.3.4", + Ports: []v1.ServicePort{{ + Port: 80, + Name: "http", + }}, + }, + } + } + + cases := []struct { + name string + inputs []any + svc *v1.Service + result *workloadapi.Service + conditions model.ConditionSet + }{ + { + name: "service bound to waypoint", + inputs: []any{ + waypoint, + ns, + }, + svc: makeServiceWithLabels(map[string]string{ + label.IoIstioUseWaypoint.Name: "waypoint", + label.IoIstioUseWaypointNamespace.Name: "waypoint-ns", + }), + conditions: map[model.ConditionType]*model.Condition{ + model.WaypointBound: { + Status: true, + Reason: string(model.WaypointAccepted), + Message: "Successfully attached to waypoint waypoint-ns/waypoint", + }, + }, + }, + { + name: "service bound to waypoint and using waypoint for ingress", + inputs: []any{ + waypoint, + ns, + }, + svc: makeServiceWithLabels(map[string]string{ + label.IoIstioUseWaypoint.Name: "waypoint", + label.IoIstioUseWaypointNamespace.Name: "waypoint-ns", + "istio.io/ingress-use-waypoint": "true", + }), + conditions: map[model.ConditionType]*model.Condition{ + model.WaypointBound: { + Status: true, + Reason: string(model.WaypointAccepted), + Message: "Successfully attached to waypoint waypoint-ns/waypoint. Ingress traffic will traverse the waypoint", + }, + }, + }, + { + name: "service bound to waypoint and ingress label is malformed", + inputs: []any{ + waypoint, + ns, + }, + svc: makeServiceWithLabels(map[string]string{ + label.IoIstioUseWaypoint.Name: "waypoint", + label.IoIstioUseWaypointNamespace.Name: "waypoint-ns", + "istio.io/ingress-use-waypoint": "eurt", + }), + conditions: map[model.ConditionType]*model.Condition{ + model.WaypointBound: { + Status: true, + Reason: string(model.WaypointAccepted), + Message: "Successfully attached to waypoint waypoint-ns/waypoint. " + + "Ingress traffic is not using the waypoint, set the istio.io/ingress-use-waypoint label to true if desired.", + }, + }, + }, + } + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + mock := krttest.NewMock(t, tt.inputs) + a := newAmbientUnitTest() + builder := a.serviceServiceBuilder( + krttest.GetMockCollection[Waypoint](mock), + krttest.GetMockCollection[*v1.Namespace](mock), + ) + res := builder(krt.TestingDummyContext{}, tt.svc) + assert.Equal(t, res.GetConditions(), tt.conditions) }) } } diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/sidecar_interop.go b/pilot/pkg/serviceregistry/kube/controller/ambient/sidecar_interop.go index f6c005107830..5991caedc7cc 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/sidecar_interop.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/sidecar_interop.go @@ -51,6 +51,7 @@ func RegisterEdsShim( WorkloadsByServiceKey krt.Index[string, model.WorkloadInfo], Services krt.Collection[model.ServiceInfo], ServicesByAddress krt.Index[networkAddress, model.ServiceInfo], + opts KrtOptions, ) { ServiceEds := krt.NewCollection( Services, @@ -91,7 +92,7 @@ func RegisterEdsShim( }), } }, - krt.WithName("ServiceEds")) + opts.WithName("ServiceEds")...) ServiceEds.RegisterBatch( PushXds(xdsUpdater, func(svc serviceEDS) model.ConfigKey { ns, hostname, _ := strings.Cut(svc.ServiceKey, "/") @@ -105,7 +106,7 @@ func (a *index) ServicesWithWaypoint(key string) []model.ServiceWaypointInfo { if key == "" { svcs = a.services.List() } else { - svcs = ptr.ToList(a.services.GetKey(krt.Key[model.ServiceInfo](key))) + svcs = ptr.ToList(a.services.GetKey(key)) } for _, s := range svcs { wp := s.Service.GetWaypoint() diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/conversion.go b/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/conversion.go index 8e871dbae327..f8e54815f05b 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/conversion.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/conversion.go @@ -25,7 +25,6 @@ import ( "istio.io/istio/pkg/config/schema/collections" "istio.io/istio/pkg/config/schema/resource" "istio.io/istio/pkg/slices" - "istio.io/istio/pkg/util/smallset" ) type statusConditions struct { @@ -42,31 +41,40 @@ type conditions struct { // translateToPatch converts a ConditionSet to a patch // The ConditionSet is expected to contain all Types owned by this controller; if they should be unset, they should nil. // Failure to do so means the status may not properly get pruned. -func translateToPatch(object model.TypedObject, status model.ConditionSet, currentConditionsList []string) []byte { - currentConditions := smallset.New(currentConditionsList...) +// currentConditions must be set to the current conditions. This is used to determine if we need a write. +// Note: we do not simply rely on SSA to tell us if a change is needed, because every write does a mutation due to LastTransitionTime. +func translateToPatch(object model.TypedObject, status model.ConditionSet, currentConditions map[string]model.Condition) []byte { conds := make([]any, 0, len(status)) - needsDelete := false + changesNeeded := false - for t, values := range status { - if currentConditions.Contains(string(t)) { - needsDelete = true + for t, v := range status { + nowExists := v != nil + cc, curExists := currentConditions[string(t)] + if nowExists != curExists { + changesNeeded = true } - for _, v := range values { - s := string(metav1.ConditionFalse) - if v.Status { - s = string(metav1.ConditionTrue) - } - conds = append(conds, &v1alpha1.IstioCondition{ - Type: string(t), - Status: s, - LastTransitionTime: timestamppb.Now(), - Reason: v.Reason, - Message: v.Message, - }) + if !nowExists { + continue } + if !cc.Equals(v) { + changesNeeded = true + } + + s := string(metav1.ConditionFalse) + if v.Status { + s = string(metav1.ConditionTrue) + } + conds = append(conds, &v1alpha1.IstioCondition{ + Type: string(t), + Status: s, + LastTransitionTime: timestamppb.Now(), + Reason: v.Reason, + Message: v.Message, + ObservedGeneration: v.ObservedGeneration, + }) } - if len(conds) == 0 && !needsDelete { + if !changesNeeded { return nil } // TODO: it would be nice to have a more direct kind -> GVK mapping diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/conversion_test.go b/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/conversion_test.go new file mode 100644 index 000000000000..52f54d0e911d --- /dev/null +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/conversion_test.go @@ -0,0 +1,79 @@ +// Copyright Istio Authors +// +// Licensed 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 statusqueue + +import ( + "testing" + + "istio.io/istio/pilot/pkg/model" + "istio.io/istio/pkg/config/schema/kind" + "istio.io/istio/pkg/test/util/assert" +) + +func TestTranslateToPatch(t *testing.T) { + typ := model.WaypointBound + cond := model.Condition{ + ObservedGeneration: 0, + Reason: "something", + Message: "hello", + Status: true, + } + tests := []struct { + name string + desired model.ConditionSet + cur map[string]model.Condition + wantUpdate bool + }{ + { + name: "both no status", + desired: map[model.ConditionType]*model.Condition{ + typ: nil, + }, + cur: map[string]model.Condition{}, + wantUpdate: false, + }, + { + name: "first status write", + desired: map[model.ConditionType]*model.Condition{ + typ: &cond, + }, + cur: map[string]model.Condition{}, + wantUpdate: true, + }, + { + name: "status remove", + desired: map[model.ConditionType]*model.Condition{ + typ: nil, + }, + cur: map[string]model.Condition{string(typ): cond}, + wantUpdate: true, + }, + { + name: "status unchanged", + desired: map[model.ConditionType]*model.Condition{ + typ: &cond, + }, + cur: map[string]model.Condition{string(typ): cond}, + wantUpdate: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + obj := model.TypedObject{Kind: kind.Service} + got := translateToPatch(obj, tt.desired, tt.cur) + assert.Equal(t, got != nil, tt.wantUpdate) + }) + } +} diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/queue.go b/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/queue.go index 9e159ae11dba..a33ad569c5ce 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/queue.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/queue.go @@ -127,7 +127,7 @@ type StatusWriter interface { // statusReporter is a generics-erased object storing context on how to write status for a given type. type statusReporter struct { getObject func(string) (StatusWriter, bool) - patcher func(StatusWriter) (kclient.Patcher, []string) + patcher func(StatusWriter) (kclient.Patcher, map[string]model.Condition) relist func() start func() } @@ -135,23 +135,23 @@ type statusReporter struct { // Register registers a collection to have status reconciled. // The Collection is expected to produce objects that implement StatusWriter, which tells us what status to write. // The name is user facing, and ends up as a fieldManager for server-side-apply. It must be unique. -func Register[T StatusWriter](q *StatusQueue, name string, col krt.Collection[T], getPatcher func(T) (kclient.Patcher, []string)) { +func Register[T StatusWriter](q *StatusQueue, name string, col krt.Collection[T], getPatcher func(T) (kclient.Patcher, map[string]model.Condition)) { sr := statusReporter{ getObject: func(s string) (StatusWriter, bool) { - if o := col.GetKey(krt.Key[T](s)); o != nil { + if o := col.GetKey(s); o != nil { return *o, true } return nil, false }, // Wrapper to remove generics - patcher: func(writer StatusWriter) (kclient.Patcher, []string) { + patcher: func(writer StatusWriter) (kclient.Patcher, map[string]model.Condition) { return getPatcher(writer.(T)) }, relist: func() { log.Debugf("processing snapshot") for _, obj := range col.List() { q.queue.Add(statusItem{ - Key: string(krt.GetKey(obj)), + Key: krt.GetKey(obj), Reporter: name, }) } @@ -163,7 +163,7 @@ func Register[T StatusWriter](q *StatusQueue, name string, col krt.Collection[T] } for _, o := range events { ol := o.Latest() - key := string(krt.GetKey(ol)) + key := krt.GetKey(ol) log.Debugf("registering key for processing: %s", key) q.queue.Add(statusItem{ Key: key, diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/queue_test.go b/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/queue_test.go index 009fa6d7c156..1214ecd11cf2 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/queue_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/statusqueue/queue_test.go @@ -69,7 +69,10 @@ func TestQueue(t *testing.T) { } for _, set := range strings.Split(i.Annotations["conditions"], ",") { k, v, _ := strings.Cut(set, "=") - conds[model.ConditionType(k)] = []model.Condition{{Status: v == "true", Reason: "some reason"}} + if k == "" { + continue + } + conds[model.ConditionType(k)] = &model.Condition{Status: v == "true", Reason: "some reason"} } return &serviceStatus{ Target: model.TypedObject{ @@ -79,7 +82,7 @@ func TestQueue(t *testing.T) { Conditions: conds, } }) - statusqueue.Register(q, "services", col, func(status serviceStatus) (kclient.Patcher, []string) { + statusqueue.Register(q, "services", col, func(status serviceStatus) (kclient.Patcher, map[string]model.Condition) { return kclient.ToPatcher(svc), nil }) clienttest.Wrap(t, svc).Create(&v1.Service{ObjectMeta: metav1.ObjectMeta{Name: "none", Namespace: "default"}}) @@ -114,7 +117,7 @@ func TestQueue(t *testing.T) { } } if len(have) > 0 { - return fmt.Errorf("unexpected conditions, wanted %v, got %v", maps.Keys(conds), allHave) + return fmt.Errorf("unexpected conditions, wanted %v, got %v/%v", maps.Keys(conds), allHave, have) } return nil }) @@ -142,7 +145,7 @@ func TestQueueLeaderElection(t *testing.T) { } for _, set := range strings.Split(i.Annotations["conditions"], ",") { k, v, _ := strings.Cut(set, "=") - conds[model.ConditionType(k)] = []model.Condition{{Status: v == "true", Reason: "some reason"}} + conds[model.ConditionType(k)] = &model.Condition{Status: v == "true", Reason: "some reason"} } return &serviceStatus{ Target: model.TypedObject{ @@ -152,7 +155,7 @@ func TestQueueLeaderElection(t *testing.T) { Conditions: conds, } }) - statusqueue.Register(q, "services", col, func(status serviceStatus) (kclient.Patcher, []string) { + statusqueue.Register(q, "services", col, func(status serviceStatus) (kclient.Patcher, map[string]model.Condition) { return kclient.ToPatcher(svc), nil }) clienttest.Wrap(t, svc).Create(&v1.Service{ObjectMeta: metav1.ObjectMeta{Name: "none", Namespace: "default"}}) diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-permissive-workload-in.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-permissive-workload-in.yaml new file mode 100644 index 000000000000..f2ea35c5d249 --- /dev/null +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-permissive-workload-in.yaml @@ -0,0 +1,21 @@ +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: default-mesh + namespace: istio-system +spec: + mtls: + mode: PERMISSIVE +--- +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: workload + namespace: foo +spec: + selector: + matchLabels: + app: a + portLevelMtls: + 9090: + mode: PERMISSIVE diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-permissive-workload.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-permissive-workload.yaml new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-strict-namespace-permissive-workload-in.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-strict-namespace-permissive-workload-in.yaml new file mode 100644 index 000000000000..376e97199616 --- /dev/null +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-strict-namespace-permissive-workload-in.yaml @@ -0,0 +1,30 @@ +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: default-mesh + namespace: istio-system +spec: + mtls: + mode: PERMISSIVE +--- +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: default-foo + namespace: foo +spec: + mtls: + mode: STRICT +--- +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: workload + namespace: foo +spec: + selector: + matchLabels: + app: a + portLevelMtls: + 9090: + mode: PERMISSIVE diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-strict-namespace-permissive-workload.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-strict-namespace-permissive-workload.yaml new file mode 100644 index 000000000000..7abcb27893a7 --- /dev/null +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-permissive-root-strict-namespace-permissive-workload.yaml @@ -0,0 +1,12 @@ +action: DENY +groups: +- rules: + - matches: + - notDestinationPorts: + - 9090 + - matches: + - notPrincipals: + - presence: {} +name: converted_peer_authentication_workload +namespace: foo +scope: WORKLOAD_SELECTOR diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-namespace-strict-workload-in.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-namespace-strict-workload-in.yaml new file mode 100644 index 000000000000..1f98a64d8748 --- /dev/null +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-namespace-strict-workload-in.yaml @@ -0,0 +1,30 @@ +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: default-mesh + namespace: istio-system +spec: + mtls: + mode: STRICT +--- +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: default-foo + namespace: foo +spec: + mtls: + mode: PERMISSIVE +--- +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: workload + namespace: foo +spec: + selector: + matchLabels: + app: a + portLevelMtls: + 9090: + mode: STRICT diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-namespace-strict-workload.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-namespace-strict-workload.yaml new file mode 100644 index 000000000000..e6e3be4b97fb --- /dev/null +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-namespace-strict-workload.yaml @@ -0,0 +1,11 @@ +action: DENY +groups: +- rules: + - matches: + - destinationPorts: + - 9090 + notPrincipals: + - presence: {} +name: converted_peer_authentication_workload +namespace: foo +scope: WORKLOAD_SELECTOR diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-workload-in.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-workload-in.yaml new file mode 100644 index 000000000000..5b91c25576e5 --- /dev/null +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-workload-in.yaml @@ -0,0 +1,21 @@ +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: default-mesh + namespace: istio-system +spec: + mtls: + mode: STRICT +--- +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: workload + namespace: foo +spec: + selector: + matchLabels: + app: a + portLevelMtls: + 9090: + mode: PERMISSIVE diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-workload.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-workload.yaml new file mode 100644 index 000000000000..7abcb27893a7 --- /dev/null +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-strict-root-permissive-workload.yaml @@ -0,0 +1,12 @@ +action: DENY +groups: +- rules: + - matches: + - notDestinationPorts: + - 9090 + - matches: + - notPrincipals: + - presence: {} +name: converted_peer_authentication_workload +namespace: foo +scope: WORKLOAD_SELECTOR diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-unset-port-mtls-permissive-in.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-unset-port-mtls-permissive-in.yaml deleted file mode 100644 index 71858410f3c5..000000000000 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-unset-port-mtls-permissive-in.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: security.istio.io/v1 -kind: PeerAuthentication -metadata: - name: strict-mtls -spec: - selector: - matchLabels: - app: a - mtls: - mode: UNSET - portLevelMtls: - 9090: - mode: PERMISSIVE diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-unset-port-mtls-permissive.yaml b/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-unset-port-mtls-permissive.yaml deleted file mode 100644 index 0cb5212ecb38..000000000000 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/testdata/peer-authn-unset-port-mtls-permissive.yaml +++ /dev/null @@ -1,8 +0,0 @@ -action: DENY -groups: -- rules: - - matches: - - notDestinationPorts: - - 9090 -name: converted_peer_authentication_strict-mtls -scope: WORKLOAD_SELECTOR diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/waypoints.go b/pilot/pkg/serviceregistry/kube/controller/ambient/waypoints.go index 579be87feca5..005770a8df24 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/waypoints.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/waypoints.go @@ -207,6 +207,7 @@ func (a *index) WaypointsCollection( gateways krt.Collection[*v1beta1.Gateway], gatewayClasses krt.Collection[*v1beta1.GatewayClass], pods krt.Collection[*v1.Pod], + opts KrtOptions, ) krt.Collection[Waypoint] { podsByNamespace := krt.NewNamespaceIndex(pods) return krt.NewCollection(gateways, func(ctx krt.HandlerContext, gateway *v1beta1.Gateway) *Waypoint { @@ -241,7 +242,7 @@ func (a *index) WaypointsCollection( } return a.makeWaypoint(gateway, gatewayClass, serviceAccounts, trafficType) - }, krt.WithName("Waypoints")) + }, opts.WithName("Waypoints")...) } func makeInboundBinding(gateway *v1beta1.Gateway, gatewayClass *v1beta1.GatewayClass) *InboundBinding { diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/workloads.go b/pilot/pkg/serviceregistry/kube/controller/ambient/workloads.go index 778a81550b0e..801b74fd19ee 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/workloads.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/workloads.go @@ -64,6 +64,7 @@ func (a *index) WorkloadsCollection( serviceEntries krt.Collection[*networkingclient.ServiceEntry], endpointSlices krt.Collection[*discovery.EndpointSlice], namespaces krt.Collection[*v1.Namespace], + opts KrtOptions, ) krt.Collection[model.WorkloadInfo] { WorkloadServicesNamespaceIndex := krt.NewNamespaceIndex(workloadServices) EndpointSlicesByIPIndex := endpointSliceAddressIndex(endpointSlices) @@ -82,20 +83,20 @@ func (a *index) WorkloadsCollection( namespaces, nodes, ), - krt.WithName("PodWorkloads"), + opts.WithName("PodWorkloads")..., ) // Workloads coming from workloadEntries. These are 1:1 with WorkloadEntry. WorkloadEntryWorkloads := krt.NewCollection( workloadEntries, a.workloadEntryWorkloadBuilder(meshConfig, authorizationPolicies, peerAuths, waypoints, workloadServices, WorkloadServicesNamespaceIndex, namespaces), - krt.WithName("WorkloadEntryWorkloads"), + opts.WithName("WorkloadEntryWorkloads")..., ) // Workloads coming from serviceEntries. These are inlined workloadEntries (under `spec.endpoints`); these serviceEntries will // also be generating `workloadapi.Service` definitions in the `ServicesCollection` logic. ServiceEntryWorkloads := krt.NewManyCollection( serviceEntries, a.serviceEntryWorkloadBuilder(meshConfig, authorizationPolicies, peerAuths, waypoints, namespaces), - krt.WithName("ServiceEntryWorkloads"), + opts.WithName("ServiceEntryWorkloads")..., ) // Workloads coming from endpointSlices. These are for *manually added* endpoints. Typically, Kubernetes will insert each pod // into the EndpointSlice. This is because Kubernetes has 3 APIs in its model: Service, Pod, and EndpointSlice. @@ -105,12 +106,12 @@ func (a *index) WorkloadsCollection( EndpointSliceWorkloads := krt.NewManyCollection( endpointSlices, a.endpointSlicesBuilder(meshConfig, workloadServices), - krt.WithName("EndpointSliceWorkloads")) + opts.WithName("EndpointSliceWorkloads")...) NetworkGatewayWorkloads := krt.NewManyFromNothing[model.WorkloadInfo](func(ctx krt.HandlerContext) []model.WorkloadInfo { a.networkUpdateTrigger.MarkDependant(ctx) // Mark we depend on out of band a.Network - return slices.Map(a.LookupNetworkGateways(), convertGateway) - }, krt.WithName("NetworkGatewayWorkloads")) + return slices.Map(a.LookupAllNetworkGateway(), convertGateway) + }, opts.WithName("NetworkGatewayWorkloads")...) Workloads := krt.JoinCollection([]krt.Collection[model.WorkloadInfo]{ PodWorkloads, @@ -118,7 +119,7 @@ func (a *index) WorkloadsCollection( ServiceEntryWorkloads, EndpointSliceWorkloads, NetworkGatewayWorkloads, - }, krt.WithName("Workloads")) + }, opts.WithName("Workloads")...) return Workloads } @@ -136,13 +137,11 @@ func (a *index) workloadEntryWorkloadBuilder( wle = serviceentry.ConvertClientWorkloadEntry(wle) meshCfg := krt.FetchOne(ctx, meshConfig.AsCollection()) policies := a.buildWorkloadPolicies(ctx, authorizationPolicies, peerAuths, meshCfg, wle.Labels, wle.Namespace) - var waypoint *Waypoint - if wle.Labels[label.GatewayManaged.Name] != constants.ManagedGatewayMeshControllerLabel { - // TODO: report status for workload-attached waypoints - waypoint, _ = fetchWaypointForWorkload(ctx, waypoints, namespaces, wle.ObjectMeta) - } + + appTunnel, targetWaypoint := computeWaypoint(ctx, waypoints, namespaces, wle.ObjectMeta) + fo := []krt.FetchOption{krt.FilterIndex(workloadServicesNamespaceIndex, wle.Namespace), krt.FilterSelectsNonEmpty(wle.GetLabels())} - if !features.EnableK8SServiceSelectWorkloadEntries { + if !a.Flags.EnableK8SServiceSelectWorkloadEntries { fo = append(fo, krt.FilterGeneric(func(a any) bool { return a.(model.ServiceInfo).Source.Kind == kind.ServiceEntry })) @@ -155,7 +154,7 @@ func (a *index) workloadEntryWorkloadBuilder( } // enforce traversing waypoints - policies = append(policies, implicitWaypointPolicies(ctx, waypoints, waypoint, services)...) + policies = append(policies, implicitWaypointPolicies(a.Flags, ctx, waypoints, targetWaypoint, services)...) w := &workloadapi.Workload{ Uid: a.generateWorkloadEntryUID(wle.Namespace, wle.Name), @@ -168,7 +167,8 @@ func (a *index) workloadEntryWorkloadBuilder( Services: constructServicesFromWorkloadEntry(&wle.Spec, services), AuthorizationPolicies: policies, Status: workloadapi.WorkloadStatus_HEALTHY, // TODO: WE can be unhealthy - Waypoint: waypoint.GetAddress(), + Waypoint: targetWaypoint.GetAddress(), + ApplicationTunnel: appTunnel, TrustDomain: pickTrustDomain(meshCfg), Locality: getWorkloadEntryLocality(&wle.Spec), } @@ -179,7 +179,8 @@ func (a *index) workloadEntryWorkloadBuilder( log.Warnf("skipping workload entry %s/%s; DNS Address resolution is not yet implemented", wle.Namespace, wle.Name) } // Else it is an empty address with network set, this is ok - w.WorkloadName, w.WorkloadType = wle.Name, workloadapi.WorkloadType_POD // XXX(shashankram): HACK to impersonate pod + w.WorkloadName = kubelabels.WorkloadNameFromWorkloadEntry(wle.Name, wle.Annotations, wle.Labels) + w.WorkloadType = workloadapi.WorkloadType_POD // XXX(shashankram): HACK to impersonate pod w.CanonicalName, w.CanonicalRevision = kubelabels.CanonicalService(wle.Labels, w.WorkloadName) setTunnelProtocol(wle.Labels, wle.Annotations, w) @@ -187,6 +188,30 @@ func (a *index) workloadEntryWorkloadBuilder( } } +func computeWaypoint( + ctx krt.HandlerContext, + waypoints krt.Collection[Waypoint], + namespaces krt.Collection[*v1.Namespace], + workloadMeta metav1.ObjectMeta, +) (*workloadapi.ApplicationTunnel, *Waypoint) { + var appTunnel *workloadapi.ApplicationTunnel + var targetWaypoint *Waypoint + if instancedWaypoint := fetchWaypointForInstance(ctx, waypoints, workloadMeta); instancedWaypoint != nil { + // we're an instance of a waypoint, set inbound tunnel info if needed + if db := instancedWaypoint.DefaultBinding; db != nil { + appTunnel = &workloadapi.ApplicationTunnel{ + Protocol: db.Protocol, + Port: db.Port, + } + } + } else if waypoint, err := fetchWaypointForWorkload(ctx, waypoints, namespaces, workloadMeta); err == nil { + // there is a workload-attached waypoint, point there with a GatewayAddress + // TODO: report status for workload-attached waypoints + targetWaypoint = waypoint + } + return appTunnel, targetWaypoint +} + func (a *index) podWorkloadBuilder( meshConfig krt.Singleton[MeshConfig], authorizationPolicies krt.Collection[model.WorkloadAuthorization], @@ -241,24 +266,10 @@ func (a *index) podWorkloadBuilder( // We only check the network of the first IP. This should be fine; it is not supported for a single pod to span multiple networks network := a.Network(p.Status.PodIP, p.Labels).String() - var appTunnel *workloadapi.ApplicationTunnel - var targetWaypoint *Waypoint - if instancedWaypoint := fetchWaypointForInstance(ctx, waypoints, p.ObjectMeta); instancedWaypoint != nil { - // we're an instance of a waypoint, set inbound tunnel info if needed - if db := instancedWaypoint.DefaultBinding; db != nil { - appTunnel = &workloadapi.ApplicationTunnel{ - Protocol: db.Protocol, - Port: db.Port, - } - } - } else if waypoint, err := fetchWaypointForWorkload(ctx, waypoints, namespaces, p.ObjectMeta); err == nil { - // there is a workload-attached waypoint, point there with a GatewayAddress - // TODO: report status for workload-attached waypoints - targetWaypoint = waypoint - } + appTunnel, targetWaypoint := computeWaypoint(ctx, waypoints, namespaces, p.ObjectMeta) // enforce traversing waypoints - policies = append(policies, implicitWaypointPolicies(ctx, waypoints, targetWaypoint, services)...) + policies = append(policies, implicitWaypointPolicies(a.Flags, ctx, waypoints, targetWaypoint, services)...) w := &workloadapi.Workload{ Uid: a.generatePodUID(p), @@ -431,21 +442,20 @@ func (a *index) serviceEntryWorkloadBuilder( policies := a.buildWorkloadPolicies(ctx, authorizationPolicies, peerAuths, meshCfg, se.Labels, se.Namespace) - var waypoint *Waypoint + var appTunnel *workloadapi.ApplicationTunnel + var targetWaypoint *Waypoint // Endpoint does not have a real ObjectMeta, so make one if !implicitEndpoints { - if wp, err := fetchWaypointForWorkload(ctx, waypoints, namespaces, metav1.ObjectMeta{ + objMeta := metav1.ObjectMeta{ Name: se.Name, Namespace: se.Namespace, Labels: wle.Labels, - }); err == nil { - // TODO: report status for workload-attached waypoints - waypoint = wp } + appTunnel, targetWaypoint = computeWaypoint(ctx, waypoints, namespaces, objMeta) } // enforce traversing waypoints - policies = append(policies, implicitWaypointPolicies(ctx, waypoints, waypoint, services)...) + policies = append(policies, implicitWaypointPolicies(a.Flags, ctx, waypoints, targetWaypoint, services)...) a.networkUpdateTrigger.MarkDependant(ctx) // Mark we depend on out of band a.Network network := a.Network(wle.Address, wle.Labels).String() @@ -463,7 +473,8 @@ func (a *index) serviceEntryWorkloadBuilder( Services: constructServicesFromWorkloadEntry(wle, services), AuthorizationPolicies: policies, Status: workloadapi.WorkloadStatus_HEALTHY, - Waypoint: waypoint.GetAddress(), + Waypoint: targetWaypoint.GetAddress(), + ApplicationTunnel: appTunnel, TrustDomain: pickTrustDomain(meshCfg), Locality: getWorkloadEntryLocality(wle), } @@ -704,7 +715,7 @@ func constructServicesFromWorkloadEntry(p *networkingv1alpha3.WorkloadEntry, ser } func workloadNameAndType(pod *v1.Pod) (string, workloadapi.WorkloadType) { - objMeta, typeMeta := kubeutil.GetDeployMetaFromPod(pod) + objMeta, typeMeta := kubeutil.GetWorkloadMetaFromPod(pod) switch typeMeta.Kind { case "Deployment": return objMeta.Name, workloadapi.WorkloadType_DEPLOYMENT @@ -786,8 +797,14 @@ func getWorkloadEntryLocality(p *networkingv1alpha3.WorkloadEntry) *workloadapi. } } -func implicitWaypointPolicies(ctx krt.HandlerContext, Waypoints krt.Collection[Waypoint], waypoint *Waypoint, services []model.ServiceInfo) []string { - if !features.DefaultAllowFromWaypoint { +func implicitWaypointPolicies( + flags FeatureFlags, + ctx krt.HandlerContext, + Waypoints krt.Collection[Waypoint], + waypoint *Waypoint, + services []model.ServiceInfo, +) []string { + if !flags.DefaultAllowFromWaypoint { return nil } serviceWaypointKeys := slices.MapFilter(services, func(si model.ServiceInfo) *string { @@ -798,7 +815,7 @@ func implicitWaypointPolicies(ctx krt.HandlerContext, Waypoints krt.Collection[W }) if len(serviceWaypointKeys) == 0 { if waypoint != nil { - n := implicitWaypointPolicyName(waypoint) + n := implicitWaypointPolicyName(flags, waypoint) if n != "" { return []string{waypoint.Namespace + "/" + n} } @@ -811,7 +828,7 @@ func implicitWaypointPolicies(ctx krt.HandlerContext, Waypoints krt.Collection[W } return slices.MapFilter(waypoints, func(w Waypoint) *string { - policy := implicitWaypointPolicyName(&w) + policy := implicitWaypointPolicyName(flags, &w) if policy == "" { return nil } @@ -843,16 +860,8 @@ func convertGateway(gw model.NetworkGateway) model.WorkloadInfo { return model.WorkloadInfo{Workload: wl} } -func (a *index) getNetworkGateway(id string) []model.NetworkGateway { - gtws := a.LookupNetworkGateways() - slices.FilterInPlace(gtws, func(gateway model.NetworkGateway) bool { - return gateway.Network == network.ID(id) - }) - return gtws -} - -func (a *index) getNetworkGatewayAddress(network string) *workloadapi.GatewayAddress { - if networks := a.getNetworkGateway(network); len(networks) > 0 { +func (a *index) getNetworkGatewayAddress(n string) *workloadapi.GatewayAddress { + if networks := a.LookupNetworkGateway(network.ID(n)); len(networks) > 0 { // Currently only support one, so find the first one that is valid for _, net := range networks { if net.HBONEPort == 0 { @@ -860,8 +869,19 @@ func (a *index) getNetworkGatewayAddress(network string) *workloadapi.GatewayAdd } ip, err := netip.ParseAddr(net.Addr) if err != nil { - continue + // This is a hostname... + return &workloadapi.GatewayAddress{ + Destination: &workloadapi.GatewayAddress_Hostname{ + // probably use from Cidr instead? + Hostname: &workloadapi.NamespacedHostname{ + Namespace: net.ServiceAccount.Namespace, + Hostname: net.Addr, + }, + }, + HboneMtlsPort: net.HBONEPort, + } } + // Else it must be an IP return &workloadapi.GatewayAddress{ Destination: &workloadapi.GatewayAddress_Address{ // probably use from Cidr instead? diff --git a/pilot/pkg/serviceregistry/kube/controller/ambient/workloads_test.go b/pilot/pkg/serviceregistry/kube/controller/ambient/workloads_test.go index 540e326ce761..f43285353375 100644 --- a/pilot/pkg/serviceregistry/kube/controller/ambient/workloads_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/ambient/workloads_test.go @@ -16,6 +16,7 @@ package ambient import ( "net/netip" + "sync/atomic" "testing" v1 "k8s.io/api/core/v1" @@ -27,6 +28,7 @@ import ( networking "istio.io/api/networking/v1alpha3" networkingclient "istio.io/client-go/pkg/apis/networking/v1" securityclient "istio.io/client-go/pkg/apis/security/v1" + "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" "istio.io/istio/pkg/config/constants" "istio.io/istio/pkg/config/labels" @@ -1117,6 +1119,90 @@ func TestWorkloadEntryWorkloads(t *testing.T) { }, }, }, + { + name: "cross network we hostname gateway", + inputs: []any{}, + we: &networkingclient.WorkloadEntry{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "ns", + }, + Spec: networking.WorkloadEntry{ + Ports: map[string]uint32{ + "80": 80, + }, + Network: "remote-network-hostname", + }, + }, + result: &workloadapi.Workload{ + Uid: "cluster0/networking.istio.io/WorkloadEntry/ns/name", + Name: "name", + Namespace: "ns", + Network: "remote-network-hostname", + CanonicalName: "name", + CanonicalRevision: "latest", + WorkloadType: workloadapi.WorkloadType_POD, + WorkloadName: "name", + Status: workloadapi.WorkloadStatus_HEALTHY, + ClusterId: testC, + NetworkGateway: &workloadapi.GatewayAddress{ + Destination: &workloadapi.GatewayAddress_Hostname{Hostname: &workloadapi.NamespacedHostname{ + Hostname: "networkgateway.example.com", + Namespace: "ns-gtw", + }}, + HboneMtlsPort: 15008, + }, + }, + }, + { + name: "waypoint binding", + inputs: []any{ + Waypoint{ + Named: krt.Named{Name: "waypoint", Namespace: "ns"}, + Address: &workloadapi.GatewayAddress{ + Destination: &workloadapi.GatewayAddress_Hostname{ + Hostname: &workloadapi.NamespacedHostname{ + Namespace: "ns", + Hostname: "waypoint.example.com", + }, + }, + }, + DefaultBinding: &InboundBinding{Port: 15088, Protocol: workloadapi.ApplicationTunnel_PROXY}, + TrafficType: constants.AllTraffic, + }, + }, + we: &networkingclient.WorkloadEntry{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "ns", + Labels: map[string]string{ + label.IoK8sNetworkingGatewayGatewayName.Name: "waypoint", + }, + }, + Spec: networking.WorkloadEntry{ + Ports: map[string]uint32{ + "80": 80, + }, + }, + }, + result: &workloadapi.Workload{ + Uid: "cluster0/networking.istio.io/WorkloadEntry/ns/name", + Name: "name", + Namespace: "ns", + CanonicalName: "name", + CanonicalRevision: "latest", + Network: "testnetwork", + WorkloadType: workloadapi.WorkloadType_POD, + WorkloadName: "name", + Status: workloadapi.WorkloadStatus_HEALTHY, + ClusterId: testC, + ApplicationTunnel: &workloadapi.ApplicationTunnel{ + Protocol: workloadapi.ApplicationTunnel_PROXY, + Port: 15088, + }, + }, + }, } for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { @@ -1495,14 +1581,19 @@ func kubernetesAPIServerEndpoint(ip string) *discovery.EndpointSlice { } func newAmbientUnitTest() *index { - return &index{ + idx := &index{ networkUpdateTrigger: krt.NewRecomputeTrigger(true), + networkGateways: new(atomic.Pointer[map[network.ID][]model.NetworkGateway]), ClusterID: testC, DomainSuffix: "domain.suffix", Network: func(endpointIP string, labels labels.Instance) network.ID { return testNW }, - LookupNetworkGateways: func() []model.NetworkGateway { + Flags: FeatureFlags{ + DefaultAllowFromWaypoint: features.DefaultAllowFromWaypoint, + EnableK8SServiceSelectWorkloadEntries: features.EnableK8SServiceSelectWorkloadEntries, + }, + LookupNetworkGatewaysExpensive: func() []model.NetworkGateway { return []model.NetworkGateway{ { Network: "remote-network", @@ -1515,9 +1606,22 @@ func newAmbientUnitTest() *index { Name: "sa-gtw", }, }, + { + Network: "remote-network-hostname", + Addr: "networkgateway.example.com", + Cluster: "cluster-a", + Port: 15008, + HBONEPort: 15008, + ServiceAccount: types.NamespacedName{ + Namespace: "ns-gtw", + Name: "sa-gtw", + }, + }, } }, } + idx.SyncAll() + return idx } var podReady = []v1.PodCondition{ diff --git a/pilot/pkg/serviceregistry/kube/controller/controller.go b/pilot/pkg/serviceregistry/kube/controller/controller.go index 024a503df626..6aae309305c6 100644 --- a/pilot/pkg/serviceregistry/kube/controller/controller.go +++ b/pilot/pkg/serviceregistry/kube/controller/controller.go @@ -49,6 +49,7 @@ import ( kubelib "istio.io/istio/pkg/kube" "istio.io/istio/pkg/kube/controllers" "istio.io/istio/pkg/kube/kclient" + "istio.io/istio/pkg/kube/krt" istiolog "istio.io/istio/pkg/log" "istio.io/istio/pkg/maps" "istio.io/istio/pkg/monitoring" @@ -260,7 +261,7 @@ func NewController(kubeClient kubelib.Client, options Options) *Controller { c.services = kclient.NewFiltered[*v1.Service](kubeClient, kclient.Filter{ObjectFilter: kubeClient.ObjectFilter()}) - registerHandlers[*v1.Service](c, c.services, "Services", c.onServiceEvent, nil) + registerHandlers(c, c.services, "Services", c.onServiceEvent, nil) c.endpoints = newEndpointSliceController(c) @@ -277,7 +278,7 @@ func NewController(kubeClient kubelib.Client, options Options) *Controller { return c.endpoints.podArrived(key.Name, key.Namespace) }) }) - registerHandlers[*v1.Pod](c, c.podsClient, "Pods", c.pods.onEvent, c.pods.labelFilter) + registerHandlers[*v1.Pod](c, c.podsClient, "Pods", c.pods.onEvent, nil) if features.EnableAmbient { c.ambientIndex = ambient.New(ambient.Options{ @@ -290,6 +291,11 @@ func NewController(kubeClient kubelib.Client, options Options) *Controller { LookupNetwork: c.Network, LookupNetworkGateways: c.NetworkGateways, StatusNotifier: options.StatusWritingEnabled, + Debugger: krt.GlobalDebugHandler, + Flags: ambient.FeatureFlags{ + DefaultAllowFromWaypoint: features.DefaultAllowFromWaypoint, + EnableK8SServiceSelectWorkloadEntries: features.EnableK8SServiceSelectWorkloadEntries, + }, }) } c.exports = newServiceExportCache(c) @@ -404,10 +410,12 @@ func (c *Controller) deleteService(svc *model.Service) { c.Lock() delete(c.servicesMap, svc.Hostname) delete(c.nodeSelectorsForServices, svc.Hostname) - _, isNetworkGateway := c.networkGatewaysBySvc[svc.Hostname] - delete(c.networkGatewaysBySvc, svc.Hostname) c.Unlock() + c.networkManager.Lock() + _, isNetworkGateway := c.networkGatewaysBySvc[svc.Hostname] + delete(c.networkGatewaysBySvc, svc.Hostname) + c.networkManager.Unlock() if isNetworkGateway { c.NotifyGatewayHandlers() // TODO trigger push via handler @@ -418,8 +426,9 @@ func (c *Controller) deleteService(svc *model.Service) { shard := model.ShardKeyFromRegistry(c) event := model.EventDelete c.opts.XDSUpdater.SvcUpdate(shard, string(svc.Hostname), svc.Attributes.Namespace, event) - - c.handlers.NotifyServiceHandlers(nil, svc, event) + if !svc.Attributes.ExportTo.Contains(visibility.None) { + c.handlers.NotifyServiceHandlers(nil, svc, event) + } } // recomputeServiceForPod is called when a pod changes and service endpoints need to be recomputed. @@ -479,7 +488,7 @@ func (c *Controller) addOrUpdateService(pre, curr *v1.Service, currConv *model.S prevConv := c.servicesMap[currConv.Hostname] c.servicesMap[currConv.Hostname] = currConv c.Unlock() - // This full push needed to update ALL ends endpoints, even though we do a full push on service add/update + // This full push needed to update all endpoints, even though we do a full push on service add/update // as that full push is only triggered for the specific service. if needsFullPush { // networks are different, we need to update all eds endpoints @@ -498,13 +507,11 @@ func (c *Controller) addOrUpdateService(pre, curr *v1.Service, currConv *model.S } } - // filter out same service event - if event == model.EventUpdate && !serviceUpdateNeedsPush(pre, curr, prevConv, currConv) { - return - } - c.opts.XDSUpdater.SvcUpdate(shard, string(currConv.Hostname), ns, event) - c.handlers.NotifyServiceHandlers(prevConv, currConv, event) + if serviceUpdateNeedsPush(pre, curr, prevConv, currConv) { + log.Debugf("Service %s in namespace %s updated and needs push", currConv.Hostname, ns) + c.handlers.NotifyServiceHandlers(prevConv, currConv, event) + } } func (c *Controller) buildEndpointsForService(svc *model.Service, updateCache bool) []*model.IstioEndpoint { @@ -1193,10 +1200,11 @@ func (c *Controller) servicesForNamespacedName(name types.NamespacedName) []*mod } func serviceUpdateNeedsPush(prev, curr *v1.Service, preConv, currConv *model.Service) bool { + // New Service - If it is not exported, no need to push. if preConv == nil { return !currConv.Attributes.ExportTo.Contains(visibility.None) } - // if service are not exported, no need to push + // if service Visibility is None and has not changed in the update/delete, no need to push. if preConv.Attributes.ExportTo.Contains(visibility.None) && currConv.Attributes.ExportTo.Contains(visibility.None) { return false diff --git a/pilot/pkg/serviceregistry/kube/controller/controller_test.go b/pilot/pkg/serviceregistry/kube/controller/controller_test.go index 4d9824456a41..83cc27014136 100644 --- a/pilot/pkg/serviceregistry/kube/controller/controller_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/controller_test.go @@ -48,6 +48,7 @@ import ( "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/mesh" "istio.io/istio/pkg/config/protocol" + "istio.io/istio/pkg/config/schema/kind" "istio.io/istio/pkg/config/visibility" kubelib "istio.io/istio/pkg/kube" "istio.io/istio/pkg/kube/kclient/clienttest" @@ -272,7 +273,6 @@ func TestController_GetPodLocality(t *testing.T) { for _, tc := range testCases { // If using t.Parallel() you must copy the iteration to a new local variable // https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables - tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() // Setup kube caches @@ -2430,6 +2430,47 @@ func TestUpdateEdsCacheOnServiceUpdate(t *testing.T) { fx.WaitOrFail(t, "eds cache") } +func TestVisibilityNoneService(t *testing.T) { + controller, fx := NewFakeControllerWithOptions(t, FakeControllerOptions{}) + serviceHandler := func(_, curr *model.Service, _ model.Event) { + pushReq := &model.PushRequest{ + Full: true, + ConfigsUpdated: sets.New(model.ConfigKey{Kind: kind.ServiceEntry, Name: string(curr.Hostname), Namespace: curr.Attributes.Namespace}), + Reason: model.NewReasonStats(model.ServiceUpdate), + } + fx.ConfigUpdate(pushReq) + } + controller.Controller.AppendServiceHandler(serviceHandler) + + // Create an initial pod with a service with None visibility, and endpoint. + pod1 := generatePod([]string{"172.0.1.1"}, "pod1", "nsA", "", "node1", map[string]string{"app": "prod-app"}, map[string]string{}) + pod2 := generatePod([]string{"172.0.1.2"}, "pod2", "nsA", "", "node1", map[string]string{"app": "prod-app"}, map[string]string{}) + pods := []*corev1.Pod{pod1, pod2} + nodes := []*corev1.Node{ + generateNode("node1", map[string]string{NodeZoneLabel: "zone1", NodeRegionLabel: "region1", label.TopologySubzone.Name: "subzone1"}), + } + addNodes(t, controller, nodes...) + addPods(t, controller, fx, pods...) + createServiceWait(controller, "svc1", "nsA", []string{"10.0.0.1"}, nil, map[string]string{annotation.NetworkingExportTo.Name: "~"}, + []int32{8080}, map[string]string{"app": "prod-app"}, t) + + pod1Ips := []string{"172.0.1.1"} + portNames := []string{"tcp-port"} + createEndpoints(t, controller, "svc1", "nsA", portNames, pod1Ips, nil, nil) + // We should not get any events - service should be ignored. + fx.AssertEmpty(t, 0) + + // update service and remove exportTo annotation. + svc := getService(controller, "svc1", "nsA", t) + svc.Annotations = map[string]string{} + updateService(controller, svc, t) + fx.WaitOrFail(t, "eds cache") + fx.WaitOrFail(t, "service") + host := string(kube.ServiceHostname("svc1", "nsA", controller.opts.DomainSuffix)) + // We should see a full push. + fx.MatchOrFail(t, xdsfake.Event{Type: "xds full", ID: host}) +} + func TestDiscoverySelector(t *testing.T) { networksWatcher := mesh.NewFixedNetworksWatcher(&meshconfig.MeshNetworks{ Networks: map[string]*meshconfig.Network{ diff --git a/pilot/pkg/serviceregistry/kube/controller/endpoint_builder.go b/pilot/pkg/serviceregistry/kube/controller/endpoint_builder.go index 8987dc82d874..8917ad8107b5 100644 --- a/pilot/pkg/serviceregistry/kube/controller/endpoint_builder.go +++ b/pilot/pkg/serviceregistry/kube/controller/endpoint_builder.go @@ -66,7 +66,7 @@ func (c *Controller) NewEndpointBuilder(pod *v1.Pod) *EndpointBuilder { ip = pod.Status.PodIP node = pod.Spec.NodeName } - dm, _ := kubeUtil.GetDeployMetaFromPod(pod) + dm, _ := kubeUtil.GetWorkloadMetaFromPod(pod) out := &EndpointBuilder{ controller: c, serviceAccount: sa, diff --git a/pilot/pkg/serviceregistry/kube/controller/endpointslice.go b/pilot/pkg/serviceregistry/kube/controller/endpointslice.go index e6fdf4ce26c2..1f4dc7ff1983 100644 --- a/pilot/pkg/serviceregistry/kube/controller/endpointslice.go +++ b/pilot/pkg/serviceregistry/kube/controller/endpointslice.go @@ -15,6 +15,7 @@ package controller import ( + "strings" "sync" "github.com/hashicorp/go-multierror" @@ -26,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/types" mcs "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1" + "istio.io/api/annotation" "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" "istio.io/istio/pkg/config" @@ -102,50 +104,48 @@ func (esc *endpointSliceController) onEventInternal(_, ep *v1.EndpointSlice, eve } else { esc.updateEndpointSlice(ep) } - hostnames := esc.c.hostNamesForNamespacedName(namespacedName) - // Trigger EDS push for all hostnames. - esc.pushEDS(hostnames, namespacedName.Namespace) + // Now check if we need to do a full push for the service. + // If the service is headless, we need to do a full push if service exposes TCP ports + // to create IP based listeners. For pure HTTP headless services, we only need to push NDS. name := serviceNameForEndpointSlice(esLabels) namespace := ep.GetNamespace() svc := esc.c.services.Get(name, namespace) - if svc == nil || svc.Spec.ClusterIP != corev1.ClusterIPNone || svc.Spec.Type == corev1.ServiceTypeExternalName { + if svc != nil && !serviceNeedsPush(svc) { return } - configs := []types.NamespacedName{} - pureHTTP := true - for _, modelSvc := range esc.c.servicesForNamespacedName(config.NamespacedName(svc)) { - // skip push if it is not exported - if modelSvc.Attributes.ExportTo.Contains(visibility.None) { - continue - } + hostnames := esc.c.hostNamesForNamespacedName(namespacedName) + log.Debugf("triggering EDS push for %s in namespace %s", hostnames, namespacedName.Namespace) + // Trigger EDS push for all hostnames. + esc.pushEDS(hostnames, namespacedName.Namespace) - configs = append(configs, types.NamespacedName{Name: modelSvc.Hostname.String(), Namespace: svc.Namespace}) + if svc == nil || svc.Spec.ClusterIP != corev1.ClusterIPNone || svc.Spec.Type == corev1.ServiceTypeExternalName { + return + } + configsUpdated := sets.New[model.ConfigKey]() + supportsOnlyHTTP := true + for _, modelSvc := range esc.c.servicesForNamespacedName(config.NamespacedName(svc)) { for _, p := range modelSvc.Ports { if !p.Protocol.IsHTTP() { - pureHTTP = false + supportsOnlyHTTP = false break } } - } - - configsUpdated := sets.New[model.ConfigKey]() - for _, config := range configs { - if !pureHTTP { - configsUpdated.Insert(model.ConfigKey{Kind: kind.ServiceEntry, Name: config.Name, Namespace: config.Namespace}) - } else { + if supportsOnlyHTTP { // pure HTTP headless services should not need a full push since they do not // require a Listener based on IP: https://github.com/istio/istio/issues/48207 - configsUpdated.Insert(model.ConfigKey{Kind: kind.DNSName, Name: config.Name, Namespace: config.Namespace}) + configsUpdated.Insert(model.ConfigKey{Kind: kind.DNSName, Name: modelSvc.Hostname.String(), Namespace: svc.Namespace}) + } else { + configsUpdated.Insert(model.ConfigKey{Kind: kind.ServiceEntry, Name: modelSvc.Hostname.String(), Namespace: svc.Namespace}) } } if len(configsUpdated) > 0 { - // For headless services, trigger a full push. - // If EnableHeadlessService is true and svc ports are not pure HTTP, we need to regenerate listeners per endpoint. - // Otherwise we only need to push NDS, but still need to set full but we skip all other xDS except NDS during the push. + // For headless services, trigger a full push to regenerate listeners per endpoint. + // Otherwise we only need to push NDS, but still need to set Full as true but we skip + // all other xDS except NDS during the push. esc.c.opts.XDSUpdater.ConfigUpdate(&model.PushRequest{ Full: true, ConfigsUpdated: configsUpdated, @@ -154,6 +154,19 @@ func (esc *endpointSliceController) onEventInternal(_, ep *v1.EndpointSlice, eve } } +func serviceNeedsPush(svc *corev1.Service) bool { + if svc.Annotations[annotation.NetworkingExportTo.Name] != "" { + namespaces := strings.Split(svc.Annotations[annotation.NetworkingExportTo.Name], ",") + for _, ns := range namespaces { + ns = strings.TrimSpace(ns) + if ns == string(visibility.None) { + return false + } + } + } + return true +} + // GetProxyServiceTargets returns service instances co-located with a given proxy // This is only used to find the targets associated with a headless service. // For the service with selector, it will use GetProxyServiceTargetsByPod to get the service targets. diff --git a/pilot/pkg/serviceregistry/kube/controller/multicluster.go b/pilot/pkg/serviceregistry/kube/controller/multicluster.go index e450229f83f4..cc519bb4493b 100644 --- a/pilot/pkg/serviceregistry/kube/controller/multicluster.go +++ b/pilot/pkg/serviceregistry/kube/controller/multicluster.go @@ -20,7 +20,6 @@ import ( "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" "istio.io/api/annotation" "istio.io/istio/pilot/pkg/config/kube/crdclient" @@ -76,13 +75,9 @@ type Multicluster struct { // options to use when creating kube controllers opts Options - // client for reading remote-secrets to initialize multicluster registries - client kubernetes.Interface - s server.Instance + s server.Instance serviceEntryController *serviceentry.Controller - configController model.ConfigStoreController - XDSUpdater model.XDSUpdater clusterLocal model.ClusterLocalProvider @@ -90,19 +85,14 @@ type Multicluster struct { caBundleWatcher *keycertbundle.Watcher revision string - // secretNamespace where we get cluster-access secrets - secretNamespace string - component *multicluster.Component[*kubeController] + component *multicluster.Component[*kubeController] } // NewMulticluster initializes data structure to store multicluster information func NewMulticluster( serverID string, - kc kubernetes.Interface, - secretNamespace string, opts Options, serviceEntryController *serviceentry.Controller, - configController model.ConfigStoreController, caBundleWatcher *keycertbundle.Watcher, revision string, startNsController bool, @@ -114,14 +104,10 @@ func NewMulticluster( serverID: serverID, opts: opts, serviceEntryController: serviceEntryController, - configController: configController, startNsController: startNsController, caBundleWatcher: caBundleWatcher, revision: revision, - XDSUpdater: opts.XDSUpdater, clusterLocal: clusterLocal, - secretNamespace: secretNamespace, - client: kc, s: s, } mc.component = multicluster.BuildMultiClusterComponent(controller, func(cluster *multicluster.Cluster) *kubeController { @@ -160,7 +146,7 @@ func (m *Multicluster) initializeCluster(cluster *multicluster.Cluster, kubeCont kubeRegistry.AppendWorkloadHandler(m.serviceEntryController.WorkloadInstanceHandler) } - if configCluster && m.serviceEntryController != nil && features.EnableEnhancedResourceScoping { + if configCluster && m.serviceEntryController != nil { kubeRegistry.AppendNamespaceDiscoveryHandlers(m.serviceEntryController.NamespaceDiscoveryHandler) } @@ -181,9 +167,7 @@ func (m *Multicluster) initializeCluster(cluster *multicluster.Cluster, kubeCont kubeController.workloadEntryController.AppendWorkloadHandler(kubeRegistry.WorkloadInstanceHandler) // ServiceEntry selects WorkloadEntry from remote cluster kubeController.workloadEntryController.AppendWorkloadHandler(m.serviceEntryController.WorkloadInstanceHandler) - if features.EnableEnhancedResourceScoping { - kubeRegistry.AppendNamespaceDiscoveryHandlers(kubeController.workloadEntryController.NamespaceDiscoveryHandler) - } + kubeRegistry.AppendNamespaceDiscoveryHandlers(kubeController.workloadEntryController.NamespaceDiscoveryHandler) m.opts.MeshServiceController.AddRegistryAndRun(kubeController.workloadEntryController, clusterStopCh) go configStore.Run(clusterStopCh) } diff --git a/pilot/pkg/serviceregistry/kube/controller/multicluster_test.go b/pilot/pkg/serviceregistry/kube/controller/multicluster_test.go index 97655b885754..33ead02e1702 100644 --- a/pilot/pkg/serviceregistry/kube/controller/multicluster_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/multicluster_test.go @@ -95,12 +95,12 @@ func Test_KubeSecretController(t *testing.T) { stop := test.NewStop(t) s := server.New() mcc := initController(clientset, testSecretNameSpace, stop) - mc := NewMulticluster("pilot-abc-123", clientset.Kube(), testSecretNameSpace, Options{ + mc := NewMulticluster("pilot-abc-123", Options{ ClusterID: "cluster-1", DomainSuffix: DomainSuffix, MeshWatcher: mesh.NewFixedWatcher(&meshconfig.MeshConfig{}), MeshServiceController: mockserviceController, - }, nil, nil, nil, "default", false, nil, s, mcc) + }, nil, nil, "default", false, nil, s, mcc) assert.NoError(t, mcc.Run(stop)) go mockserviceController.Run(stop) clientset.RunAndWait(stop) @@ -138,12 +138,12 @@ func Test_KubeSecretController_ExternalIstiod_MultipleClusters(t *testing.T) { s := server.New() certWatcher := keycertbundle.NewWatcher() mcc := initController(clientset, testSecretNameSpace, stop) - mc := NewMulticluster("pilot-abc-123", clientset.Kube(), testSecretNameSpace, Options{ + mc := NewMulticluster("pilot-abc-123", Options{ ClusterID: "cluster-1", DomainSuffix: DomainSuffix, MeshWatcher: mesh.NewFixedWatcher(&meshconfig.MeshConfig{}), MeshServiceController: mockserviceController, - }, nil, nil, certWatcher, "default", false, nil, s, mcc) + }, nil, certWatcher, "default", false, nil, s, mcc) assert.NoError(t, mcc.Run(stop)) go mockserviceController.Run(stop) clientset.RunAndWait(stop) diff --git a/pilot/pkg/serviceregistry/kube/controller/namespacecontroller.go b/pilot/pkg/serviceregistry/kube/controller/namespacecontroller.go index e10dbe34aa7c..88073256e6a1 100644 --- a/pilot/pkg/serviceregistry/kube/controller/namespacecontroller.go +++ b/pilot/pkg/serviceregistry/kube/controller/namespacecontroller.go @@ -68,10 +68,10 @@ func NewNamespaceController(kubeClient kube.Client, caBundleWatcher *keycertbund c.configmaps = kclient.NewFiltered[*v1.ConfigMap](kubeClient, kclient.Filter{ FieldSelector: "metadata.name=" + CACertNamespaceConfigMap, - ObjectFilter: kube.FilterIfEnhancedFilteringEnabled(kubeClient), + ObjectFilter: kubeClient.ObjectFilter(), }) c.namespaces = kclient.NewFiltered[*v1.Namespace](kubeClient, kclient.Filter{ - ObjectFilter: kube.FilterIfEnhancedFilteringEnabled(kubeClient), + ObjectFilter: kubeClient.ObjectFilter(), }) // kube-system is not skipped to enable deploying ztunnel in that namespace c.ignoredNamespaces = inject.IgnoredNamespaces.Copy().Delete(constants.KubeSystemNamespace) diff --git a/pilot/pkg/serviceregistry/kube/controller/network.go b/pilot/pkg/serviceregistry/kube/controller/network.go index 53aeb97a960e..f7416bdd5611 100644 --- a/pilot/pkg/serviceregistry/kube/controller/network.go +++ b/pilot/pkg/serviceregistry/kube/controller/network.go @@ -154,12 +154,10 @@ func (c *Controller) onNetworkChange() { if err := c.endpoints.initializeNamespace(metav1.NamespaceAll, true); err != nil { log.Errorf("one or more errors force-syncing endpoints: %v", err) } - c.reloadNetworkGateways() - // This is to ensure the ambient workloads are updated dynamically, aligning them with the current network settings. - // With this, the pod do not need to restart when the network configuration changes. - if c.ambientIndex != nil { - c.ambientIndex.SyncAll() + if c.reloadNetworkGateways() { + c.opts.XDSUpdater.ConfigUpdate(&model.PushRequest{Full: true, Reason: model.NewReasonStats(model.NetworksTrigger)}) } + c.NotifyGatewayHandlers() } // reloadMeshNetworks will read the mesh networks configuration to setup @@ -244,7 +242,7 @@ func (c *Controller) NetworkGateways() []model.NetworkGateway { // extractGatewaysFromService checks if the service is a cross-network gateway // and if it is, updates the controller's gateways. func (c *Controller) extractGatewaysFromService(svc *model.Service) bool { - changed := c.extractGatewaysInner(svc) + changed := c.networkManager.extractGatewaysInner(svc) if changed { c.NotifyGatewayHandlers() } @@ -252,27 +250,23 @@ func (c *Controller) extractGatewaysFromService(svc *model.Service) bool { } // reloadNetworkGateways performs extractGatewaysFromService for all services registered with the controller. +// It returns whether there is a gateway changed. // It is called only by `onNetworkChange`. // It iterates over all services, because mesh networks can be set with a service name. -func (c *Controller) reloadNetworkGateways() { +func (c *Controller) reloadNetworkGateways() bool { c.Lock() - gwsChanged := false + defer c.Unlock() + gwChanged := false for _, svc := range c.servicesMap { if c.extractGatewaysInner(svc) { - gwsChanged = true - break + gwChanged = true } } - c.Unlock() - if gwsChanged { - c.NotifyGatewayHandlers() - // TODO ConfigUpdate via gateway handler - c.opts.XDSUpdater.ConfigUpdate(&model.PushRequest{Full: true, Reason: model.NewReasonStats(model.NetworksTrigger)}) - } + return gwChanged } -// extractGatewaysInner performs the logic for extractGatewaysFromService without locking the controller. -// Returns true if any gateways changed. +// extractGatewaysInner updates the gateway address inferred from the service. +// Returns true if any gateway address changed. func (n *networkManager) extractGatewaysInner(svc *model.Service) bool { n.Lock() defer n.Unlock() diff --git a/pilot/pkg/serviceregistry/kube/controller/network_test.go b/pilot/pkg/serviceregistry/kube/controller/network_test.go index 3f587a3597e9..25ace1eb4c83 100644 --- a/pilot/pkg/serviceregistry/kube/controller/network_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/network_test.go @@ -58,7 +58,7 @@ func TestNetworkUpdateTriggers(t *testing.T) { t.Fatal("did not expect any gateways yet") } - notifyCh := make(chan struct{}, 1) + notifyCh := make(chan struct{}, 10) var ( gwMu sync.Mutex gws []model.NetworkGateway @@ -80,48 +80,52 @@ func TestNetworkUpdateTriggers(t *testing.T) { }) expectGateways := func(t *testing.T, expectedGws int) { // wait for a notification - assert.ChannelHasItem(t, notifyCh) - if n := len(getGws()); n != expectedGws { - t.Errorf("expected %d gateways but got %d", expectedGws, n) + // We may get up to 3 since we are creating 2 services, though sometimes it is collapsed into a single event depending no timing + for range 3 { + assert.ChannelHasItem(t, notifyCh) + if n := len(getGws()); n == expectedGws { + return + } } + t.Errorf("expected %d gateways but got %v", expectedGws, getGws()) } t.Run("add meshnetworks", func(t *testing.T) { addMeshNetworksFromRegistryGateway(t, c, meshNetworks) - expectGateways(t, 2) + expectGateways(t, 3) }) t.Run("add labeled service", func(t *testing.T) { addLabeledServiceGateway(t, c, "nw0") - expectGateways(t, 3) + expectGateways(t, 4) }) t.Run("update labeled service network", func(t *testing.T) { addLabeledServiceGateway(t, c, "nw1") - expectGateways(t, 3) + expectGateways(t, 4) }) t.Run("add kubernetes gateway", func(t *testing.T) { addOrUpdateGatewayResource(t, c, 35443) - expectGateways(t, 7) + expectGateways(t, 8) }) t.Run("update kubernetes gateway", func(t *testing.T) { addOrUpdateGatewayResource(t, c, 45443) - expectGateways(t, 7) + expectGateways(t, 8) }) t.Run("remove kubernetes gateway", func(t *testing.T) { removeGatewayResource(t, c) - expectGateways(t, 3) + expectGateways(t, 4) }) t.Run("remove labeled service", func(t *testing.T) { removeLabeledServiceGateway(t, c) - expectGateways(t, 2) + expectGateways(t, 3) }) // gateways are created even with out service t.Run("add kubernetes gateway", func(t *testing.T) { addOrUpdateGatewayResource(t, c, 35443) - expectGateways(t, 6) + expectGateways(t, 7) }) t.Run("remove kubernetes gateway", func(t *testing.T) { removeGatewayResource(t, c) - expectGateways(t, 2) + expectGateways(t, 3) }) t.Run("remove meshnetworks", func(t *testing.T) { meshNetworks.SetNetworks(nil) @@ -206,6 +210,17 @@ func addMeshNetworksFromRegistryGateway(t *testing.T, c *FakeController, watcher Ports: []corev1.PortStatus{{Port: 15443, Protocol: corev1.ProtocolTCP}}, }}}}, }) + clienttest.Wrap(t, c.services).Create(&corev1.Service{ + ObjectMeta: metav1.ObjectMeta{Name: "istio-meshnetworks-gw-2", Namespace: "istio-system"}, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Ports: []corev1.ServicePort{{Port: 15443, Protocol: corev1.ProtocolTCP}}, + }, + Status: corev1.ServiceStatus{LoadBalancer: corev1.LoadBalancerStatus{Ingress: []corev1.LoadBalancerIngress{{ + IP: "1.2.3.5", + Ports: []corev1.PortStatus{{Port: 15443, Protocol: corev1.ProtocolTCP}}, + }}}}, + }) watcher.SetNetworks(&meshconfig.MeshNetworks{Networks: map[string]*meshconfig.Network{ "nw0": { Endpoints: []*meshconfig.Network_NetworkEndpoints{{ @@ -225,6 +240,15 @@ func addMeshNetworksFromRegistryGateway(t *testing.T, c *FakeController, watcher Gw: &meshconfig.Network_IstioNetworkGateway_RegistryServiceName{RegistryServiceName: "istio-meshnetworks-gw.istio-system.svc.cluster.local"}, }}, }, + "nw2": { + Endpoints: []*meshconfig.Network_NetworkEndpoints{{ + Ne: &meshconfig.Network_NetworkEndpoints_FromRegistry{FromRegistry: "Kubernetes"}, + }}, + Gateways: []*meshconfig.Network_IstioNetworkGateway{{ + Port: 15443, + Gw: &meshconfig.Network_IstioNetworkGateway_RegistryServiceName{RegistryServiceName: "istio-meshnetworks-gw-2.istio-system.svc.cluster.local"}, + }}, + }, }}) } diff --git a/pilot/pkg/serviceregistry/kube/controller/pod.go b/pilot/pkg/serviceregistry/kube/controller/pod.go index bb5837fdc865..4e53f9031fc2 100644 --- a/pilot/pkg/serviceregistry/kube/controller/pod.go +++ b/pilot/pkg/serviceregistry/kube/controller/pod.go @@ -140,16 +140,11 @@ func (pc *PodCache) labelFilter(old, cur *v1.Pod) bool { // Annotations are only used in endpoints in one case, so just compare that one relevantAnnotationsChanged := old.Annotations[annotation.AmbientRedirection.Name] != cur.Annotations[annotation.AmbientRedirection.Name] changed := labelsChanged || relevantAnnotationsChanged - if cur.Status.PodIP != "" && changed { - pc.proxyUpdates(cur, true) - } - - // always continue calling pc.onEvent - return false + return changed } // onEvent updates the IP-based index (pc.podsByIP). -func (pc *PodCache) onEvent(_, pod *v1.Pod, ev model.Event) error { +func (pc *PodCache) onEvent(old, pod *v1.Pod, ev model.Event) error { ip := pod.Status.PodIP // PodIP will be empty when pod is just created, but before the IP is assigned // via UpdateStatus. @@ -161,7 +156,7 @@ func (pc *PodCache) onEvent(_, pod *v1.Pod, ev model.Event) error { switch ev { case model.EventAdd: if shouldPodBeInEndpoints(pod) && IsPodReady(pod) { - pc.addPod(pod, ip, key) + pc.addPod(pod, ip, key, false) } else { return nil } @@ -173,7 +168,8 @@ func (pc *PodCache) onEvent(_, pod *v1.Pod, ev model.Event) error { } ev = model.EventDelete } else if shouldPodBeInEndpoints(pod) && IsPodReady(pod) { - pc.addPod(pod, ip, key) + labelUpdated := pc.labelFilter(old, pod) + pc.addPod(pod, ip, key, labelUpdated) } else { return nil } @@ -240,11 +236,14 @@ func (pc *PodCache) deleteIP(ip string, podKey types.NamespacedName) bool { return false } -func (pc *PodCache) addPod(pod *v1.Pod, ip string, key types.NamespacedName) { +func (pc *PodCache) addPod(pod *v1.Pod, ip string, key types.NamespacedName, labelUpdated bool) { pc.Lock() // if the pod has been cached, return if pc.podsByIP[ip].Contains(key) { pc.Unlock() + if labelUpdated { + pc.proxyUpdates(pod, true) + } return } if current, f := pc.IPByPods[key]; f { @@ -263,8 +262,7 @@ func (pc *PodCache) addPod(pod *v1.Pod, ip string, key types.NamespacedName) { } pc.Unlock() - const isPodUpdate = false - pc.proxyUpdates(pod, isPodUpdate) + pc.proxyUpdates(pod, false) } // queueEndpointEventOnPodArrival registers this endpoint and queues endpoint event diff --git a/pilot/pkg/serviceregistry/kube/controller/pod_test.go b/pilot/pkg/serviceregistry/kube/controller/pod_test.go index 87eb50c19852..d81eea6244fe 100644 --- a/pilot/pkg/serviceregistry/kube/controller/pod_test.go +++ b/pilot/pkg/serviceregistry/kube/controller/pod_test.go @@ -95,7 +95,6 @@ func initTestEnv(t *testing.T, ki kubernetes.Interface, fx *xdsfake.Updater) { func cleanup(ki kubernetes.Interface) { for _, n := range []string{"nsa", "nsb"} { - n := n pods, err := ki.CoreV1().Pods(n).List(context.TODO(), metav1.ListOptions{}) if err == nil { // Make sure the pods don't exist @@ -257,7 +256,7 @@ func TestPodCacheEvents(t *testing.T) { notReadyCondition := []v1.PodCondition{{Type: v1.PodReady, Status: v1.ConditionFalse}} readyCondition := []v1.PodCondition{{Type: v1.PodReady, Status: v1.ConditionTrue}} - if err := f(nil, + if err := f(&v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{Conditions: notReadyCondition, PodIP: ip, Phase: v1.PodPending}}, &v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{Conditions: notReadyCondition, PodIP: ip, Phase: v1.PodPending}}, model.EventUpdate); err != nil { t.Error(err) @@ -266,7 +265,9 @@ func TestPodCacheEvents(t *testing.T) { t.Errorf("notified workload handler %d times, want %d", handled, 0) } - if err := f(nil, &v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodPending}}, model.EventUpdate); err != nil { + if err := f(&v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{Conditions: notReadyCondition, PodIP: ip, Phase: v1.PodPending}}, + &v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodPending}}, + model.EventUpdate); err != nil { t.Error(err) } if handled != 1 { @@ -274,7 +275,7 @@ func TestPodCacheEvents(t *testing.T) { } assert.Equal(t, c.pods.getPodKeys(ip), []types.NamespacedName{{Name: "pod1", Namespace: "default"}}) - if err := f(nil, + if err := f(&v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodPending}}, &v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodFailed}}, model.EventUpdate); err != nil { t.Error(err) } @@ -284,7 +285,8 @@ func TestPodCacheEvents(t *testing.T) { assert.Equal(t, podCache.getPodKeys(ip), nil) pod1.DeletionTimestamp = &metav1.Time{Time: time.Now()} - if err := f(nil, &v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{PodIP: ip, Phase: v1.PodFailed}}, model.EventUpdate); err != nil { + if err := f(&v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodFailed}}, + &v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{PodIP: ip, Phase: v1.PodFailed}}, model.EventUpdate); err != nil { t.Error(err) } if handled != 2 { @@ -292,7 +294,9 @@ func TestPodCacheEvents(t *testing.T) { } pod2 := metav1.ObjectMeta{Name: "pod2", Namespace: ns} - if err := f(nil, &v1.Pod{ObjectMeta: pod2, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodRunning}}, model.EventAdd); err != nil { + if err := f(&v1.Pod{ObjectMeta: pod1, Status: v1.PodStatus{PodIP: ip, Phase: v1.PodFailed}}, + &v1.Pod{ObjectMeta: pod2, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodRunning}}, + model.EventAdd); err != nil { t.Error(err) } if handled != 3 { @@ -308,9 +312,12 @@ func TestPodCacheEvents(t *testing.T) { } assert.Equal(t, sets.New(c.pods.getPodKeys(ip)...), sets.New(types.NamespacedName{Name: "pod2", Namespace: "default"})) - if err := f(nil, &v1.Pod{ObjectMeta: pod2, Spec: v1.PodSpec{ + if err := f(&v1.Pod{ObjectMeta: pod2, Spec: v1.PodSpec{ RestartPolicy: v1.RestartPolicyOnFailure, - }, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodFailed}}, model.EventUpdate); err != nil { + }, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodFailed}}, + &v1.Pod{ObjectMeta: pod2, Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyOnFailure, + }, Status: v1.PodStatus{Conditions: readyCondition, PodIP: ip, Phase: v1.PodFailed}}, model.EventUpdate); err != nil { t.Error(err) } if handled != 4 { diff --git a/pilot/pkg/serviceregistry/serviceentry/controller.go b/pilot/pkg/serviceregistry/serviceentry/controller.go index 9e5807395580..5b06e3511c05 100644 --- a/pilot/pkg/serviceregistry/serviceentry/controller.go +++ b/pilot/pkg/serviceregistry/serviceentry/controller.go @@ -377,7 +377,7 @@ func getUpdatedConfigs(services []*model.Service) sets.Set[model.ConfigKey] { func (s *Controller) serviceEntryHandler(old, curr config.Config, event model.Event) { log.Debugf("Handle event %s for service entry %s/%s", event, curr.Namespace, curr.Name) currentServiceEntry := curr.Spec.(*networking.ServiceEntry) - cs := convertServices(curr, s.clusterID) + cs := convertServices(curr) configsUpdated := sets.New[model.ConfigKey]() key := curr.NamespacedName() diff --git a/pilot/pkg/serviceregistry/serviceentry/controller_test.go b/pilot/pkg/serviceregistry/serviceentry/controller_test.go index cf19570a9481..e0f0dbbae315 100644 --- a/pilot/pkg/serviceregistry/serviceentry/controller_test.go +++ b/pilot/pkg/serviceregistry/serviceentry/controller_test.go @@ -26,6 +26,7 @@ import ( "istio.io/api/label" networking "istio.io/api/networking/v1alpha3" "istio.io/istio/pilot/pkg/config/memory" + "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/serviceregistry/util/xdsfake" "istio.io/istio/pkg/config" @@ -1621,7 +1622,7 @@ func expectEvents(t testing.TB, ch *xdsfake.Updater, events ...Event) { func expectServiceInstances(t testing.TB, sd *Controller, cfg *config.Config, port int, expected ...[]*model.ServiceInstance) { t.Helper() - svcs := convertServices(*cfg, "") + svcs := convertServices(*cfg) if len(svcs) != len(expected) { t.Fatalf("got more services than expected: %v vs %v", len(svcs), len(expected)) } @@ -1636,7 +1637,7 @@ func expectServiceInstances(t testing.TB, sd *Controller, cfg *config.Config, po // The system is eventually consistent, so add some retries retry.UntilSuccessOrFail(t, func() error { for i, svc := range svcs { - endpoints := GetEndpointsForPort(svc, sd.XdsUpdater.(*xdsfake.Updater).Delegate.(*model.EndpointIndexUpdater).Index, port) + endpoints := GetEndpointsForPort(svc, sd.XdsUpdater.(*xdsfake.Updater).Delegate.(*model.FakeEndpointIndexUpdater).Index, port) if endpoints == nil { endpoints = []*model.IstioEndpoint{} // To simplify tests a bit } @@ -1855,8 +1856,8 @@ func TestServicesDiff(t *testing.T) { for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { - as := convertServices(*tt.current, "") - bs := convertServices(*tt.new, "") + as := convertServices(*tt.current) + bs := convertServices(*tt.new) added, deleted, updated, unchanged := servicesDiff(as, bs) for i, item := range []struct { hostnames []host.Name @@ -1968,7 +1969,9 @@ func sortPorts(ports []*model.Port) { }) } -func Test_autoAllocateIP_conditions(t *testing.T) { +func Test_legacyAutoAllocateIP_conditions(t *testing.T) { + // We are testing the old IP allocation which turns off if the new one is enabled + test.SetForTest(t, &features.EnableIPAutoallocate, false) tests := []struct { name string inServices []*model.Service @@ -2167,7 +2170,9 @@ func Test_autoAllocateIP_conditions(t *testing.T) { } } -func Test_autoAllocateIP_values(t *testing.T) { +func Test_legacyAutoAllocateIP_values(t *testing.T) { + // We are testing the old IP allocation which turns off if the new one is enabled + test.SetForTest(t, &features.EnableIPAutoallocate, false) ips := maxIPs inServices := make([]*model.Service, ips) for i := 0; i < ips; i++ { @@ -2245,7 +2250,9 @@ func BenchmarkAutoAllocateIPs(t *testing.B) { } // Validate that ipaddress allocation is deterministic based on hash. -func Test_autoAllocateIP_deterministic(t *testing.T) { +func Test_legacyAutoAllocateIP_deterministic(t *testing.T) { + // We are testing the old IP allocation which turns off if the new one is enabled + test.SetForTest(t, &features.EnableIPAutoallocate, false) inServices := make([]*model.Service, 0) originalServices := map[string]string{ "a.com": "240.240.109.8", @@ -2329,6 +2336,9 @@ func Test_autoAllocateIP_deterministic(t *testing.T) { } func Test_autoAllocateIP_with_duplicated_host(t *testing.T) { + // Only the old IP auto-allocator has this functionality + // TODO(https://github.com/istio/istio/issues/53676): implement this in the new one, and test both + test.SetForTest(t, &features.EnableIPAutoallocate, false) inServices := make([]*model.Service, 0) originalServices := map[string]string{ "a.com": "240.240.109.8", diff --git a/pilot/pkg/serviceregistry/serviceentry/conversion.go b/pilot/pkg/serviceregistry/serviceentry/conversion.go index 956398ca3368..701303c2e288 100644 --- a/pilot/pkg/serviceregistry/serviceentry/conversion.go +++ b/pilot/pkg/serviceregistry/serviceentry/conversion.go @@ -34,7 +34,6 @@ import ( "istio.io/istio/pkg/config/visibility" "istio.io/istio/pkg/kube/labels" "istio.io/istio/pkg/network" - "istio.io/istio/pkg/slices" "istio.io/istio/pkg/spiffe" netutil "istio.io/istio/pkg/util/net" "istio.io/istio/pkg/util/sets" @@ -50,7 +49,7 @@ func convertPort(port *networking.ServicePort) *model.Port { type HostAddress struct { host string - addresses []string + address string autoAssignedV4 string autoAssignedV6 string } @@ -62,6 +61,7 @@ type HostAddress struct { // See kube.ConvertService for the conversion from K8S to internal Service. func ServiceToServiceEntry(svc *model.Service, proxy *model.Proxy) *config.Config { gvk := gvk.ServiceEntry + getSvcAddresses := func(s *model.Service, node *model.Proxy) []string { if node.Metadata != nil && node.Metadata.ClusterID == "" { var addresses []string @@ -78,9 +78,9 @@ func ServiceToServiceEntry(svc *model.Service, proxy *model.Proxy) *config.Confi // Host is fully qualified: name, namespace, domainSuffix Hosts: []string{string(svc.Hostname)}, - // ServiceEntry can represent multiple services, so we return all the addresses of the services - // if proxy ClusterID unset. - // And only the cluster specific addresses when proxy ClusterID set. + // Internal Service and K8S Service have a single Address. + // ServiceEntry can represent multiple - but we are not using that. SE may be merged. + // Will be 0.0.0.0 if not specified as ClusterIP or ClusterIP==None. In such case resolution is Passthrough. Addresses: getSvcAddresses(svc, proxy), // This is based on alpha.istio.io/canonical-serviceaccounts and @@ -154,7 +154,7 @@ func ServiceToServiceEntry(svc *model.Service, proxy *model.Proxy) *config.Confi } // convertServices transforms a ServiceEntry config to a list of internal Service objects. -func convertServices(cfg config.Config, clusterID cluster.ID) []*model.Service { +func convertServices(cfg config.Config) []*model.Service { serviceEntry := cfg.Spec.(*networking.ServiceEntry) // ShouldV2AutoAllocateIP already checks that there are no addresses in the spec however this is critical enough to likely be worth checking // explicitly as well in case the logic changes. We never want to overwrite addresses in the spec if there are any @@ -202,26 +202,22 @@ func convertServices(cfg config.Config, clusterID cluster.ID) []*model.Service { if serviceEntry.WorkloadSelector != nil { labelSelectors = serviceEntry.WorkloadSelector.Labels } - hostAddresses := []*HostAddress{} for _, hostname := range serviceEntry.Hosts { - localAddresses := addresses - if len(localAddresses) > 0 { - ha := &HostAddress{hostname, []string{}, "", ""} - for _, address := range localAddresses { - // Check if addresses is an IP first because that is the most common case. + if len(serviceEntry.Addresses) > 0 { + for _, address := range serviceEntry.Addresses { + // Check if address is an IP first because that is the most common case. if netutil.IsValidIPAddress(address) { - ha.addresses = append(ha.addresses, address) + hostAddresses = append(hostAddresses, &HostAddress{hostname, address, "", ""}) } else if cidr, cidrErr := netip.ParsePrefix(address); cidrErr == nil { newAddress := address if cidr.Bits() == cidr.Addr().BitLen() { - // /32 mask. Remove the /32 and make it a normal IP addresses + // /32 mask. Remove the /32 and make it a normal IP address newAddress = cidr.Addr().String() } - ha.addresses = append(ha.addresses, newAddress) + hostAddresses = append(hostAddresses, &HostAddress{hostname, newAddress, "", ""}) } } - hostAddresses = append(hostAddresses, ha) } else { var v4, v6 string if autoAddresses, ok := addressLookup[hostname]; ok { @@ -234,7 +230,7 @@ func convertServices(cfg config.Config, clusterID cluster.ID) []*model.Service { } } } - hostAddresses = append(hostAddresses, &HostAddress{hostname, []string{constants.UnspecifiedIP}, v4, v6}) + hostAddresses = append(hostAddresses, &HostAddress{hostname, constants.UnspecifiedIP, v4, v6}) } } @@ -248,7 +244,7 @@ func convertServices(cfg config.Config, clusterID cluster.ID) []*model.Service { CreationTime: creationTime, MeshExternal: serviceEntry.Location == networking.ServiceEntry_MESH_EXTERNAL, Hostname: host.Name(ha.host), - DefaultAddress: ha.addresses[0], + DefaultAddress: ha.address, Ports: svcPorts, Resolution: resolution, Attributes: model.ServiceAttributes{ @@ -269,13 +265,6 @@ func convertServices(cfg config.Config, clusterID cluster.ID) []*model.Service { if ha.autoAssignedV6 != "" { svc.AutoAllocatedIPv6Address = ha.autoAssignedV6 } - if !slices.Equal(ha.addresses, []string{constants.UnspecifiedIP}) { - svc.ClusterVIPs = model.AddressMap{ - Addresses: map[cluster.ID][]string{ - clusterID: ha.addresses, - }, - } - } out = append(out, svc) } return out @@ -370,7 +359,7 @@ func (s *Controller) convertServiceEntryToInstances(cfg config.Config, services return nil } if services == nil { - services = convertServices(cfg, s.clusterID) + services = convertServices(cfg) } endpointsNum := len(serviceEntry.Endpoints) @@ -473,7 +462,7 @@ func (s *Controller) convertWorkloadEntryToWorkloadInstance(cfg config.Config, c dnsServiceEntryOnly = true } if addr != "" && !netutil.IsValidIPAddress(addr) { - // k8s can't use workloads with hostnames in the addresses field. + // k8s can't use workloads with hostnames in the address field. dnsServiceEntryOnly = true } tlsMode := getTLSModeFromWorkloadEntry(we) @@ -486,7 +475,7 @@ func (s *Controller) convertWorkloadEntryToWorkloadInstance(cfg config.Config, c if locality == "" && len(we.Labels[model.LocalityLabel]) > 0 { locality = model.GetLocalityLabel(we.Labels[model.LocalityLabel]) } - labels := labelutil.AugmentLabels(we.Labels, clusterID, locality, "", networkID) + lbls := labelutil.AugmentLabels(we.Labels, clusterID, locality, "", networkID) return &model.WorkloadInstance{ Endpoint: &model.IstioEndpoint{ Addresses: []string{addr}, @@ -500,8 +489,8 @@ func (s *Controller) convertWorkloadEntryToWorkloadInstance(cfg config.Config, c Namespace: cfg.Namespace, // Workload entry config name is used as workload name, which will appear in metric label. // After VM auto registry is introduced, workload group annotation should be used for workload name. - WorkloadName: cfg.Name, - Labels: labels, + WorkloadName: labels.WorkloadNameFromWorkloadEntry(cfg.Name, cfg.Annotations, cfg.Labels), + Labels: lbls, TLSMode: tlsMode, ServiceAccount: sa, }, diff --git a/pilot/pkg/serviceregistry/serviceentry/conversion_test.go b/pilot/pkg/serviceregistry/serviceentry/conversion_test.go index cd3015cb4aeb..6202f583e9d4 100644 --- a/pilot/pkg/serviceregistry/serviceentry/conversion_test.go +++ b/pilot/pkg/serviceregistry/serviceentry/conversion_test.go @@ -36,7 +36,6 @@ import ( "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/config/schema/gvk" "istio.io/istio/pkg/network" - "istio.io/istio/pkg/slices" "istio.io/istio/pkg/spiffe" "istio.io/istio/pkg/test" ) @@ -604,11 +603,6 @@ func makeService(hostname host.Name, configName, configNamespace string, address K8sAttributes: model.K8sAttributes{ObjectName: configName}, }, } - if !slices.Equal(addresses, []string{constants.UnspecifiedIP}) { - svc.ClusterVIPs = model.AddressMap{ - Addresses: map[cluster.ID][]string{"": addresses}, - } - } if autoV4 != "" { svc.AutoAllocatedIPv4Address = autoV4 @@ -663,7 +657,7 @@ func makeInstanceWithServiceAccount(cfg *config.Config, addresses []string, port func makeTarget(cfg *config.Config, address string, port int, svcPort *networking.ServicePort, svcLabels map[string]string, mtlsMode MTLSMode, ) model.ServiceTarget { - services := convertServices(*cfg, "") + services := convertServices(*cfg) svc := services[0] // default for _, s := range services { if string(s.Hostname) == address { @@ -694,7 +688,7 @@ func makeTarget(cfg *config.Config, address string, port int, func makeInstance(cfg *config.Config, addresses []string, port int, svcPort *networking.ServicePort, svcLabels map[string]string, mtlsMode MTLSMode, ) *model.ServiceInstance { - services := convertServices(*cfg, "") + services := convertServices(*cfg) svc := services[0] // default getSvc := false for _, s := range services { @@ -738,7 +732,6 @@ func makeInstance(cfg *config.Config, addresses []string, port int, } func TestConvertService(t *testing.T) { - test.SetForTest(t, &features.EnableIPAutoallocate, true) testConvertServiceBody(t) test.SetForTest(t, &features.CanonicalServiceForMeshExternalServiceEntry, true) testConvertServiceBody(t) @@ -860,8 +853,12 @@ func testConvertServiceBody(t *testing.T) { services: []*model.Service{ makeService("tcp1.com", "multiAddrInternal", "multiAddrInternal", []string{"1.1.1.0/16", "2.2.2.0/16"}, "", "", map[string]int{"tcp-444": 444}, false, model.Passthrough), + makeService("tcp1.com", "multiAddrInternal", "multiAddrInternal", []string{"2.2.2.0/16", "1.1.1.0/16"}, "", "", + map[string]int{"tcp-444": 444}, false, model.Passthrough), makeService("tcp2.com", "multiAddrInternal", "multiAddrInternal", []string{"1.1.1.0/16", "2.2.2.0/16"}, "", "", map[string]int{"tcp-444": 444}, false, model.Passthrough), + makeService("tcp2.com", "multiAddrInternal", "multiAddrInternal", []string{"2.2.2.0/16", "1.1.1.0/16"}, "", "", + map[string]int{"tcp-444": 444}, false, model.Passthrough), }, }, } @@ -879,7 +876,7 @@ func testConvertServiceBody(t *testing.T) { }) for _, tt := range serviceTests { - services := convertServices(*tt.externalSvc, "") + services := convertServices(*tt.externalSvc) if err := compare(t, services, tt.services); err != nil { t.Errorf("testcase: %v\n%v ", tt.externalSvc.Name, err) } @@ -1066,7 +1063,7 @@ func TestConvertWorkloadEntryToServiceInstances(t *testing.T) { for _, tt := range serviceInstanceTests { t.Run(tt.name, func(t *testing.T) { - services := convertServices(*tt.se, "") + services := convertServices(*tt.se) s := &Controller{meshWatcher: mesh.NewFixedWatcher(mesh.DefaultMeshConfig())} instances := s.convertWorkloadEntryToServiceInstances(tt.wle, services, tt.se.Spec.(*networking.ServiceEntry), &configKey{}, tt.clusterID) sortServiceInstances(instances) diff --git a/pilot/pkg/serviceregistry/serviceregistry_test.go b/pilot/pkg/serviceregistry/serviceregistry_test.go index 4ce4d4761378..e3edf6794646 100644 --- a/pilot/pkg/serviceregistry/serviceregistry_test.go +++ b/pilot/pkg/serviceregistry/serviceregistry_test.go @@ -1681,7 +1681,7 @@ func expectServiceEndpointsFromIndex(t *testing.T, ei *model.EndpointIndex, svc // nolint: unparam func expectServiceEndpoints(t *testing.T, fx *xdsfake.Updater, svc *model.Service, port int, expected []EndpointResponse) { t.Helper() - expectServiceEndpointsFromIndex(t, fx.Delegate.(*model.EndpointIndexUpdater).Index, svc, port, expected) + expectServiceEndpointsFromIndex(t, fx.Delegate.(*model.FakeEndpointIndexUpdater).Index, svc, port, expected) } func setPodReady(pod *v1.Pod) { diff --git a/pilot/pkg/xds/ads.go b/pilot/pkg/xds/ads.go index c65aff773eab..9e88319ec135 100644 --- a/pilot/pkg/xds/ads.go +++ b/pilot/pkg/xds/ads.go @@ -386,6 +386,8 @@ func (s *DiscoveryServer) initializeProxy(con *Connection) error { } func (s *DiscoveryServer) computeProxyState(proxy *model.Proxy, request *model.PushRequest) { + proxy.Lock() + defer proxy.Unlock() var shouldResetGateway, shouldResetSidecarScope bool // 1. If request == nil(initiation phase) or request.ConfigsUpdated == nil(global push), set proxy serviceTargets. // 2. otherwise only set when svc update, this is for the case that a service may select the proxy diff --git a/pilot/pkg/xds/bench_test.go b/pilot/pkg/xds/bench_test.go index c9a034680338..787e1b1f7ffb 100644 --- a/pilot/pkg/xds/bench_test.go +++ b/pilot/pkg/xds/bench_test.go @@ -338,7 +338,6 @@ func runBenchmark(b *testing.B, tpe string, testCases []ConfigInput) { } func testBenchmark(t *testing.T, tpe string, testCases []ConfigInput) { - test.SetForTest(t, &features.EnableAmbient, true) for _, tt := range testCases { if tt.OnlyRunType != "" && tt.OnlyRunType != tpe { // Not applicable for this type @@ -398,7 +397,7 @@ func setupTest(t testing.TB, config ConfigInput) (*xds.FakeDiscoveryServer, *mod "istio.io/benchmark": "true", }, ClusterID: constants.DefaultClusterName, - IstioVersion: "1.24.0", + IstioVersion: "1.25.0", }, ConfigNamespace: "default", VerifiedIdentity: &spiffe.Identity{Namespace: "default"}, diff --git a/pilot/pkg/xds/cds.go b/pilot/pkg/xds/cds.go index f5ae16309283..7e805a5b62d3 100644 --- a/pilot/pkg/xds/cds.go +++ b/pilot/pkg/xds/cds.go @@ -64,6 +64,10 @@ var pushCdsGatewayConfig = func() sets.Set[kind.Kind] { }() func cdsNeedsPush(req *model.PushRequest, proxy *model.Proxy) bool { + if proxy.Type == model.Ztunnel { + // Not supported for ztunnel + return false + } if req == nil { return true } diff --git a/pilot/pkg/xds/debug.go b/pilot/pkg/xds/debug.go index ddc77231db32..33acf443b812 100644 --- a/pilot/pkg/xds/debug.go +++ b/pilot/pkg/xds/debug.go @@ -41,12 +41,13 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/networking/util" "istio.io/istio/pilot/pkg/util/protoconv" - "istio.io/istio/pilot/pkg/xds/endpoints" v3 "istio.io/istio/pilot/pkg/xds/v3" "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/schema/resource" "istio.io/istio/pkg/config/xds" + "istio.io/istio/pkg/kube/krt" istiolog "istio.io/istio/pkg/log" + "istio.io/istio/pkg/maps" "istio.io/istio/pkg/security" "istio.io/istio/pkg/slices" "istio.io/istio/pkg/util/protomarshal" @@ -186,9 +187,9 @@ func (s *DiscoveryServer) AddDebugHandlers(mux, internalMux *http.ServeMux, enab s.addDebugHandler(mux, internalMux, "/debug/force_disconnect", "Disconnects a proxy from this Pilot", s.forceDisconnect) } - s.addDebugHandler(mux, internalMux, "/debug/ecdsz", "Status and debug interface for ECDS", s.ecdsz) - s.addDebugHandler(mux, internalMux, "/debug/edsz", "Status and debug interface for EDS", s.Edsz) - s.addDebugHandler(mux, internalMux, "/debug/ndsz", "Status and debug interface for NDS", s.ndsz) + s.addDebugHandler(mux, internalMux, "/debug/ecdsz", "Status and debug interface for ECDS", s.typedConfigDumpHandler("ecds")) + s.addDebugHandler(mux, internalMux, "/debug/edsz", "Status and debug interface for EDS", s.typedConfigDumpHandler("eds")) + s.addDebugHandler(mux, internalMux, "/debug/ndsz", "Status and debug interface for NDS", s.typedConfigDumpHandler("nds")) s.addDebugHandler(mux, internalMux, "/debug/adsz", "Status and debug interface for ADS", s.adsz) s.addDebugHandler(mux, internalMux, "/debug/adsz?push=true", "Initiates push of the current state to all connected endpoints", s.adsz) @@ -205,6 +206,7 @@ func (s *DiscoveryServer) AddDebugHandlers(mux, internalMux *http.ServeMux, enab s.addDebugHandler(mux, internalMux, "/debug/resourcesz", "Debug support for watched resources", s.resourcez) s.addDebugHandler(mux, internalMux, "/debug/instancesz", "Debug support for service instances", s.instancesz) s.addDebugHandler(mux, internalMux, "/debug/ambientz", "Debug support for ambient", s.ambientz) + s.addDebugHandler(mux, internalMux, "/debug/krtz", "Debug support for krt (internal state)", s.krtz) s.addDebugHandler(mux, internalMux, "/debug/authorizationz", "Internal authorization policies", s.authorizationz) s.addDebugHandler(mux, internalMux, "/debug/telemetryz", "Debug Telemetry configuration", s.telemetryz) @@ -530,24 +532,13 @@ func (s *DiscoveryServer) adsz(w http.ResponseWriter, req *http.Request) { writeJSON(w, adsClients, req) } -// ecdsz implements a status and debug interface for ECDS. -// It is mapped to /debug/ecdsz -func (s *DiscoveryServer) ecdsz(w http.ResponseWriter, req *http.Request) { - if s.handlePushRequest(w, req) { - return - } - proxyID, con := s.getDebugConnection(req) - if con == nil { - s.errorHandler(w, proxyID, con) - return - } - - dump := s.getConfigDumpByResourceType(con, nil, []string{v3.ExtensionConfigurationType}) - if len(dump[v3.ExtensionConfigurationType]) == 0 { - w.WriteHeader(http.StatusNotFound) - return +func (s *DiscoveryServer) typedConfigDumpHandler(typ string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + q := r.URL.Query() + q.Set("types", typ) + r.URL.RawQuery = q.Encode() + s.ConfigDump(w, r) } - writeJSON(w, dump[v3.ExtensionConfigurationType], req) } // ConfigDump returns information in the form of the Envoy admin API config dump for the specified proxy @@ -583,7 +574,7 @@ func (s *DiscoveryServer) ConfigDump(w http.ResponseWriter, req *http.Request) { return } - includeEds := req.URL.Query().Get("include_eds") == "true" + includeEds := req.URL.Query().Has("include_eds") dump, err := s.connectionConfigDump(con, includeEds) if err != nil { handleHTTPError(w, err) @@ -598,7 +589,13 @@ func (s *DiscoveryServer) getResourceTypes(req *http.Request) []string { resourceTypes := sets.New[string]() for _, t := range ts { - resourceTypes.Insert(v3.GetResourceType(t)) + rType := v3.GetResourceType(t) + resourceTypes.Insert(rType) + // special case for AddressType, include WorkloadType as well + // because they shared same short type name `WDS` + if rType == v3.AddressType { + resourceTypes.Insert(v3.WorkloadType) + } } return resourceTypes.UnsortedList() @@ -875,6 +872,11 @@ func (s *DiscoveryServer) pushContextHandler(w http.ResponseWriter, req *http.Re writeJSON(w, push, req) } +// DebugEndpoints lists all the supported debug endpoints. +func (s *DiscoveryServer) DebugEndpoints() []string { + return slices.Sort(maps.Keys(s.debugHandlers)) +} + // Debug lists all the supported debug endpoints. func (s *DiscoveryServer) Debug(w http.ResponseWriter, req *http.Request) { type debugEndpoint struct { @@ -920,57 +922,6 @@ func (s *DiscoveryServer) list(w http.ResponseWriter, req *http.Request) { writeJSON(w, cmdNames, req) } -// ndsz implements a status and debug interface for NDS. -// It is mapped to /debug/ndsz on the monitor port (15014). -func (s *DiscoveryServer) ndsz(w http.ResponseWriter, req *http.Request) { - if s.handlePushRequest(w, req) { - return - } - proxyID, con := s.getDebugConnection(req) - if con == nil { - s.errorHandler(w, proxyID, con) - return - } - if !con.proxy.Metadata.DNSCapture { - w.WriteHeader(http.StatusBadRequest) - _, _ = w.Write([]byte("DNS capture is not enabled in the proxy\n")) - return - } - - if s.Generators[v3.NameTableType] != nil { - nds, _, _ := s.Generators[v3.NameTableType].Generate(con.proxy, nil, &model.PushRequest{ - Push: con.proxy.LastPushContext, - Full: true, - }) - if len(nds) == 0 { - return - } - writeJSON(w, nds[0], req) - } -} - -// Edsz implements a status and debug interface for EDS. -// It is mapped to /debug/edsz on the monitor port (15014). -func (s *DiscoveryServer) Edsz(w http.ResponseWriter, req *http.Request) { - if s.handlePushRequest(w, req) { - return - } - - proxyID, con := s.getDebugConnection(req) - if con == nil { - s.errorHandler(w, proxyID, con) - return - } - - clusters := con.Clusters() - eps := make([]jsonMarshalProto, 0, len(clusters)) - for _, clusterName := range clusters { - builder := endpoints.NewEndpointBuilder(clusterName, con.proxy, con.proxy.LastPushContext) - eps = append(eps, jsonMarshalProto{builder.BuildClusterLoadAssignment(s.Env.EndpointIndex)}) - } - writeJSON(w, eps, req) -} - func (s *DiscoveryServer) forceDisconnect(w http.ResponseWriter, req *http.Request) { proxyID, con := s.getDebugConnection(req) if con == nil { @@ -1080,6 +1031,10 @@ func (s *DiscoveryServer) ambientz(w http.ResponseWriter, req *http.Request) { writeJSON(w, res, req) } +func (s *DiscoveryServer) krtz(w http.ResponseWriter, req *http.Request) { + writeJSON(w, krt.GlobalDebugHandler, req) +} + func (s *DiscoveryServer) networkz(w http.ResponseWriter, req *http.Request) { if s.Env == nil || s.Env.NetworkManager == nil { return diff --git a/pilot/pkg/xds/delta_test.go b/pilot/pkg/xds/delta_test.go index 181efcf4a4f9..e03155d12911 100644 --- a/pilot/pkg/xds/delta_test.go +++ b/pilot/pkg/xds/delta_test.go @@ -21,7 +21,6 @@ import ( discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" v3 "istio.io/istio/pilot/pkg/xds/v3" "istio.io/istio/pilot/test/xds" @@ -29,7 +28,6 @@ import ( "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/config/schema/kind" "istio.io/istio/pkg/slices" - "istio.io/istio/pkg/test" "istio.io/istio/pkg/test/util/assert" "istio.io/istio/pkg/test/util/retry" "istio.io/istio/pkg/util/sets" @@ -80,6 +78,7 @@ func TestDeltaCDS(t *testing.T) { assert.Equal(t, sets.New(got...), sets.New(names...).Merge(base)) } s := xds.NewFakeDiscoveryServer(t, xds.FakeOptions{}) + spamDebugEndpointsToDetectRace(t, s) addTestClientEndpoints(s.MemRegistry) s.MemRegistry.AddHTTPService(edsIncSvc, edsIncVip, 8080) s.MemRegistry.SetEndpoints(edsIncSvc, "", @@ -331,7 +330,6 @@ func TestDeltaReconnectRequests(t *testing.T) { } func TestDeltaWDS(t *testing.T) { - test.SetForTest(t, &features.EnableAmbient, true) s := xds.NewFakeDiscoveryServer(t, xds.FakeOptions{}) wlA := &model.WorkloadInfo{ Workload: &workloadapi.Workload{ diff --git a/pilot/pkg/xds/discovery_test.go b/pilot/pkg/xds/discovery_test.go index ac73c35e0bb6..df74a207dee1 100644 --- a/pilot/pkg/xds/discovery_test.go +++ b/pilot/pkg/xds/discovery_test.go @@ -71,7 +71,6 @@ func TestSendPushesManyPushes(t *testing.T) { pushesMu := &sync.Mutex{} for _, proxy := range proxies { - proxy := proxy // Start receive thread go func() { for { @@ -125,7 +124,6 @@ func TestSendPushesSinglePush(t *testing.T) { pushesMu := &sync.Mutex{} for _, proxy := range proxies { - proxy := proxy // Start receive thread go func() { for { diff --git a/pilot/pkg/xds/ecds.go b/pilot/pkg/xds/ecds.go index 305d1ebd75e9..acbabc566bcf 100644 --- a/pilot/pkg/xds/ecds.go +++ b/pilot/pkg/xds/ecds.go @@ -38,7 +38,11 @@ type EcdsGenerator struct { var _ model.XdsResourceGenerator = &EcdsGenerator{} -func ecdsNeedsPush(req *model.PushRequest) bool { +func ecdsNeedsPush(req *model.PushRequest, proxy *model.Proxy) bool { + if proxy.Type == model.Ztunnel { + // Not supported for ztunnel + return false + } if req == nil { return true } @@ -80,7 +84,7 @@ func onlyReferencedConfigsUpdated(req *model.PushRequest) bool { // Generate returns ECDS resources for a given proxy. func (e *EcdsGenerator) Generate(proxy *model.Proxy, w *model.WatchedResource, req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) { - if !ecdsNeedsPush(req) { + if !ecdsNeedsPush(req, proxy) { return nil, model.DefaultXdsLogDetails, nil } diff --git a/pilot/pkg/xds/eds.go b/pilot/pkg/xds/eds.go index 8ce9286a5c37..6d28a4ea23ae 100644 --- a/pilot/pkg/xds/eds.go +++ b/pilot/pkg/xds/eds.go @@ -49,7 +49,7 @@ func (s *DiscoveryServer) EDSUpdate(shard model.ShardKey, serviceName string, na ) { inboundEDSUpdates.Increment() // Update the endpoint shards - pushType := s.Env.EndpointIndex.UpdateServiceEndpoints(shard, serviceName, namespace, istioEndpoints) + pushType := s.Env.EndpointIndex.UpdateServiceEndpoints(shard, serviceName, namespace, istioEndpoints, true) if pushType == model.IncrementalPush || pushType == model.FullPush { // Trigger a push s.ConfigUpdate(&model.PushRequest{ @@ -72,7 +72,7 @@ func (s *DiscoveryServer) EDSCacheUpdate(shard model.ShardKey, serviceName strin ) { inboundEDSUpdates.Increment() // Update the endpoint shards - s.Env.EndpointIndex.UpdateServiceEndpoints(shard, serviceName, namespace, istioEndpoints) + s.Env.EndpointIndex.UpdateServiceEndpoints(shard, serviceName, namespace, istioEndpoints, false) } func (s *DiscoveryServer) RemoveShard(shardKey model.ShardKey) { @@ -108,7 +108,11 @@ var skippedEdsConfigs = sets.New( kind.GRPCRoute, ) -func edsNeedsPush(updates model.XdsUpdates) bool { +func edsNeedsPush(updates model.XdsUpdates, proxy *model.Proxy) bool { + if proxy.Type == model.Ztunnel { + // Not supported for ztunnel + return false + } // If none set, we will always push if len(updates) == 0 { return true @@ -122,7 +126,7 @@ func edsNeedsPush(updates model.XdsUpdates) bool { } func (eds *EdsGenerator) Generate(proxy *model.Proxy, w *model.WatchedResource, req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) { - if !edsNeedsPush(req.ConfigsUpdated) { + if !edsNeedsPush(req.ConfigsUpdated, proxy) { return nil, model.DefaultXdsLogDetails, nil } resources, logDetails := eds.buildEndpoints(proxy, req, w) @@ -132,7 +136,7 @@ func (eds *EdsGenerator) Generate(proxy *model.Proxy, w *model.WatchedResource, func (eds *EdsGenerator) GenerateDeltas(proxy *model.Proxy, req *model.PushRequest, w *model.WatchedResource, ) (model.Resources, model.DeletedResources, model.XdsLogDetails, bool, error) { - if !edsNeedsPush(req.ConfigsUpdated) { + if !edsNeedsPush(req.ConfigsUpdated, proxy) { return nil, nil, model.DefaultXdsLogDetails, false, nil } if !shouldUseDeltaEds(req) { diff --git a/pilot/pkg/xds/eds_test.go b/pilot/pkg/xds/eds_test.go index 7c2f1e1f7633..3417ecec30c8 100644 --- a/pilot/pkg/xds/eds_test.go +++ b/pilot/pkg/xds/eds_test.go @@ -1346,8 +1346,7 @@ func testEdsz(t *testing.T, s *xdsfake.FakeDiscoveryServer, proxyID string) { t.Fatal(err) } rr := httptest.NewRecorder() - debug := http.HandlerFunc(s.Discovery.Edsz) - debug.ServeHTTP(rr, req) + s.DiscoveryDebug.ServeHTTP(rr, req) data, err := io.ReadAll(rr.Body) if err != nil { diff --git a/pilot/pkg/xds/lds.go b/pilot/pkg/xds/lds.go index 45d753481756..9db8cffff42b 100644 --- a/pilot/pkg/xds/lds.go +++ b/pilot/pkg/xds/lds.go @@ -63,6 +63,10 @@ var skippedLdsConfigs = map[model.NodeType]sets.Set[kind.Kind]{ } func ldsNeedsPush(proxy *model.Proxy, req *model.PushRequest) bool { + if proxy.Type == model.Ztunnel { + // Not supported for ztunnel + return false + } if req == nil { return true } diff --git a/pilot/pkg/xds/lds_test.go b/pilot/pkg/xds/lds_test.go index cb0292c0493e..ca7901439ba6 100644 --- a/pilot/pkg/xds/lds_test.go +++ b/pilot/pkg/xds/lds_test.go @@ -293,7 +293,6 @@ func TestLDSEnvoyFilterWithWorkloadSelector(t *testing.T) { } for _, test := range tests { - test := test t.Run(test.name, func(t *testing.T) { adsc := s.Connect(&model.Proxy{ ConfigNamespace: "consumerns", diff --git a/pilot/pkg/xds/mesh_network_test.go b/pilot/pkg/xds/mesh_network_test.go index 57bbff2d3f68..ab90400f91c0 100644 --- a/pilot/pkg/xds/mesh_network_test.go +++ b/pilot/pkg/xds/mesh_network_test.go @@ -282,13 +282,10 @@ func TestMeshNetworking(t *testing.T) { } for ingrType, ingressObjects := range ingressServiceScenarios { - ingrType, ingressObjects := ingrType, ingressObjects t.Run(string(ingrType), func(t *testing.T) { for name, networkConfig := range meshNetworkConfigs { - name, networkConfig := name, networkConfig t.Run(name, func(t *testing.T) { for _, cfg := range trafficConfigs { - cfg := cfg t.Run(cfg.Meta.Name, func(t *testing.T) { pod := &workload{ kind: Pod, diff --git a/pilot/pkg/xds/nds.go b/pilot/pkg/xds/nds.go index 3a076e26bb97..1e941ac947e1 100644 --- a/pilot/pkg/xds/nds.go +++ b/pilot/pkg/xds/nds.go @@ -60,7 +60,11 @@ var skippedNdsConfigs = sets.New( kind.GRPCRoute, ) -func ndsNeedsPush(req *model.PushRequest) bool { +func ndsNeedsPush(req *model.PushRequest, proxy *model.Proxy) bool { + if proxy.Type == model.Ztunnel { + // Not supported for ztunnel + return false + } if req == nil { return true } @@ -85,7 +89,7 @@ func headlessEndpointsUpdated(req *model.PushRequest) bool { } func (n NdsGenerator) Generate(proxy *model.Proxy, _ *model.WatchedResource, req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) { - if !ndsNeedsPush(req) { + if !ndsNeedsPush(req, proxy) { return nil, model.DefaultXdsLogDetails, nil } nt := n.ConfigGenerator.BuildNameTable(proxy, req.Push) diff --git a/pilot/pkg/xds/nds_test.go b/pilot/pkg/xds/nds_test.go index e527d8fb8dfa..ce52b8f7308b 100644 --- a/pilot/pkg/xds/nds_test.go +++ b/pilot/pkg/xds/nds_test.go @@ -23,15 +23,20 @@ import ( "github.com/google/go-cmp/cmp" "google.golang.org/protobuf/testing/protocmp" + "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/util/protoconv" v3 "istio.io/istio/pilot/pkg/xds/v3" "istio.io/istio/pilot/test/xds" "istio.io/istio/pkg/config/constants" dnsProto "istio.io/istio/pkg/dns/proto" + "istio.io/istio/pkg/test" ) func TestNDS(t *testing.T) { + // The "auto allocate" test only needs a special case for the legacy auto allocation mode, so we disable the new one here + // and only test the old one. The new one appears identically to manually-allocated SE from NDS perspective. + test.SetForTest(t, &features.EnableIPAutoallocate, false) cases := []struct { name string meta model.NodeMetadata diff --git a/pilot/pkg/xds/rds.go b/pilot/pkg/xds/rds.go index bc2a17f05caa..a0d0c2cf14fa 100644 --- a/pilot/pkg/xds/rds.go +++ b/pilot/pkg/xds/rds.go @@ -41,7 +41,11 @@ var skippedRdsConfigs = sets.New[kind.Kind]( kind.DNSName, ) -func rdsNeedsPush(req *model.PushRequest) bool { +func rdsNeedsPush(req *model.PushRequest, proxy *model.Proxy) bool { + if proxy.Type == model.Ztunnel { + // Not supported for ztunnel + return false + } if req == nil { return true } @@ -62,7 +66,7 @@ func rdsNeedsPush(req *model.PushRequest) bool { } func (c RdsGenerator) Generate(proxy *model.Proxy, w *model.WatchedResource, req *model.PushRequest) (model.Resources, model.XdsLogDetails, error) { - if !rdsNeedsPush(req) { + if !rdsNeedsPush(req, proxy) { return nil, model.DefaultXdsLogDetails, nil } resources, logDetails := c.ConfigGenerator.BuildHTTPRoutes(proxy, req, w.ResourceNames) diff --git a/pilot/pkg/xds/waypoint_test.go b/pilot/pkg/xds/waypoint_test.go index f885aaf91232..52ae9988f9b9 100644 --- a/pilot/pkg/xds/waypoint_test.go +++ b/pilot/pkg/xds/waypoint_test.go @@ -18,13 +18,19 @@ import ( "strings" "testing" + hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" + + "istio.io/api/label" + meshconfig "istio.io/api/mesh/v1alpha1" "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/test/xds" "istio.io/istio/pilot/test/xdstest" + "istio.io/istio/pkg/config/mesh" "istio.io/istio/pkg/slices" "istio.io/istio/pkg/test" "istio.io/istio/pkg/test/util/assert" + "istio.io/istio/pkg/util/sets" "istio.io/istio/pkg/wellknown" ) @@ -82,6 +88,7 @@ metadata: istio.io/use-waypoint: waypoint spec: hosts: [app.com] + addresses: [1.2.3.4] ports: - number: 80 name: http @@ -220,7 +227,7 @@ spec: hasTLSInspector(443, true) } -func TestWaypoint(t *testing.T) { +func TestWaypointEndpoints(t *testing.T) { d, proxy := setupWaypointTest(t, waypointGateway, waypointSvc, @@ -228,7 +235,7 @@ func TestWaypoint(t *testing.T) { waypointInstance, appWorkloadEntry, appServiceEntry) - eps := slices.Sort(xdstest.ExtractEndpoints(d.Endpoints(proxy)[0])) + eps := slices.Sort(xdstest.ExtractEndpoints(d.Endpoints(proxy)[1])) assert.Equal(t, eps, []string{ // No tunnel, should get dual IPs "1.1.1.3:80,[2001:20::3]:80", @@ -238,18 +245,274 @@ func TestWaypoint(t *testing.T) { }) } +func TestWaypointTelemetry(t *testing.T) { + telemetry := `apiVersion: telemetry.istio.io/v1 +kind: Telemetry +metadata: + name: logs + namespace: default +spec: + targetRefs: + - kind: ServiceEntry + name: app + group: networking.istio.io + accessLogging: + - providers: + - name: envoy + metrics: + - providers: + - name: prometheus + tracing: + - providers: + - name: otel +` + notSelectedAppServiceEntry := `apiVersion: networking.istio.io/v1 +kind: ServiceEntry +metadata: + name: not-app + namespace: default + labels: + istio.io/use-waypoint: waypoint +spec: + hosts: [not-app.com] + addresses: [2.3.4.5] + ports: + - number: 80 + name: http + protocol: HTTP + resolution: STATIC + workloadSelector: + labels: + app: app` + d, proxy := setupWaypointTest(t, + waypointGateway, waypointSvc, waypointInstance, + appServiceEntry, notSelectedAppServiceEntry, + telemetry) + + l := xdstest.ExtractListener("main_internal", d.Listeners(proxy)) + app := xdstest.ExtractHTTPConnectionManager(t, + xdstest.ExtractFilterChain(model.BuildSubsetKey(model.TrafficDirectionInboundVIP, "http", "app.com", 80), l)) + notApp := xdstest.ExtractHTTPConnectionManager(t, + xdstest.ExtractFilterChain(model.BuildSubsetKey(model.TrafficDirectionInboundVIP, "http", "not-app.com", 80), l)) + + // The selected service should get all 3 types + assert.Equal(t, app.AccessLog != nil, true) + assert.Equal(t, sets.New(slices.Map(app.HttpFilters, (*hcm.HttpFilter).GetName)...).Contains("istio.stats"), true) + assert.Equal(t, app.Tracing.Provider != nil, true) + + // Unselected service should get none + assert.Equal(t, notApp.AccessLog == nil, true) + assert.Equal(t, sets.New(slices.Map(notApp.HttpFilters, (*hcm.HttpFilter).GetName)...).Contains("istio.stats"), false) + assert.Equal(t, notApp.Tracing.Provider == nil, true) +} + +func TestWaypointRequestAuth(t *testing.T) { + // jwks mostly from https://datatracker.ietf.org/doc/html/rfc7517#appendix-A.1 + requestAuthn := `apiVersion: security.istio.io/v1 +kind: RequestAuthentication +metadata: + name: jwt-on-waypoint + namespace: default +spec: + targetRefs: + - group: networking.istio.io + kind: ServiceEntry + name: app + jwtRules: + - issuer: "example.ietf.org" + jwks: | + {"keys": + [ + {"kty":"EC", + "crv":"P-256", + "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + "use":"enc", + "kid":"1"} + ] + }` + notSelectedAppServiceEntry := `apiVersion: networking.istio.io/v1 +kind: ServiceEntry +metadata: + name: not-app + namespace: default + labels: + istio.io/use-waypoint: waypoint +spec: + hosts: [not-app.com] + addresses: [2.3.4.5] + ports: + - number: 80 + name: http + protocol: HTTP + resolution: STATIC + workloadSelector: + labels: + app: app` + d, proxy := setupWaypointTest(t, + waypointGateway, waypointSvc, waypointInstance, + appServiceEntry, notSelectedAppServiceEntry, requestAuthn) + + l := xdstest.ExtractListener("main_internal", d.Listeners(proxy)) + + app := xdstest.ExtractHTTPConnectionManager(t, + xdstest.ExtractFilterChain(model.BuildSubsetKey(model.TrafficDirectionInboundVIP, "http", "app.com", 80), l)) + assert.Equal(t, sets.New(slices.Map(app.HttpFilters, (*hcm.HttpFilter).GetName)...).Contains("envoy.filters.http.jwt_authn"), true) + + // assert not-app.com has not gotten config from the req authn + notApp := xdstest.ExtractHTTPConnectionManager(t, + xdstest.ExtractFilterChain(model.BuildSubsetKey(model.TrafficDirectionInboundVIP, "http", "not-app.com", 80), l)) + assert.Equal(t, sets.New(slices.Map(notApp.HttpFilters, (*hcm.HttpFilter).GetName)...).Contains("envoy.filters.http.jwt_authn"), false) +} + +func TestCrossNamespaceWaypointRequestAuth(t *testing.T) { + // jwks mostly from https://datatracker.ietf.org/doc/html/rfc7517#appendix-A.1 + requestAuthn := `apiVersion: security.istio.io/v1 +kind: RequestAuthentication +metadata: + name: jwt-on-waypoint + namespace: app +spec: + targetRefs: + - group: networking.istio.io + kind: ServiceEntry + name: app + jwtRules: + - issuer: "example.ietf.org" + jwks: | + {"keys": + [ + {"kty":"EC", + "crv":"P-256", + "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", + "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", + "use":"enc", + "kid":"1"} + ] + }` + waypointSvc := `apiVersion: v1 +kind: Service +metadata: + labels: + gateway.istio.io/managed: istio.io-mesh-controller + gateway.networking.k8s.io/gateway-name: waypoint + istio.io/gateway-name: waypoint + name: waypoint + namespace: default +spec: + clusterIP: 3.0.0.0 + ports: + - appProtocol: hbone + name: mesh + port: 15008 + selector: + gateway.networking.k8s.io/gateway-name: waypoint` + + waypointInstance := `apiVersion: networking.istio.io/v1 +kind: WorkloadEntry +metadata: + name: waypoint-a + namespace: default +spec: + address: 3.0.0.1 + labels: + gateway.networking.k8s.io/gateway-name: waypoint` + + waypointGateway := `apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: waypoint + namespace: default +spec: + gatewayClassName: waypoint + listeners: + - name: mesh + port: 15008 + protocol: HBONE + allowedRoutes: + namespaces: + from: All +status: + addresses: + - type: Hostname + value: waypoint.default.svc.cluster.local` + + appServiceEntry := `apiVersion: networking.istio.io/v1 +kind: ServiceEntry +metadata: + name: app + namespace: app + labels: + istio.io/use-waypoint: waypoint + istio.io/use-waypoint-namespace: default +spec: + hosts: [app.com] + addresses: [1.2.3.4] + ports: + - number: 80 + name: http + protocol: HTTP + resolution: STATIC + workloadSelector: + labels: + app: app` + notSelectedAppServiceEntry := `apiVersion: networking.istio.io/v1 +kind: ServiceEntry +metadata: + name: not-app + namespace: app + labels: + istio.io/use-waypoint: waypoint + istio.io/use-waypoint-namespace: default +spec: + hosts: [not-app.com] + addresses: [2.3.4.5] + ports: + - number: 80 + name: http + protocol: HTTP + resolution: STATIC + workloadSelector: + labels: + app: app` + + d, proxy := setupWaypointTest(t, + waypointGateway, waypointSvc, waypointInstance, + appServiceEntry, notSelectedAppServiceEntry, requestAuthn) + + l := xdstest.ExtractListener("main_internal", d.Listeners(proxy)) + + app := xdstest.ExtractHTTPConnectionManager(t, + xdstest.ExtractFilterChain(model.BuildSubsetKey(model.TrafficDirectionInboundVIP, "http", "app.com", 80), l)) + assert.Equal(t, sets.New(slices.Map(app.HttpFilters, (*hcm.HttpFilter).GetName)...).Contains("envoy.filters.http.jwt_authn"), true) + + // assert not-app.com has not gotten config from the req authn + notApp := xdstest.ExtractHTTPConnectionManager(t, + xdstest.ExtractFilterChain(model.BuildSubsetKey(model.TrafficDirectionInboundVIP, "http", "not-app.com", 80), l)) + assert.Equal(t, sets.New(slices.Map(notApp.HttpFilters, (*hcm.HttpFilter).GetName)...).Contains("envoy.filters.http.jwt_authn"), false) +} + func setupWaypointTest(t *testing.T, configs ...string) (*xds.FakeDiscoveryServer, *model.Proxy) { - test.SetForTest(t, &features.EnableAmbient, true) test.SetForTest(t, &features.EnableDualStack, true) c := joinYaml(configs...) + mc := mesh.DefaultMeshConfig() + mc.ExtensionProviders = append(mc.ExtensionProviders, &meshconfig.MeshConfig_ExtensionProvider{ + Name: "otel", + Provider: &meshconfig.MeshConfig_ExtensionProvider_Opentelemetry{ + // Pointing to the waypoint is silly, we just need some valid service to point to and it exists + Opentelemetry: &meshconfig.MeshConfig_ExtensionProvider_OpenTelemetryTracingProvider{Service: "waypoint.default.svc.cluster.local", Port: 15008}, + }, + }) // Ambient controller needs objects as kube, so apply to both d := xds.NewFakeDiscoveryServer(t, xds.FakeOptions{ ConfigString: c, KubernetesObjectString: c, + MeshConfig: mc, }) proxy := d.SetupProxy(&model.Proxy{ Type: model.Waypoint, ConfigNamespace: "default", + Labels: map[string]string{label.IoK8sNetworkingGatewayGatewayName.Name: "waypoint"}, IPAddresses: []string{"3.0.0.1"}, // match the WE }) return d, proxy diff --git a/pilot/pkg/xds/workload.go b/pilot/pkg/xds/workload.go index f03e61e43e05..444e30c411ad 100644 --- a/pilot/pkg/xds/workload.go +++ b/pilot/pkg/xds/workload.go @@ -45,7 +45,7 @@ func (e WorkloadGenerator) GenerateDeltas( req *model.PushRequest, w *model.WatchedResource, ) (model.Resources, model.DeletedResources, model.XdsLogDetails, bool, error) { - updatedAddresses := model.ConfigNameOfKind(req.ConfigsUpdated, kind.Address) + updatedAddresses := model.ConfigNamesOfKind(req.ConfigsUpdated, kind.Address) isReq := req.IsRequest() if len(updatedAddresses) == 0 && len(req.ConfigsUpdated) > 0 { // Nothing changed.. @@ -137,6 +137,8 @@ func (e WorkloadGenerator) GenerateDeltas( removed = subs.Difference(have).Difference(haveAliases).Merge(removed) } + proxy.Lock() + defer proxy.Unlock() if !w.Wildcard { // For on-demand, we may have requested a VIP but gotten Pod IPs back. We need to update // the internal book-keeping to subscribe to the Pods, so that we push updates to those Pods. diff --git a/pilot/pkg/xds/workload_test.go b/pilot/pkg/xds/workload_test.go index e3a1c70486aa..1b45f896cb9c 100644 --- a/pilot/pkg/xds/workload_test.go +++ b/pilot/pkg/xds/workload_test.go @@ -16,6 +16,10 @@ package xds_test import ( "context" + "io" + "net/http" + "net/http/httptest" + "strings" "testing" "time" @@ -36,11 +40,17 @@ import ( "istio.io/istio/pkg/config/constants" "istio.io/istio/pkg/config/schema/gvk" "istio.io/istio/pkg/kube/kclient/clienttest" + "istio.io/istio/pkg/log" "istio.io/istio/pkg/test" "istio.io/istio/pkg/test/util/assert" "istio.io/istio/pkg/util/sets" ) +func init() { + // Most tests need this, and setting it per-test can trigger races from tests still executing after completion + features.EnableAmbient = true +} + func buildExpect(t *testing.T) func(resp *discovery.DeltaDiscoveryResponse, names ...string) { return func(resp *discovery.DeltaDiscoveryResponse, names ...string) { t.Helper() @@ -90,7 +100,6 @@ func buildExpectAddedAndRemoved(t *testing.T) func(resp *discovery.DeltaDiscover } func TestWorkloadReconnect(t *testing.T) { - test.SetForTest(t, &features.EnableAmbient, true) t.Run("ondemand", func(t *testing.T) { expect := buildExpect(t) s := xds.NewFakeDiscoveryServer(t, xds.FakeOptions{ @@ -165,7 +174,6 @@ func TestWorkloadReconnect(t *testing.T) { } func TestWorkload(t *testing.T) { - test.SetForTest(t, &features.EnableAmbient, true) t.Run("ondemand", func(t *testing.T) { expect := buildExpect(t) expectRemoved := buildExpectExpectRemoved(t) @@ -173,6 +181,7 @@ func TestWorkload(t *testing.T) { DebounceTime: time.Millisecond * 25, }) ads := s.ConnectDeltaADS().WithTimeout(time.Second * 5).WithType(v3.AddressType).WithMetadata(model.NodeMetadata{NodeName: "node"}) + spamDebugEndpointsToDetectRace(t, s) ads.Request(&discovery.DeltaDiscoveryRequest{ ResourceNamesSubscribe: []string{"*"}, @@ -250,6 +259,7 @@ func TestWorkload(t *testing.T) { DebounceTime: time.Millisecond * 25, }) ads := s.ConnectDeltaADS().WithTimeout(time.Second * 5).WithType(v3.AddressType).WithMetadata(model.NodeMetadata{NodeName: "node"}) + spamDebugEndpointsToDetectRace(t, s) ads.Request(&discovery.DeltaDiscoveryRequest{ ResourceNamesSubscribe: []string{"*"}, @@ -281,6 +291,45 @@ func TestWorkload(t *testing.T) { }) } +// Historically, the debug interface has been a common source of race conditions in the discovery server +// spamDebugEndpointsToDetectRace hits all the endpoints, attempting to trigger any latent race conditions. +func spamDebugEndpointsToDetectRace(t *testing.T, s *xds.FakeDiscoveryServer) { + stop := test.NewStop(t) + go func() { + for _, proxySpecific := range []bool{true, false} { + for range 10 { + for _, url := range s.Discovery.DebugEndpoints() { + select { + case <-stop: + // Test is over, stop early + return + default: + } + // Drop mutating URLs + if strings.Contains(url, "push=true") { + continue + } + if strings.Contains(url, "clear=true") { + continue + } + if proxySpecific { + url += "?proxyID=test" + } + req, err := http.NewRequest(http.MethodGet, url, nil) + if err != nil { + panic(err.Error()) + } + log.Debugf("calling %v..", req.URL) + rr := httptest.NewRecorder() + h, _ := s.DiscoveryDebug.Handler(req) + h.ServeHTTP(rr, req) + _, _ = io.Copy(io.Discard, rr.Body) + } + } + } + }() +} + func deletePod(s *xds.FakeDiscoveryServer, name string) { err := s.KubeClient().Kube().CoreV1().Pods("default").Delete(context.Background(), name, metav1.DeleteOptions{}) if err != nil { @@ -384,7 +433,6 @@ func createService(s *xds.FakeDiscoveryServer, name, namespace string, selector } func TestWorkloadAuthorizationPolicy(t *testing.T) { - test.SetForTest(t, &features.EnableAmbient, true) expect := buildExpect(t) expectRemoved := buildExpectExpectRemoved(t) s := xds.NewFakeDiscoveryServer(t, xds.FakeOptions{}) @@ -412,7 +460,6 @@ func TestWorkloadAuthorizationPolicy(t *testing.T) { } func TestWorkloadPeerAuthentication(t *testing.T) { - test.SetForTest(t, &features.EnableAmbient, true) expect := buildExpect(t) expectAddedAndRemoved := buildExpectAddedAndRemoved(t) s := xds.NewFakeDiscoveryServer(t, xds.FakeOptions{}) @@ -457,7 +504,6 @@ func TestWorkloadPeerAuthentication(t *testing.T) { // Regression tests for NOP PeerAuthentication triggering a removal func TestPeerAuthenticationUpdate(t *testing.T) { - test.SetForTest(t, &features.EnableAmbient, true) expectAddedAndRemoved := buildExpectAddedAndRemoved(t) s := xds.NewFakeDiscoveryServer(t, xds.FakeOptions{}) ads := s.ConnectDeltaADS().WithType(v3.WorkloadAuthorizationType).WithTimeout(time.Second * 10).WithNodeType(model.Ztunnel) diff --git a/pilot/test/xds/fake.go b/pilot/test/xds/fake.go index 042cf720ae7f..ccf7a2b6372b 100644 --- a/pilot/test/xds/fake.go +++ b/pilot/test/xds/fake.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "net" + "net/http" "strings" "time" @@ -113,14 +114,15 @@ type FakeOptions struct { type FakeDiscoveryServer struct { *core.ConfigGenTest - t test.Failer - Discovery *xds.DiscoveryServer - Listener net.Listener - BufListener *bufconn.Listener - kubeClient kubelib.Client - KubeRegistry *kube.FakeController - XdsUpdater model.XDSUpdater - MemRegistry *memregistry.ServiceDiscovery + t test.Failer + Discovery *xds.DiscoveryServer + DiscoveryDebug *http.ServeMux + Listener net.Listener + BufListener *bufconn.Listener + kubeClient kubelib.Client + KubeRegistry *kube.FakeController + XdsUpdater model.XDSUpdater + MemRegistry *memregistry.ServiceDiscovery } func NewFakeDiscoveryServer(t test.Failer, opts FakeOptions) *FakeDiscoveryServer { @@ -256,6 +258,10 @@ func NewFakeDiscoveryServer(t test.Failer, opts FakeOptions) *FakeDiscoveryServe s.Generators[v3.SecretType] = xds.NewSecretGen(creds, s.Cache, opts.DefaultClusterName, nil) s.Generators[v3.ExtensionConfigurationType].(*xds.EcdsGenerator).SetCredController(creds) + debugMux := s.InitDebug(http.NewServeMux(), false, func() map[string]string { + return nil + }) + memRegistry := cg.MemRegistry memRegistry.XdsUpdater = s @@ -343,15 +349,16 @@ func NewFakeDiscoveryServer(t test.Failer, opts FakeOptions) *FakeDiscoveryServe bufListener, _ := listener.(*bufconn.Listener) fake := &FakeDiscoveryServer{ - t: t, - Discovery: s, - Listener: listener, - BufListener: bufListener, - ConfigGenTest: cg, - kubeClient: defaultKubeClient, - KubeRegistry: defaultKubeController, - XdsUpdater: xdsUpdater, - MemRegistry: memRegistry, + t: t, + Discovery: s, + DiscoveryDebug: debugMux, + Listener: listener, + BufListener: bufListener, + ConfigGenTest: cg, + kubeClient: defaultKubeClient, + KubeRegistry: defaultKubeController, + XdsUpdater: xdsUpdater, + MemRegistry: memRegistry, } return fake diff --git a/pilot/test/xdstest/extract.go b/pilot/test/xdstest/extract.go index 3338c8b6d27c..f9200cee24ee 100644 --- a/pilot/test/xdstest/extract.go +++ b/pilot/test/xdstest/extract.go @@ -316,6 +316,15 @@ func ExtractLoadAssignments(cla []*endpoint.ClusterLoadAssignment) map[string][] return got } +func ExtractListenerAddresses(l *listener.Listener) []string { + res := []string{} + res = append(res, addressToString(l.Address, nil)) + for _, aa := range l.AdditionalAddresses { + res = append(res, addressToString(aa.Address, nil)) + } + return res +} + // ExtractHealthEndpoints returns all health and unhealth endpoints func ExtractHealthEndpoints(cla *endpoint.ClusterLoadAssignment) ([]string, []string) { if cla == nil { @@ -334,19 +343,7 @@ func ExtractHealthEndpoints(cla *endpoint.ClusterLoadAssignment) ([]string, []st if i != 0 { addrString += "," } - switch addr.Address.(type) { - case *core.Address_SocketAddress: - addrString += net.JoinHostPort(addr.GetSocketAddress().Address, fmt.Sprint(addr.GetSocketAddress().GetPortValue())) - case *core.Address_Pipe: - addrString += addr.GetPipe().Path - case *core.Address_EnvoyInternalAddress: - internalAddr := addr.GetEnvoyInternalAddress().GetServerListenerName() - destinationAddr := lb.GetMetadata().GetFilterMetadata()[util.OriginalDstMetadataKey].GetFields()["local"].GetStringValue() - addrString += fmt.Sprintf("%s;%s", internalAddr, destinationAddr) - if wp := lb.GetMetadata().GetFilterMetadata()[util.OriginalDstMetadataKey].GetFields()["waypoint"].GetStringValue(); wp != "" { - addrString += fmt.Sprintf(";%s", wp) - } - } + addrString += addressToString(addr, lb) } if lb.HealthStatus == core.HealthStatus_HEALTHY { healthy = append(healthy, addrString) @@ -358,6 +355,26 @@ func ExtractHealthEndpoints(cla *endpoint.ClusterLoadAssignment) ([]string, []st return healthy, unhealthy } +func addressToString(addr *core.Address, lb *endpoint.LbEndpoint) string { + res := "" + switch addr.Address.(type) { + case *core.Address_SocketAddress: + res = net.JoinHostPort(addr.GetSocketAddress().Address, fmt.Sprint(addr.GetSocketAddress().GetPortValue())) + case *core.Address_Pipe: + res = addr.GetPipe().Path + case *core.Address_EnvoyInternalAddress: + internalAddr := addr.GetEnvoyInternalAddress().GetServerListenerName() + if lb != nil { + destinationAddr := lb.GetMetadata().GetFilterMetadata()[util.OriginalDstMetadataKey].GetFields()["local"].GetStringValue() + res = fmt.Sprintf("%s;%s", internalAddr, destinationAddr) + if wp := lb.GetMetadata().GetFilterMetadata()[util.OriginalDstMetadataKey].GetFields()["waypoint"].GetStringValue(); wp != "" { + res += fmt.Sprintf(";%s", wp) + } + } + } + return res +} + // ExtractEndpoints returns all endpoints in the load assignment (including unhealthy endpoints) func ExtractEndpoints(cla *endpoint.ClusterLoadAssignment) []string { h, uh := ExtractHealthEndpoints(cla) diff --git a/pilot/test/xdstest/validate.go b/pilot/test/xdstest/validate.go index 8cf51e7e770d..8bdb97cb6df0 100644 --- a/pilot/test/xdstest/validate.go +++ b/pilot/test/xdstest/validate.go @@ -32,7 +32,13 @@ import ( func ValidateListeners(t testing.TB, ls []*listener.Listener) { t.Helper() found := sets.New[string]() + foundAddresses := sets.New[string]() for _, l := range ls { + for _, addr := range ExtractListenerAddresses(l) { + if foundAddresses.InsertContains(addr) { + t.Errorf("found duplicate address %s", addr) + } + } if found.InsertContains(l.Name) { t.Errorf("duplicate listener name %v", l.Name) } diff --git a/pkg/adsc/delta.go b/pkg/adsc/delta.go index 7ee1ccb4fb97..9ceb182cedd2 100644 --- a/pkg/adsc/delta.go +++ b/pkg/adsc/delta.go @@ -198,6 +198,11 @@ type Client struct { // initialWatches is the list of resources we are watching on startup initialWatches []resourceKey + // initialWatches is a list of resources we were initially watching and have not yet received + pendingWatches sets.Set[resourceKey] + // synced is used to indicate the initial watches have all been seen + synced chan struct{} + // sendNodeMeta is set to true if the connection is new - and we need to send node meta sendNodeMeta bool @@ -262,11 +267,19 @@ func (c *Client) Run(ctx context.Context) { c.runWithReconnects(ctx) } +// Synced returns a channel that will close once the client has received all initial watches +func (c *Client) Synced() <-chan struct{} { + return c.synced +} + func (c *Client) runOnce(ctx context.Context) error { if err := c.dial(ctx); err != nil { return fmt.Errorf("dial fail: %v", err) } + defer c.conn.Close() + ctx, cancel := context.WithCancel(ctx) + defer cancel() xds := discovery.NewAggregatedDiscoveryServiceClient(c.conn) xdsClient, err := xds.DeltaAggregatedResources(ctx, grpc.MaxCallRecvMsgSize(math.MaxInt32)) if err != nil { @@ -285,6 +298,9 @@ func (c *Client) runOnce(ctx context.Context) error { } func (c *Client) dial(ctx context.Context) error { + if c.conn != nil { + _ = c.conn.Close() + } conn, err := dialWithConfig(ctx, &c.cfg.Config) if err != nil { return err @@ -328,6 +344,8 @@ func NewDelta(discoveryAddr string, config *DeltaADSConfig, opts ...Option) *Cli handlers: map[string]HandlerFunc{}, tree: map[resourceKey]resourceNode{}, errChan: make(chan error, 10), + synced: make(chan struct{}), + pendingWatches: sets.New[resourceKey](), lastReceivedNonce: map[string]string{}, closed: atomic.NewBool(false), } @@ -392,6 +410,7 @@ func initWatch(typeURL string, resourceName string) Option { } } c.initialWatches = append(c.initialWatches, key) + c.pendingWatches.Insert(key) } } @@ -428,6 +447,11 @@ func (c *Client) handleDeltaResponse(d *discovery.DeltaDiscoveryResponse) error // No need to ack and type check for debug types return nil } + + c.markReceived(resourceKey{ + Name: "", // If they did a wildcard sub + TypeURL: d.TypeUrl, + }) for _, r := range d.Resources { if d.TypeUrl != r.Resource.TypeUrl { c.log.Errorf("Invalid response: mismatch of type url: %v vs %v", d.TypeUrl, r.Resource.TypeUrl) @@ -441,6 +465,7 @@ func (c *Client) handleDeltaResponse(d *discovery.DeltaDiscoveryResponse) error Name: r.Name, TypeURL: r.Resource.TypeUrl, } + c.markReceived(parentKey) c.establishResource(parentKey) if ctx.nack != nil { rejects = append(rejects, ctx.nack) @@ -487,6 +512,15 @@ func (c *Client) handleDeltaResponse(d *discovery.DeltaDiscoveryResponse) error return nil } +func (c *Client) markReceived(k resourceKey) { + if c.pendingWatches.Contains(k) { + c.pendingWatches.Delete(k) + if c.pendingWatches.Len() == 0 { + close(c.synced) + } + } +} + func joinError(rejects []error) error { var e []string for _, r := range rejects { diff --git a/pkg/adsc/delta_test.go b/pkg/adsc/delta_test.go index e7a00e682705..a62d92ec6c6d 100644 --- a/pkg/adsc/delta_test.go +++ b/pkg/adsc/delta_test.go @@ -224,6 +224,7 @@ func TestDeltaClient(t *testing.T) { serverResponses []*discovery.DeltaDiscoveryResponse expectedRecv []string expectedTree string + expectSynced bool }{ { desc: "initial request cluster with no secret", @@ -305,7 +306,8 @@ LDS/: `, }, { - desc: "put things together", + desc: "put things together", + expectSynced: true, serverResponses: []*discovery.DeltaDiscoveryResponse{ { TypeUrl: v3.ClusterType, @@ -400,7 +402,7 @@ LDS/: log.Error(err) } }() - defer xds.GracefulStop() + defer l.Close() if err != nil { t.Errorf("Could not start serving ads server %v", err) return @@ -423,6 +425,9 @@ LDS/: })) tracker.WaitUnordered(wantRecv...) tracker.Empty() + if tt.expectSynced { + assert.ChannelIsClosed(t, client.synced) + } // Close the listener and wait for things to gracefully close down cancel() assert.NoError(t, l.Close()) diff --git a/pkg/bootstrap/platform/gcp.go b/pkg/bootstrap/platform/gcp.go index 520a8add584c..9f02d203e4cc 100644 --- a/pkg/bootstrap/platform/gcp.go +++ b/pkg/bootstrap/platform/gcp.go @@ -27,6 +27,7 @@ import ( "cloud.google.com/go/compute/metadata" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + "go.uber.org/atomic" "golang.org/x/oauth2" "golang.org/x/oauth2/google" @@ -48,12 +49,14 @@ const ( GCEInstanceTemplate = "gcp_gce_instance_template" GCEInstanceCreatedBy = "gcp_gce_instance_created_by" GCPQuotaProject = "gcp_quota_project" + GCPZone = "gcp_zone" ) // GCPStaticMetadata holds the statically defined GCP metadata var GCPStaticMetadata = func() map[string]string { gcpm := env.Register("GCP_METADATA", "", "Pipe separated GCP metadata, schemed as PROJECT_ID|PROJECT_NUMBER|CLUSTER_NAME|CLUSTER_ZONE").Get() quota := env.Register("GCP_QUOTA_PROJECT", "", "Allows specification of a quota project to be used in requests to GCP APIs.").Get() + zone := env.Register("GCP_ZONE", "", "GCP Zone where the workload is running on.").Get() if len(gcpm) == 0 { return map[string]string{} } @@ -73,6 +76,10 @@ var GCPStaticMetadata = func() map[string]string { if clusterURL, err := constructGKEClusterURL(md); err == nil { md[GCPClusterURL] = clusterURL } + + if zone != "" { + md[GCPZone] = zone + } return md }() @@ -87,6 +94,7 @@ var ( numericProjectIDFn = metadata.NumericProjectID instanceNameFn = metadata.InstanceName instanceIDFn = metadata.InstanceID + zoneFn = metadata.ZoneWithContext clusterNameFn = func() (string, error) { cn, err := metadata.InstanceAttributeValue("cluster-name") @@ -148,6 +156,8 @@ type gcpEnv struct { sync.Mutex metadata map[string]string fillMetadata lazy.Lazy[bool] + + cachedZone *atomic.String } // IsGCP returns whether or not the platform for bootstrapping is Google Cloud Platform. @@ -167,6 +177,7 @@ func NewGCP() Environment { fillMetadata: lazy.New(func() (bool, error) { return shouldFillMetadata(), nil }), + cachedZone: atomic.NewString(GCPStaticMetadata[GCPZone]), } } @@ -249,33 +260,50 @@ func waitForMetadataSuppliers(suppliers []metadataSupplier, md map[string]string return &wg } +// Zones are in the form --. +var zoneRE = regexp.MustCompile(`^([^-]+-[^-]+)-[^-]+$`) + // Converts a GCP zone into a region. func zoneToRegion(z string) (string, error) { - // Zones are in the form -, so capture everything but the suffix. - re := regexp.MustCompile("(.*)-.*") - m := re.FindStringSubmatch(z) + m := zoneRE.FindStringSubmatch(z) if len(m) != 2 { return "", fmt.Errorf("unable to extract region from GCP zone: %s", z) } return m[1], nil } +// Returns the zone where the pod is located in. +func (e *gcpEnv) getPodZone() (string, error) { + z := e.cachedZone.Load() + if z != "" { + return z, nil + } + ctx, cfn := context.WithTimeout(context.Background(), 10*time.Second) + defer cfn() + z, err := zoneFn(ctx) + if err != nil { + log.Warnf("Error fetching GCP zone from the metadata server: %v", err) + return "", err + } + e.cachedZone.Store(z) + return z, nil +} + // Locality returns the GCP-specific region and zone. func (e *gcpEnv) Locality() *core.Locality { var l core.Locality - loc := e.Metadata()[GCPLocation] - if loc == "" { - log.Warnf("Error fetching GCP zone: %v", loc) + z, err := e.getPodZone() + if err != nil { return &l } - r, err := zoneToRegion(loc) + r, err := zoneToRegion(z) if err != nil { - log.Warnf("Error fetching GCP region: %v", err) + log.Warnf("Error fetching GCP region from zone: %v", z, err) return &l } return &core.Locality{ Region: r, - Zone: loc, + Zone: z, SubZone: "", // GCP has no subzone concept } } diff --git a/pkg/bootstrap/platform/gcp_test.go b/pkg/bootstrap/platform/gcp_test.go index 6cd9ea2c1c6d..2ae40d97252b 100644 --- a/pkg/bootstrap/platform/gcp_test.go +++ b/pkg/bootstrap/platform/gcp_test.go @@ -15,6 +15,7 @@ package platform import ( + "context" "errors" "testing" @@ -361,77 +362,36 @@ func TestDefaultPort(t *testing.T) { func TestLocality(t *testing.T) { tests := []struct { - name string - shouldFill shouldFillFn - projectIDFn metadataFn - numericProjectIDFn metadataFn - locationFn metadataFn - clusterNameFn metadataFn - instanceNameFn metadataFn - instanceIDFn metadataFn - instanceTemplateFn metadataFn - instanceCreatedByFn metadataFn - env map[string]string - want map[string]string + name string + zoneFn func(context.Context) (string, error) + env map[string]string + want map[string]string }{ { "fill by env variable", - func() bool { return true }, - func() (string, error) { return "pid", nil }, - func() (string, error) { return "npid", nil }, - func() (string, error) { return "location", nil }, - func() (string, error) { return "cluster", nil }, - func() (string, error) { return "instanceName", nil }, - func() (string, error) { return "instance", nil }, - func() (string, error) { return "instanceTemplate", nil }, - func() (string, error) { return "createdBy", nil }, + func(context.Context) (string, error) { return "us-east1-ir", nil }, map[string]string{ - GCPProject: "env_pid", - GCPProjectNumber: "env_pn", - GCPCluster: "env_cluster", - GCPLocation: "us-west1-ir", + GCPZone: "us-central2-ir", }, - map[string]string{"Zone": "us-west1-ir", "Region": "us-west1"}, + map[string]string{"Zone": "us-central2-ir", "Region": "us-central2"}, }, { - "no env variable", - func() bool { return true }, - func() (string, error) { return "pid", nil }, - func() (string, error) { return "npid", nil }, - func() (string, error) { return "us-west1-ir", nil }, - func() (string, error) { return "cluster", nil }, - func() (string, error) { return "instanceName", nil }, - func() (string, error) { return "instance", nil }, - func() (string, error) { return "instanceTemplate", nil }, - func() (string, error) { return "createdBy", nil }, + "fill by metadata server", + func(context.Context) (string, error) { return "us-east1-ir", nil }, map[string]string{}, - map[string]string{"Zone": "us-west1-ir", "Region": "us-west1"}, + map[string]string{"Zone": "us-east1-ir", "Region": "us-east1"}, }, { - "empty result", - func() bool { return false }, - func() (string, error) { return "pid", nil }, - func() (string, error) { return "npid", nil }, - func() (string, error) { return "us-west1-ir", nil }, - func() (string, error) { return "cluster", nil }, - func() (string, error) { return "instanceName", nil }, - func() (string, error) { return "instance", nil }, - func() (string, error) { return "instanceTemplate", nil }, - func() (string, error) { return "createdBy", nil }, - map[string]string{}, - map[string]string{}, + "fill by env variable without compute metadata", + func(context.Context) (string, error) { return "", errors.New("error") }, + map[string]string{ + GCPZone: "us-central2-ir", + }, + map[string]string{"Zone": "us-central2-ir", "Region": "us-central2"}, }, { - "unable to reach compute metadata", - func() bool { return true }, - func() (string, error) { return "", errors.New("error") }, - func() (string, error) { return "", errors.New("error") }, - func() (string, error) { return "", errors.New("error") }, - func() (string, error) { return "cluster", nil }, - func() (string, error) { return "instanceName", nil }, - func() (string, error) { return "instance", nil }, - func() (string, error) { return "instanceTemplate", nil }, - func() (string, error) { return "createdBy", nil }, + "no env variable and unable to reach compute metadata", + func(context.Context) (string, error) { return "", errors.New("error") }, map[string]string{}, map[string]string{}, }, @@ -439,10 +399,7 @@ func TestLocality(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { test.SetForTest(t, &GCPStaticMetadata, tt.env) - shouldFillMetadata, projectIDFn, numericProjectIDFn, clusterLocationFn, clusterNameFn, - instanceNameFn, instanceIDFn, instanceTemplateFn, createdByFn = tt.shouldFill, tt.projectIDFn, - tt.numericProjectIDFn, tt.locationFn, tt.clusterNameFn, tt.instanceNameFn, tt.instanceIDFn, tt.instanceTemplateFn, tt.instanceCreatedByFn - + zoneFn = tt.zoneFn e := NewGCP() got := e.Locality() assert.Equal(t, got.Zone, tt.want["Zone"]) @@ -450,3 +407,42 @@ func TestLocality(t *testing.T) { }) } } + +func TestZoneToRegion(t *testing.T) { + tests := []struct { + zone string + wantRegion string + wantErr bool + }{ + { + zone: "us-central1-f", + wantRegion: "us-central1", + }, + { + zone: "us-central1", + wantErr: true, + }, + { + zone: "abcd", + wantErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.zone, func(t *testing.T) { + got, err := zoneToRegion(tc.zone) + if tc.wantErr { + if err == nil { + t.Errorf("expected error was not raised") + } + } else { + if err != nil { + t.Fatalf("unexpected error was raised") + } + if got != tc.wantRegion { + t.Errorf("unexpected region was returned. (got: %v, want: %v)", got, tc.wantRegion) + } + } + }) + } +} diff --git a/pkg/config/analysis/analyzers/analyzers_bench_test.go b/pkg/config/analysis/analyzers/analyzers_bench_test.go index 95e9ecacf8e3..efb483a1b2c4 100644 --- a/pkg/config/analysis/analyzers/analyzers_bench_test.go +++ b/pkg/config/analysis/analyzers/analyzers_bench_test.go @@ -34,7 +34,6 @@ import ( // This is a very basic benchmark on unit test data, so it doesn't tell us anything about how an analyzer performs at scale func BenchmarkAnalyzers(b *testing.B) { for _, tc := range testGrid { - tc := tc // Capture range variable so subtests work correctly b.Run(tc.name+"-bench", func(b *testing.B) { sa, err := setupAnalyzerForCase(tc, nil) if err != nil { diff --git a/pkg/config/analysis/analyzers/analyzers_test.go b/pkg/config/analysis/analyzers/analyzers_test.go index d6d9111a363f..4a4224da6543 100644 --- a/pkg/config/analysis/analyzers/analyzers_test.go +++ b/pkg/config/analysis/analyzers/analyzers_test.go @@ -987,7 +987,6 @@ func TestAnalyzers(t *testing.T) { // For each test case, verify we get the expected messages as output for _, tc := range testGrid { - tc := tc // Capture range variable so subtests work correctly t.Run(tc.name, func(t *testing.T) { g := NewWithT(t) diff --git a/pkg/config/analysis/analyzers/multicluster_analyzers_test.go b/pkg/config/analysis/analyzers/multicluster_analyzers_test.go index 953ed794c917..5c4fa43d0b85 100644 --- a/pkg/config/analysis/analyzers/multicluster_analyzers_test.go +++ b/pkg/config/analysis/analyzers/multicluster_analyzers_test.go @@ -65,7 +65,6 @@ func TestMultiClusterAnalyzers(t *testing.T) { requestedInputsByAnalyzer := make(map[string]map[config.GroupVersionKind]struct{}) // For each test case, verify we get the expected messages as output for _, tc := range mcTestGrid { - tc := tc // Capture range variable so subtests work correctly t.Run(tc.name, func(t *testing.T) { g := NewWithT(t) diff --git a/pkg/config/analysis/analyzers/testdata/common/sidecar-injector-configmap.yaml b/pkg/config/analysis/analyzers/testdata/common/sidecar-injector-configmap.yaml index 314d0b4e5f6a..2e94999ac4c2 100644 --- a/pkg/config/analysis/analyzers/testdata/common/sidecar-injector-configmap.yaml +++ b/pkg/config/analysis/analyzers/testdata/common/sidecar-injector-configmap.yaml @@ -48,6 +48,10 @@ data: - "-k" - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" {{ end -}} + {{ if (isset .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces`) -}} + - "-k" + - "{{ index .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces` }}" + {{ end -}} imagePullPolicy: "{{ valueOrDefault .Values.global.imagePullPolicy `Always` }}" {{- if .Values.global.proxy_init.resources }} resources: diff --git a/pkg/config/analysis/analyzers/testdata/sidecar-injector-configmap-absolute-override.yaml b/pkg/config/analysis/analyzers/testdata/sidecar-injector-configmap-absolute-override.yaml index 23a21c991e09..a2986e87c1eb 100644 --- a/pkg/config/analysis/analyzers/testdata/sidecar-injector-configmap-absolute-override.yaml +++ b/pkg/config/analysis/analyzers/testdata/sidecar-injector-configmap-absolute-override.yaml @@ -48,6 +48,10 @@ data: - "-k" - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" {{ end -}} + {{ if (isset .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces`) -}} + - "-k" + - "{{ index .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces` }}" + {{ end -}} imagePullPolicy: "{{ valueOrDefault .Values.global.imagePullPolicy `Always` }}" {{- if .Values.global.proxy_init.resources }} resources: diff --git a/pkg/config/analysis/analyzers/testdata/sidecar-injector-configmap-with-revision-canary.yaml b/pkg/config/analysis/analyzers/testdata/sidecar-injector-configmap-with-revision-canary.yaml index e3338cdd590b..5fcb799fc059 100644 --- a/pkg/config/analysis/analyzers/testdata/sidecar-injector-configmap-with-revision-canary.yaml +++ b/pkg/config/analysis/analyzers/testdata/sidecar-injector-configmap-with-revision-canary.yaml @@ -48,6 +48,10 @@ data: - "-k" - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" {{ end -}} + {{ if (isset .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces`) -}} + - "-k" + - "{{ index .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces` }}" + {{ end -}} imagePullPolicy: "{{ valueOrDefault .Values.global.imagePullPolicy `Always` }}" {{- if .Values.global.proxy_init.resources }} resources: diff --git a/pkg/config/schema/kubeclient/common.go b/pkg/config/schema/kubeclient/common.go index 394f22df88d1..2ce5544491c0 100644 --- a/pkg/config/schema/kubeclient/common.go +++ b/pkg/config/schema/kubeclient/common.go @@ -63,7 +63,14 @@ type ClientGetter interface { Informers() informerfactory.InformerFactory } -func GetInformerFiltered[T runtime.Object](c ClientGetter, opts ktypes.InformerOptions) informerfactory.StartableInformer { +// GetInformerFiltered attempts to use type information to setup the informer +// based on registered types. If no registered type is found, this will +// fallback to the same behavior as GetInformerFilteredFromGVR. +func GetInformerFiltered[T runtime.Object]( + c ClientGetter, + opts ktypes.InformerOptions, + gvr schema.GroupVersionResource, +) informerfactory.StartableInformer { reg := typemap.Get[TypeRegistration[T]](registerTypes) if reg != nil { // This is registered type @@ -79,9 +86,13 @@ func GetInformerFiltered[T runtime.Object](c ClientGetter, opts ktypes.InformerO return inf }) } - return GetInformerFilteredFromGVR(c, opts, kubetypes.MustGVRFromType[T]()) + return GetInformerFilteredFromGVR(c, opts, gvr) } +// GetInformerFilteredFromGVR will build an informer for the given GVR. When +// using ktypes.StandardInformer as the InformerType, the clients are selected +// from a statically defined list. Use GetInformerFiltered[T] for dynamically +// registered types. func GetInformerFilteredFromGVR(c ClientGetter, opts ktypes.InformerOptions, g schema.GroupVersionResource) informerfactory.StartableInformer { switch opts.InformerType { case ktypes.DynamicInformer: diff --git a/pkg/config/schema/kubeclient/common_test.go b/pkg/config/schema/kubeclient/common_test.go index 1ef20bef82f5..ceb49ac7e1fa 100644 --- a/pkg/config/schema/kubeclient/common_test.go +++ b/pkg/config/schema/kubeclient/common_test.go @@ -29,9 +29,10 @@ import ( ) func TestCustomRegistration(t *testing.T) { + gvr := v1.SchemeGroupVersion.WithResource("networkpolicies") + gvk := v1.SchemeGroupVersion.WithKind("NetworkPolicy") Register[*v1.NetworkPolicy]( - v1.SchemeGroupVersion.WithResource("networkpolicies"), - v1.SchemeGroupVersion.WithKind("NetworkPolicy"), + gvr, gvk, func(c ClientGetter, namespace string, o metav1.ListOptions) (runtime.Object, error) { return c.Kube().NetworkingV1().NetworkPolicies(namespace).List(context.Background(), o) }, @@ -39,12 +40,11 @@ func TestCustomRegistration(t *testing.T) { return c.Kube().NetworkingV1().NetworkPolicies(namespace).Watch(context.Background(), o) }, ) - ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "funkyns"}} client := kube.NewFakeClient(ns) - inf := GetInformerFiltered[*v1.NetworkPolicy](client, ktypes.InformerOptions{}) + inf := GetInformerFiltered[*v1.NetworkPolicy](client, ktypes.InformerOptions{}, gvr) if inf.Informer == nil { t.Errorf("Expected valid informer, got empty") } diff --git a/pkg/config/schema/metadata.yaml b/pkg/config/schema/metadata.yaml index 1e919118eb3d..f13ca4d50b63 100644 --- a/pkg/config/schema/metadata.yaml +++ b/pkg/config/schema/metadata.yaml @@ -444,7 +444,7 @@ resources: plural: "telemetries" group: "telemetry.istio.io" version: "v1" - versionAliases: + versionAliases: - "v1alpha1" proto: "istio.telemetry.v1alpha1.Telemetry" protoPackage: "istio.io/api/telemetry/v1alpha1" diff --git a/pkg/config/security/security.go b/pkg/config/security/security.go index c54f8b5dcf42..69dfc1f79691 100644 --- a/pkg/config/security/security.go +++ b/pkg/config/security/security.go @@ -18,6 +18,7 @@ import ( "fmt" "net/netip" "net/url" + "regexp" "strconv" "strings" "unicode" @@ -60,6 +61,10 @@ const ( var ( MatchOneTemplate = "{*}" MatchAnyTemplate = "{**}" + + // Valid pchar from https://datatracker.ietf.org/doc/html/rfc3986#appendix-A + // pchar = unreserved / pct-encoded / sub-delims / ":" / "@" + validLiteral = regexp.MustCompile("^[a-zA-Z0-9-._~%!$&'()+,;:@=]+$") ) // ParseJwksURI parses the input URI and returns the corresponding hostname, port, and whether SSL is used. @@ -108,28 +113,46 @@ func CheckEmptyValues(key string, values []string) error { func CheckValidPathTemplate(key string, paths []string) error { for _, path := range paths { containsPathTemplate := ContainsPathTemplate(path) + foundMatchAnyTemplate := false + // Strip leading and trailing slashes if they exist + path = strings.Trim(path, "/") globs := strings.Split(path, "/") for _, glob := range globs { - // If glob is a supported path template, skip the check. - if glob == MatchAnyTemplate || glob == MatchOneTemplate { + // If glob is a supported path template, skip the check + // If glob is {**}, it must be the last operator in the template + if glob == MatchOneTemplate && !foundMatchAnyTemplate { + continue + } else if glob == MatchAnyTemplate && !foundMatchAnyTemplate { + foundMatchAnyTemplate = true continue + } else if (glob == MatchAnyTemplate || glob == MatchOneTemplate) && foundMatchAnyTemplate { + return fmt.Errorf("invalid or unsupported path %s, found in %s. "+ + "{**} is not the last operator", path, key) } + // If glob is not a supported path template and contains `{`, or `}` it is invalid. + // Path is invalid if it contains `{` or `}` beyond a supported path template. if strings.ContainsAny(glob, "{}") { - return fmt.Errorf("invalid or unsupported path %s, found in %s."+ + return fmt.Errorf("invalid or unsupported path %s, found in %s. "+ "Contains '{' or '}' beyond a supported path template", path, key) } - // If glob contains `*`, is not a supported path template and - // the path contains a supported path template, it is invalid. - if strings.Contains(glob, "*") && containsPathTemplate { - return fmt.Errorf("invalid or unsupported path %s, found in %s."+ - "Contains '*' beyond a supported path template", path, key) + + // Validate glob is valid string literal + // Meets Envoy's valid pchar requirements from https://datatracker.ietf.org/doc/html/rfc3986#appendix-A + if containsPathTemplate && !IsValidLiteral(glob) { + return fmt.Errorf("invalid or unsupported path %s, found in %s. "+ + "Contains segment %s with invalid string literal", path, key, glob) } } } return nil } +// IsValidLiteral returns true if the glob is a valid string literal. +func IsValidLiteral(glob string) bool { + return validLiteral.MatchString(glob) +} + // ContainsPathTemplate returns true if the path contains a valid path template. func ContainsPathTemplate(value string) bool { return strings.Contains(value, MatchOneTemplate) || strings.Contains(value, MatchAnyTemplate) diff --git a/pkg/config/security/security_test.go b/pkg/config/security/security_test.go index 98f4421de208..188eda7cff8f 100644 --- a/pkg/config/security/security_test.go +++ b/pkg/config/security/security_test.go @@ -230,6 +230,10 @@ func TestCheckValidPathTemplate(t *testing.T) { name: "valid path template - matchOneTemplate", values: []string{"/{*}/foo"}, }, + { + name: "valid path template - matchOneTemplate with trailing slash", + values: []string{"/{*}/foo/"}, + }, { name: "valid path template - matchAnyTemplate", values: []string{"/foo/{**}/bar"}, @@ -308,6 +312,26 @@ func TestCheckValidPathTemplate(t *testing.T) { values: []string{"/{*}/foo/temp}/*"}, wantError: true, }, + { + name: "unsupported path template - matchAnyTemplate is not the last operator in the template", + values: []string{"/{**}/foo/temp/{*}/bar"}, + wantError: true, + }, + { + name: "unsupported path template - simple multiple matchAnyTemplates", + values: []string{"/{**}/{**}"}, + wantError: true, + }, + { + name: "unsupported path template - multiple matchAnyTemplates", + values: []string{"/{**}/foo/temp/{**}/bar"}, + wantError: true, + }, + { + name: "unsupported path template - invalid literal in path template", + values: []string{"/{*}/foo/?abc"}, + wantError: true, + }, } for _, c := range cases { err := security.CheckValidPathTemplate(c.name, c.values) @@ -317,6 +341,102 @@ func TestCheckValidPathTemplate(t *testing.T) { } } +func TestIsValidLiteral(t *testing.T) { + // Valid literals: + // "a-zA-Z0-9-._~" - Unreserved + // "%" - pct-encoded + // "!$&'()+,;" - sub-delims excluding *= + // ":@" + // "=" - user included "=" allowed + cases := []struct { + name string + glob string + expected bool + }{ + { + name: "valid - alphabet chars and nums", + glob: "123abcABC", + expected: true, + }, + { + name: "valid - unreserved chars", + glob: "._~-", + expected: true, + }, + { + name: "valid - equals", + glob: "a=c", + expected: true, + }, + { + name: "valid - mixed chars", + glob: "-._~%20!$&'()+,;:@", + expected: true, + }, + { + name: "invalid - mixed chars", + glob: "`~!@#$%^&()-_+;:,<.>'\"\\| ", + expected: false, + }, + { + name: "invalid - slash", + glob: "abc/", + expected: false, + }, + { + name: "invalid - star with other chars", + glob: "ab*c", + expected: false, + }, + { + name: "invalid - star", + glob: "*", + expected: false, + }, + { + name: "invalid - double star with other chars", + glob: "ab**c", + expected: false, + }, + { + name: "invalid - double star", + glob: "**", + expected: false, + }, + { + name: "invalid - question mark", + glob: "?abc", + expected: false, + }, + { + name: "invalid - question mark with equals", + glob: "?a=c", + expected: false, + }, + { + name: "invalid - left curly brace", + glob: "{abc", + expected: false, + }, + { + name: "invalid - right curly brace", + glob: "abc}", + expected: false, + }, + { + name: "invalid - curly brace set", + glob: "{abc}", + expected: false, + }, + } + for _, c := range cases { + actual := security.IsValidLiteral(c.glob) + if c.expected != actual { + t.Fatalf("IsValidLiteral(%s): expected (%v), got (%v)", c.name, c.expected, actual) + } + } +} + func TestContainsPathTemplate(t *testing.T) { testCases := []struct { name string diff --git a/pkg/config/validation/agent/extensionprovider_test.go b/pkg/config/validation/agent/extensionprovider_test.go index ced7a109f580..531f1fdc8e3a 100644 --- a/pkg/config/validation/agent/extensionprovider_test.go +++ b/pkg/config/validation/agent/extensionprovider_test.go @@ -63,7 +63,6 @@ func TestValidateExtensionProviderService(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { err := validateExtensionProviderService(tt.service) valid := err == nil diff --git a/pkg/config/validation/agent/validation_test.go b/pkg/config/validation/agent/validation_test.go index c6c6572ed863..162693783431 100644 --- a/pkg/config/validation/agent/validation_test.go +++ b/pkg/config/validation/agent/validation_test.go @@ -65,7 +65,6 @@ func TestValidateFQDN(t *testing.T) { }, } for _, tt := range tests { - tt := tt t.Run(tt.name, func(t *testing.T) { err := ValidateFQDN(tt.fqdn) valid := err == nil @@ -73,7 +72,6 @@ func TestValidateFQDN(t *testing.T) { t.Errorf("Expected valid=%v, got valid=%v for %v", tt.valid, valid, tt.fqdn) } }) - } } diff --git a/pkg/config/validation/validation.go b/pkg/config/validation/validation.go index c61d8741cc91..acc6060596b7 100644 --- a/pkg/config/validation/validation.go +++ b/pkg/config/validation/validation.go @@ -38,7 +38,6 @@ import ( security_beta "istio.io/api/security/v1beta1" telemetry "istio.io/api/telemetry/v1alpha1" type_beta "istio.io/api/type/v1beta1" - "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/networking/serviceentry" "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" @@ -2820,9 +2819,6 @@ var ValidateServiceEntry = RegisterValidateFunc("ValidateServiceEntry", } if port.TargetPort != 0 { errs = AppendValidation(errs, agent.ValidatePort(int(port.TargetPort))) - if serviceEntry.Resolution == networking.ServiceEntry_NONE && !features.PassthroughTargetPort { - errs = AppendWarningf(errs, "targetPort has no effect when resolution mode is NONE") - } } if len(serviceEntry.Addresses) == 0 && !autoAllocation { if port.Protocol == "" || port.Protocol == "TCP" { diff --git a/pkg/config/xds/filter_types.gen.go b/pkg/config/xds/filter_types.gen.go index c9a21c269d56..06d0a619f9b6 100644 --- a/pkg/config/xds/filter_types.gen.go +++ b/pkg/config/xds/filter_types.gen.go @@ -95,6 +95,7 @@ import ( _ "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/zstd/compressor/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/compression/zstd/decompressor/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/config/validators/minimum_clusters/v3" + _ "github.com/envoyproxy/go-control-plane/envoy/extensions/dynamic_modules/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/early_data/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/common/dependency/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/common/fault/v3" @@ -103,6 +104,7 @@ import ( _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/adaptive_concurrency/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/admission_control/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/alternate_protocols_cache/v3" + _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/api_key_auth/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/aws_lambda/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/aws_request_signing/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/bandwidth_limit/v3" @@ -119,6 +121,7 @@ import ( _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/custom_response/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/decompressor/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/dynamic_forward_proxy/v3" + _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/dynamic_modules/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ext_authz/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/ext_proc/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/fault/v3" @@ -246,6 +249,7 @@ import ( _ "github.com/envoyproxy/go-control-plane/envoy/extensions/outlier_detection_monitors/consecutive_errors/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/path/match/uri_template/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/path/rewrite/uri_template/v3" + _ "github.com/envoyproxy/go-control-plane/envoy/extensions/quic/connection_debug_visitor/quic_stats/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/quic/connection_debug_visitor/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/quic/connection_id_generator/v3" _ "github.com/envoyproxy/go-control-plane/envoy/extensions/quic/crypto_stream/v3" diff --git a/pkg/dns/client/dns.go b/pkg/dns/client/dns.go index 5ea216a1b8a8..98be140d5dd0 100644 --- a/pkg/dns/client/dns.go +++ b/pkg/dns/client/dns.go @@ -31,6 +31,7 @@ import ( "istio.io/istio/pkg/config/host" dnsProto "istio.io/istio/pkg/dns/proto" istiolog "istio.io/istio/pkg/log" + "istio.io/istio/pkg/slices" netutil "istio.io/istio/pkg/util/net" "istio.io/istio/pkg/util/sets" ) @@ -362,13 +363,13 @@ func roundRobin(in []dns.RR) []dns.RR { return out } -func roundRobinShuffle(records []dns.RR) { - switch l := len(records); l { +func roundRobinShuffle[T any](entries []T) { + switch l := len(entries); l { case 0, 1: break case 2: if dns.Id()%2 == 0 { - records[0], records[1] = records[1], records[0] + entries[0], entries[1] = entries[1], entries[0] } default: for j := 0; j < l*(int(dns.Id())%4+1); j++ { @@ -377,7 +378,7 @@ func roundRobinShuffle(records []dns.RR) { if q == p { p = (p + 1) % l } - records[q], records[p] = records[p], records[q] + entries[q], entries[p] = entries[p], entries[q] } } } @@ -394,8 +395,9 @@ func (h *LocalDNSServer) queryUpstream(upstreamClient *dns.Client, req *dns.Msg, } var response *dns.Msg - - for _, upstream := range h.resolvConfServers { + servers := slices.Clone(h.resolvConfServers) + roundRobinShuffle(servers) + for _, upstream := range servers { cResponse, _, err := upstreamClient.Exchange(req, upstream) if err == nil { response = cResponse diff --git a/pkg/dns/proto/nds.pb.go b/pkg/dns/proto/nds.pb.go index 373532b5073b..b81e919943cb 100644 --- a/pkg/dns/proto/nds.pb.go +++ b/pkg/dns/proto/nds.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc (unknown) // source: dns/proto/nds.proto diff --git a/pkg/dns/server/name_table.go b/pkg/dns/server/name_table.go index 40e636898ed5..5f6f49b827fc 100644 --- a/pkg/dns/server/name_table.go +++ b/pkg/dns/server/name_table.go @@ -41,120 +41,122 @@ func BuildNameTable(cfg Config) *dnsProto.NameTable { out := &dnsProto.NameTable{ Table: make(map[string]*dnsProto.NameTable_NameInfo), } - for _, svc := range cfg.Node.SidecarScope.Services() { - var addressList []string - hostName := svc.Hostname - headless := false - for _, svcAddress := range svc.GetAllAddressesForProxy(cfg.Node) { - if svcAddress == constants.UnspecifiedIP { - headless = true - break - } - // Filter out things we cannot parse as IP. Generally this means CIDRs, as anything else - // should be caught in validation. - if !netutil.IsValidIPAddress(svcAddress) { - continue + for _, el := range cfg.Node.SidecarScope.EgressListeners { + for _, svc := range el.Services() { + var addressList []string + hostName := svc.Hostname + headless := false + for _, svcAddress := range svc.GetAllAddressesForProxy(cfg.Node) { + if svcAddress == constants.UnspecifiedIP { + headless = true + break + } + // Filter out things we cannot parse as IP. Generally this means CIDRs, as anything else + // should be caught in validation. + if !netutil.IsValidIPAddress(svcAddress) { + continue + } + addressList = append(addressList, svcAddress) } - addressList = append(addressList, svcAddress) - } - if headless { - // The IP will be unspecified here if its headless service or if the auto - // IP allocation logic for service entry was unable to allocate an IP. - if svc.Resolution == model.Passthrough && len(svc.Ports) > 0 { - for _, instance := range cfg.Push.ServiceEndpointsByPort(svc, svc.Ports[0].Port, nil) { - // addresses may be empty or invalid here - isValidInstance := true - for _, addr := range instance.Addresses { - if !netutil.IsValidIPAddress(addr) { - isValidInstance = false - break + if headless { + // The IP will be unspecified here if its headless service or if the auto + // IP allocation logic for service entry was unable to allocate an IP. + if svc.Resolution == model.Passthrough && len(svc.Ports) > 0 { + for _, instance := range cfg.Push.ServiceEndpointsByPort(svc, svc.Ports[0].Port, nil) { + // addresses may be empty or invalid here + isValidInstance := true + for _, addr := range instance.Addresses { + if !netutil.IsValidIPAddress(addr) { + isValidInstance = false + break + } } - } - if len(instance.Addresses) == 0 || !isValidInstance || - (!svc.Attributes.PublishNotReadyAddresses && instance.HealthStatus == model.UnHealthy) { - continue - } - // TODO(stevenctl): headless across-networks https://github.com/istio/istio/issues/38327 - sameNetwork := cfg.Node.InNetwork(instance.Network) - sameCluster := cfg.Node.InCluster(instance.Locality.ClusterID) - // For all k8s headless services, populate the dns table with the endpoint IPs as k8s does. - // And for each individual pod, populate the dns table with the endpoint IP with a manufactured host name. - if instance.SubDomain != "" && sameNetwork { - // Follow k8s pods dns naming convention of "...svc." - // i.e. "mysql-0.mysql.default.svc.cluster.local". - parts := strings.SplitN(hostName.String(), ".", 2) - if len(parts) != 2 { + if len(instance.Addresses) == 0 || !isValidInstance || + (!svc.Attributes.PublishNotReadyAddresses && instance.HealthStatus == model.UnHealthy) { continue } - address := instance.Addresses - shortName := instance.HostName + "." + instance.SubDomain - host := shortName + "." + parts[1] // Add cluster domain. - nameInfo := &dnsProto.NameTable_NameInfo{ - Ips: address, - Registry: string(svc.Attributes.ServiceRegistry), - Namespace: svc.Attributes.Namespace, - Shortname: shortName, - } + // TODO(stevenctl): headless across-networks https://github.com/istio/istio/issues/38327 + sameNetwork := cfg.Node.InNetwork(instance.Network) + sameCluster := cfg.Node.InCluster(instance.Locality.ClusterID) + // For all k8s headless services, populate the dns table with the endpoint IPs as k8s does. + // And for each individual pod, populate the dns table with the endpoint IP with a manufactured host name. + if instance.SubDomain != "" && sameNetwork { + // Follow k8s pods dns naming convention of "...svc." + // i.e. "mysql-0.mysql.default.svc.cluster.local". + parts := strings.SplitN(hostName.String(), ".", 2) + if len(parts) != 2 { + continue + } + address := instance.Addresses + shortName := instance.HostName + "." + instance.SubDomain + host := shortName + "." + parts[1] // Add cluster domain. + nameInfo := &dnsProto.NameTable_NameInfo{ + Ips: address, + Registry: string(svc.Attributes.ServiceRegistry), + Namespace: svc.Attributes.Namespace, + Shortname: shortName, + } - if _, f := out.Table[host]; !f || sameCluster { - // We may have the same pod in two clusters (ie mysql-0 deployed in both places). - // We can only return a single IP for these queries. We should prefer the local cluster, - // so if the entry already exists only overwrite it if the instance is in our own cluster. - out.Table[host] = nameInfo + if _, f := out.Table[host]; !f || sameCluster { + // We may have the same pod in two clusters (ie mysql-0 deployed in both places). + // We can only return a single IP for these queries. We should prefer the local cluster, + // so if the entry already exists only overwrite it if the instance is in our own cluster. + out.Table[host] = nameInfo + } } + skipForMulticluster := !cfg.MulticlusterHeadlessEnabled && !sameCluster + if skipForMulticluster || !sameNetwork { + // We take only cluster-local endpoints. While this seems contradictory to + // our logic other parts of the code, where cross-cluster is the default. + // However, this only impacts the DNS response. If we were to send all + // endpoints, cross network routing would break, as we do passthrough LB and + // don't go through the network gateway. While we could, hypothetically, send + // "network-local" endpoints, this would still make enabling DNS give vastly + // different load balancing than without, so its probably best to filter. + // This ends up matching the behavior of Kubernetes DNS. + continue + } + // TODO: should we skip the node's own IP like we do in listener? + addressList = append(addressList, instance.Addresses...) } - skipForMulticluster := !cfg.MulticlusterHeadlessEnabled && !sameCluster - if skipForMulticluster || !sameNetwork { - // We take only cluster-local endpoints. While this seems contradictory to - // our logic other parts of the code, where cross-cluster is the default. - // However, this only impacts the DNS response. If we were to send all - // endpoints, cross network routing would break, as we do passthrough LB and - // don't go through the network gateway. While we could, hypothetically, send - // "network-local" endpoints, this would still make enabling DNS give vastly - // different load balancing than without, so its probably best to filter. - // This ends up matching the behavior of Kubernetes DNS. - continue - } - // TODO: should we skip the node's own IP like we do in listener? - addressList = append(addressList, instance.Addresses...) } } - } - if len(addressList) == 0 { - // could not reliably determine the addresses of endpoints of headless service - // or this is not a k8s service - continue - } - - if ni, f := out.Table[hostName.String()]; !f { - nameInfo := &dnsProto.NameTable_NameInfo{ - Ips: addressList, - Registry: string(svc.Attributes.ServiceRegistry), - } - if svc.Attributes.ServiceRegistry == provider.Kubernetes && - !strings.HasSuffix(hostName.String(), "."+constants.DefaultClusterSetLocalDomain) { - // The agent will take care of resolving a, a.ns, a.ns.svc, etc. - // No need to provide a DNS entry for each variant. - // - // NOTE: This is not done for Kubernetes Multi-Cluster Services (MCS) hosts, in order - // to avoid conflicting with the entries for the regular (cluster.local) service. - nameInfo.Namespace = svc.Attributes.Namespace - nameInfo.Shortname = svc.Attributes.Name + if len(addressList) == 0 { + // could not reliably determine the addresses of endpoints of headless service + // or this is not a k8s service + continue } - out.Table[hostName.String()] = nameInfo - } else if provider.ID(ni.Registry) != provider.Kubernetes { - // 2 possible cases: - // 1. If the SE has multiple addresses(vips) specified, merge the ips - // 2. If the previous SE is a decorator of the k8s service, give precedence to the k8s service - if svc.Attributes.ServiceRegistry == provider.Kubernetes { - ni.Ips = addressList - ni.Registry = string(provider.Kubernetes) - if !strings.HasSuffix(hostName.String(), "."+constants.DefaultClusterSetLocalDomain) { - ni.Namespace = svc.Attributes.Namespace - ni.Shortname = svc.Attributes.Name + + if ni, f := out.Table[hostName.String()]; !f { + nameInfo := &dnsProto.NameTable_NameInfo{ + Ips: addressList, + Registry: string(svc.Attributes.ServiceRegistry), + } + if svc.Attributes.ServiceRegistry == provider.Kubernetes && + !strings.HasSuffix(hostName.String(), "."+constants.DefaultClusterSetLocalDomain) { + // The agent will take care of resolving a, a.ns, a.ns.svc, etc. + // No need to provide a DNS entry for each variant. + // + // NOTE: This is not done for Kubernetes Multi-Cluster Services (MCS) hosts, in order + // to avoid conflicting with the entries for the regular (cluster.local) service. + nameInfo.Namespace = svc.Attributes.Namespace + nameInfo.Shortname = svc.Attributes.Name + } + out.Table[hostName.String()] = nameInfo + } else if provider.ID(ni.Registry) != provider.Kubernetes { + // 2 possible cases: + // 1. If the SE has multiple addresses(vips) specified, merge the ips + // 2. If the previous SE is a decorator of the k8s service, give precedence to the k8s service + if svc.Attributes.ServiceRegistry == provider.Kubernetes { + ni.Ips = addressList + ni.Registry = string(provider.Kubernetes) + if !strings.HasSuffix(hostName.String(), "."+constants.DefaultClusterSetLocalDomain) { + ni.Namespace = svc.Attributes.Namespace + ni.Shortname = svc.Attributes.Name + } + } else { + ni.Ips = append(ni.Ips, addressList...) } - } else { - ni.Ips = append(ni.Ips, addressList...) } } } diff --git a/pkg/dns/server/name_table_test.go b/pkg/dns/server/name_table_test.go index a0e3faf73f5d..22be4b8bbe76 100644 --- a/pkg/dns/server/name_table_test.go +++ b/pkg/dns/server/name_table_test.go @@ -33,19 +33,6 @@ import ( "istio.io/istio/pkg/test" ) -// nolint -func makeServiceInstances(proxy *model.Proxy, service *model.Service, hostname, subdomain string) map[int][]*model.IstioEndpoint { - instances := make(map[int][]*model.IstioEndpoint) - for _, port := range service.Ports { - instances[port.Port] = makeInstances(proxy, service, port.Port, port.Port) - instances[port.Port][0].HostName = hostname - instances[port.Port][0].SubDomain = subdomain - instances[port.Port][0].Network = proxy.Metadata.Network - instances[port.Port][0].Locality.ClusterID = proxy.Metadata.ClusterID - } - return instances -} - func TestNameTable(t *testing.T) { test.SetForTest(t, &features.EnableDualStack, true) mesh := &meshconfig.MeshConfig{RootNamespace: "istio-system"} @@ -116,6 +103,23 @@ func TestNameTable(t *testing.T) { }, } + headlessServiceWithPublishNonReadyEnabled := &model.Service{ + Hostname: host.Name("headless-svc.testns.svc.cluster.local"), + DefaultAddress: constants.UnspecifiedIP, + Ports: model.PortList{&model.Port{ + Name: "tcp-port", + Port: 9000, + Protocol: protocol.TCP, + }}, + Resolution: model.Passthrough, + Attributes: model.ServiceAttributes{ + Name: "headless-svc", + Namespace: "testns", + ServiceRegistry: provider.Kubernetes, + K8sAttributes: model.K8sAttributes{PublishNotReadyAddresses: true}, + }, + } + headlessServiceForServiceEntry := &model.Service{ Hostname: host.Name("foo.bar.com"), DefaultAddress: constants.UnspecifiedIP, @@ -230,13 +234,29 @@ func TestNameTable(t *testing.T) { push.Mesh = mesh push.AddPublicServices([]*model.Service{headlessService}) push.AddServiceInstances(headlessService, - makeServiceInstances(pod1, headlessService, "pod1", "headless-svc")) + makeServiceInstances(pod1, headlessService, "pod1", "headless-svc", model.Healthy)) push.AddServiceInstances(headlessService, - makeServiceInstances(pod2, headlessService, "pod2", "headless-svc")) + makeServiceInstances(pod2, headlessService, "pod2", "headless-svc", model.Healthy)) push.AddServiceInstances(headlessService, - makeServiceInstances(pod3, headlessService, "pod3", "headless-svc")) + makeServiceInstances(pod3, headlessService, "pod3", "headless-svc", model.Healthy)) push.AddServiceInstances(headlessService, - makeServiceInstances(pod4, headlessService, "pod4", "headless-svc")) + makeServiceInstances(pod4, headlessService, "pod4", "headless-svc", model.Healthy)) + + uhpush := model.NewPushContext() + uhpush.Mesh = mesh + uhpush.AddPublicServices([]*model.Service{headlessService}) + uhpush.AddServiceInstances(headlessService, + makeServiceInstances(pod1, headlessService, "pod1", "headless-svc", model.Healthy)) + uhpush.AddServiceInstances(headlessService, + makeServiceInstances(pod2, headlessService, "pod2", "headless-svc", model.UnHealthy)) + + uhreadypush := model.NewPushContext() + uhreadypush.Mesh = mesh + uhreadypush.AddPublicServices([]*model.Service{headlessServiceWithPublishNonReadyEnabled}) + uhreadypush.AddServiceInstances(headlessService, + makeServiceInstances(pod1, headlessService, "pod1", "headless-svc", model.Healthy)) + uhreadypush.AddServiceInstances(headlessService, + makeServiceInstances(pod2, headlessService, "pod2", "headless-svc", model.UnHealthy)) wpush := model.NewPushContext() wpush.Mesh = mesh @@ -250,13 +270,13 @@ func TestNameTable(t *testing.T) { sepush.Mesh = mesh sepush.AddPublicServices([]*model.Service{headlessServiceForServiceEntry}) sepush.AddServiceInstances(headlessServiceForServiceEntry, - makeServiceInstances(pod1, headlessServiceForServiceEntry, "", "")) + makeServiceInstances(pod1, headlessServiceForServiceEntry, "", "", model.Healthy)) sepush.AddServiceInstances(headlessServiceForServiceEntry, - makeServiceInstances(pod2, headlessServiceForServiceEntry, "", "")) + makeServiceInstances(pod2, headlessServiceForServiceEntry, "", "", model.Healthy)) sepush.AddServiceInstances(headlessServiceForServiceEntry, - makeServiceInstances(pod3, headlessServiceForServiceEntry, "", "")) + makeServiceInstances(pod3, headlessServiceForServiceEntry, "", "", model.Healthy)) sepush.AddServiceInstances(headlessServiceForServiceEntry, - makeServiceInstances(pod4, headlessServiceForServiceEntry, "", "")) + makeServiceInstances(pod4, headlessServiceForServiceEntry, "", "", model.Healthy)) cases := []struct { name string @@ -416,6 +436,71 @@ func TestNameTable(t *testing.T) { }, }, }, + { + name: "headless service with unhealthy pods", + proxy: cl1proxy, + push: uhpush, + enableMultiClusterHeadless: true, + expectedNameTable: &dnsProto.NameTable{ + Table: map[string]*dnsProto.NameTable_NameInfo{ + "pod1.headless-svc.testns.svc.cluster.local": { + Ips: []string{"1.2.3.4"}, + Registry: "Kubernetes", + Shortname: "pod1.headless-svc", + Namespace: "testns", + }, + "headless-svc.testns.svc.cluster.local": { + Ips: []string{"1.2.3.4"}, + Registry: "Kubernetes", + Shortname: "headless-svc", + Namespace: "testns", + }, + }, + }, + }, + { + name: "wildcard service pods", + proxy: proxy, + push: wpush, + expectedNameTable: &dnsProto.NameTable{ + Table: map[string]*dnsProto.NameTable_NameInfo{ + "*.testns.svc.cluster.local": { + Ips: []string{"172.10.10.10"}, + Registry: "Kubernetes", + Shortname: "wildcard-svc", + Namespace: "testns", + }, + }, + }, + }, + { + name: "publish unready headless service with unhealthy pods", + proxy: cl1proxy, + push: uhreadypush, + enableMultiClusterHeadless: true, + expectedNameTable: &dnsProto.NameTable{ + Table: map[string]*dnsProto.NameTable_NameInfo{ + "pod1.headless-svc.testns.svc.cluster.local": { + Ips: []string{"1.2.3.4"}, + Registry: "Kubernetes", + Shortname: "pod1.headless-svc", + Namespace: "testns", + }, + "pod2.headless-svc.testns.svc.cluster.local": { + Ips: []string{"9.6.7.8"}, + Registry: "Kubernetes", + Shortname: "pod2.headless-svc", + Namespace: "testns", + }, + "headless-svc.testns.svc.cluster.local": { + Ips: []string{"1.2.3.4", "9.6.7.8"}, + Registry: "Kubernetes", + Shortname: "headless-svc", + Namespace: "testns", + }, + }, + }, + }, { name: "wildcard service pods", proxy: proxy, @@ -508,7 +593,7 @@ func TestNameTable(t *testing.T) { expectedNameTable: &dnsProto.NameTable{ Table: map[string]*dnsProto.NameTable_NameInfo{ serviceWithVIP1.Hostname.String(): { - Ips: []string{serviceWithVIP1.DefaultAddress}, + Ips: []string{serviceWithVIP1.DefaultAddress, serviceWithVIP2.DefaultAddress}, Registry: provider.External.String(), }, }, @@ -570,7 +655,22 @@ func TestNameTable(t *testing.T) { } } -func makeInstances(proxy *model.Proxy, svc *model.Service, servicePort int, targetPort int) []*model.IstioEndpoint { +// nolint +func makeServiceInstances(proxy *model.Proxy, service *model.Service, hostname, subdomain string, healthStatus model.HealthStatus) map[int][]*model.IstioEndpoint { + instances := make(map[int][]*model.IstioEndpoint) + for _, port := range service.Ports { + instances[port.Port] = makeInstances(proxy, service, port.Port, port.Port, healthStatus) + instances[port.Port][0].HostName = hostname + instances[port.Port][0].SubDomain = subdomain + instances[port.Port][0].Network = proxy.Metadata.Network + instances[port.Port][0].Locality.ClusterID = proxy.Metadata.ClusterID + } + return instances +} + +func makeInstances(proxy *model.Proxy, svc *model.Service, servicePort int, targetPort int, + healthStatus model.HealthStatus, +) []*model.IstioEndpoint { ret := make([]*model.IstioEndpoint, 0) for _, p := range svc.Ports { if p.Port != servicePort { @@ -580,6 +680,7 @@ func makeInstances(proxy *model.Proxy, svc *model.Service, servicePort int, targ Addresses: proxy.IPAddresses, ServicePortName: p.Name, EndpointPort: uint32(targetPort), + HealthStatus: healthStatus, }) } return ret diff --git a/pkg/envoy/proxy.go b/pkg/envoy/proxy.go index 80cb818f2614..0ead84dd03a6 100644 --- a/pkg/envoy/proxy.go +++ b/pkg/envoy/proxy.go @@ -156,8 +156,6 @@ func (e *envoy) args(fname string, overrideFname string) []string { return startupArgs } -var HostIP = os.Getenv("HOST_IP") - // readBootstrapToJSON reads a config file, in YAML or JSON, and returns JSON string func readBootstrapToJSON(fname string) (string, error) { b, err := os.ReadFile(fname) @@ -167,7 +165,15 @@ func readBootstrapToJSON(fname string) (string, error) { // Replace host with HOST_IP env var if it is "$(HOST_IP)". // This is to support some tracer setting (Datadog, Zipkin), where "$(HOST_IP)" is used for address. - b = bytes.ReplaceAll(b, []byte("$(HOST_IP)"), []byte(HostIP)) + HostIPEnv := os.Getenv("HOST_IP") + + if strings.Contains(HostIPEnv, ":") { // For IPv6, address needs to be of form `[ff06::c3]:8126` + HostIPEnv = "[" + HostIPEnv + "]" + // Avoid adding extra [] where users add them explicitly + b = bytes.ReplaceAll(b, []byte("[$(HOST_IP)]"), []byte(HostIPEnv)) + } + b = bytes.ReplaceAll(b, []byte("$(HOST_IP)"), []byte(HostIPEnv)) + converted, err := yaml.YAMLToJSON(b) if err != nil { return "", fmt.Errorf("failed to convert to JSON: %s, %v", fname, err) diff --git a/pkg/envoy/proxy_test.go b/pkg/envoy/proxy_test.go index 99ccdc99e710..4b9fc00fb6c8 100644 --- a/pkg/envoy/proxy_test.go +++ b/pkg/envoy/proxy_test.go @@ -15,6 +15,7 @@ package envoy import ( + "os" "reflect" "testing" @@ -71,12 +72,31 @@ func TestEnvoyArgs(t *testing.T) { } } -func TestReadToJSON(t *testing.T) { +func TestReadToJSONIPv4(t *testing.T) { + err := os.Setenv("HOST_IP", "169.254.169.254") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + got, err := readBootstrapToJSON("testdata/bootstrap.yaml") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + want := `{"ip":"[169.254.169.254]:8126","ip2":"169.254.169.254:8126","key":"value"}` + if got != want { + t.Errorf("readBootstrapToJSON() => got:\n%v,\nwant:\n%v", got, want) + } +} + +func TestReadToJSONIPv6(t *testing.T) { + err := os.Setenv("HOST_IP", "dead::beef") + if err != nil { + t.Errorf("unexpected error: %v", err) + } got, err := readBootstrapToJSON("testdata/bootstrap.yaml") if err != nil { t.Errorf("unexpected error: %v", err) } - want := `{"key":"value"}` + want := `{"ip":"[dead::beef]:8126","ip2":"[dead::beef]:8126","key":"value"}` if got != want { t.Errorf("readBootstrapToJSON() => got:\n%v,\nwant:\n%v", got, want) } diff --git a/pkg/envoy/testdata/bootstrap.yaml b/pkg/envoy/testdata/bootstrap.yaml index f29cc778b73d..772890e3be8b 100644 --- a/pkg/envoy/testdata/bootstrap.yaml +++ b/pkg/envoy/testdata/bootstrap.yaml @@ -1,3 +1,5 @@ --- # Sample custom bootstrap in YAML key: value +ip: "[$(HOST_IP)]:8126" +ip2: "$(HOST_IP):8126" diff --git a/pkg/istio-agent/health/health_check.go b/pkg/istio-agent/health/health_check.go index ae7b5678789a..72f854f23f3a 100644 --- a/pkg/istio-agent/health/health_check.go +++ b/pkg/istio-agent/health/health_check.go @@ -51,7 +51,7 @@ const ( lastStateUnhealthy ) -func fillInDefaults(cfg *v1alpha3.ReadinessProbe, ipAddresses []string) *v1alpha3.ReadinessProbe { +func fillInDefaults(cfg *v1alpha3.ReadinessProbe) *v1alpha3.ReadinessProbe { cfg = cfg.DeepCopy() // Thresholds have a minimum of 1 cfg.FailureThreshold = orDefault(cfg.FailureThreshold, 1) @@ -70,13 +70,6 @@ func fillInDefaults(cfg *v1alpha3.ReadinessProbe, ipAddresses []string) *v1alpha h.HttpGet.Scheme = string(apimirror.URISchemeHTTP) } h.HttpGet.Scheme = strings.ToLower(h.HttpGet.Scheme) - if h.HttpGet.Host == "" { - if len(ipAddresses) == 0 || status.LegacyLocalhostProbeDestination.Get() { - h.HttpGet.Host = "localhost" - } else { - h.HttpGet.Host = ipAddresses[0] - } - } } return cfg } @@ -86,15 +79,18 @@ func NewWorkloadHealthChecker(cfg *v1alpha3.ReadinessProbe, envoyProbe ready.Pro if cfg == nil { return nil } - cfg = fillInDefaults(cfg, proxyAddrs) + cfg = fillInDefaults(cfg) + defaultHost := resolveDefaultHost(proxyAddrs) var prober Prober switch healthCheckMethod := cfg.HealthCheckMethod.(type) { case *v1alpha3.ReadinessProbe_HttpGet: - prober = NewHTTPProber(healthCheckMethod.HttpGet, ipv6) + prober = NewHTTPProber(healthCheckMethod.HttpGet, defaultHost, ipv6) case *v1alpha3.ReadinessProbe_TcpSocket: - prober = &TCPProber{Config: healthCheckMethod.TcpSocket} + prober = NewTCPProber(healthCheckMethod.TcpSocket, defaultHost) case *v1alpha3.ReadinessProbe_Exec: prober = &ExecProber{Config: healthCheckMethod.Exec} + case *v1alpha3.ReadinessProbe_Grpc: + prober = NewGRPCProber(healthCheckMethod.Grpc, defaultHost) default: prober = nil } @@ -116,6 +112,13 @@ func NewWorkloadHealthChecker(cfg *v1alpha3.ReadinessProbe, envoyProbe ready.Pro } } +func resolveDefaultHost(ipAddresses []string) string { + if len(ipAddresses) == 0 || status.LegacyLocalhostProbeDestination.Get() { + return "localhost" + } + return ipAddresses[0] +} + func orDefault(val int32, def int32) int32 { if val == 0 { return def diff --git a/pkg/istio-agent/health/health_probers.go b/pkg/istio-agent/health/health_probers.go index 613a3b8dbcf1..f42271635da2 100644 --- a/pkg/istio-agent/health/health_probers.go +++ b/pkg/istio-agent/health/health_probers.go @@ -25,6 +25,12 @@ import ( "strconv" "time" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/health/grpc_health_v1" + grpc_status "google.golang.org/grpc/status" + "istio.io/api/networking/v1alpha3" "istio.io/istio/pilot/cmd/pilot-agent/status" "istio.io/istio/pilot/cmd/pilot-agent/status/ready" @@ -54,14 +60,74 @@ func (p *ProbeResult) IsHealthy() bool { return *p == Healthy } +type GRPCProber struct { + Config *v1alpha3.GrpcHealthCheckConfig + DefaultHost string +} + +var _ Prober = &GRPCProber{} + +func NewGRPCProber(cfg *v1alpha3.GrpcHealthCheckConfig, defaultHost string) *GRPCProber { + return &GRPCProber{ + Config: cfg, + DefaultHost: defaultHost, + } +} + +func (g *GRPCProber) Probe(timeout time.Duration) (ProbeResult, error) { + if g.Config == nil { + return Unknown, fmt.Errorf("grpc health check config is nil") + } + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + conn, err := grpc.DialContext(ctx, net.JoinHostPort(g.DefaultHost, fmt.Sprintf("%d", g.Config.Port)), + grpc.WithBlock(), + grpc.WithUserAgent("istio-probe/1.0"), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { + return status.ProbeDialer().DialContext(ctx, "tcp", addr) + }), + ) + if err != nil { + return Unhealthy, fmt.Errorf("failed to connect health check grpc service on port %d: %v", g.Config.Port, err) + } + defer conn.Close() + client := grpc_health_v1.NewHealthClient(conn) + req := &grpc_health_v1.HealthCheckRequest{ + Service: g.Config.Service, + } + resp, err := client.Check(ctx, req) + if err != nil { + if stat, ok := grpc_status.FromError(err); ok { + switch stat.Code() { + case codes.Unimplemented: + return Unhealthy, fmt.Errorf("service on port %d doesn't implement the grpc health protocol grpc.health.v1.Health: %v", g.Config.Port, err) + case codes.DeadlineExceeded: + return Unhealthy, fmt.Errorf("health rpc probe timed out after %v: %v", timeout, err) + default: + return Unhealthy, fmt.Errorf("health rpc probe failed with status %v: %v", stat.Code(), err) + } + } else { + return Unhealthy, fmt.Errorf("health rpc probe failed: %v", err) + } + } + switch resp.GetStatus() { + case grpc_health_v1.HealthCheckResponse_SERVING: + return Healthy, nil + default: + return Unhealthy, nil + } +} + type HTTPProber struct { - Config *v1alpha3.HTTPHealthCheckConfig - Transport *http.Transport + Config *v1alpha3.HTTPHealthCheckConfig + Transport *http.Transport + DefaultHost string } var _ Prober = &HTTPProber{} -func NewHTTPProber(cfg *v1alpha3.HTTPHealthCheckConfig, ipv6 bool) *HTTPProber { +func NewHTTPProber(cfg *v1alpha3.HTTPHealthCheckConfig, defaultHost string, ipv6 bool) *HTTPProber { h := new(HTTPProber) h.Config = cfg @@ -85,6 +151,7 @@ func NewHTTPProber(cfg *v1alpha3.HTTPHealthCheckConfig, ipv6 bool) *HTTPProber { d.LocalAddr = status.UpstreamLocalAddressIPv6 } h.Transport.DialContext = d.DialContext + h.DefaultHost = defaultHost return h } @@ -109,7 +176,11 @@ func (h *HTTPProber) Probe(timeout time.Duration) (ProbeResult, error) { } } targetURL.Scheme = h.Config.Scheme - targetURL.Host = net.JoinHostPort(h.Config.Host, strconv.Itoa(int(h.Config.Port))) + if h.Config.Host == "" { + targetURL.Host = net.JoinHostPort(h.DefaultHost, strconv.Itoa(int(h.Config.Port))) + } else { + targetURL.Host = net.JoinHostPort(h.Config.Host, strconv.Itoa(int(h.Config.Port))) + } if err != nil { healthCheckLog.Errorf("unable to parse url: %v", err) return Unknown, err @@ -145,7 +216,15 @@ func (h *HTTPProber) Probe(timeout time.Duration) (ProbeResult, error) { } type TCPProber struct { - Config *v1alpha3.TCPHealthCheckConfig + Config *v1alpha3.TCPHealthCheckConfig + DefaultHost string +} + +func NewTCPProber(cfg *v1alpha3.TCPHealthCheckConfig, host string) *TCPProber { + return &TCPProber{ + Config: cfg, + DefaultHost: host, + } } var _ Prober = &TCPProber{} @@ -154,7 +233,12 @@ func (t *TCPProber) Probe(timeout time.Duration) (ProbeResult, error) { // if we cant connect, count as fail d := status.ProbeDialer() d.Timeout = timeout - hostPort := net.JoinHostPort(t.Config.Host, strconv.Itoa(int(t.Config.Port))) + var hostPort string + if t.Config.Host == "" { + hostPort = net.JoinHostPort(t.DefaultHost, strconv.Itoa(int(t.Config.Port))) + } else { + hostPort = net.JoinHostPort(t.Config.Host, strconv.Itoa(int(t.Config.Port))) + } conn, err := d.Dial("tcp", hostPort) if err != nil { return Unhealthy, err diff --git a/pkg/istio-agent/health/health_probers_test.go b/pkg/istio-agent/health/health_probers_test.go index 409d7af97f8b..791a9934dafa 100644 --- a/pkg/istio-agent/health/health_probers_test.go +++ b/pkg/istio-agent/health/health_probers_test.go @@ -16,6 +16,7 @@ package health import ( "errors" + "fmt" "net" "net/http" "net/http/httptest" @@ -24,6 +25,10 @@ import ( "testing" "time" + "google.golang.org/grpc" + "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" + "istio.io/api/networking/v1alpha3" ) @@ -64,7 +69,7 @@ func TestHttpProber(t *testing.T) { Port: port, Host: "127.0.0.1", Scheme: "http", - }, false) + }, "localhost", false) if tt.statusCode == -1 { server.Close() @@ -78,6 +83,99 @@ func TestHttpProber(t *testing.T) { } } +func TestGrpcProber(t *testing.T) { + tests := []struct { + desc string + service string + port uint32 + servingStatus grpc_health_v1.HealthCheckResponse_ServingStatus + expectedProbeResult ProbeResult + expectedError error + }{ + { + desc: "Healthy - Serving status", + service: "grpc.health.v1.Health", + port: 50051, + servingStatus: grpc_health_v1.HealthCheckResponse_SERVING, + expectedProbeResult: Healthy, + expectedError: nil, + }, + { + desc: "Unhealthy - Not Serving status", + service: "grpc.health.v1.Health", + port: 50051, + servingStatus: grpc_health_v1.HealthCheckResponse_NOT_SERVING, + expectedProbeResult: Unhealthy, + expectedError: nil, + }, + { + desc: "Unhealthy - Unknown Serving status", + service: "grpc.health.v1.Health", + port: 50051, + servingStatus: grpc_health_v1.HealthCheckResponse_UNKNOWN, + expectedProbeResult: Unhealthy, + expectedError: nil, + }, + { + desc: "Unhealthy - Unknown service Serving status", + service: "grpc.health.v1.Health", + port: 50051, + servingStatus: grpc_health_v1.HealthCheckResponse_SERVICE_UNKNOWN, + expectedProbeResult: Unhealthy, + expectedError: nil, + }, + { + desc: "Unhealthy - wrong service port", + service: "grpc.health.v1.Health", + port: 50052, + servingStatus: grpc_health_v1.HealthCheckResponse_SERVING, + expectedProbeResult: Unhealthy, + expectedError: fmt.Errorf("failed to connect health check grpc service on port 50052: context deadline exceeded"), + }, + { + desc: "Unhealthy - incorrect service name", + service: "grpc.unknown.service", + port: 50051, + servingStatus: grpc_health_v1.HealthCheckResponse_SERVICE_UNKNOWN, + expectedProbeResult: Unhealthy, + expectedError: fmt.Errorf("health rpc probe failed with status NotFound: rpc error: code = NotFound desc = unknown service"), + }, + { + desc: "Unknown - nil grpc config", + servingStatus: grpc_health_v1.HealthCheckResponse_SERVICE_UNKNOWN, + expectedProbeResult: Unknown, + expectedError: fmt.Errorf("grpc health check config is nil"), + }, + } + + server := grpc.NewServer() + healthServer := health.NewServer() + grpc_health_v1.RegisterHealthServer(server, healthServer) + err := startGrpcServer(server) + if err != nil { + t.Error("test grpc server failed to start on port") + } + defer server.GracefulStop() + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + healthServer.SetServingStatus("grpc.health.v1.Health", tt.servingStatus) + grpcProber := &GRPCProber{} + if tt.service != "" { + grpcProber = NewGRPCProber( + &v1alpha3.GrpcHealthCheckConfig{ + Port: tt.port, + Service: tt.service, + }, "localhost") + } + got, err := grpcProber.Probe(time.Second) + if got != tt.expectedProbeResult || (err == nil && tt.expectedError != nil) || (err != nil && tt.expectedError == nil) || + (err != nil && tt.expectedError != nil && err.Error() != tt.expectedError.Error()) { + t.Errorf("%s: got: %v, expected: %v, got error: %v, expected error %v", tt.desc, got, tt.expectedProbeResult, err, tt.expectedError) + } + }) + } +} + func TestTcpProber(t *testing.T) { tests := []struct { desc string @@ -182,3 +280,16 @@ func createHTTPServer(statusCode int) (*httptest.Server, uint32) { return server, uint32(port) } + +func startGrpcServer(server *grpc.Server) error { + listener, err := net.Listen("tcp", ":50051") + if err != nil { + return err + } + go func() { + if serverErr := server.Serve(listener); serverErr != nil { + err = serverErr + } + }() + return err +} diff --git a/pkg/istio-agent/xds_proxy_delta_test.go b/pkg/istio-agent/xds_proxy_delta_test.go index ec39bb2f8097..3802b50fc548 100644 --- a/pkg/istio-agent/xds_proxy_delta_test.go +++ b/pkg/istio-agent/xds_proxy_delta_test.go @@ -15,13 +15,13 @@ package istioagent import ( - "errors" "os" "path" "testing" - "time" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + rbacv3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" + httprbac "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3" wasm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/wasm/v3" wasmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/wasm/v3" discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" @@ -35,7 +35,6 @@ import ( "istio.io/istio/pkg/config/constants" "istio.io/istio/pkg/test/env" "istio.io/istio/pkg/test/util/assert" - "istio.io/istio/pkg/test/util/retry" ) // Validates basic xds proxy flow by proxying one CDS requests end to end. @@ -165,7 +164,6 @@ func TestDeltaECDSWasmConversion(t *testing.T) { if !proto.Equal(gotEcdsConfig, wantEcdsConfig) { t.Errorf("xds proxy wasm config conversion got %v want %v", gotEcdsConfig, wantEcdsConfig) } - n1 := proxy.ecdsLastNonce // reset wasm cache to a NACK cache, and recreate xds server as well to simulate a version bump proxy.wasmCache = &fakeNackCache{} @@ -189,11 +187,24 @@ func TestDeltaECDSWasmConversion(t *testing.T) { t.Fatal(err) } - // Wait until nonce was updated, which represents an ACK/NACK has been received. - retry.UntilSuccessOrFail(t, func() error { - if proxy.ecdsLastNonce.Load() == n1.Load() { - return errors.New("last process nonce has not been updated. no ecds ack/nack is received yet") - } - return nil - }, retry.Timeout(time.Second), retry.Delay(time.Millisecond)) + gotResp, err = downstream.Recv() + if err != nil { + t.Fatal(err) + } + if len(gotResp.Resources) != 1 { + t.Errorf("xds proxy ecds wasm conversion number of received resource got %v want 1", len(gotResp.Resources)) + } + if err := gotResp.Resources[0].Resource.UnmarshalTo(gotEcdsConfig); err != nil { + t.Fatalf("wasm config conversion output %v failed to unmarshal", gotResp.Resources[0]) + } + httpDenyAll := &httprbac.RBAC{ + Rules: &rbacv3.RBAC{}, + } + wantEcdsConfig = &core.TypedExtensionConfig{ + Name: "extension-config", + TypedConfig: protoconv.MessageToAny(httpDenyAll), + } + if !proto.Equal(gotEcdsConfig, wantEcdsConfig) { + t.Errorf("xds proxy wasm config conversion got %v want %v", gotEcdsConfig, wantEcdsConfig) + } } diff --git a/pkg/istio-agent/xds_proxy_test.go b/pkg/istio-agent/xds_proxy_test.go index cbfbb2e8c7e8..8784d2e736bb 100644 --- a/pkg/istio-agent/xds_proxy_test.go +++ b/pkg/istio-agent/xds_proxy_test.go @@ -26,6 +26,8 @@ import ( "time" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + rbacv3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" + httprbac "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3" wasm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/wasm/v3" wasmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/wasm/v3" discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" @@ -501,8 +503,6 @@ func TestECDSWasmConversion(t *testing.T) { if !proto.Equal(gotEcdsConfig, wantEcdsConfig) { t.Errorf("xds proxy wasm config conversion got %v want %v", gotEcdsConfig, wantEcdsConfig) } - v1 := proxy.ecdsLastAckVersion - n1 := proxy.ecdsLastNonce // reset wasm cache to a NACK cache, and recreate xds server as well to simulate a version bump proxy.wasmCache = &fakeNackCache{} @@ -527,18 +527,25 @@ func TestECDSWasmConversion(t *testing.T) { t.Fatal(err) } - // Wait until nonce was updated, which represents an ACK/NACK has been received. - retry.UntilSuccessOrFail(t, func() error { - if proxy.ecdsLastNonce.Load() == n1.Load() { - return errors.New("last process nonce has not been updated. no ecds ack/nack is received yet") - } - return nil - }, retry.Timeout(time.Second), retry.Delay(time.Millisecond)) - - // Verify that the last ack version remains the same, which represents the latest DiscoveryRequest is a NACK. - v2 := proxy.ecdsLastAckVersion - if v1.Load() == v2.Load() { - t.Errorf("last ack ecds request was updated. expect it to remain the same which represents a nack for ecds update") + gotResp, err = downstream.Recv() + if err != nil { + t.Fatal(err) + } + if len(gotResp.Resources) != 1 { + t.Errorf("xds proxy ecds wasm conversion number of received resource got %v want 1", len(gotResp.Resources)) + } + if err := gotResp.Resources[0].UnmarshalTo(gotEcdsConfig); err != nil { + t.Fatalf("wasm config conversion output %v failed to unmarshal", gotResp.Resources[0]) + } + httpDenyAll := &httprbac.RBAC{ + Rules: &rbacv3.RBAC{}, + } + wantEcdsConfig = &core.TypedExtensionConfig{ + Name: "extension-config", + TypedConfig: protoconv.MessageToAny(httpDenyAll), + } + if !proto.Equal(gotEcdsConfig, wantEcdsConfig) { + t.Errorf("xds proxy wasm config conversion got %v want %v", gotEcdsConfig, wantEcdsConfig) } } diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 9bb44cc83138..accc026e1cee 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -81,7 +81,6 @@ import ( clienttelemetryalpha "istio.io/client-go/pkg/apis/telemetry/v1alpha1" istioclient "istio.io/client-go/pkg/clientset/versioned" istiofake "istio.io/client-go/pkg/clientset/versioned/fake" - "istio.io/istio/pilot/pkg/features" "istio.io/istio/pkg/cluster" "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/schema/collections" @@ -192,6 +191,12 @@ type CLIClient interface { // PodLogs retrieves the logs for the given pod. PodLogs(ctx context.Context, podName string, podNamespace string, container string, previousLog bool) (string, error) + // PodLogsFollow retrieves the logs for the given pod, following until the pod log stream is interrupted + PodLogsFollow(ctx context.Context, podName string, podNamespace string, container string) (string, error) + + // ServicesForSelector finds services matching selector. + ServicesForSelector(ctx context.Context, namespace string, labelSelectors ...string) (*v1.ServiceList, error) + // NewPortForwarder creates a new PortForwarder configured for the given pod. If localPort=0, a port will be // dynamically selected. If localAddress is empty, "localhost" is used. NewPortForwarder(podName string, ns string, localAddress string, localPort int, podPort int) (PortForwarder, error) @@ -802,6 +807,26 @@ func (c *client) PodLogs(ctx context.Context, podName, podNamespace, container s return builder.String(), nil } +func (c *client) PodLogsFollow(ctx context.Context, podName, podNamespace, container string) (string, error) { + opts := &v1.PodLogOptions{ + Container: container, + Previous: false, + Follow: true, + } + res, err := c.kube.CoreV1().Pods(podNamespace).GetLogs(podName, opts).Stream(ctx) + if err != nil { + return "", err + } + defer closeQuietly(res) + + builder := &strings.Builder{} + if _, err = io.Copy(builder, res); err != nil { + return "", err + } + + return builder.String(), nil +} + func (c *client) AllDiscoveryDo(ctx context.Context, istiodNamespace, path string) (map[string][]byte, error) { istiods, err := c.GetIstioPods(ctx, istiodNamespace, metav1.ListOptions{ LabelSelector: "app=istiod", @@ -1004,10 +1029,15 @@ func (c *client) PodsForSelector(ctx context.Context, namespace string, labelSel }) } +func (c *client) ServicesForSelector(ctx context.Context, namespace string, labelSelectors ...string) (*v1.ServiceList, error) { + return c.kube.CoreV1().Services(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: strings.Join(labelSelectors, ","), + }) +} + func (c *client) ApplyYAMLFiles(namespace string, yamlFiles ...string) error { g, _ := errgroup.WithContext(context.TODO()) for _, f := range removeEmptyFiles(yamlFiles) { - f := f g.Go(func() error { return c.ssapplyYAMLFile(namespace, false, f) }) @@ -1020,7 +1050,6 @@ func (c *client) ApplyYAMLContents(namespace string, yamls ...string) error { for _, yaml := range yamls { cfgs := yml.SplitString(yaml) for _, cfg := range cfgs { - cfg := cfg g.Go(func() error { return c.ssapplyYAML(cfg, namespace, false) }) @@ -1032,7 +1061,6 @@ func (c *client) ApplyYAMLContents(namespace string, yamls ...string) error { func (c *client) ApplyYAMLFilesDryRun(namespace string, yamlFiles ...string) error { g, _ := errgroup.WithContext(context.TODO()) for _, f := range removeEmptyFiles(yamlFiles) { - f := f g.Go(func() error { return c.ssapplyYAMLFile(namespace, true, f) }) @@ -1140,7 +1168,6 @@ func (c *client) DeleteYAMLFiles(namespace string, yamlFiles ...string) (err err errs := make([]error, len(yamlFiles)) g, _ := errgroup.WithContext(context.TODO()) for i, f := range yamlFiles { - i, f := i, f g.Go(func() error { errs[i] = c.deleteYAMLFile(namespace, false, f) return errs[i] @@ -1157,7 +1184,6 @@ func (c *client) DeleteYAMLFilesDryRun(namespace string, yamlFiles ...string) (e errs := make([]error, len(yamlFiles)) g, _ := errgroup.WithContext(context.TODO()) for i, f := range yamlFiles { - i, f := i, f g.Go(func() error { errs[i] = c.deleteYAMLFile(namespace, true, f) return errs[i] @@ -1329,11 +1355,3 @@ func FindIstiodMonitoringPort(pod *v1.Pod) int { } return 15014 } - -// FilterIfEnhancedFilteringEnabled returns the namespace filter if EnhancedResourceScoping is enabled, otherwise a NOP filter. -func FilterIfEnhancedFilteringEnabled(k Client) kubetypes.DynamicObjectFilter { - if features.EnableEnhancedResourceScoping { - return k.ObjectFilter() - } - return nil -} diff --git a/pkg/kube/inject/app_probe.go b/pkg/kube/inject/app_probe.go index 2cd1ee10a106..69ed259a8666 100644 --- a/pkg/kube/inject/app_probe.go +++ b/pkg/kube/inject/app_probe.go @@ -80,18 +80,53 @@ func convertAppProber(probe *corev1.Probe, newURL string, statusPort int) *corev return nil } +// rewriteHTTPGetAction rewrites a HTTPGet action with given URL and port. +// Also rewrites the scheme to HTTP if the scheme is HTTPS +// as pilot agent uses https to request application endpoint. +func rewriteHTTPGetAction(action *corev1.HTTPGetAction, url string, port int) { + action.Port = intstr.FromInt32(int32(port)) + action.Path = url + // Kubelet -> HTTP -> Pilot Agent -> HTTPS -> Application + if action.Scheme == corev1.URISchemeHTTPS { + action.Scheme = corev1.URISchemeHTTP + } +} + +// convertAppLifecycleHandler returns an overwritten `LifecycleHandler` for pilot agent to take over. +func convertAppLifecycleHandler(lifecycleHandler *corev1.LifecycleHandler, newURL string, statusPort int) *corev1.LifecycleHandler { + if lifecycleHandler == nil { + return nil + } + if lifecycleHandler.HTTPGet != nil { + return convertAppLifecycleHandlerHTTPGet(lifecycleHandler, newURL, statusPort) + } + if lifecycleHandler.TCPSocket != nil { + return convertAppLifecycleHandlerTCPSocket(lifecycleHandler, newURL, statusPort) + } + return nil +} + +// convertAppLifecycleHandlerHTTPGet returns an overwritten `LifecycleHandler` with HTTPGet for pilot agent to take over. +func convertAppLifecycleHandlerHTTPGet(lifecycleHandler *corev1.LifecycleHandler, newURL string, statusPort int) *corev1.LifecycleHandler { + lh := lifecycleHandler.DeepCopy() + rewriteHTTPGetAction(lh.HTTPGet, newURL, statusPort) + return lh +} + +// convertAppLifecycleHandlerTCPSocket returns an overwritten `LifecycleHandler` with TCPSocket for pilot agent to take over. +func convertAppLifecycleHandlerTCPSocket(lifecycleHandler *corev1.LifecycleHandler, newURL string, statusPort int) *corev1.LifecycleHandler { + lh := lifecycleHandler.DeepCopy() + // the sidecar intercepts all tcp connections, so we change it to a HTTP probe and the sidecar will check tcp + lh.HTTPGet = &corev1.HTTPGetAction{} + rewriteHTTPGetAction(lh.HTTPGet, newURL, statusPort) + lh.TCPSocket = nil + return lh +} + // convertAppProberHTTPGet returns an overwritten `Probe` (HttpGet) for pilot agent to take over. func convertAppProberHTTPGet(probe *corev1.Probe, newURL string, statusPort int) *corev1.Probe { p := probe.DeepCopy() - // Change the application container prober config. - p.HTTPGet.Port = intstr.FromInt32(int32(statusPort)) - p.HTTPGet.Path = newURL - // For HTTPS prober, we change to HTTP, - // and pilot agent uses https to request application prober endpoint. - // Kubelet -> HTTP -> Pilot Agent -> HTTPS -> Application - if p.HTTPGet.Scheme == corev1.URISchemeHTTPS { - p.HTTPGet.Scheme = corev1.URISchemeHTTP - } + rewriteHTTPGetAction(p.HTTPGet, newURL, statusPort) return p } @@ -100,9 +135,7 @@ func convertAppProberTCPSocket(probe *corev1.Probe, newURL string, statusPort in p := probe.DeepCopy() // the sidecar intercepts all tcp connections, so we change it to a HTTP probe and the sidecar will check tcp p.HTTPGet = &corev1.HTTPGetAction{} - p.HTTPGet.Port = intstr.FromInt32(int32(statusPort)) - p.HTTPGet.Path = newURL - + rewriteHTTPGetAction(p.HTTPGet, newURL, statusPort) p.TCPSocket = nil return p } @@ -112,8 +145,7 @@ func convertAppProberGRPC(probe *corev1.Probe, newURL string, statusPort int) *c p := probe.DeepCopy() // the sidecar intercepts all gRPC connections, so we change it to a HTTP probe and the sidecar will check gRPC p.HTTPGet = &corev1.HTTPGetAction{} - p.HTTPGet.Port = intstr.FromInt32(int32(statusPort)) - p.HTTPGet.Path = newURL + rewriteHTTPGetAction(p.HTTPGet, newURL, statusPort) // For gRPC prober, we change to HTTP, // and pilot agent uses gRPC to request application prober endpoint. // Kubelet -> HTTP -> Pilot Agent -> gRPC -> Application @@ -170,7 +202,7 @@ func DumpAppProbers(pod *corev1.Pod, targetPort int32) string { if c.Name == ProxyContainerName { continue } - readyz, livez, startupz := status.FormatProberURL(c.Name) + readyz, livez, startupz, prestopz, poststartz := status.FormatProberURL(c.Name) portMap := map[string]int32{} for _, p := range c.Ports { if p.Name != "" { @@ -186,7 +218,14 @@ func DumpAppProbers(pod *corev1.Pod, targetPort int32) string { if h := updateNamedPort(kubeProbeToInternalProber(c.StartupProbe), portMap); h != nil { out[startupz] = h } - + if c.Lifecycle != nil { + if h := updateNamedPort(kubeLifecycleHandlerToInternalProber(c.Lifecycle.PreStop), portMap); h != nil { + out[prestopz] = h + } + if h := updateNamedPort(kubeLifecycleHandlerToInternalProber(c.Lifecycle.PostStart), portMap); h != nil { + out[poststartz] = h + } + } } // prevent generate '{}' if len(out) == 0 { @@ -233,7 +272,7 @@ func patchRewriteProbe(annotations map[string]string, pod *corev1.Pod, defaultPo } func convertProbe(c *corev1.Container, statusPort int) { - readyz, livez, startupz := status.FormatProberURL(c.Name) + readyz, livez, startupz, prestopz, poststartz := status.FormatProberURL(c.Name) if probePatch := convertAppProber(c.ReadinessProbe, readyz, statusPort); probePatch != nil { c.ReadinessProbe = probePatch } @@ -243,6 +282,14 @@ func convertProbe(c *corev1.Container, statusPort int) { if probePatch := convertAppProber(c.StartupProbe, startupz, statusPort); probePatch != nil { c.StartupProbe = probePatch } + if c.Lifecycle != nil { + if lifecycleHandlerPatch := convertAppLifecycleHandler(c.Lifecycle.PreStop, prestopz, statusPort); lifecycleHandlerPatch != nil { + c.Lifecycle.PreStop = lifecycleHandlerPatch + } + if lifecycleHandlerPatch := convertAppLifecycleHandler(c.Lifecycle.PostStart, poststartz, statusPort); lifecycleHandlerPatch != nil { + c.Lifecycle.PostStart = lifecycleHandlerPatch + } + } } // kubeProbeToInternalProber converts a Kubernetes Probe to an Istio internal Prober @@ -274,3 +321,22 @@ func kubeProbeToInternalProber(probe *corev1.Probe) *Prober { return nil } + +// kubeLifecycleHandlerToInternalProber converts a Kubernetes LifecycleHandler to an Istio internal Prober +func kubeLifecycleHandlerToInternalProber(lifecycelHandler *corev1.LifecycleHandler) *Prober { + if lifecycelHandler == nil { + return nil + } + if lifecycelHandler.HTTPGet != nil { + return &Prober{ + HTTPGet: lifecycelHandler.HTTPGet, + } + } + if lifecycelHandler.TCPSocket != nil { + return &Prober{ + TCPSocket: lifecycelHandler.TCPSocket, + } + } + + return nil +} diff --git a/pkg/kube/inject/app_probe_test.go b/pkg/kube/inject/app_probe_test.go index 49945673fb71..ad24fc429be8 100644 --- a/pkg/kube/inject/app_probe_test.go +++ b/pkg/kube/inject/app_probe_test.go @@ -185,7 +185,7 @@ func TestDumpAppGRPCProbers(t *testing.T) { }`, }, { - name: "gRPC startup probe with service and timeout", + name: "gRPC startup probe with service and timeout including a http lifecycle handler", pod: &corev1.Pod{Spec: corev1.PodSpec{ Containers: []corev1.Container{ { @@ -199,18 +199,38 @@ func TestDumpAppGRPCProbers(t *testing.T) { }, TimeoutSeconds: 10, }, + Lifecycle: &corev1.Lifecycle{ + PreStop: &corev1.LifecycleHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/foo", + Port: intstr.IntOrString{ + IntVal: 1234, + }, + Host: "foo", + Scheme: "HTTP", + }, + }, + }, }, }, }}, expected: ` { - "/app-health/foo/startupz": { - "grpc": { - "port": 1234, - "service": "foo" - }, - "timeoutSeconds": 10 + "/app-health/foo/startupz": { + "grpc": { + "port": 1234, + "service": "foo" + }, + "timeoutSeconds": 10 + }, + "/app-lifecycle/foo/prestopz": { + "httpGet": { + "path": "/foo", + "port": 1234, + "host": "foo", + "scheme": "HTTP" } + } }`, }, } { diff --git a/pkg/kube/inject/inject_test.go b/pkg/kube/inject/inject_test.go index 69e92f98ab32..6e427fb491a4 100644 --- a/pkg/kube/inject/inject_test.go +++ b/pkg/kube/inject/inject_test.go @@ -54,6 +54,22 @@ import ( // TestInjection tests both the mutating webhook and kube-inject. It does this by sharing the same input and output // test files and running through the two different code paths. func TestInjection(t *testing.T) { + multi := multicluster.NewFakeController() + client := kube.NewFakeClient( + &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-ns", + Annotations: map[string]string{ + securityv1.UIDRangeAnnotation: "1000620000/10000", + securityv1.SupplementalGroupsAnnotation: "1000620000/10000", + }, + }, + }) + multiclusterNamespaceController := multicluster.BuildMultiClusterKclientComponent[*corev1.Namespace](multi, kubetypes.Filter{}) + stop := test.NewStop(t) + multi.Add(constants.DefaultClusterName, client, stop) + client.RunAndWait(stop) + type testCase struct { in string want string @@ -141,6 +157,17 @@ func TestInjection(t *testing.T) { `values.global.proxy.readinessFailureThreshold=300`, }, }, + { + // Verifies that the kubevirtInterfaces list are applied properly from parameters.. + in: "reroute-virtual-interfaces.yaml", + want: "reroute-virtual-interfaces.yaml.injected", + setFlags: []string{ + `values.global.proxy.statusPort=123`, + `values.global.proxy.readinessInitialDelaySeconds=100`, + `values.global.proxy.readinessPeriodSeconds=200`, + `values.global.proxy.readinessFailureThreshold=300`, + }, + }, { // Verifies that global.imagePullSecrets are applied properly in: "hello.yaml", @@ -461,21 +488,9 @@ func TestInjection(t *testing.T) { cases = append(cases, testCase{in: f.Name(), want: want}) } - // Precompute injection settings. This may seem like a premature optimization, but due to the size of - // YAMLs, with -race this was taking >10min in some cases to generate! - if util.Refresh() { - cleanupOldFiles(t) - writeInjectionSettings(t, "default", nil, "") - for i, c := range cases { - if c.setFlags != nil || c.inFilePath != "" { - writeInjectionSettings(t, fmt.Sprintf("%s.%d", c.in, i), c.setFlags, c.inFilePath) - } - } - } // Preload default settings. Computation here is expensive, so this speeds the tests up substantially - defaultTemplate, defaultValues, defaultMesh := readInjectionSettings(t, "default") + defaultTemplate, defaultValues, defaultMesh := getInjectionSettings(t, nil, "") for i, c := range cases { - i, c := i, c testName := fmt.Sprintf("[%02d] %s", i, c.want) if c.expectedError != "" { testName = fmt.Sprintf("[%02d] %s", i, c.in) @@ -494,7 +509,7 @@ func TestInjection(t *testing.T) { } sidecarTemplate, valuesConfig := defaultTemplate, defaultValues if c.setFlags != nil || c.inFilePath != "" { - sidecarTemplate, valuesConfig, mc = readInjectionSettings(t, fmt.Sprintf("%s.%d", c.in, i)) + sidecarTemplate, valuesConfig, mc = getInjectionSettings(t, c.setFlags, c.inFilePath) } if c.mesh != nil { c.mesh(mc) @@ -570,31 +585,15 @@ func TestInjection(t *testing.T) { ProxyConfigs: &model.ProxyConfigs{}, }) - multi := multicluster.NewFakeController() - client := kube.NewFakeClient( - &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-ns", - Annotations: map[string]string{ - securityv1.UIDRangeAnnotation: "1000620000/10000", - securityv1.SupplementalGroupsAnnotation: "1000620000/10000", - }, - }, - }) - webhook := &Webhook{ Config: sidecarTemplate, meshConfig: mc, env: env, valuesConfig: valuesConfig, revision: "default", - namespaces: multicluster.BuildMultiClusterKclientComponent[*corev1.Namespace](multi, kubetypes.Filter{}), + namespaces: multiclusterNamespaceController, } - stop := test.NewStop(t) - multi.Add(constants.DefaultClusterName, client, stop) - client.RunAndWait(stop) - // Split multi-part yaml documents. Input and output will have the same number of parts. inputYAMLs := splitYamlFile(inputFilePath, t) wantYAMLs := splitYamlFile(wantFilePath, t) @@ -1023,7 +1022,6 @@ func TestAppendMultusNetwork(t *testing.T) { } for _, tc := range cases { - tc := tc t.Run(tc.name, func(t *testing.T) { t.Parallel() actual := appendMultusNetwork(tc.in, "istio-cni") @@ -1233,7 +1231,7 @@ func BenchmarkInjection(b *testing.B) { for _, tt := range cases { b.Run(tt.name, func(b *testing.B) { // Preload default settings. Computation here is expensive, so this speeds the tests up substantially - sidecarTemplate, valuesConfig, mc := readInjectionSettings(b, "default") + sidecarTemplate, valuesConfig, mc := getInjectionSettings(b, nil, "") env := &model.Environment{} env.SetPushContext(&model.PushContext{ ProxyConfigs: &model.ProxyConfigs{}, diff --git a/pkg/kube/inject/testdata/inject/deploymentconfig-with-canonical-service-label.yaml b/pkg/kube/inject/testdata/inject/deploymentconfig-with-canonical-service-label.yaml index a1d499d206e2..ad1ed24f9c3d 100644 --- a/pkg/kube/inject/testdata/inject/deploymentconfig-with-canonical-service-label.yaml +++ b/pkg/kube/inject/testdata/inject/deploymentconfig-with-canonical-service-label.yaml @@ -11,6 +11,7 @@ spec: tier: backend track: stable service.istio.io/canonical-name: test-service-name + service.istio.io/workload-name: test-workload-name spec: containers: - name: hello diff --git a/pkg/kube/inject/testdata/inject/deploymentconfig-with-canonical-service-label.yaml.injected b/pkg/kube/inject/testdata/inject/deploymentconfig-with-canonical-service-label.yaml.injected index dc94bff88c4d..0853d2ddbbb5 100644 --- a/pkg/kube/inject/testdata/inject/deploymentconfig-with-canonical-service-label.yaml.injected +++ b/pkg/kube/inject/testdata/inject/deploymentconfig-with-canonical-service-label.yaml.injected @@ -25,6 +25,7 @@ spec: security.istio.io/tlsMode: istio service.istio.io/canonical-name: test-service-name service.istio.io/canonical-revision: latest + service.istio.io/workload-name: test-workload-name tier: backend track: stable spec: @@ -102,7 +103,7 @@ spec: - name: ISTIO_META_INTERCEPTION_MODE value: REDIRECT - name: ISTIO_META_WORKLOAD_NAME - value: hello + value: test-workload-name - name: ISTIO_META_OWNER value: kubernetes://apis/v1/namespaces/default/deploymentconfigs/hello - name: ISTIO_META_MESH_ID diff --git a/pkg/kube/inject/testdata/inject/hello-probes.proxyHoldsApplication.yaml.injected b/pkg/kube/inject/testdata/inject/hello-probes.proxyHoldsApplication.yaml.injected index c9afff6a85c7..6f9462bf716b 100644 --- a/pkg/kube/inject/testdata/inject/hello-probes.proxyHoldsApplication.yaml.injected +++ b/pkg/kube/inject/testdata/inject/hello-probes.proxyHoldsApplication.yaml.injected @@ -107,7 +107,7 @@ spec: - name: TRUST_DOMAIN value: cluster.local - name: ISTIO_KUBE_APP_PROBERS - value: '{"/app-health/hello/livez":{"httpGet":{"port":80}},"/app-health/hello/readyz":{"httpGet":{"port":3333}},"/app-health/world/livez":{"httpGet":{"port":90}}}' + value: '{"/app-health/hello/livez":{"httpGet":{"port":80}},"/app-health/hello/readyz":{"httpGet":{"port":3333}},"/app-health/world/livez":{"httpGet":{"port":90}},"/app-lifecycle/hello/poststartz":{"tcpSocket":{"port":93}},"/app-lifecycle/hello/prestopz":{"httpGet":{"port":91}}}' image: gcr.io/istio-testing/proxyv2:latest lifecycle: postStart: @@ -169,6 +169,15 @@ spec: - mountPath: /etc/istio/pod name: istio-podinfo - image: fake.docker.io/google-samples/hello-go-gke:1.0 + lifecycle: + postStart: + httpGet: + path: /app-lifecycle/hello/poststartz + port: 15020 + preStop: + httpGet: + path: /app-lifecycle/hello/prestopz + port: 15020 livenessProbe: httpGet: path: /app-health/hello/livez diff --git a/pkg/kube/inject/testdata/inject/hello-probes.yaml b/pkg/kube/inject/testdata/inject/hello-probes.yaml index 1804ebbdafe3..3f8db99e9b10 100644 --- a/pkg/kube/inject/testdata/inject/hello-probes.yaml +++ b/pkg/kube/inject/testdata/inject/hello-probes.yaml @@ -28,6 +28,13 @@ spec: readinessProbe: httpGet: port: 3333 + lifecycle: + preStop: + httpGet: + port: 91 + postStart: + tcpSocket: + port: 93 - name: world image: "fake.docker.io/google-samples/hello-go-gke:1.0" ports: diff --git a/pkg/kube/inject/testdata/inject/hello-probes.yaml.injected b/pkg/kube/inject/testdata/inject/hello-probes.yaml.injected index 9ae0f1278a27..4259a7a2e6d0 100644 --- a/pkg/kube/inject/testdata/inject/hello-probes.yaml.injected +++ b/pkg/kube/inject/testdata/inject/hello-probes.yaml.injected @@ -32,6 +32,15 @@ spec: spec: containers: - image: fake.docker.io/google-samples/hello-go-gke:1.0 + lifecycle: + postStart: + httpGet: + path: /app-lifecycle/hello/poststartz + port: 15020 + preStop: + httpGet: + path: /app-lifecycle/hello/prestopz + port: 15020 livenessProbe: httpGet: path: /app-health/hello/livez @@ -136,7 +145,7 @@ spec: - name: TRUST_DOMAIN value: cluster.local - name: ISTIO_KUBE_APP_PROBERS - value: '{"/app-health/hello/livez":{"httpGet":{"port":80}},"/app-health/hello/readyz":{"httpGet":{"port":3333}},"/app-health/world/livez":{"httpGet":{"port":90}}}' + value: '{"/app-health/hello/livez":{"httpGet":{"port":80}},"/app-health/hello/readyz":{"httpGet":{"port":3333}},"/app-health/world/livez":{"httpGet":{"port":90}},"/app-lifecycle/hello/poststartz":{"tcpSocket":{"port":93}},"/app-lifecycle/hello/prestopz":{"httpGet":{"port":91}}}' image: gcr.io/istio-testing/proxyv2:latest name: istio-proxy ports: diff --git a/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces.yaml b/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces.yaml new file mode 100644 index 000000000000..7b7be1737788 --- /dev/null +++ b/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hello +spec: + replicas: 7 + selector: + matchLabels: + app: hello + tier: backend + track: stable + template: + metadata: + annotations: + istio.io/reroute-virtual-interfaces: "net0ps2" + labels: + app: hello + tier: backend + track: stable + spec: + containers: + - name: hello + image: "fake.docker.io/google-samples/hello-go-gke:1.0" + ports: + - name: http + containerPort: 80 diff --git a/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces.yaml.injected b/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces.yaml.injected new file mode 100644 index 000000000000..df6bb92fb788 --- /dev/null +++ b/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces.yaml.injected @@ -0,0 +1,243 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + name: hello +spec: + replicas: 7 + selector: + matchLabels: + app: hello + tier: backend + track: stable + strategy: {} + template: + metadata: + annotations: + istio.io/reroute-virtual-interfaces: net0ps2 + istio.io/rev: default + kubectl.kubernetes.io/default-container: hello + kubectl.kubernetes.io/default-logs-container: hello + prometheus.io/path: /stats/prometheus + prometheus.io/port: "15020" + prometheus.io/scrape: "true" + sidecar.istio.io/status: '{"initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["workload-socket","credential-socket","workload-certs","istio-envoy","istio-data","istio-podinfo","istio-token","istiod-ca-cert"],"imagePullSecrets":null,"revision":"default"}' + creationTimestamp: null + labels: + app: hello + security.istio.io/tlsMode: istio + service.istio.io/canonical-name: hello + service.istio.io/canonical-revision: latest + tier: backend + track: stable + spec: + containers: + - image: fake.docker.io/google-samples/hello-go-gke:1.0 + name: hello + ports: + - containerPort: 80 + name: http + resources: {} + - args: + - proxy + - sidecar + - --domain + - $(POD_NAMESPACE).svc.cluster.local + - --proxyLogLevel=warning + - --proxyComponentLogLevel=misc:error + - --log_output_level=default:info + env: + - name: PILOT_CERT_PROVIDER + value: istiod + - name: CA_ADDR + value: istiod.istio-system.svc:15012 + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + divisor: "0" + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {} + - name: ISTIO_META_POD_PORTS + value: |- + [ + {"name":"http","containerPort":80} + ] + - name: ISTIO_META_APP_CONTAINERS + value: hello + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + divisor: "0" + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + divisor: "0" + resource: limits.cpu + - name: ISTIO_META_CLUSTER_ID + value: Kubernetes + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: ISTIO_META_INTERCEPTION_MODE + value: REDIRECT + - name: ISTIO_META_WORKLOAD_NAME + value: hello + - name: ISTIO_META_OWNER + value: kubernetes://apis/apps/v1/namespaces/default/deployments/hello + - name: ISTIO_META_MESH_ID + value: cluster.local + - name: TRUST_DOMAIN + value: cluster.local + image: gcr.io/istio-testing/proxyv2:latest + name: istio-proxy + ports: + - containerPort: 15090 + name: http-envoy-prom + protocol: TCP + readinessProbe: + failureThreshold: 300 + httpGet: + path: /healthz/ready + port: 15021 + initialDelaySeconds: 100 + periodSeconds: 200 + timeoutSeconds: 3 + resources: + limits: + cpu: "2" + memory: 1Gi + requests: + cpu: 100m + memory: 128Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsGroup: 1337 + runAsNonRoot: true + runAsUser: 1337 + startupProbe: + failureThreshold: 600 + httpGet: + path: /healthz/ready + port: 15021 + periodSeconds: 1 + timeoutSeconds: 3 + volumeMounts: + - mountPath: /var/run/secrets/workload-spiffe-uds + name: workload-socket + - mountPath: /var/run/secrets/credential-uds + name: credential-socket + - mountPath: /var/run/secrets/workload-spiffe-credentials + name: workload-certs + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + - mountPath: /var/lib/istio/data + name: istio-data + - mountPath: /etc/istio/proxy + name: istio-envoy + - mountPath: /var/run/secrets/tokens + name: istio-token + - mountPath: /etc/istio/pod + name: istio-podinfo + initContainers: + - args: + - istio-iptables + - -p + - "15001" + - -z + - "15006" + - -u + - "1337" + - -m + - REDIRECT + - -i + - '*' + - -x + - "" + - -b + - '*' + - -d + - 15090,15021,123 + - -k + - net0ps2 + - --log_output_level=default:info + image: gcr.io/istio-testing/proxyv2:latest + name: istio-init + resources: + limits: + cpu: "2" + memory: 1Gi + requests: + cpu: 100m + memory: 128Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_ADMIN + - NET_RAW + drop: + - ALL + privileged: false + readOnlyRootFilesystem: false + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + volumes: + - name: workload-socket + - name: credential-socket + - name: workload-certs + - emptyDir: + medium: Memory + name: istio-envoy + - emptyDir: {} + name: istio-data + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.labels + path: labels + - fieldRef: + fieldPath: metadata.annotations + path: annotations + name: istio-podinfo + - name: istio-token + projected: + sources: + - serviceAccountToken: + audience: istio-ca + expirationSeconds: 43200 + path: istio-token + - configMap: + name: istio-ca-root-cert + name: istiod-ca-cert +status: {} +--- diff --git a/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces_list.yaml b/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces_list.yaml new file mode 100644 index 000000000000..d84c97d77951 --- /dev/null +++ b/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces_list.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hello +spec: + replicas: 7 + selector: + matchLabels: + app: hello + tier: backend + track: stable + template: + metadata: + annotations: + istio.io/reroute-virtual-interfaces: "net1ps5,net2qr9" + labels: + app: hello + tier: backend + track: stable + spec: + containers: + - name: hello + image: "fake.docker.io/google-samples/hello-go-gke:1.0" + ports: + - name: http + containerPort: 80 diff --git a/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces_list.yaml.injected b/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces_list.yaml.injected new file mode 100644 index 000000000000..6ef129a6801e --- /dev/null +++ b/pkg/kube/inject/testdata/inject/reroute-virtual-interfaces_list.yaml.injected @@ -0,0 +1,242 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + creationTimestamp: null + name: hello +spec: + replicas: 7 + selector: + matchLabels: + app: hello + tier: backend + track: stable + strategy: {} + template: + metadata: + annotations: + istio.io/reroute-virtual-interfaces: net1ps5,net2qr9 + istio.io/rev: default + kubectl.kubernetes.io/default-container: hello + kubectl.kubernetes.io/default-logs-container: hello + prometheus.io/path: /stats/prometheus + prometheus.io/port: "15020" + prometheus.io/scrape: "true" + sidecar.istio.io/status: '{"initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["workload-socket","credential-socket","workload-certs","istio-envoy","istio-data","istio-podinfo","istio-token","istiod-ca-cert"],"imagePullSecrets":null,"revision":"default"}' + creationTimestamp: null + labels: + app: hello + security.istio.io/tlsMode: istio + service.istio.io/canonical-name: hello + service.istio.io/canonical-revision: latest + tier: backend + track: stable + spec: + containers: + - image: fake.docker.io/google-samples/hello-go-gke:1.0 + name: hello + ports: + - containerPort: 80 + name: http + resources: {} + - args: + - proxy + - sidecar + - --domain + - $(POD_NAMESPACE).svc.cluster.local + - --proxyLogLevel=warning + - --proxyComponentLogLevel=misc:error + - --log_output_level=default:info + env: + - name: PILOT_CERT_PROVIDER + value: istiod + - name: CA_ADDR + value: istiod.istio-system.svc:15012 + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + divisor: "0" + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {} + - name: ISTIO_META_POD_PORTS + value: |- + [ + {"name":"http","containerPort":80} + ] + - name: ISTIO_META_APP_CONTAINERS + value: hello + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + divisor: "0" + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + divisor: "0" + resource: limits.cpu + - name: ISTIO_META_CLUSTER_ID + value: Kubernetes + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: ISTIO_META_INTERCEPTION_MODE + value: REDIRECT + - name: ISTIO_META_WORKLOAD_NAME + value: hello + - name: ISTIO_META_OWNER + value: kubernetes://apis/apps/v1/namespaces/default/deployments/hello + - name: ISTIO_META_MESH_ID + value: cluster.local + - name: TRUST_DOMAIN + value: cluster.local + image: gcr.io/istio-testing/proxyv2:latest + name: istio-proxy + ports: + - containerPort: 15090 + name: http-envoy-prom + protocol: TCP + readinessProbe: + failureThreshold: 4 + httpGet: + path: /healthz/ready + port: 15021 + periodSeconds: 15 + timeoutSeconds: 3 + resources: + limits: + cpu: "2" + memory: 1Gi + requests: + cpu: 100m + memory: 128Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + runAsGroup: 1337 + runAsNonRoot: true + runAsUser: 1337 + startupProbe: + failureThreshold: 600 + httpGet: + path: /healthz/ready + port: 15021 + periodSeconds: 1 + timeoutSeconds: 3 + volumeMounts: + - mountPath: /var/run/secrets/workload-spiffe-uds + name: workload-socket + - mountPath: /var/run/secrets/credential-uds + name: credential-socket + - mountPath: /var/run/secrets/workload-spiffe-credentials + name: workload-certs + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + - mountPath: /var/lib/istio/data + name: istio-data + - mountPath: /etc/istio/proxy + name: istio-envoy + - mountPath: /var/run/secrets/tokens + name: istio-token + - mountPath: /etc/istio/pod + name: istio-podinfo + initContainers: + - args: + - istio-iptables + - -p + - "15001" + - -z + - "15006" + - -u + - "1337" + - -m + - REDIRECT + - -i + - '*' + - -x + - "" + - -b + - '*' + - -d + - 15090,15021,15020 + - -k + - net1ps5,net2qr9 + - --log_output_level=default:info + image: gcr.io/istio-testing/proxyv2:latest + name: istio-init + resources: + limits: + cpu: "2" + memory: 1Gi + requests: + cpu: 100m + memory: 128Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + add: + - NET_ADMIN + - NET_RAW + drop: + - ALL + privileged: false + readOnlyRootFilesystem: false + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + volumes: + - name: workload-socket + - name: credential-socket + - name: workload-certs + - emptyDir: + medium: Memory + name: istio-envoy + - emptyDir: {} + name: istio-data + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.labels + path: labels + - fieldRef: + fieldPath: metadata.annotations + path: annotations + name: istio-podinfo + - name: istio-token + projected: + sources: + - serviceAccountToken: + audience: istio-ca + expirationSeconds: 43200 + path: istio-token + - configMap: + name: istio-ca-root-cert + name: istiod-ca-cert +status: {} +--- diff --git a/pkg/kube/inject/testdata/inputs/custom-template.yaml.43.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/custom-template.yaml.43.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/custom-template.yaml.43.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/custom-template.yaml.43.template.gen.yaml b/pkg/kube/inject/testdata/inputs/custom-template.yaml.43.template.gen.yaml deleted file mode 100644 index a94eb95dc83d..000000000000 --- a/pkg/kube/inject/testdata/inputs/custom-template.yaml.43.template.gen.yaml +++ /dev/null @@ -1,1857 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - custom: | - metadata: - annotations: - # Disable the built-in transformations. In the future we may want a template-level API - prometheus.istio.io/merge-metrics: "false" - sidecar.istio.io/rewriteAppHTTPProbers: "false" - foo: bar - spec: - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: SOME_ENV - value: "true" - - name: SOME_FILE - value: /var/lib/data/foo.json - volumeMounts: - - mountPath: /var/lib/data/foo.json - subPath: foo.json - name: some-injected-file - {{- end}} - volumes: - - name: some-injected-file - downwardAPI: - items: - - path: foo.json - fieldRef: - fieldPath: "metadata.annotations['foo']" \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/custom-template.yaml.43.values.gen.yaml b/pkg/kube/inject/testdata/inputs/custom-template.yaml.43.values.gen.yaml deleted file mode 100644 index 16c4518ed4ff..000000000000 --- a/pkg/kube/inject/testdata/inputs/custom-template.yaml.43.values.gen.yaml +++ /dev/null @@ -1,129 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": { - "custom": "metadata:\n annotations:\n # Disable the built-in transformations. In the future we may want a template-level API\n prometheus.istio.io/merge-metrics: \"false\"\n sidecar.istio.io/rewriteAppHTTPProbers: \"false\"\n foo: bar\nspec:\n containers:\n {{- range $index, $container := .Spec.Containers }}\n - name: {{ $container.Name }}\n env:\n - name: SOME_ENV\n value: \"true\"\n - name: SOME_FILE\n value: /var/lib/data/foo.json\n volumeMounts:\n - mountPath: /var/lib/data/foo.json\n subPath: foo.json\n name: some-injected-file\n {{- end}}\n volumes:\n - name: some-injected-file\n downwardAPI:\n items:\n - path: foo.json\n fieldRef:\n fieldPath: \"metadata.annotations['foo']\"\n" - } - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/default.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/default.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/default.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/default.template.gen.yaml b/pkg/kube/inject/testdata/inputs/default.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/default.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/default.values.gen.yaml b/pkg/kube/inject/testdata/inputs/default.values.gen.yaml deleted file mode 100644 index ef605b4fd018..000000000000 --- a/pkg/kube/inject/testdata/inputs/default.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks-json.yaml.15.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks-json.yaml.15.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks-json.yaml.15.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks-json.yaml.15.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks-json.yaml.15.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks-json.yaml.15.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks-json.yaml.15.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks-json.yaml.15.values.gen.yaml deleted file mode 100644 index 940706a8155e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks-json.yaml.15.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": true, - "provider": "multus" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks.yaml.14.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks.yaml.14.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks.yaml.14.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks.yaml.14.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks.yaml.14.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks.yaml.14.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks.yaml.14.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks.yaml.14.values.gen.yaml deleted file mode 100644 index 940706a8155e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-existing-cncf-networks.yaml.14.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": true, - "provider": "multus" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-image-pull-secret.yaml.10.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-image-pull-secret.yaml.10.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-image-pull-secret.yaml.10.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-image-pull-secret.yaml.10.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-image-pull-secret.yaml.10.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-image-pull-secret.yaml.10.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-image-pull-secret.yaml.10.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-image-pull-secret.yaml.10.values.gen.yaml deleted file mode 100644 index 288a911ef4f3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-image-pull-secret.yaml.10.values.gen.yaml +++ /dev/null @@ -1,129 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [ - "barSecret" - ], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-openshift-custom-injection.yaml.51.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-openshift-custom-injection.yaml.51.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-openshift-custom-injection.yaml.51.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-openshift-custom-injection.yaml.51.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-openshift-custom-injection.yaml.51.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-openshift-custom-injection.yaml.51.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-openshift-custom-injection.yaml.51.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-openshift-custom-injection.yaml.51.values.gen.yaml deleted file mode 100644 index 5c0121312443..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-openshift-custom-injection.yaml.51.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": true, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-openshift.yaml.50.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-openshift.yaml.50.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-openshift.yaml.50.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-openshift.yaml.50.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-openshift.yaml.50.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-openshift.yaml.50.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-openshift.yaml.50.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-openshift.yaml.50.values.gen.yaml deleted file mode 100644 index 5c0121312443..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-openshift.yaml.50.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": true, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-probes-noProxyHoldApplication-ProxyConfig.yaml.19.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-probes-noProxyHoldApplication-ProxyConfig.yaml.19.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-probes-noProxyHoldApplication-ProxyConfig.yaml.19.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-probes-noProxyHoldApplication-ProxyConfig.yaml.19.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-probes-noProxyHoldApplication-ProxyConfig.yaml.19.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-probes-noProxyHoldApplication-ProxyConfig.yaml.19.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-probes-noProxyHoldApplication-ProxyConfig.yaml.19.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-probes-noProxyHoldApplication-ProxyConfig.yaml.19.values.gen.yaml deleted file mode 100644 index b9961df7892c..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-probes-noProxyHoldApplication-ProxyConfig.yaml.19.values.gen.yaml +++ /dev/null @@ -1,128 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "holdApplicationUntilProxyStarts": true, - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-probes.yaml.17.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-probes.yaml.17.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-probes.yaml.17.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-probes.yaml.17.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-probes.yaml.17.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-probes.yaml.17.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello-probes.yaml.17.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello-probes.yaml.17.values.gen.yaml deleted file mode 100644 index b9961df7892c..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello-probes.yaml.17.values.gen.yaml +++ /dev/null @@ -1,128 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "holdApplicationUntilProxyStarts": true, - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.0.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.0.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.0.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.0.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.0.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.0.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.0.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.0.values.gen.yaml deleted file mode 100644 index 76e08d9616f7..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.0.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "network1", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": true, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.1.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.1.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.1.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.1.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.1.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.1.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.1.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.1.values.gen.yaml deleted file mode 100644 index 89f90c4a5220..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.1.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyTest", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.11.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.11.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.11.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.11.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.11.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.11.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.11.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.11.values.gen.yaml deleted file mode 100644 index 55488640c702..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.11.values.gen.yaml +++ /dev/null @@ -1,131 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "podDNSSearchNamespaces": [ - "global", - "{{ valueOrDefault .DeploymentMeta.Namespace \"default\" }}.global" - ], - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.12.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.12.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.12.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.12.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.12.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.12.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.12.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.12.values.gen.yaml deleted file mode 100644 index a01983f3fd07..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.12.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": true, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.13.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.13.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.13.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.13.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.13.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.13.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.13.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.13.values.gen.yaml deleted file mode 100644 index 940706a8155e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.13.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": true, - "provider": "multus" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.16.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.16.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.16.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.16.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.16.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.16.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.16.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.16.values.gen.yaml deleted file mode 100644 index b9961df7892c..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.16.values.gen.yaml +++ /dev/null @@ -1,128 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "holdApplicationUntilProxyStarts": true, - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.3.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.3.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.3.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.3.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.3.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.3.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.3.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.3.values.gen.yaml deleted file mode 100644 index 25b6f561043f..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.3.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "Always", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.4.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.4.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.4.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.4.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.4.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.4.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.4.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.4.values.gen.yaml deleted file mode 100644 index 457231b037d0..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.4.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "Never", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.9.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.9.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.9.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.9.template.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.9.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.9.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/hello.yaml.9.values.gen.yaml b/pkg/kube/inject/testdata/inputs/hello.yaml.9.values.gen.yaml deleted file mode 100644 index 288a911ef4f3..000000000000 --- a/pkg/kube/inject/testdata/inputs/hello.yaml.9.values.gen.yaml +++ /dev/null @@ -1,129 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [ - "barSecret" - ], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/kubevirtInterfaces.yaml.8.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/kubevirtInterfaces.yaml.8.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/kubevirtInterfaces.yaml.8.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/kubevirtInterfaces.yaml.8.template.gen.yaml b/pkg/kube/inject/testdata/inputs/kubevirtInterfaces.yaml.8.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/kubevirtInterfaces.yaml.8.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/kubevirtInterfaces.yaml.8.values.gen.yaml b/pkg/kube/inject/testdata/inputs/kubevirtInterfaces.yaml.8.values.gen.yaml deleted file mode 100644 index 95b14c66a9e4..000000000000 --- a/pkg/kube/inject/testdata/inputs/kubevirtInterfaces.yaml.8.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 300, - "readinessInitialDelaySeconds": 100, - "readinessPeriodSeconds": 200, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 123, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/merge-probers.yaml.46.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/merge-probers.yaml.46.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/merge-probers.yaml.46.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/merge-probers.yaml.46.template.gen.yaml b/pkg/kube/inject/testdata/inputs/merge-probers.yaml.46.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/merge-probers.yaml.46.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/merge-probers.yaml.46.values.gen.yaml b/pkg/kube/inject/testdata/inputs/merge-probers.yaml.46.values.gen.yaml deleted file mode 100644 index b9961df7892c..000000000000 --- a/pkg/kube/inject/testdata/inputs/merge-probers.yaml.46.values.gen.yaml +++ /dev/null @@ -1,128 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "holdApplicationUntilProxyStarts": true, - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/proxy-override-runas.yaml.33.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/proxy-override-runas.yaml.33.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/proxy-override-runas.yaml.33.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/proxy-override-runas.yaml.33.template.gen.yaml b/pkg/kube/inject/testdata/inputs/proxy-override-runas.yaml.33.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/proxy-override-runas.yaml.33.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/proxy-override-runas.yaml.33.values.gen.yaml b/pkg/kube/inject/testdata/inputs/proxy-override-runas.yaml.33.values.gen.yaml deleted file mode 100644 index 5c0121312443..000000000000 --- a/pkg/kube/inject/testdata/inputs/proxy-override-runas.yaml.33.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 15020, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": true, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/status_params.yaml.7.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/status_params.yaml.7.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/status_params.yaml.7.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/status_params.yaml.7.template.gen.yaml b/pkg/kube/inject/testdata/inputs/status_params.yaml.7.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/status_params.yaml.7.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/status_params.yaml.7.values.gen.yaml b/pkg/kube/inject/testdata/inputs/status_params.yaml.7.values.gen.yaml deleted file mode 100644 index 95b14c66a9e4..000000000000 --- a/pkg/kube/inject/testdata/inputs/status_params.yaml.7.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "", - "excludeInboundPorts": "", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "*", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 300, - "readinessInitialDelaySeconds": 100, - "readinessPeriodSeconds": 200, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 123, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/traffic-params.yaml.6.mesh.gen.yaml b/pkg/kube/inject/testdata/inputs/traffic-params.yaml.6.mesh.gen.yaml deleted file mode 100644 index 29e80375bc7e..000000000000 --- a/pkg/kube/inject/testdata/inputs/traffic-params.yaml.6.mesh.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -defaultConfig: - discoveryAddress: istiod.istio-system.svc:15012 -defaultProviders: - metrics: - - prometheus -enablePrometheusMerge: true -rootNamespace: istio-system -trustDomain: cluster.local \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/traffic-params.yaml.6.template.gen.yaml b/pkg/kube/inject/testdata/inputs/traffic-params.yaml.6.template.gen.yaml deleted file mode 100644 index a0522de27ae3..000000000000 --- a/pkg/kube/inject/testdata/inputs/traffic-params.yaml.6.template.gen.yaml +++ /dev/null @@ -1,1829 +0,0 @@ -# defaultTemplates defines the default template to use for pods that do not explicitly specify a template -defaultTemplates: [sidecar] -policy: enabled -alwaysInjectSelector: - [] -neverInjectSelector: - [] -injectedAnnotations: -template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" -templates: - sidecar: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} - {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} - networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} - {{- end }} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - {{- if .Values.pilot.cni.enabled }} - {{- if eq .Values.pilot.cni.provider "multus" }} - k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', - {{- end }} - sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} - {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} - traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} - traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} - traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", - {{- end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} - {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} - {{- end }} - } - spec: - {{- $holdProxy := and - (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) - (not $nativeSidecar) }} - initContainers: - {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} - {{ if .Values.pilot.cni.enabled -}} - - name: istio-validation - {{ else -}} - - name: istio-init - {{ end -}} - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - args: - - istio-iptables - - "-p" - - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} - - "-z" - - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} - - "-u" - - {{ .ProxyUID | default "1337" | quote }} - - "-m" - - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" - - "-i" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" - - "-x" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" - - "-b" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" - - "-d" - {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} - - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" - {{- else }} - - "15090,15021" - {{- end }} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} - - "-q" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" - {{ end -}} - {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} - - "-o" - - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} - - "-k" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" - {{ end -}} - {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} - - "-c" - - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" - {{ end -}} - - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" - {{ if .Values.global.logAsJson -}} - - "--log_as_json" - {{ end -}} - {{ if .Values.pilot.cni.enabled -}} - - "--run-validation" - - "--skip-rule-apply" - {{ else if .Values.global.proxy_init.forceApplyIptables -}} - - "--force-apply" - {{ end -}} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{- if .ProxyConfig.ProxyMetadata }} - env: - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - securityContext: - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - privileged: {{ .Values.global.proxy.privileged }} - capabilities: - {{- if not .Values.pilot.cni.enabled }} - add: - - NET_ADMIN - - NET_RAW - {{- end }} - drop: - - ALL - {{- if not .Values.pilot.cni.enabled }} - readOnlyRootFilesystem: false - runAsGroup: 0 - runAsNonRoot: false - runAsUser: 0 - {{- else }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsUser: {{ .ProxyUID | default "1337" }} - runAsNonRoot: true - {{- end }} - {{ end -}} - {{ if not $nativeSidecar }} - containers: - {{ end }} - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{ if $nativeSidecar }}restartPolicy: Always{{end}} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.outlierLogPath }} - - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} - {{- end}} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- else if $holdProxy }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - {{- else if $nativeSidecar }} - {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} - lifecycle: - preStop: - exec: - command: - - pilot-agent - - request - - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} - - POST - - drain - {{- end }} - env: - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: ISTIO_BOOTSTRAP_OVERRIDE - value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" - {{- end }} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - {{ if .Values.global.proxy.startupProbe.enabled }} - startupProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: 0 - periodSeconds: 1 - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} - {{ end }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - {{ end -}} - securityContext: - {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} - allowPrivilegeEscalation: true - capabilities: - add: - - NET_ADMIN - drop: - - ALL - privileged: true - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: false - runAsUser: 0 - {{- else }} - allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} - capabilities: - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - add: - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} - - NET_ADMIN - {{- end }} - {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} - - NET_BIND_SERVICE - {{- end }} - {{- end }} - drop: - - ALL - privileged: {{ .Values.global.proxy.privileged }} - readOnlyRootFilesystem: true - runAsGroup: {{ .ProxyGID | default "1337" }} - {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} - runAsNonRoot: false - runAsUser: 0 - {{- else -}} - runAsNonRoot: true - runAsUser: {{ .ProxyUID | default "1337" }} - {{- end }} - {{- end }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - mountPath: /etc/istio/custom-bootstrap - name: custom-bootstrap-volume - {{- end }} - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} - name: lightstep-certs - readOnly: true - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - - emptyDir: - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} - - name: lightstep-certs - secret: - optional: true - secretName: lightstep.cacert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - gateway: | - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if eq (len $containers) 1 }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{ end }} - } - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 4 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- end }} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} - {{- end }} - securityContext: - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - {{- if .CompliancePolicy }} - - name: COMPLIANCE_POLICY - value: "{{ .CompliancePolicy }}" - {{- end }} - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15021 - initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - grpc-simple: | - metadata: - annotations: - sidecar.istio.io/rewriteAppHTTPProbers: "false" - spec: - initContainers: - - name: grpc-bootstrap-init - image: busybox:1.28 - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - env: - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: ISTIO_NAMESPACE - value: | - {{ .Values.global.istioNamespace }} - command: - - sh - - "-c" - - |- - NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" - SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" - echo ' - { - "xds_servers": [ - { - "server_uri": "'${SERVER_URI}'", - "channel_creds": [{"type": "insecure"}], - "server_features" : ["xds_v3"] - } - ], - "node": { - "id": "'${NODE_ID}'", - "metadata": { - "GENERATOR": "grpc" - } - } - }' > /var/lib/grpc/data/bootstrap.json - containers: - {{- range $index, $container := .Spec.Containers }} - - name: {{ $container.Name }} - env: - - name: GRPC_XDS_BOOTSTRAP - value: /var/lib/grpc/data/bootstrap.json - - name: GRPC_GO_LOG_VERBOSITY_LEVEL - value: "99" - - name: GRPC_GO_LOG_SEVERITY_LEVEL - value: info - volumeMounts: - - mountPath: /var/lib/grpc/data/ - name: grpc-io-proxyless-bootstrap - {{- end }} - volumes: - - name: grpc-io-proxyless-bootstrap - emptyDir: {} - grpc-agent: | - {{- define "resources" }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} - requests: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" - {{ end }} - {{- end }} - {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} - limits: - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} - cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" - {{ end }} - {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} - memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" - {{ end }} - {{- end }} - {{- else }} - {{- if .Values.global.proxy.resources }} - {{ toYaml .Values.global.proxy.resources | indent 6 }} - {{- end }} - {{- end }} - {{- end }} - {{- $containers := list }} - {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} - metadata: - labels: - {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} - service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} - service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} - annotations: { - istio.io/rev: {{ .Revision | default "default" | quote }}, - {{- if ge (len $containers) 1 }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} - kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", - {{- end }} - {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} - kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", - {{- end }} - {{- end }} - sidecar.istio.io/rewriteAppHTTPProbers: "false", - } - spec: - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - ports: - - containerPort: 15020 - protocol: TCP - name: mesh-metrics - args: - - proxy - - sidecar - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} - - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} - - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - lifecycle: - postStart: - exec: - command: - - pilot-agent - - wait - - --url=http://localhost:15020/healthz/ready - env: - - name: ISTIO_META_GENERATOR - value: grpc - - name: OUTPUT_CERTS - value: /var/lib/istio/data - {{- if eq .InboundTrafficPolicyMode "localhost" }} - - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION - value: "true" - {{- end }} - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: |- - [ - {{- $first := true }} - {{- range $index1, $c := .Spec.Containers }} - {{- range $index2, $p := $c.Ports }} - {{- if (structToJSON $p) }} - {{if not $first}},{{end}}{{ structToJSON $p }} - {{- $first = false }} - {{- end }} - {{- end}} - {{- end}} - ] - - name: ISTIO_META_APP_CONTAINERS - value: "{{ $containers | join "," }}" - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - {{- if .Values.global.network }} - - name: ISTIO_META_NETWORK - value: "{{ .Values.global.network }}" - {{- end }} - {{- if .DeploymentMeta.Name }} - - name: ISTIO_META_WORKLOAD_NAME - value: "{{ .DeploymentMeta.Name }}" - {{ end }} - {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} - - name: ISTIO_META_OWNER - value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} - {{- end}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - # grpc uses xds:/// to resolve – no need to resolve VIP - - name: ISTIO_META_DNS_CAPTURE - value: "false" - - name: DISABLE_ENVOY - value: "true" - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} - readinessProbe: - httpGet: - path: /healthz/ready - port: 15020 - initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} - periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} - timeoutSeconds: 3 - failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} - resources: - {{ template "resources" . }} - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - - mountPath: /var/run/secrets/tokens - name: istio-token - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - mountPath: /etc/certs/ - name: istio-certs - readOnly: true - {{- end }} - - name: istio-podinfo - mountPath: /etc/istio/pod - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} - {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 6 }} - {{ end }} - {{- end }} - {{- range $index, $container := .Spec.Containers }} - {{ if not (eq $container.Name "istio-proxy") }} - - name: {{ $container.Name }} - env: - - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" - value: "true" - - name: "GRPC_XDS_BOOTSTRAP" - value: "/etc/istio/proxy/grpc-bootstrap.json" - volumeMounts: - - mountPath: /var/lib/istio/data - name: istio-data - # UDS channel between istioagent and gRPC client for XDS/SDS - - mountPath: /etc/istio/proxy - name: istio-xds - {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- end }} - {{- end }} - volumes: - - emptyDir: - name: workload-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else }} - - emptyDir: - name: workload-certs - {{- end }} - {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} - - name: custom-bootstrap-volume - configMap: - name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-xds - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.mountMtlsCerts }} - # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - - name: istio-certs - secret: - optional: true - {{ if eq .Spec.ServiceAccountName "" }} - secretName: istio.default - {{ else -}} - secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} - {{ end -}} - {{- end }} - {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} - {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} - - name: "{{ $index }}" - {{ toYaml $value | indent 4 }} - {{ end }} - {{ end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - waypoint: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": "{{.Name}}" - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "istio.io/dataplane-mode" "none" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-mesh-controller" - ) | nindent 8}} - spec: - {{- if .Values.global.waypoint.affinity }} - affinity: - {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.topologySpreadConstraints }} - topologySpreadConstraints: - {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.nodeSelector }} - nodeSelector: - {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} - {{- end }} - {{- if .Values.global.waypoint.tolerations }} - tolerations: - {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} - {{- end }} - terminationGracePeriodSeconds: 2 - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - args: - - proxy - - waypoint - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --serviceCluster - - {{.ServiceAccount}}.$(POD_NAMESPACE) - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - env: - - name: ISTIO_META_SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - {{- if .ProxyConfig.ProxyMetadata }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- end }} - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" - {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} - {{- if $network }} - - name: ISTIO_META_NETWORK - value: "{{ $network }}" - {{- end }} - - name: ISTIO_META_INTERCEPTION_MODE - value: REDIRECT - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName}} - - name: ISTIO_META_OWNER - value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- if .Values.global.waypoint.resources }} - resources: - {{- toYaml .Values.global.waypoint.resources | nindent 10 }} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - securityContext: - privileged: false - {{- if not (eq .Values.global.platform "openshift") }} - runAsGroup: 1337 - runAsUser: 1337 - {{- end }} - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - capabilities: - drop: - - ALL - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} - {{- end }} - volumeMounts: - - mountPath: /var/run/secrets/workload-spiffe-uds - name: workload-socket - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - - mountPath: /var/lib/istio/data - name: istio-data - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - mountPath: /etc/istio/pod - name: istio-podinfo - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: - medium: Memory - name: istio-envoy - - emptyDir: - medium: Memory - name: go-proxy-envoy - - emptyDir: {} - name: istio-data - - emptyDir: {} - name: go-proxy-data - - downwardAPI: - items: - - fieldRef: - fieldPath: metadata.labels - path: labels - - fieldRef: - fieldPath: metadata.annotations - path: annotations - name: istio-podinfo - - name: istio-token - projected: - sources: - - serviceAccountToken: - audience: istio-ca - expirationSeconds: 43200 - path: istio-token - - configMap: - name: istio-ca-root-cert - name: istiod-ca-cert - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap - (strdict "networking.istio.io/traffic-distribution" "PreferClose") - (omit .InfrastructureAnnotations - "kubectl.kubernetes.io/last-applied-configuration" - "gateway.istio.io/name-override" - "gateway.istio.io/service-account" - "gateway.istio.io/controller-version" - ) | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": "{{.Name}}" - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- - kube-gateway: | - apiVersion: v1 - kind: ServiceAccount - metadata: - name: {{.ServiceAccount | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - {{- if ge .KubeVersion 128 }} - # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: "{{.Name}}" - uid: "{{.UID}}" - {{- end }} - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - annotations: - {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 4 }} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: "{{.UID}}" - spec: - selector: - matchLabels: - "{{.GatewayNameLabel}}": {{.Name}} - template: - metadata: - annotations: - {{- toJsonMap - (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") - (strdict "istio.io/rev" (.Revision | default "default")) - (strdict - "prometheus.io/path" "/stats/prometheus" - "prometheus.io/port" "15020" - "prometheus.io/scrape" "true" - ) | nindent 8 }} - labels: - {{- toJsonMap - (strdict - "sidecar.istio.io/inject" "false" - "service.istio.io/canonical-name" .DeploymentName - "service.istio.io/canonical-revision" "latest" - ) - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - "gateway.istio.io/managed" "istio.io-gateway-controller" - ) | nindent 8 }} - spec: - securityContext: - {{- if .Values.gateways.securityContext }} - {{- toYaml .Values.gateways.securityContext | nindent 8 }} - {{- else }} - sysctls: - - name: net.ipv4.ip_unprivileged_port_start - value: "0" - {{- if .Values.gateways.seccompProfile }} - seccompProfile: - {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} - {{- end }} - {{- end }} - serviceAccountName: {{.ServiceAccount | quote}} - containers: - - name: istio-proxy - {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} - image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" - {{- else }} - image: "{{ .ProxyImage }}" - {{- end }} - {{- if .Values.global.proxy.resources }} - resources: - {{- toYaml .Values.global.proxy.resources | nindent 10 }} - {{- end }} - {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} - securityContext: - capabilities: - drop: - - ALL - allowPrivilegeEscalation: false - privileged: false - readOnlyRootFilesystem: true - runAsUser: {{ .ProxyUID | default "1337" }} - runAsGroup: {{ .ProxyGID | default "1337" }} - runAsNonRoot: true - ports: - - containerPort: 15020 - name: metrics - protocol: TCP - - containerPort: 15021 - name: status-port - protocol: TCP - - containerPort: 15090 - protocol: TCP - name: http-envoy-prom - args: - - proxy - - router - - --domain - - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} - - --proxyLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} - - --proxyComponentLogLevel - - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} - - --log_output_level - - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} - {{- if .Values.global.sts.servicePort }} - - --stsPort={{ .Values.global.sts.servicePort }} - {{- end }} - {{- if .Values.global.logAsJson }} - - --log_as_json - {{- end }} - {{- if .Values.global.proxy.lifecycle }} - lifecycle: - {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} - {{- end }} - env: - - name: PILOT_CERT_PROVIDER - value: {{ .Values.global.pilotCertProvider }} - - name: CA_ADDR - {{- if .Values.global.caAddress }} - value: {{ .Values.global.caAddress }} - {{- else }} - value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 - {{- end }} - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: INSTANCE_IP - valueFrom: - fieldRef: - fieldPath: status.podIP - - name: SERVICE_ACCOUNT - valueFrom: - fieldRef: - fieldPath: spec.serviceAccountName - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - - name: ISTIO_CPU_LIMIT - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: PROXY_CONFIG - value: | - {{ protoToJSON .ProxyConfig }} - - name: ISTIO_META_POD_PORTS - value: "[]" - - name: ISTIO_META_APP_CONTAINERS - value: "" - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - resource: limits.memory - - name: GOMAXPROCS - valueFrom: - resourceFieldRef: - resource: limits.cpu - - name: ISTIO_META_CLUSTER_ID - value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" - - name: ISTIO_META_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: ISTIO_META_INTERCEPTION_MODE - value: "{{ .ProxyConfig.InterceptionMode.String }}" - {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} - - name: ISTIO_META_NETWORK - value: {{.|quote}} - {{- end }} - - name: ISTIO_META_WORKLOAD_NAME - value: {{.DeploymentName|quote}} - - name: ISTIO_META_OWNER - value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" - {{- if .Values.global.meshID }} - - name: ISTIO_META_MESH_ID - value: "{{ .Values.global.meshID }}" - {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: ISTIO_META_MESH_ID - value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" - {{- end }} - {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} - - name: TRUST_DOMAIN - value: "{{ . }}" - {{- end }} - {{- range $key, $value := .ProxyConfig.ProxyMetadata }} - - name: {{ $key }} - value: "{{ $value }}" - {{- end }} - {{- with (index .InfrastructureLabels "topology.istio.io/network") }} - - name: ISTIO_META_REQUESTED_NETWORK_VIEW - value: {{.|quote}} - {{- end }} - startupProbe: - failureThreshold: 30 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 1 - readinessProbe: - failureThreshold: 4 - httpGet: - path: /healthz/ready - port: 15021 - scheme: HTTP - initialDelaySeconds: 0 - periodSeconds: 15 - successThreshold: 1 - timeoutSeconds: 1 - volumeMounts: - - name: workload-socket - mountPath: /var/run/secrets/workload-spiffe-uds - - name: credential-socket - mountPath: /var/run/secrets/credential-uds - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - mountPath: /var/run/secrets/workload-spiffe-credentials - readOnly: true - {{- else }} - - name: workload-certs - mountPath: /var/run/secrets/workload-spiffe-credentials - {{- end }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - mountPath: /var/run/secrets/istio - name: istiod-ca-cert - {{- end }} - - mountPath: /var/lib/istio/data - name: istio-data - # SDS channel between istioagent and Envoy - - mountPath: /etc/istio/proxy - name: istio-envoy - - mountPath: /var/run/secrets/tokens - name: istio-token - - name: istio-podinfo - mountPath: /etc/istio/pod - volumes: - - emptyDir: {} - name: workload-socket - - emptyDir: {} - name: credential-socket - {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} - - name: gke-workload-certificate - csi: - driver: workloadcertificates.security.cloud.google.com - {{- else}} - - emptyDir: {} - name: workload-certs - {{- end }} - # SDS channel between istioagent and Envoy - - emptyDir: - medium: Memory - name: istio-envoy - - name: istio-data - emptyDir: {} - - name: istio-podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "annotations" - fieldRef: - fieldPath: metadata.annotations - - name: istio-token - projected: - sources: - - serviceAccountToken: - path: istio-token - expirationSeconds: 43200 - audience: {{ .Values.global.sds.token.aud }} - {{- if eq .Values.global.pilotCertProvider "istiod" }} - - name: istiod-ca-cert - configMap: - name: istio-ca-root-cert - {{- end }} - {{- if .Values.global.imagePullSecrets }} - imagePullSecrets: - {{- range .Values.global.imagePullSecrets }} - - name: {{ . }} - {{- end }} - {{- end }} - --- - apiVersion: v1 - kind: Service - metadata: - annotations: - {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} - labels: - {{- toJsonMap - .InfrastructureLabels - (strdict - "gateway.networking.k8s.io/gateway-name" .Name - ) | nindent 4 }} - name: {{.DeploymentName | quote}} - namespace: {{.Namespace | quote}} - ownerReferences: - - apiVersion: gateway.networking.k8s.io/v1beta1 - kind: Gateway - name: {{.Name}} - uid: {{.UID}} - spec: - ipFamilyPolicy: PreferDualStack - ports: - {{- range $key, $val := .Ports }} - - name: {{ $val.Name | quote }} - port: {{ $val.Port }} - protocol: TCP - appProtocol: {{ $val.AppProtocol }} - {{- end }} - selector: - "{{.GatewayNameLabel}}": {{.Name}} - {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} - loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} - {{- end }} - type: {{ .ServiceType | quote }} - --- \ No newline at end of file diff --git a/pkg/kube/inject/testdata/inputs/traffic-params.yaml.6.values.gen.yaml b/pkg/kube/inject/testdata/inputs/traffic-params.yaml.6.values.gen.yaml deleted file mode 100644 index 1c2bd2718054..000000000000 --- a/pkg/kube/inject/testdata/inputs/traffic-params.yaml.6.values.gen.yaml +++ /dev/null @@ -1,127 +0,0 @@ -{ - "gateways": { - "seccompProfile": {}, - "securityContext": {} - }, - "global": { - "caAddress": "", - "caName": "", - "certSigners": [], - "configCluster": false, - "configValidation": true, - "defaultPodDisruptionBudget": { - "enabled": true - }, - "defaultResources": { - "requests": { - "cpu": "10m" - } - }, - "externalIstiod": false, - "hub": "gcr.io/istio-testing", - "imagePullPolicy": "", - "imagePullSecrets": [], - "istioNamespace": "istio-system", - "istiod": { - "enableAnalysis": false - }, - "logAsJson": false, - "logging": { - "level": "default:info" - }, - "meshID": "", - "meshNetworks": {}, - "mountMtlsCerts": false, - "multiCluster": { - "clusterName": "", - "enabled": false - }, - "network": "", - "omitSidecarInjectorConfigMap": false, - "operatorManageWebhooks": false, - "pilotCertProvider": "istiod", - "priorityClassName": "", - "proxy": { - "autoInject": "enabled", - "clusterDomain": "cluster.local", - "componentLogLevel": "misc:error", - "excludeIPRanges": "10.96.0.2/24,10.96.0.3/24", - "excludeInboundPorts": "4,5,6", - "excludeOutboundPorts": "", - "image": "proxyv2", - "includeIPRanges": "127.0.0.1/24,10.96.0.1/24", - "includeInboundPorts": "*", - "includeOutboundPorts": "", - "logLevel": "warning", - "outlierLogPath": "", - "privileged": false, - "readinessFailureThreshold": 4, - "readinessInitialDelaySeconds": 0, - "readinessPeriodSeconds": 15, - "resources": { - "limits": { - "cpu": "2000m", - "memory": "1024Mi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "startupProbe": { - "enabled": true, - "failureThreshold": 600 - }, - "statusPort": 0, - "tracer": "none" - }, - "proxy_init": { - "forceApplyIptables": false, - "image": "proxyv2" - }, - "remotePilotAddress": "", - "sds": { - "token": { - "aud": "istio-ca" - } - }, - "sts": { - "servicePort": 0 - }, - "tag": "latest", - "variant": "", - "waypoint": { - "affinity": {}, - "nodeSelector": {}, - "resources": { - "limits": { - "cpu": "2", - "memory": "1Gi" - }, - "requests": { - "cpu": "100m", - "memory": "128Mi" - } - }, - "tolerations": [], - "topologySpreadConstraints": [] - } - }, - "pilot": { - "cni": { - "enabled": false, - "provider": "default" - } - }, - "revision": "", - "sidecarInjectorWebhook": { - "alwaysInjectSelector": [], - "defaultTemplates": [], - "enableNamespacesByDefault": false, - "injectedAnnotations": {}, - "neverInjectSelector": [], - "reinvocationPolicy": "Never", - "rewriteAppHTTPProbe": true, - "templates": {} - } -} \ No newline at end of file diff --git a/pkg/kube/inject/validate.go b/pkg/kube/inject/validate.go index 54d43528925c..d885f88d9c06 100644 --- a/pkg/kube/inject/validate.go +++ b/pkg/kube/inject/validate.go @@ -36,7 +36,6 @@ type annotationValidationFunc func(value string) error var ( AnnotationValidation = map[string]annotationValidationFunc{ annotation.SidecarInterceptionMode.Name: validateInterceptionMode, - annotation.SidecarEnableCoreDump.Name: validateBool, annotation.SidecarStatusPort.Name: validateStatusPort, annotation.SidecarStatusReadinessInitialDelaySeconds.Name: validateUInt32, annotation.SidecarStatusReadinessPeriodSeconds.Name: validateUInt32, diff --git a/pkg/kube/inject/webhook.go b/pkg/kube/inject/webhook.go index b4b209db9034..02d76f8a7372 100644 --- a/pkg/kube/inject/webhook.go +++ b/pkg/kube/inject/webhook.go @@ -218,10 +218,10 @@ func NewWebhook(p WebhookParameters) (*Webhook, error) { wh.MultiCast = mc sidecarConfig, valuesConfig, err := p.Watcher.Get() if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get initial configuration: %v", err) } if err := wh.updateConfig(sidecarConfig, valuesConfig); err != nil { - log.Errorf("failed to process webhook config: %v", err) + return nil, fmt.Errorf("failed to process webhook config: %v", err) } p.Mux.HandleFunc("/inject", wh.serveInject) @@ -247,7 +247,7 @@ func (wh *Webhook) updateConfig(sidecarConfig *Config, valuesConfig string) erro wh.Config = sidecarConfig vc, err := NewValuesConfig(valuesConfig) if err != nil { - return err + return fmt.Errorf("failed to create new values config: %v", err) } wh.valuesConfig = vc return nil @@ -264,7 +264,6 @@ const ( func moveContainer(from, to []corev1.Container, name string) ([]corev1.Container, []corev1.Container) { var container *corev1.Container for i, c := range from { - c := c if from[i].Name == name { from = slices.Delete(from, i) container = &c @@ -281,7 +280,6 @@ func modifyContainers(cl []corev1.Container, name string, modifier ContainerReor containers := []corev1.Container{} var match *corev1.Container for _, c := range cl { - c := c if c.Name != name { containers = append(containers, c) } else { diff --git a/pkg/kube/inject/webhook_test.go b/pkg/kube/inject/webhook_test.go index 945deee98fd7..5999a8d432c6 100644 --- a/pkg/kube/inject/webhook_test.go +++ b/pkg/kube/inject/webhook_test.go @@ -54,7 +54,6 @@ import ( "istio.io/istio/pkg/config/schema/gvk" "istio.io/istio/pkg/monitoring/monitortest" "istio.io/istio/pkg/test" - "istio.io/istio/pkg/test/util/file" ) const yamlSeparator = "\n---" @@ -583,43 +582,9 @@ func objectToPod(t testing.TB, obj runtime.Object) *corev1.Pod { return nil } -func readInjectionSettings(t testing.TB, fname string) (*Config, ValuesConfig, *meshconfig.MeshConfig) { - values := file.AsStringOrFail(t, filepath.Join("testdata", "inputs", fname+".values.gen.yaml")) - template := file.AsBytesOrFail(t, filepath.Join("testdata", "inputs", fname+".template.gen.yaml")) - meshc := file.AsStringOrFail(t, filepath.Join("testdata", "inputs", fname+".mesh.gen.yaml")) - - vc, err := NewValuesConfig(values) - if err != nil { - t.Fatal(err) - } - - cfg, err := UnmarshalConfig(template) - if err != nil { - t.Fatalf("failed to unmarshal injectionConfig: %v", err) - } - meshConfig, err := mesh.ApplyMeshConfig(meshc, mesh.DefaultMeshConfig()) - if err != nil { - t.Fatalf("failed to unmarshal meshconfig: %v", err) - } - - return &cfg, vc, meshConfig -} - -func cleanupOldFiles(t testing.TB) { - files, err := filepath.Glob(filepath.Join("testdata", "inputs", "*.yaml")) - if err != nil { - t.Fatal(err) - } - for _, f := range files { - if err := os.Remove(f); err != nil { - t.Fatal(err) - } - } -} - // loadInjectionSettings will render the charts using the operator, with given yaml overrides. // This allows us to fully simulate what will actually happen at run time. -func writeInjectionSettings(t testing.TB, fname string, setFlags []string, inFilePath string) { +func getInjectionSettings(t testing.TB, setFlags []string, inFilePath string) (config *Config, valuesConfig ValuesConfig, meshConfig *meshconfig.MeshConfig) { // add --set installPackagePath= setFlags = append(setFlags, "installPackagePath="+defaultInstallPackageDir(), "profile=empty", "components.pilot.enabled=true") var inFilenames []string @@ -638,7 +603,7 @@ func writeInjectionSettings(t testing.TB, fname string, setFlags []string, inFil if !ok { t.Fatalf("failed to convert %v", o) } - config, ok := data["config"].(string) + rawConfig, ok := data["config"].(string) if !ok { t.Fatalf("failed to config %v", data) } @@ -646,12 +611,18 @@ func writeInjectionSettings(t testing.TB, fname string, setFlags []string, inFil if !ok { t.Fatalf("failed to config %v", data) } - if err := os.WriteFile(filepath.Join("testdata", "inputs", fname+".values.gen.yaml"), []byte(vs), 0o644); err != nil { + vc, err := NewValuesConfig(vs) + if err != nil { t.Fatal(err) } - if err := os.WriteFile(filepath.Join("testdata", "inputs", fname+".template.gen.yaml"), []byte(config), 0o644); err != nil { - t.Fatal(err) + valuesConfig = vc + + cfg, err := UnmarshalConfig([]byte(rawConfig)) + if err != nil { + t.Fatalf("failed to unmarshal injectionConfig: %v", err) } + + config = &cfg } else if o.GetName() == "istio" && o.GetKind() == gvk.ConfigMap.Kind { data, ok := o.Object["data"].(map[string]any) if !ok { @@ -661,12 +632,15 @@ func writeInjectionSettings(t testing.TB, fname string, setFlags []string, inFil if !ok { t.Fatalf("failed to get meshconfig %v", data) } - if err := os.WriteFile(filepath.Join("testdata", "inputs", fname+".mesh.gen.yaml"), []byte(meshdata), 0o644); err != nil { - t.Fatal(err) + mcfg, err := mesh.ApplyMeshConfig(meshdata, mesh.DefaultMeshConfig()) + if err != nil { + t.Fatalf("failed to unmarshal meshconfig: %v", err) } + meshConfig = mcfg } } } + return config, valuesConfig, meshConfig } func splitYamlFile(yamlFile string, t *testing.T) [][]byte { @@ -871,7 +845,7 @@ func createWebhook(t testing.TB, cfg *Config, pcResources int) *Webhook { if err != nil { t.Fatalf("Could not marshal test injection config: %v", err) } - _, values, _ := readInjectionSettings(t, "default") + _, values, _ := getInjectionSettings(t, nil, "") var ( configFile = filepath.Join(dir, "config-file.yaml") valuesFile = filepath.Join(dir, "values-file.yaml") @@ -1037,7 +1011,7 @@ func testSideCarInjectorMetrics(mt *monitortest.MetricsTest) { } func benchmarkInjectServe(pcs int, b *testing.B) { - sidecarTemplate, _, _ := readInjectionSettings(b, "default") + sidecarTemplate, _, _ := getInjectionSettings(b, nil, "") wh := createWebhook(b, sidecarTemplate, pcs) stop := make(chan struct{}) @@ -1377,3 +1351,68 @@ func defaultInstallPackageDir() string { } return filepath.Join(wd, "../../../manifests/") } + +func TestNewWebhookConfigParsingError(t *testing.T) { + // Create a watcher that returns valid sidecarConfig but invalid valuesConfig + faultyWatcher := &FaultyWatcher{ + sidecarConfig: &Config{}, + valuesConfig: "invalid: values: config", + } + + whParams := WebhookParameters{ + Watcher: faultyWatcher, + Port: 0, + Env: &model.Environment{}, + Mux: http.NewServeMux(), + } + + _, err := NewWebhook(whParams) + if err == nil || !strings.Contains(err.Error(), "failed to process webhook config") { + t.Fatalf("Expected error when creating webhook with faulty valuesConfig, but got: %v", err) + } +} + +// FaultyWatcher is a mock Watcher that returns predefined sidecarConfig and valuesConfig +type FaultyWatcher struct { + sidecarConfig *Config + valuesConfig string +} + +func (fw *FaultyWatcher) Run(stop <-chan struct{}) {} + +func (fw *FaultyWatcher) Get() (*Config, string, error) { + return fw.sidecarConfig, fw.valuesConfig, nil +} + +func (fw *FaultyWatcher) SetHandler(handler func(*Config, string) error) {} + +func TestNewWebhookConfigParsingSuccess(t *testing.T) { + // Create a watcher that returns valid sidecarConfig and valid valuesConfig + validValuesConfig := ` +global: + proxy: + image: proxyv2 +` + faultyWatcher := &FaultyWatcher{ + sidecarConfig: &Config{}, + valuesConfig: validValuesConfig, + } + + whParams := WebhookParameters{ + Watcher: faultyWatcher, + Port: 0, + Env: &model.Environment{ + Watcher: mesh.NewFixedWatcher(&meshconfig.MeshConfig{}), + }, + Mux: http.NewServeMux(), + } + + wh, err := NewWebhook(whParams) + if err != nil { + t.Fatalf("Expected no error when creating webhook with valid valuesConfig, but got: %v", err) + } + + if wh.valuesConfig.raw != validValuesConfig { + t.Fatalf("Expected valuesConfig to be set correctly, but got: %v", wh.valuesConfig.raw) + } +} diff --git a/pkg/kube/kclient/client.go b/pkg/kube/kclient/client.go index 722df587c4f8..279586d09505 100644 --- a/pkg/kube/kclient/client.go +++ b/pkg/kube/kclient/client.go @@ -176,7 +176,13 @@ func (n *informerClient[T]) ShutdownHandlers() { } } -func (n *informerClient[T]) AddEventHandler(h cache.ResourceEventHandler) { +type neverReady struct{} + +func (a neverReady) HasSynced() bool { + return false +} + +func (n *informerClient[T]) AddEventHandler(h cache.ResourceEventHandler) cache.ResourceEventHandlerRegistration { fh := cache.FilteringResourceEventHandler{ FilterFunc: func(obj interface{}) bool { if n.filter == nil { @@ -195,9 +201,10 @@ func (n *informerClient[T]) AddEventHandler(h cache.ResourceEventHandler) { reg, err := n.informer.AddEventHandler(fh) if err != nil { // Should only happen if its already stopped. We should exit early. - return + return neverReady{} } n.registeredHandlers = append(n.registeredHandlers, handlerRegistration{registration: reg, handler: h}) + return reg } func (n *informerClient[T]) HasSynced() bool { @@ -215,6 +222,10 @@ func (n *informerClient[T]) HasSynced() bool { return true } +func (n *informerClient[T]) HasSyncedIgnoringHandlers() bool { + return n.informer.HasSynced() +} + func (n *informerClient[T]) List(namespace string, selector klabels.Selector) []T { var res []T err := cache.ListAllByNamespace(n.informer.GetIndexer(), namespace, selector, func(i any) { @@ -264,7 +275,7 @@ func New[T controllers.ComparableObject](c kube.Client) Client[T] { // Use with caution. func NewFiltered[T controllers.ComparableObject](c kube.Client, filter Filter) Client[T] { gvr := types.MustToGVR[T](types.MustGVKFromType[T]()) - inf := kubeclient.GetInformerFiltered[T](c, ToOpts(c, gvr, filter)) + inf := kubeclient.GetInformerFiltered[T](c, ToOpts(c, gvr, filter), gvr) return &fullClient[T]{ writeClient: writeClient[T]{client: c}, Informer: newInformerClient[T](gvr, inf, filter), @@ -291,7 +302,7 @@ func NewDelayedInformer[T controllers.ComparableObject]( inf := func() informerfactory.StartableInformer { opts := ToOpts(c, gvr, filter) opts.InformerType = informerType - return kubeclient.GetInformerFilteredFromGVR(c, opts, gvr) + return kubeclient.GetInformerFiltered[T](c, opts, gvr) } return newDelayedInformer[T](gvr, inf, delay, filter) } diff --git a/pkg/kube/kclient/client_test.go b/pkg/kube/kclient/client_test.go index a771461ed785..3732a0f8b9ba 100644 --- a/pkg/kube/kclient/client_test.go +++ b/pkg/kube/kclient/client_test.go @@ -15,6 +15,7 @@ package kclient_test import ( + "context" "fmt" "reflect" "strings" @@ -28,6 +29,7 @@ import ( klabels "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes/fake" k8stesting "k8s.io/client-go/testing" @@ -35,10 +37,13 @@ import ( meshconfig "istio.io/api/mesh/v1alpha1" istioclient "istio.io/client-go/pkg/apis/extensions/v1alpha1" istionetclient "istio.io/client-go/pkg/apis/networking/v1" + oldistionetclient "istio.io/client-go/pkg/apis/networking/v1alpha3" "istio.io/istio/pilot/pkg/features" "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/mesh" + "istio.io/istio/pkg/config/schema/gvk" "istio.io/istio/pkg/config/schema/gvr" + "istio.io/istio/pkg/config/schema/kubeclient" "istio.io/istio/pkg/kube" "istio.io/istio/pkg/kube/controllers" "istio.io/istio/pkg/kube/kclient" @@ -197,6 +202,46 @@ func TestSwappingClient(t *testing.T) { }) } +func TestDelayedClientWithRegisteredType(t *testing.T) { + kubeclient.Register[*oldistionetclient.DestinationRule]( + gvr.DestinationRule_v1beta1, + gvk.DestinationRule_v1beta1.Kubernetes(), + func(c kubeclient.ClientGetter, namespace string, o metav1.ListOptions) (runtime.Object, error) { + // HACK: we can't use clienttest.NewWriter with the old struct + return &oldistionetclient.DestinationRuleList{ + Items: []*oldistionetclient.DestinationRule{{ + ObjectMeta: metav1.ObjectMeta{Name: "fake-item", Namespace: "test-ns"}, + }}, + }, nil + }, + func(c kubeclient.ClientGetter, namespace string, o metav1.ListOptions) (watch.Interface, error) { + return c.Istio().NetworkingV1beta1().DestinationRules(namespace).Watch(context.Background(), o) + }, + ) + + c := kube.NewFakeClient() + clienttest.MakeCRD(t, c, gvr.DestinationRule_v1beta1) + inf := kclient.NewDelayedInformer[*oldistionetclient.DestinationRule]( + c, + gvr.DestinationRule_v1beta1, + kubetypes.StandardInformer, + kubetypes.Filter{}, + ) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + c.RunAndWait(ctx.Done()) + kube.WaitForCacheSync("sync test", ctx.Done(), inf.HasSynced) + + items := inf.List("test-ns", klabels.Everything()) + if len(items) == 0 { + t.Fatalf("expected > 0 items, got %d", len(items)) + } + if items[0].Name != "fake-item" { + t.Fatalf("expected item name 'fake-item', got '%s'", items[0].Name) + } +} + // setup some calls to ensure we trigger the race detector, if there was a race. func constantlyAccessForRaceDetection(stop chan struct{}, wt kclient.Untyped) { for { diff --git a/pkg/kube/kclient/delayed.go b/pkg/kube/kclient/delayed.go index d72fc6a40e68..79f84cbdb2e6 100644 --- a/pkg/kube/kclient/delayed.go +++ b/pkg/kube/kclient/delayed.go @@ -36,11 +36,27 @@ type delayedClient[T controllers.ComparableObject] struct { delayed kubetypes.DelayedFilter hm sync.Mutex - handlers []cache.ResourceEventHandler + handlers []delayedHandler indexers []delayedIndex[T] started <-chan struct{} } +type delayedHandler struct { + cache.ResourceEventHandler + hasSynced delayedHandlerRegistration +} + +type delayedHandlerRegistration struct { + hasSynced *atomic.Pointer[func() bool] +} + +func (r delayedHandlerRegistration) HasSynced() bool { + if s := r.hasSynced.Load(); s != nil { + return (*s)() + } + return false +} + type delayedIndex[T any] struct { indexer *atomic.Pointer[RawIndexer] extract func(o T) []string @@ -86,14 +102,20 @@ func (s *delayedClient[T]) ListUnfiltered(namespace string, selector klabels.Sel return nil } -func (s *delayedClient[T]) AddEventHandler(h cache.ResourceEventHandler) { +func (s *delayedClient[T]) AddEventHandler(h cache.ResourceEventHandler) cache.ResourceEventHandlerRegistration { if c := s.inf.Load(); c != nil { - (*c).AddEventHandler(h) - } else { - s.hm.Lock() - defer s.hm.Unlock() - s.handlers = append(s.handlers, h) + return (*c).AddEventHandler(h) } + s.hm.Lock() + defer s.hm.Unlock() + + hasSynced := delayedHandlerRegistration{hasSynced: new(atomic.Pointer[func() bool])} + hasSynced.hasSynced.Store(ptr.Of(s.delayed.HasSynced)) + s.handlers = append(s.handlers, delayedHandler{ + ResourceEventHandler: h, + hasSynced: hasSynced, + }) + return hasSynced } func (s *delayedClient[T]) HasSynced() bool { @@ -106,6 +128,16 @@ func (s *delayedClient[T]) HasSynced() bool { return hs } +func (s *delayedClient[T]) HasSyncedIgnoringHandlers() bool { + if c := s.inf.Load(); c != nil { + return (*c).HasSyncedIgnoringHandlers() + } + // If we haven't loaded the informer yet, we want to check if the delayed filter is synced. + // This ensures that at startup, we only return HasSynced=true if we are sure the CRD is not ready. + hs := s.delayed.HasSynced() + return hs +} + func (s *delayedClient[T]) ShutdownHandlers() { if c := s.inf.Load(); c != nil { (*c).ShutdownHandlers() @@ -133,7 +165,8 @@ func (s *delayedClient[T]) set(inf Informer[T]) { s.hm.Lock() defer s.hm.Unlock() for _, h := range s.handlers { - inf.AddEventHandler(h) + reg := inf.AddEventHandler(h) + h.hasSynced.hasSynced.Store(ptr.Of(reg.HasSynced)) } s.handlers = nil for _, i := range s.indexers { diff --git a/pkg/kube/kclient/index.go b/pkg/kube/kclient/index.go index 365fbf6adc79..701078d762ff 100644 --- a/pkg/kube/kclient/index.go +++ b/pkg/kube/kclient/index.go @@ -48,6 +48,8 @@ func (i index[K, O]) Lookup(k K) []O { // CreateStringIndex creates a simple index, keyed by a string, over an informer for O. This is similar to // Informer.AddIndex, but is easier to use and can be added after an informer has already started. // This is split from CreateIndex because string does not implement fmt.Stringer. +// WARNING: This index will not respect client-side filtering, and filters +// should be re-applied to the index on lookup. see https://github.com/istio/istio/issues/54280 func CreateStringIndex[O controllers.ComparableObject]( client Informer[O], extract func(o O) []string, @@ -58,6 +60,8 @@ func CreateStringIndex[O controllers.ComparableObject]( // CreateIndex creates a simple index, keyed by key K, over an informer for O. This is similar to // Informer.AddIndex, but is easier to use and can be added after an informer has already started. // Keys can be any object, but they must encode down to a *unique* value with String(). +// WARNING: This index will not respect client-side filtering, and filters +// should be re-applied to the index on lookup. see https://github.com/istio/istio/issues/54280 func CreateIndex[K fmt.Stringer, O controllers.ComparableObject]( client Informer[O], extract func(o O) []K, diff --git a/pkg/kube/kclient/interfaces.go b/pkg/kube/kclient/interfaces.go index c784d8ea377b..0441ea90c9cb 100644 --- a/pkg/kube/kclient/interfaces.go +++ b/pkg/kube/kclient/interfaces.go @@ -40,11 +40,15 @@ type Informer[T controllers.Object] interface { ListUnfiltered(namespace string, selector klabels.Selector) []T // AddEventHandler inserts a handler. The handler will be called for all Create/Update/Removals. // When ShutdownHandlers is called, the handler is removed. - AddEventHandler(h cache.ResourceEventHandler) + AddEventHandler(h cache.ResourceEventHandler) cache.ResourceEventHandlerRegistration // HasSynced returns true when the informer is initially populated and that all handlers added // via AddEventHandler have been called with the initial state. // note: this differs from a standard informer HasSynced, which does not check handlers have been called. HasSynced() bool + // HasSyncedIgnoringHandlers returns true when the underlying informer has synced. + // Warning: this ignores whether handlers are ready! HasSynced, which takes handlers into account, is recommended. + // When using this, the ResourceEventHandlerRegistration from AddEventHandler can be used to check individual handlers + HasSyncedIgnoringHandlers() bool // ShutdownHandlers terminates all handlers added by AddEventHandler. // Warning: this only applies to handlers called via AddEventHandler; any handlers directly added // to the underlying informer are not touched diff --git a/pkg/kube/krt/collection.go b/pkg/kube/krt/collection.go index ebdc73ef75a9..26424752c1f3 100644 --- a/pkg/kube/krt/collection.go +++ b/pkg/kube/krt/collection.go @@ -23,10 +23,110 @@ import ( istiolog "istio.io/istio/pkg/log" "istio.io/istio/pkg/maps" "istio.io/istio/pkg/ptr" + "istio.io/istio/pkg/queue" "istio.io/istio/pkg/slices" "istio.io/istio/pkg/util/sets" ) +type dependencyState[I any] struct { + // collectionDependencies specifies the set of collections we depend on from within the transformation functions (via Fetch). + // These are keyed by the internal uid() function on collections. + // Note this does not include `parent`, which is the *primary* dependency declared outside of transformation functions. + collectionDependencies sets.Set[collectionUID] + // Stores a map of I -> secondary dependencies (added via Fetch) + objectDependencies map[Key[I]][]*dependency + indexedDependencies map[indexedDependency]sets.Set[Key[I]] + indexedDependenciesExtractor map[collectionUID]objectKeyExtractor +} + +func (i dependencyState[I]) update(key Key[I], deps []*dependency) { + // Update the I -> Dependency mapping + i.objectDependencies[key] = deps + for _, d := range deps { + if depKey, extractor, ok := d.filter.reverseIndexKey(); ok { + k := indexedDependency{ + id: d.id, + key: depKey, + } + sets.InsertOrNew(i.indexedDependencies, k, key) + i.indexedDependenciesExtractor[d.id] = extractor + } + } +} + +func (i dependencyState[I]) delete(key Key[I]) { + old, f := i.objectDependencies[key] + if !f { + return + } + delete(i.objectDependencies, key) + for _, d := range old { + if depKey, _, ok := d.filter.reverseIndexKey(); ok { + k := indexedDependency{ + id: d.id, + key: depKey, + } + sets.DeleteCleanupLast(i.indexedDependencies, k, key) + } + } +} + +func (i dependencyState[I]) changedInputKeys(sourceCollection collectionUID, events []Event[any]) sets.Set[Key[I]] { + changedInputKeys := sets.Set[Key[I]]{} + // Check old and new + for _, ev := range events { + // We have a possibly dependant object changed. For each input object, see if it depends on the object. + // Naively, we can look through every item in this collection and check if it matches the filter. However, this is + // inefficient, especially when the dependency changes frequently and the collection is large. + // Where possible, we utilize the reverse-indexing to get the precise list of potentially changed objects. + if extractor, f := i.indexedDependenciesExtractor[sourceCollection]; f { + // We have a reverse index + for _, item := range ev.Items() { + // Find all the reverse index keys for this object. For each key we will find impacted input objects. + keys := extractor(item) + for _, key := range keys { + for iKey := range i.indexedDependencies[indexedDependency{id: sourceCollection, key: key}] { + if changedInputKeys.Contains(iKey) { + // We may have already found this item, skip it + continue + } + dependencies := i.objectDependencies[iKey] + if changed := objectChanged(dependencies, sourceCollection, ev, true); changed { + changedInputKeys.Insert(iKey) + } + } + } + } + } else { + for iKey, dependencies := range i.objectDependencies { + if changed := objectChanged(dependencies, sourceCollection, ev, false); changed { + changedInputKeys.Insert(iKey) + } + } + } + } + return changedInputKeys +} + +func objectChanged(dependencies []*dependency, sourceCollection collectionUID, ev Event[any], preFiltered bool) bool { + for _, dep := range dependencies { + id := dep.id + if id != sourceCollection { + continue + } + // For each input, we will check if it depends on this event. + // We use Items() to check both the old and new object; we will recompute if either matched + for _, item := range ev.Items() { + match := dep.filter.Matches(item, preFiltered) + if match { + // Its a match! Return now. We don't need to check all dependencies, since we just need to find if any of them changed + return true + } + } + } + return false +} + // manyCollection builds a mapping from I->O. // This can be built from transformation functions of I->*O or I->[]O; both are implemented by this same struct. // Locking used here is somewhat complex. We use two locks, mu and recomputeMu. @@ -44,26 +144,18 @@ type manyCollection[I, O any] struct { // log is a logger for the collection, with additional labels already added to identify it. log *istiolog.Scope - - // recomputeMu blocks a recomputation of I->O. - recomputeMu sync.Mutex - + // This can be acquired with blockNewEvents held, but only with strict ordering (mu inside blockNewEvents) // mu protects all items grouped below. // This is acquired for reads and writes of data. - // This can be acquired with recomputeMu held, but only with strict ordering (mu inside recomputeMu) mu sync.Mutex collectionState multiIndex[I, O] - // collectionDependencies specifies the set of collections we depend on from within the transformation functions (via Fetch). - // These are keyed by the internal uid() function on collections. - // Note this does not include `parent`, which is the *primary* dependency declared outside of transformation functions. - collectionDependencies sets.Set[collectionUID] - // Stores a map of I -> secondary dependencies (added via Fetch) - objectDependencies map[Key[I]][]*dependency + dependencyState dependencyState[I] + // internal indexes indexes []collectionIndex[I, O] // eventHandlers is a list of event handlers registered for the collection. On any changes, each will be notified. - eventHandlers *handlers[O] + eventHandlers *handlerSet[O] transformation TransformationMulti[I, O] @@ -71,6 +163,7 @@ type manyCollection[I, O any] struct { augmentation func(a any) any synced chan struct{} stop <-chan struct{} + queue queue.Instance } type collectionIndex[I, O any] struct { @@ -159,24 +252,38 @@ func (h *manyCollection[I, O]) Synced() Syncer { } // nolint: unused // (not true, its to implement an interface) -func (h *manyCollection[I, O]) dump() { - h.recomputeMu.Lock() - defer h.recomputeMu.Unlock() +func (h *manyCollection[I, O]) dump() CollectionDump { h.mu.Lock() defer h.mu.Unlock() - h.log.Errorf(">>> BEGIN DUMP") - for k, deps := range h.objectDependencies { - for _, dep := range deps { - h.log.Errorf("Dependencies for: %v: %v (%v)", k, dep.collectionName, dep.filter) + + inputs := make(map[string]InputDump, len(h.collectionState.inputs)) + for k, v := range h.collectionState.mappings { + output := make([]string, 0, len(v)) + for vv := range v { + output = append(output, string(vv)) + } + slices.Sort(output) + inputs[string(k)] = InputDump{ + Outputs: output, + Dependencies: nil, // filled later } } - for i, os := range h.collectionState.mappings { - h.log.Errorf("Input %v -> %v", i, os.UnsortedList()) + for k, deps := range h.dependencyState.objectDependencies { + depss := make([]string, 0, len(deps)) + for _, dep := range deps { + depss = append(depss, dep.collectionName) + } + slices.Sort(depss) + cur := inputs[string(k)] + cur.Dependencies = depss + inputs[string(k)] = cur } - for os, o := range h.collectionState.outputs { - h.log.Errorf("Output %v -> %v", os, o) + + return CollectionDump{ + Outputs: eraseMap(h.collectionState.outputs), + Inputs: inputs, + InputCollection: h.parent.(internalCollection[I]).name(), } - h.log.Errorf("<<< END DUMP") } // nolint: unused // (not true, its to implement an interface) @@ -210,13 +317,9 @@ func (h *manyCollection[I, O]) index(extract func(o O) []string) kclient.RawInde // onPrimaryInputEvent takes a list of I's that changed and reruns the handler over them. // This is called either when I directly changes, or if a secondary dependency changed. In this case, we compute which I's depended // on the secondary dependency, and call onPrimaryInputEvent with them -func (h *manyCollection[I, O]) onPrimaryInputEvent(items []Event[I], lock bool) { - if lock { - h.recomputeMu.Lock() - defer h.recomputeMu.Unlock() - } +func (h *manyCollection[I, O]) onPrimaryInputEvent(items []Event[I]) { // Between the events being enqueued and now, the input may have changed. Update with latest info. - // Note we now have the recomputeMu so this is safe; any futures calls will do the same so always have up-to-date information. + // Note we now have the `blockNewEvents` lock so this is safe; any futures calls will do the same so always have up-to-date information. for idx, ev := range items { iKey := GetKey(ev.Latest()) iObj := h.parent.GetKey(iKey) @@ -240,26 +343,29 @@ func (h *manyCollection[I, O]) onPrimaryInputEvent(items []Event[I], lock bool) func (h *manyCollection[I, O]) onPrimaryInputEventLocked(items []Event[I]) { var events []Event[O] recomputedResults := make([]map[Key[O]]O, len(items)) + + pendingDepStateUpdates := make(map[Key[I]]*collectionDependencyTracker[I, O], len(items)) for idx, a := range items { if a.Event == controllers.EventDelete { // handled below, with full lock... continue } i := a.Latest() - iKey := GetKey(i) + iKey := getTypedKey(i) ctx := &collectionDependencyTracker[I, O]{h, nil, iKey} - results := slices.GroupUnique(h.transformation(ctx, i), GetKey[O]) + results := slices.GroupUnique(h.transformation(ctx, i), getTypedKey[O]) recomputedResults[idx] = results - // Update the I -> Dependency mapping - h.objectDependencies[iKey] = ctx.d + // Store new dependency state, to insert in the next loop under the lock + pendingDepStateUpdates[iKey] = ctx } // Now acquire the full lock. Note we still have recomputeMu held! h.mu.Lock() + defer h.mu.Unlock() for idx, a := range items { i := a.Latest() - iKey := GetKey(i) + iKey := getTypedKey(i) if a.Event == controllers.EventDelete { for oKey := range h.collectionState.mappings[iKey] { oldRes, f := h.collectionState.outputs[oKey] @@ -282,8 +388,9 @@ func (h *manyCollection[I, O]) onPrimaryInputEventLocked(items []Event[I]) { } delete(h.collectionState.mappings, iKey) delete(h.collectionState.inputs, iKey) - delete(h.objectDependencies, iKey) + h.dependencyState.delete(iKey) } else { + h.dependencyState.update(iKey, pendingDepStateUpdates[iKey].d) results := recomputedResults[idx] newKeys := sets.New(maps.Keys(results)...) oldKeys := h.collectionState.mappings[iKey] @@ -328,20 +435,15 @@ func (h *manyCollection[I, O]) onPrimaryInputEventLocked(items []Event[I]) { } } } - h.mu.Unlock() // Short circuit if we have nothing to do if len(events) == 0 { return } - handlers := h.eventHandlers.Get() - if h.log.DebugEnabled() { - h.log.WithLabels("events", len(events), "handlers", len(handlers)).Debugf("calling handlers") - } - for _, handler := range handlers { - handler(slices.Clone(events), false) + h.log.WithLabels("events", len(events)).Debugf("calling handlers") } + h.eventHandlers.Distribute(events, false) } // WithName allows explicitly naming a controller. This is a best practice to make debugging easier. @@ -374,6 +476,13 @@ func WithStop(stop <-chan struct{}) CollectionOption { } } +// WithDebugging enables debugging of the collection +func WithDebugging(handler *DebugHandler) CollectionOption { + return func(c *collectionOptions) { + c.debugger = handler + } +} + // NewCollection transforms a Collection[I] to a Collection[O] by applying the provided transformation function. // This applies for one-to-one relationships between I and O. // For zero-to-one, use NewSingleton. For one-to-many, use NewManyCollection. @@ -407,75 +516,69 @@ func NewManyCollection[I, O any](c Collection[I], hf TransformationMulti[I, O], func newManyCollection[I, O any](cc Collection[I], hf TransformationMulti[I, O], opts collectionOptions) Collection[O] { c := cc.(internalCollection[I]) h := &manyCollection[I, O]{ - transformation: hf, - collectionName: opts.name, - id: nextUID(), - log: log.WithLabels("owner", opts.name), - parent: c, - collectionDependencies: sets.New[collectionUID](), - objectDependencies: map[Key[I]][]*dependency{}, + transformation: hf, + collectionName: opts.name, + id: nextUID(), + log: log.WithLabels("owner", opts.name), + parent: c, + dependencyState: dependencyState[I]{ + collectionDependencies: sets.New[collectionUID](), + objectDependencies: map[Key[I]][]*dependency{}, + indexedDependencies: map[indexedDependency]sets.Set[Key[I]]{}, + indexedDependenciesExtractor: map[collectionUID]func(o any) []string{}, + }, collectionState: multiIndex[I, O]{ inputs: map[Key[I]]I{}, outputs: map[Key[O]]O{}, mappings: map[Key[I]]sets.Set[Key[O]]{}, }, - eventHandlers: &handlers[O]{}, + eventHandlers: &handlerSet[O]{}, augmentation: opts.augmentation, synced: make(chan struct{}), stop: opts.stop, } - go func() { - // Wait for primary dependency to be ready - if !c.Synced().WaitUntilSynced(h.stop) { - return - } - // Now, register our handler. This will call Add() for the initial state - // Locking here is tricky. We want to make sure we don't get duplicate events. - // When we run RegisterBatch, it will trigger events for the initial state. However, other events could trigger - // while we are processing these. - // By holding the lock, we ensure we have exclusive access during this time. - h.recomputeMu.Lock() - h.eventHandlers.MarkInitialized() - handlerReg := c.RegisterBatch(func(events []Event[I], initialSync bool) { - if log.DebugEnabled() { - h.log.WithLabels("dep", "primary", "batch", len(events)). - Debugf("got event") - } - // Lock after the initial sync only - // For initial sync we explicitly hold the lock ourselves to ensure we have a broad enough critical section. - lock := !initialSync - h.onPrimaryInputEvent(events, lock) - }, true) - if !handlerReg.WaitUntilSynced(h.stop) { - h.recomputeMu.Unlock() - return - } - h.recomputeMu.Unlock() + maybeRegisterCollectionForDebugging(h, opts.debugger) + + // Create our queue. When it syncs (that is, all items that were present when Run() was called), we mark ourselves as synced. + h.queue = queue.NewWithSync(func() { close(h.synced) h.log.Infof("%v synced", h.name()) - }() + }, h.collectionName) + + // Finally, async wait for the primary to be synced. Once it has, we know it has enqueued the initial state. + // After this, we can run our queue. + // The queue will process the initial state and mark ourselves as synced (from the NewWithSync callback) + go h.runQueue() + return h } +func (h *manyCollection[I, O]) runQueue() { + c := h.parent + // Wait for primary dependency to be ready + if !c.Synced().WaitUntilSynced(h.stop) { + return + } + // Now register to our primary collection. On any event, we will enqueue the update. + syncer := c.RegisterBatch(func(o []Event[I], initialSync bool) { + h.queue.Push(func() error { + h.onPrimaryInputEvent(o) + return nil + }) + }, true) + // Wait for everything initial state to be enqueued + if !syncer.WaitUntilSynced(h.stop) { + return + } + h.queue.Run(h.stop) +} + // Handler is called when a dependency changes. We will take as inputs the item that changed. // Then we find all of our own values (I) that changed and onPrimaryInputEvent() them func (h *manyCollection[I, O]) onSecondaryDependencyEvent(sourceCollection collectionUID, events []Event[any]) { - h.recomputeMu.Lock() - defer h.recomputeMu.Unlock() // A secondary dependency changed... // Got an event. Now we need to find out who depends on it.. - changedInputKeys := sets.Set[Key[I]]{} - // Check old and new - for _, ev := range events { - // We have a possibly dependant object changed. For each input object, see if it depends on the object. - // This can be by name or the entire type. - // objectRelations stores each input key to dependency specification. - for iKey, dependencies := range h.objectDependencies { - if changed := h.objectChanged(iKey, dependencies, sourceCollection, ev); changed { - changedInputKeys.Insert(iKey) - } - } - } + changedInputKeys := h.dependencyState.changedInputKeys(sourceCollection, events) h.log.Debugf("event size %v, impacts %v objects", len(events), len(changedInputKeys)) toRun := make([]Event[I], 0, len(changedInputKeys)) @@ -483,7 +586,7 @@ func (h *manyCollection[I, O]) onSecondaryDependencyEvent(sourceCollection colle // While we could just do that manually, to re-use code, we will convert these into Event[I] and use the same logic as // we would if the input itself changed. for i := range changedInputKeys { - iObj := h.parent.GetKey(i) + iObj := h.parent.GetKey(string(i)) if iObj == nil { // Object no longer found means it has been deleted. h.log.Debugf("parent deletion %v", i) @@ -512,35 +615,13 @@ func (h *manyCollection[I, O]) onSecondaryDependencyEvent(sourceCollection colle h.onPrimaryInputEventLocked(toRun) } -func (h *manyCollection[I, O]) objectChanged(iKey Key[I], dependencies []*dependency, sourceCollection collectionUID, ev Event[any]) bool { - for _, dep := range dependencies { - id := dep.id - if id != sourceCollection { - continue - } - // For each input, we will check if it depends on this event. - // We use Items() to check both the old and new object; we will recompute if either matched - for _, item := range ev.Items() { - match := dep.filter.Matches(item, false) - if h.log.DebugEnabled() { - h.log.WithLabels("item", iKey, "match", match).Debugf("dependency change for collection %T", sourceCollection) - } - if match { - // Its a match! Return now. We don't need to check all dependencies, since we just need to find if any of them changed - return true - } - } - } - return false -} - func (h *manyCollection[I, O]) _internalHandler() { } -func (h *manyCollection[I, O]) GetKey(k Key[O]) (res *O) { +func (h *manyCollection[I, O]) GetKey(k string) (res *O) { h.mu.Lock() defer h.mu.Unlock() - rf, f := h.collectionState.outputs[k] + rf, f := h.collectionState.outputs[Key[O](k)] if f { return &rf } @@ -558,36 +639,27 @@ func (h *manyCollection[I, O]) Register(f func(o Event[O])) Syncer { } func (h *manyCollection[I, O]) RegisterBatch(f func(o []Event[O], initialSync bool), runExistingState bool) Syncer { - if runExistingState { - h.recomputeMu.Lock() - defer h.recomputeMu.Unlock() - } - initialized := !h.eventHandlers.Insert(f) - if initialized && runExistingState { - // Already started. Pause everything, and run through the handler. - h.mu.Lock() - events := make([]Event[O], 0, len(h.collectionState.outputs)) - for _, o := range h.collectionState.outputs { - o := o - events = append(events, Event[O]{ - New: &o, - Event: controllers.EventAdd, - }) - } - h.mu.Unlock() - if len(events) > 0 { - if log.DebugEnabled() { - h.log.WithLabels("items", len(events)).Debugf("call handler with initial state") - } - f(events, true) - } - // We handle events in sequence here, so its always synced at this point/ - return alwaysSynced{} - } - return channelSyncer{ - name: h.collectionName + " handler", - synced: h.synced, + if !runExistingState { + // If we don't to run the initial state this is simple, we just register the handler. + return h.eventHandlers.Insert(f, h.Synced(), nil, h.stop) + } + // We need to run the initial state, but we don't want to get duplicate events. + // We should get "ADD initialObject1, ADD initialObjectN, UPDATE someLaterUpdate" without mixing the initial ADDs + // To do this we block any new event processing + // Get initial state + h.mu.Lock() + defer h.mu.Unlock() + + events := make([]Event[O], 0, len(h.collectionState.outputs)) + for _, o := range h.collectionState.outputs { + events = append(events, Event[O]{ + New: &o, + Event: controllers.EventAdd, + }) } + + // Send out all the initial objects to the handler. We will then unlock the new events so it gets the future updates. + return h.eventHandlers.Insert(f, h.Synced(), events, h.stop) } func (h *manyCollection[I, O]) name() string { @@ -621,17 +693,20 @@ func (i *collectionDependencyTracker[I, O]) name() string { func (i *collectionDependencyTracker[I, O]) registerDependency( d *dependency, syncer Syncer, - register func(f erasedEventHandler), + register func(f erasedEventHandler) Syncer, ) { i.d = append(i.d, d) // For any new collections we depend on, start watching them if its the first time we have watched them. - if !i.collectionDependencies.InsertContains(d.id) { + if !i.dependencyState.collectionDependencies.InsertContains(d.id) { i.log.WithLabels("collection", d.collectionName).Debugf("register new dependency") syncer.WaitUntilSynced(i.stop) register(func(o []Event[any], initialSync bool) { - i.onSecondaryDependencyEvent(d.id, o) - }) + i.queue.Push(func() error { + i.onSecondaryDependencyEvent(d.id, o) + return nil + }) + }).WaitUntilSynced(i.stop) } } diff --git a/pkg/kube/krt/collection_test.go b/pkg/kube/krt/collection_test.go index b88eb826eac8..b57081ad5077 100644 --- a/pkg/kube/krt/collection_test.go +++ b/pkg/kube/krt/collection_test.go @@ -34,13 +34,23 @@ import ( "istio.io/istio/pkg/util/sets" ) +// KrtOptions is a small wrapper around KRT options to make it easy to provide a common set of options to all collections +// without excessive duplication. +type KrtOptions struct { + stop chan struct{} +} + +func (k KrtOptions) WithName(n string) []krt.CollectionOption { + return []krt.CollectionOption{krt.WithDebugging(krt.GlobalDebugHandler), krt.WithStop(k.stop), krt.WithName(n)} +} + type SimplePod struct { Named Labeled IP string } -func SimplePodCollection(pods krt.Collection[*corev1.Pod]) krt.Collection[SimplePod] { +func SimplePodCollection(pods krt.Collection[*corev1.Pod], opts KrtOptions) krt.Collection[SimplePod] { return krt.NewCollection(pods, func(ctx krt.HandlerContext, i *corev1.Pod) *SimplePod { if i.Status.PodIP == "" { return nil @@ -50,7 +60,7 @@ func SimplePodCollection(pods krt.Collection[*corev1.Pod]) krt.Collection[Simple Labeled: NewLabeled(i.Labels), IP: i.Status.PodIP, } - }) + }, opts.WithName("SimplePods")...) } type SizedPod struct { @@ -58,7 +68,7 @@ type SizedPod struct { Size string } -func SizedPodCollection(pods krt.Collection[*corev1.Pod]) krt.Collection[SizedPod] { +func SizedPodCollection(pods krt.Collection[*corev1.Pod], opts KrtOptions) krt.Collection[SizedPod] { return krt.NewCollection(pods, func(ctx krt.HandlerContext, i *corev1.Pod) *SizedPod { s, f := i.Labels["size"] if !f { @@ -68,7 +78,7 @@ func SizedPodCollection(pods krt.Collection[*corev1.Pod]) krt.Collection[SizedPo Named: NewNamed(i), Size: s, } - }) + }, opts.WithName("SizedPods")...) } func NewNamed(n config.Namer) Named { @@ -104,16 +114,16 @@ type SimpleService struct { Selector map[string]string } -func SimpleServiceCollection(services krt.Collection[*corev1.Service]) krt.Collection[SimpleService] { +func SimpleServiceCollection(services krt.Collection[*corev1.Service], opts KrtOptions) krt.Collection[SimpleService] { return krt.NewCollection(services, func(ctx krt.HandlerContext, i *corev1.Service) *SimpleService { return &SimpleService{ Named: NewNamed(i), Selector: i.Spec.Selector, } - }) + }, opts.WithName("SimpleService")...) } -func SimpleServiceCollectionFromEntries(entries krt.Collection[*istioclient.ServiceEntry]) krt.Collection[SimpleService] { +func SimpleServiceCollectionFromEntries(entries krt.Collection[*istioclient.ServiceEntry], opts KrtOptions) krt.Collection[SimpleService] { return krt.NewCollection(entries, func(ctx krt.HandlerContext, i *istioclient.ServiceEntry) *SimpleService { l := i.Spec.WorkloadSelector.GetLabels() if l == nil { @@ -123,7 +133,7 @@ func SimpleServiceCollectionFromEntries(entries krt.Collection[*istioclient.Serv Named: NewNamed(i), Selector: l, } - }) + }, opts.WithName("SimpleService")...) } type SimpleEndpoint struct { @@ -137,7 +147,7 @@ func (s SimpleEndpoint) ResourceName() string { return slices.Join("/", s.Namespace+"/"+s.Service+"/"+s.Pod) } -func SimpleEndpointsCollection(pods krt.Collection[SimplePod], services krt.Collection[SimpleService]) krt.Collection[SimpleEndpoint] { +func SimpleEndpointsCollection(pods krt.Collection[SimplePod], services krt.Collection[SimpleService], opts KrtOptions) krt.Collection[SimpleEndpoint] { return krt.NewManyCollection[SimpleService, SimpleEndpoint](services, func(ctx krt.HandlerContext, svc SimpleService) []SimpleEndpoint { pods := krt.Fetch(ctx, pods, krt.FilterLabel(svc.Selector)) return slices.Map(pods, func(pod SimplePod) SimpleEndpoint { @@ -148,7 +158,7 @@ func SimpleEndpointsCollection(pods krt.Collection[SimplePod], services krt.Coll IP: pod.IP, } }) - }) + }, opts.WithName("SimpleEndpoints")...) } func init() { @@ -156,13 +166,14 @@ func init() { } func TestCollectionSimple(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} c := kube.NewFakeClient() kpc := kclient.New[*corev1.Pod](c) pc := clienttest.Wrap(t, kpc) - pods := krt.WrapClient[*corev1.Pod](kpc) - stop := test.NewStop(t) + pods := krt.WrapClient[*corev1.Pod](kpc, opts.WithName("Pods")...) c.RunAndWait(stop) - SimplePods := SimplePodCollection(pods) + SimplePods := SimplePodCollection(pods, opts) assert.Equal(t, fetcherSorted(SimplePods)(), nil) pod := &corev1.Pod{ @@ -193,6 +204,8 @@ func TestCollectionSimple(t *testing.T) { } func TestCollectionInitialState(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} c := kube.NewFakeClient( &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -210,29 +223,29 @@ func TestCollectionInitialState(t *testing.T) { Spec: corev1.ServiceSpec{Selector: map[string]string{"app": "foo"}}, }, ) - pods := krt.NewInformer[*corev1.Pod](c) - services := krt.NewInformer[*corev1.Service](c) - stop := test.NewStop(t) + pods := krt.NewInformer[*corev1.Pod](c, opts.WithName("Pods")...) + services := krt.NewInformer[*corev1.Service](c, opts.WithName("Services")...) c.RunAndWait(stop) - SimplePods := SimplePodCollection(pods) - SimpleServices := SimpleServiceCollection(services) - SimpleEndpoints := SimpleEndpointsCollection(SimplePods, SimpleServices) + SimplePods := SimplePodCollection(pods, opts) + SimpleServices := SimpleServiceCollection(services, opts) + SimpleEndpoints := SimpleEndpointsCollection(SimplePods, SimpleServices, opts) assert.Equal(t, SimpleEndpoints.Synced().WaitUntilSynced(stop), true) // Assert Equal -- not EventuallyEqual -- to ensure our WaitForCacheSync is proper assert.Equal(t, fetcherSorted(SimpleEndpoints)(), []SimpleEndpoint{{"pod", "svc", "namespace", "1.2.3.4"}}) } func TestCollectionMerged(t *testing.T) { - c := kube.NewFakeClient() - pods := krt.NewInformer[*corev1.Pod](c) - services := krt.NewInformer[*corev1.Service](c) stop := test.NewStop(t) + opts := KrtOptions{stop} + c := kube.NewFakeClient() + pods := krt.NewInformer[*corev1.Pod](c, opts.WithName("Pods")...) + services := krt.NewInformer[*corev1.Service](c, opts.WithName("Services")...) c.RunAndWait(stop) pc := clienttest.Wrap(t, kclient.New[*corev1.Pod](c)) sc := clienttest.Wrap(t, kclient.New[*corev1.Service](c)) - SimplePods := SimplePodCollection(pods) - SimpleServices := SimpleServiceCollection(services) - SimpleEndpoints := SimpleEndpointsCollection(SimplePods, SimpleServices) + SimplePods := SimplePodCollection(pods, opts) + SimpleServices := SimpleServiceCollection(services, opts) + SimpleEndpoints := SimpleEndpointsCollection(SimplePods, SimpleServices, opts) assert.Equal(t, fetcherSorted(SimpleEndpoints)(), nil) pod := &corev1.Pod{ @@ -288,12 +301,14 @@ type PodSizeCount struct { } func TestCollectionCycle(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} c := kube.NewFakeClient() - pods := krt.NewInformer[*corev1.Pod](c) - c.RunAndWait(test.NewStop(t)) + pods := krt.NewInformer[*corev1.Pod](c, opts.WithName("Pods")...) + c.RunAndWait(stop) pc := clienttest.Wrap(t, kclient.New[*corev1.Pod](c)) - SimplePods := SimplePodCollection(pods) - SizedPods := SizedPodCollection(pods) + SimplePods := SimplePodCollection(pods, opts) + SizedPods := SizedPodCollection(pods, opts) Thingys := krt.NewCollection[SimplePod, PodSizeCount](SimplePods, func(ctx krt.HandlerContext, pd SimplePod) *PodSizeCount { if _, f := pd.Labels["want-size"]; !f { return nil @@ -305,7 +320,7 @@ func TestCollectionCycle(t *testing.T) { Named: pd.Named, MatchingSizes: len(matches), } - }) + }, opts.WithName("Thingys")...) tt := assert.NewTracker[string](t) Thingys.RegisterBatch(BatchedTrackerHandler[PodSizeCount](tt), true) @@ -442,6 +457,8 @@ func fetcherSorted[T krt.ResourceNamer](c krt.Collection[T]) func() []T { } func TestCollectionMultipleFetch(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} type Result struct { Named Configs []string @@ -451,9 +468,9 @@ func TestCollectionMultipleFetch(t *testing.T) { kcc := kclient.New[*corev1.ConfigMap](c) pc := clienttest.Wrap(t, kpc) cc := clienttest.Wrap(t, kcc) - pods := krt.WrapClient[*corev1.Pod](kpc) - configMaps := krt.WrapClient[*corev1.ConfigMap](kcc) - c.RunAndWait(test.NewStop(t)) + pods := krt.WrapClient[*corev1.Pod](kpc, opts.WithName("Pods")...) + configMaps := krt.WrapClient[*corev1.ConfigMap](kcc, opts.WithName("ConfigMaps")...) + c.RunAndWait(stop) lblFoo := map[string]string{"app": "foo"} lblBar := map[string]string{"app": "bar"} @@ -468,7 +485,7 @@ func TestCollectionMultipleFetch(t *testing.T) { Named: NewNamed(i), Configs: slices.Sort(names), } - }) + }, opts.WithName("Results")...) assert.Equal(t, fetcherSorted(Results)(), nil) pod := &corev1.Pod{ diff --git a/pkg/kube/krt/conformance_test.go b/pkg/kube/krt/conformance_test.go new file mode 100644 index 000000000000..ab337a49f3c2 --- /dev/null +++ b/pkg/kube/krt/conformance_test.go @@ -0,0 +1,217 @@ +// Copyright Istio Authors +// +// Licensed 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 krt_test + +import ( + "fmt" + "math/rand" + "strings" + "testing" + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "istio.io/istio/pkg/kube" + "istio.io/istio/pkg/kube/kclient" + "istio.io/istio/pkg/kube/krt" + "istio.io/istio/pkg/slices" + "istio.io/istio/pkg/test" + "istio.io/istio/pkg/test/util/assert" +) + +type Rig[T any] interface { + krt.Collection[T] + CreateObject(key string) +} + +type informerRig struct { + krt.Collection[*corev1.ConfigMap] + client kclient.Client[*corev1.ConfigMap] +} + +func (r *informerRig) CreateObject(key string) { + ns, name, _ := strings.Cut(key, "/") + _, _ = r.client.Create(&corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns}, + }) +} + +type staticRig struct { + krt.StaticCollection[Named] +} + +func (r *staticRig) CreateObject(key string) { + ns, name, _ := strings.Cut(key, "/") + r.UpdateObject(Named{Namespace: ns, Name: name}) +} + +type joinRig struct { + krt.Collection[Named] + inner [2]krt.StaticCollection[Named] + idx int +} + +func (r *joinRig) CreateObject(key string) { + // Switch which collection we add to each time + idx := r.idx + r.idx = (r.idx + 1) % len(r.inner) + ns, name, _ := strings.Cut(key, "/") + r.inner[idx].UpdateObject(Named{Namespace: ns, Name: name}) +} + +type manyRig struct { + krt.Collection[Named] + names krt.StaticCollection[string] + namespaces krt.StaticCollection[string] +} + +func (r *manyRig) CreateObject(key string) { + // Add to our dependency collections, the collection should merge them together + ns, name, _ := strings.Cut(key, "/") + r.namespaces.UpdateObject(ns) + r.names.UpdateObject(name) +} + +// TestConformance aims to provide a 'conformance' suite for Collection implementations to ensure each collection behaves +// the same way. +// This is done by having each collection implement a small test rig that can be used to exercise various standardized paths. +// The test assumes a collection with items of any type, but with keys in the form of '/'; all current +// collection types can handle some type with this key. +func TestConformance(t *testing.T) { + t.Run("informer", func(t *testing.T) { + fc := kube.NewFakeClient() + kc := kclient.New[*corev1.ConfigMap](fc) + col := krt.WrapClient(kc, krt.WithStop(test.NewStop(t))) + rig := &informerRig{ + Collection: col, + client: kc, + } + fc.RunAndWait(test.NewStop(t)) + runConformance[*corev1.ConfigMap](t, rig) + }) + t.Run("static list", func(t *testing.T) { + col := krt.NewStaticCollection[Named](nil, krt.WithStop(test.NewStop(t))) + rig := &staticRig{ + StaticCollection: col, + } + runConformance[Named](t, rig) + }) + t.Run("join", func(t *testing.T) { + col1 := krt.NewStaticCollection[Named](nil, krt.WithStop(test.NewStop(t))) + col2 := krt.NewStaticCollection[Named](nil, krt.WithStop(test.NewStop(t))) + j := krt.JoinCollection[Named]([]krt.Collection[Named]{col1, col2}) + rig := &joinRig{ + Collection: j, + inner: [2]krt.StaticCollection[Named]{col1, col2}, + } + runConformance[Named](t, rig) + }) + t.Run("manyCollection", func(t *testing.T) { + namespaces := krt.NewStaticCollection[string](nil, krt.WithStop(test.NewStop(t))) + names := krt.NewStaticCollection[string](nil, krt.WithStop(test.NewStop(t))) + col := krt.NewManyCollection(namespaces, func(ctx krt.HandlerContext, ns string) []Named { + names := krt.Fetch[string](ctx, names) + return slices.Map(names, func(e string) Named { + return Named{Namespace: ns, Name: e} + }) + }, krt.WithStop(test.NewStop(t))) + rig := &manyRig{ + Collection: col, + namespaces: namespaces, + names: names, + } + runConformance[Named](t, rig) + }) +} + +func runConformance[T any](t *testing.T, collection Rig[T]) { + stop := test.NewStop(t) + // Collection should start empty... + assert.Equal(t, len(collection.List()), 0) + + // Register a handler at the start of the collection + earlyHandler := assert.NewTracker[string](t) + earlyHandlerSynced := collection.Register(TrackerHandler[T](earlyHandler)) + + // Ensure the collection and handler are synced + assert.Equal(t, collection.Synced().WaitUntilSynced(stop), true) + assert.Equal(t, earlyHandlerSynced.WaitUntilSynced(stop), true) + + // Create an object + collection.CreateObject("a/b") + earlyHandler.WaitOrdered("add/a/b") + assert.Equal(t, len(collection.List()), 1) + assert.Equal(t, collection.GetKey("a/b") != nil, true) + + // Now register one later + lateHandler := assert.NewTracker[string](t) + assert.Equal(t, collection.Register(TrackerHandler[T](lateHandler)).WaitUntilSynced(stop), true) + // It should get the initial state + lateHandler.WaitOrdered("add/a/b") + + // Add a new handler that blocks events. This should not block the other handlers + delayedSynced := collection.Register(func(o krt.Event[T]) { + <-stop + }) + // This should never be synced + assert.Equal(t, delayedSynced.HasSynced(), false) + + // add another object. We should get it from both handlers + collection.CreateObject("a/c") + earlyHandler.WaitOrdered("add/a/c") + lateHandler.WaitOrdered("add/a/c") + assert.Equal(t, len(collection.List()), 2) + assert.Equal(t, collection.GetKey("a/b") != nil, true) + assert.Equal(t, collection.GetKey("a/c") != nil, true) + + // Add another object. Some bad implementations could handle 1 event with a blocked handler, but not >1, so make sure we catch that + collection.CreateObject("a/d") + earlyHandler.WaitOrdered("add/a/d") + lateHandler.WaitOrdered("add/a/d") + assert.Equal(t, len(collection.List()), 3) + + // Test another handler can be added even though one is blocked + endHandler := assert.NewTracker[string](t) + endHandlerSynced := collection.Register(TrackerHandler[T](endHandler)) + assert.Equal(t, endHandlerSynced.WaitUntilSynced(stop), true) + endHandler.WaitUnordered("add/a/b", "add/a/c", "add/a/d") + + // Now, we want to test some race conditions. + // We will trigger a bunch of ADD operations, and register a handler sometime in-between + // The handler should not get any duplicates or missed events. + keys := []string{} + for n := range 20 { + keys = append(keys, fmt.Sprintf("a/%v", n)) + } + raceHandler := assert.NewTracker[string](t) + go func() { + for _, k := range keys { + collection.CreateObject(k) + } + }() + // Introduce some small jitter to help ensure we don't always just register first + // nolint: gosec // just for testing + time.Sleep(time.Microsecond * time.Duration(rand.Int31n(100))) + raceHandlerSynced := collection.Register(TrackerHandler[T](raceHandler)) + assert.Equal(t, raceHandlerSynced.WaitUntilSynced(stop), true) + want := []string{"add/a/b", "add/a/c", "add/a/d"} + for _, k := range keys { + want = append(want, fmt.Sprintf("add/%v", k)) + } + // We should get every event exactly one time + raceHandler.WaitUnordered(want...) + raceHandler.Empty() +} diff --git a/pkg/kube/krt/core.go b/pkg/kube/krt/core.go index ea4cca5dfe57..c50ab3463a9d 100644 --- a/pkg/kube/krt/core.go +++ b/pkg/kube/krt/core.go @@ -26,7 +26,7 @@ var log = istiolog.RegisterScope("krt", "") // directly. Most importantly, consumers can subscribe to events when objects change. type Collection[T any] interface { // GetKey returns an object by its key, if present. Otherwise, nil is returned. - GetKey(k Key[T]) *T + GetKey(k string) *T // List returns all objects in the collection. // Order of the list is undefined. @@ -48,6 +48,11 @@ type EventStream[T any] interface { // called. Typically, usage of Register is done internally in krt via composition of Collections with Transformations // (NewCollection, NewManyCollection, NewSingleton); however, at boundaries of the system (connecting to something not // using krt), registering directly is expected. + // Handlers have the following semantics: + // * On each event, all handlers are called. + // * Each handler has its own unbounded event queue. Slow handlers will cause this queue to accumulate, but will not block + // other handlers. + // * Events will be sent in order, and will not be dropped or deduplicated. Register(f func(o Event[T])) Syncer // Synced returns a Syncer which can be used to determine if the collection has synced. Once its synced, all dependencies have @@ -73,7 +78,7 @@ type internalCollection[T any] interface { // Uid is an internal unique ID for this collection. MUST be globally unique uid() collectionUID - dump() + dump() CollectionDump // Augment mutates an object for use in various function calls. See WithObjectAugmentation augment(any) any diff --git a/pkg/kube/krt/debug.go b/pkg/kube/krt/debug.go new file mode 100644 index 000000000000..3f461b30a0ec --- /dev/null +++ b/pkg/kube/krt/debug.go @@ -0,0 +1,81 @@ +// Copyright Istio Authors +// +// Licensed 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 krt + +import ( + "encoding/json" + "sync" +) + +// DebugHandler allows attaching a variety of collections to it and then dumping them +type DebugHandler struct { + debugCollections []DebugCollection + mu sync.RWMutex +} + +func (p *DebugHandler) MarshalJSON() ([]byte, error) { + p.mu.RLock() + defer p.mu.RUnlock() + return json.Marshal(p.debugCollections) +} + +var GlobalDebugHandler = new(DebugHandler) + +type CollectionDump struct { + // Map of output key -> output + Outputs map[string]any `json:"outputs,omitempty"` + // Name of the input collection + InputCollection string `json:"inputCollection,omitempty"` + // Map of input key -> info + Inputs map[string]InputDump `json:"inputs,omitempty"` +} +type InputDump struct { + Outputs []string `json:"outputs,omitempty"` + Dependencies []string `json:"dependencies,omitempty"` +} +type DebugCollection struct { + name string + dump func() CollectionDump +} + +func (p DebugCollection) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]any{ + "name": p.name, + "state": p.dump(), + }) +} + +// maybeRegisterCollectionForDebugging registers the collection in the debugger, if one is enabled +func maybeRegisterCollectionForDebugging[T any](c Collection[T], handler *DebugHandler) { + if handler == nil { + return + } + cc := c.(internalCollection[T]) + handler.mu.Lock() + defer handler.mu.Unlock() + handler.debugCollections = append(handler.debugCollections, DebugCollection{ + name: cc.name(), + dump: cc.dump, + }) +} + +// nolint: unused // (not true, not sure why it thinks it is!) +func eraseMap[T any](l map[Key[T]]T) map[string]any { + nm := make(map[string]any, len(l)) + for k, v := range l { + nm[string(k)] = v + } + return nm +} diff --git a/pkg/kube/krt/fetch.go b/pkg/kube/krt/fetch.go index 4c896e371671..e55c57e90dfa 100644 --- a/pkg/kube/krt/fetch.go +++ b/pkg/kube/krt/fetch.go @@ -42,13 +42,13 @@ func Fetch[T any](ctx HandlerContext, cc Collection[T], opts ...FetchOption) []T o(d) } // Important: register before we List(), so we cannot miss any events - h.registerDependency(d, c.Synced(), func(f erasedEventHandler) { + h.registerDependency(d, c.Synced(), func(f erasedEventHandler) Syncer { ff := func(o []Event[T], initialSync bool) { f(slices.Map(o, castEvent[T, any]), initialSync) } // Skip calling all the existing state for secondary dependencies, otherwise we end up with a deadlock due to // rerunning the same collection's recomputation at the same time (once for the initial event, then for the initial registration). - c.RegisterBatch(ff, false) + return c.RegisterBatch(ff, false) }) // Now we can do the real fetching @@ -59,13 +59,13 @@ func Fetch[T any](ctx HandlerContext, cc Collection[T], opts ...FetchOption) []T // If they fetch a set of keys, directly Get these. Usually this is a single resource. list = make([]T, 0, d.filter.keys.Len()) for _, k := range d.filter.keys.List() { - if i := c.GetKey(Key[T](k)); i != nil { + if i := c.GetKey(k); i != nil { list = append(list, *i) } } - } else if d.filter.listFromIndex != nil { + } else if d.filter.index != nil { // Otherwise from an index; fetch from there. Often this is a list of a namespace - list = d.filter.listFromIndex().([]T) + list = d.filter.index.list().([]T) } else { // Otherwise get everything list = c.List() diff --git a/pkg/kube/krt/filter.go b/pkg/kube/krt/filter.go index ee2920d1722b..56d0536c99d3 100644 --- a/pkg/kube/krt/filter.go +++ b/pkg/kube/krt/filter.go @@ -21,6 +21,7 @@ import ( "k8s.io/apimachinery/pkg/types" "istio.io/istio/pkg/config/labels" + "istio.io/istio/pkg/slices" "istio.io/istio/pkg/util/smallset" ) @@ -33,8 +34,30 @@ type filter struct { labels map[string]string generic func(any) bool - listFromIndex func() any - indexMatches func(any) bool + index *indexFilter +} + +type indexFilter struct { + list func() any + indexMatches func(any) bool + extractKeys objectKeyExtractor + key string +} + +type objectKeyExtractor = func(o any) []string + +func getKeyExtractor(o any) []string { + return []string{GetKey(o)} +} + +func (f *filter) reverseIndexKey() (string, objectKeyExtractor, bool) { + if f.keys.Len() == 1 { + return f.keys.List()[0], getKeyExtractor, true + } + if f.index != nil { + return f.index.key, f.index.extractKeys, true + } + return "", nil, false } func (f *filter) String() string { @@ -89,11 +112,19 @@ func FilterSelects(lbls map[string]string) FetchOption { func FilterIndex[K comparable, I any](idx Index[K, I], k K) FetchOption { return func(h *dependency) { // Index is used to pre-filter on the List, and also to match in Matches. Provide type-erased methods for both - h.filter.listFromIndex = func() any { - return idx.Lookup(k) - } - h.filter.indexMatches = func(a any) bool { - return idx.objectHasKey(a.(I), k) + h.filter.index = &indexFilter{ + list: func() any { + return idx.Lookup(k) + }, + indexMatches: func(a any) bool { + return idx.objectHasKey(a.(I), k) + }, + extractKeys: func(o any) []string { + return slices.Map(idx.extractKeys(o.(I)), func(e K) string { + return toString(e) + }) + }, + key: toString(k), } } } @@ -131,18 +162,20 @@ func (f *filter) Matches(object any, forList bool) bool { if !forList { // First, lookup directly by key. This is cheap // an empty set will match none - if !f.keys.IsNil() && !f.keys.Contains(string(GetKey[any](object))) { + if !f.keys.IsNil() && !f.keys.Contains(GetKey[any](object)) { if log.DebugEnabled() { - log.Debugf("no match key: %q vs %q", f.keys, string(GetKey[any](object))) + log.Debugf("no match key: %q vs %q", f.keys, GetKey[any](object)) } return false } // Index is also cheap, and often used to filter namespaces out. Make sure we do this early - if f.indexMatches != nil && !f.indexMatches(object) { - if log.DebugEnabled() { - log.Debugf("no match index") + if f.index != nil { + if !f.index.indexMatches(object) { + if log.DebugEnabled() { + log.Debugf("no match index") + } + return false } - return false } } diff --git a/pkg/kube/krt/helpers.go b/pkg/kube/krt/helpers.go index 2d0757c4a3e6..be01294a4696 100644 --- a/pkg/kube/krt/helpers.go +++ b/pkg/kube/krt/helpers.go @@ -24,23 +24,38 @@ import ( acmetav1 "k8s.io/client-go/applyconfigurations/meta/v1" "k8s.io/client-go/tools/cache" + "istio.io/istio/pkg/config" "istio.io/istio/pkg/kube/controllers" "istio.io/istio/pkg/ptr" ) +func getTypedKey[O any](a O) Key[O] { + return Key[O](GetKey(a)) +} + // GetKey returns the key for the provided object. // If there is none, this will panic. -func GetKey[O any](a O) Key[O] { - if k, ok := tryGetKey[O](a); ok { - return k +func GetKey[O any](a O) string { + as, ok := any(a).(string) + if ok { + return as } - - // Kubernetes types are pointers, which means our types would be double pointers - // Allow flattening - ao, ok := any(&a).(controllers.Object) + ao, ok := any(a).(controllers.Object) if ok { k, _ := cache.MetaNamespaceKeyFunc(ao) - return Key[O](k) + return k + } + ac, ok := any(a).(config.Config) + if ok { + return keyFunc(ac.Name, ac.Namespace) + } + arn, ok := any(a).(ResourceNamer) + if ok { + return arn.ResourceName() + } + ack := GetApplyConfigKey(a) + if ack != nil { + return *ack } panic(fmt.Sprintf("Cannot get Key, got %T", a)) } @@ -70,7 +85,7 @@ func (n Named) GetNamespace() string { // GetApplyConfigKey returns the key for the ApplyConfig. // If there is none, this will return nil. -func GetApplyConfigKey[O any](a O) *Key[O] { +func GetApplyConfigKey[O any](a O) *string { // Reflection is expensive; short circuit here if !strings.HasSuffix(ptr.TypeName[O](), "ApplyConfiguration") { return nil @@ -90,9 +105,9 @@ func GetApplyConfigKey[O any](a O) *Key[O] { } meta := specField.Interface().(*acmetav1.ObjectMetaApplyConfiguration) if meta.Namespace != nil && len(*meta.Namespace) > 0 { - return ptr.Of(Key[O](*meta.Namespace + "/" + *meta.Name)) + return ptr.Of(*meta.Namespace + "/" + *meta.Name) } - return ptr.Of(Key[O](*meta.Name)) + return meta.Name } // keyFunc is the internal API key function that returns "namespace"/"name" or diff --git a/pkg/kube/krt/index.go b/pkg/kube/krt/index.go index c629258a5be9..5aa5912c7a3d 100644 --- a/pkg/kube/krt/index.go +++ b/pkg/kube/krt/index.go @@ -24,6 +24,7 @@ import ( type Index[K comparable, O any] interface { Lookup(k K) []O objectHasKey(obj O, k K) bool + extractKeys(o O) []K } // NewNamespaceIndex is a small helper to index a collection by namespace @@ -63,6 +64,11 @@ func (i index[K, O]) objectHasKey(obj O, k K) bool { return false } +// nolint: unused // (not true) +func (i index[K, O]) extractKeys(o O) []K { + return i.extract(o) +} + // Lookup finds all objects matching a given key func (i index[K, O]) Lookup(k K) []O { if i.RawIndexer == nil { diff --git a/pkg/kube/krt/index_test.go b/pkg/kube/krt/index_test.go index 9bd3973c0d57..cddee38a59fe 100644 --- a/pkg/kube/krt/index_test.go +++ b/pkg/kube/krt/index_test.go @@ -32,13 +32,14 @@ import ( ) func TestIndex(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} c := kube.NewFakeClient() kpc := kclient.New[*corev1.Pod](c) pc := clienttest.Wrap(t, kpc) - pods := krt.WrapClient[*corev1.Pod](kpc) - stop := test.NewStop(t) + pods := krt.WrapClient[*corev1.Pod](kpc, opts.WithName("Pods")...) c.RunAndWait(stop) - SimplePods := SimplePodCollection(pods) + SimplePods := SimplePodCollection(pods, opts) tt := assert.NewTracker[string](t) IPIndex := krt.NewIndex[string, SimplePod](SimplePods, func(o SimplePod) []string { return []string{o.IP} @@ -89,13 +90,14 @@ func TestIndex(t *testing.T) { } func TestIndexCollection(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} c := kube.NewFakeClient() kpc := kclient.New[*corev1.Pod](c) pc := clienttest.Wrap(t, kpc) - pods := krt.WrapClient[*corev1.Pod](kpc) - stop := test.NewStop(t) + pods := krt.WrapClient[*corev1.Pod](kpc, opts.WithName("Pods")...) c.RunAndWait(stop) - SimplePods := SimplePodCollection(pods) + SimplePods := SimplePodCollection(pods, opts) tt := assert.NewTracker[string](t) IPIndex := krt.NewIndex[string, SimplePod](SimplePods, func(o SimplePod) []string { return []string{o.IP} @@ -104,7 +106,7 @@ func TestIndexCollection(t *testing.T) { pods := krt.Fetch(ctx, SimplePods, krt.FilterIndex(IPIndex, "1.2.3.5")) names := slices.Sort(slices.Map(pods, SimplePod.ResourceName)) return ptr.Of(strings.Join(names, ",")) - }) + }, opts.WithName("Collection")...) Collection.AsCollection().Synced().WaitUntilSynced(stop) fetchSorted := func(ip string) []SimplePod { return slices.SortBy(IPIndex.Lookup(ip), func(t SimplePod) string { @@ -128,7 +130,7 @@ func TestIndexCollection(t *testing.T) { pod.Status.PodIP = "1.2.3.5" pc.UpdateStatus(pod) tt.WaitUnordered("update/namespace/name") - assert.Equal(t, Collection.Get(), ptr.Of("namespace/name")) + assert.EventuallyEqual(t, Collection.Get, ptr.Of("namespace/name")) pod2 := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -139,7 +141,7 @@ func TestIndexCollection(t *testing.T) { } pc.CreateOrUpdateStatus(pod2) tt.WaitUnordered("add/namespace/name2") - assert.Equal(t, Collection.Get(), ptr.Of("namespace/name,namespace/name2")) + assert.EventuallyEqual(t, Collection.Get, ptr.Of("namespace/name,namespace/name2")) pc.Delete(pod.Name, pod.Namespace) pc.Delete(pod2.Name, pod2.Namespace) diff --git a/pkg/kube/krt/informer.go b/pkg/kube/krt/informer.go index a4569654d8cd..6bd6a0670072 100644 --- a/pkg/kube/krt/informer.go +++ b/pkg/kube/krt/informer.go @@ -27,6 +27,7 @@ import ( "istio.io/istio/pkg/kube/kubetypes" istiolog "istio.io/istio/pkg/log" "istio.io/istio/pkg/ptr" + "istio.io/istio/pkg/slices" ) type informer[I controllers.ComparableObject] struct { @@ -60,12 +61,10 @@ func (i *informer[I]) Synced() Syncer { } // nolint: unused // (not true, its to implement an interface) -func (i *informer[I]) dump() { - i.log.Errorf(">>> BEGIN DUMP") - for _, obj := range i.inf.List(metav1.NamespaceAll, klabels.Everything()) { - i.log.Errorf("%s/%s", obj.GetNamespace(), obj.GetName()) +func (i *informer[I]) dump() CollectionDump { + return CollectionDump{ + Outputs: eraseMap(slices.GroupUnique(i.inf.List(metav1.NamespaceAll, klabels.Everything()), getTypedKey)), } - i.log.Errorf("<<< END DUMP") } func (i *informer[I]) name() string { @@ -82,13 +81,13 @@ func (i *informer[I]) List() []I { return res } -func (i *informer[I]) GetKey(k Key[I]) *I { +func (i *informer[I]) GetKey(k string) *I { // ns, n := splitKeyFunc(string(k)) // Internal optimization: we know kclient will eventually lookup "ns/name" // We also have a key in this format. // Rather than split and rejoin it later, just pass it as the name // This is depending on "unstable" implementation details, but we own both libraries and tests would catch any issues. - if got := i.inf.Get(string(k), ""); !controllers.IsNil(got) { + if got := i.inf.Get(k, ""); !controllers.IsNil(got) { return &got } return nil @@ -103,15 +102,15 @@ func (i *informer[I]) RegisterBatch(f func(o []Event[I], initialSync bool), runE // Informer doesn't expose a way to do that. However, due to the runtime model of informers, this isn't a dealbreaker; // the handlers are all called async, so we don't end up with the same deadlocks we would have in the other collection types. // While this is quite kludgy, this is an internal interface so its not too bad. - if !i.eventHandlers.Insert(f) { - i.inf.AddEventHandler(informerEventHandler[I](func(o Event[I], initialSync bool) { - f([]Event[I]{o}, initialSync) - })) - } - return pollSyncer{ + synced := i.inf.AddEventHandler(informerEventHandler[I](func(o Event[I], initialSync bool) { + f([]Event[I]{o}, initialSync) + })) + base := i.Synced() + handler := pollSyncer{ name: fmt.Sprintf("%v handler", i.name()), - f: i.inf.HasSynced, + f: synced.HasSynced, } + return multiSyncer{syncers: []Syncer{base, handler}} } // nolint: unused // (not true) @@ -152,7 +151,7 @@ func informerEventHandler[I controllers.ComparableObject](handler func(o Event[I func WrapClient[I controllers.ComparableObject](c kclient.Informer[I], opts ...CollectionOption) Collection[I] { o := buildCollectionOptions(opts...) if o.name == "" { - o.name = fmt.Sprintf("NewInformer[%v]", ptr.TypeName[I]()) + o.name = fmt.Sprintf("Informer[%v]", ptr.TypeName[I]()) } h := &informer[I]{ inf: c, @@ -165,25 +164,17 @@ func WrapClient[I controllers.ComparableObject](c kclient.Informer[I], opts ...C } go func() { - // First, wait for the informer to populate - if !kube.WaitForCacheSync(o.name, o.stop, c.HasSynced) { - return - } - // Now, take all our handlers we have built up and register them... - handlers := h.eventHandlers.MarkInitialized() - for _, h := range handlers { - c.AddEventHandler(informerEventHandler[I](func(o Event[I], initialSync bool) { - h([]Event[I]{o}, initialSync) - })) - } - // Now wait for handlers to sync - if !kube.WaitForCacheSync(o.name+" handlers", o.stop, c.HasSynced) { - c.ShutdownHandlers() + defer c.ShutdownHandlers() + // First, wait for the informer to populate. We ignore handlers which have their own syncing + if !kube.WaitForCacheSync(o.name, o.stop, c.HasSyncedIgnoringHandlers) { return } close(h.synced) h.log.Infof("%v synced", h.name()) + + <-o.stop }() + maybeRegisterCollectionForDebugging(h, o.debugger) return h } diff --git a/pkg/kube/krt/informer_test.go b/pkg/kube/krt/informer_test.go index b918381260ee..4b844cc63413 100644 --- a/pkg/kube/krt/informer_test.go +++ b/pkg/kube/krt/informer_test.go @@ -34,9 +34,11 @@ import ( ) func TestNewInformer(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} c := kube.NewFakeClient() - ConfigMaps := krt.NewInformer[*corev1.ConfigMap](c) - c.RunAndWait(test.NewStop(t)) + ConfigMaps := krt.NewInformer[*corev1.ConfigMap](c, opts.WithName("ConfigMaps")...) + c.RunAndWait(stop) cmt := clienttest.NewWriter[*corev1.ConfigMap](t, c) tt := assert.NewTracker[string](t) ConfigMaps.Register(TrackerHandler[*corev1.ConfigMap](tt)) @@ -86,6 +88,8 @@ func TestNewInformer(t *testing.T) { } func TestUnregisteredTypeCollection(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} np := &v1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "netpol", @@ -104,7 +108,7 @@ func TestUnregisteredTypeCollection(t *testing.T) { return c.Kube().NetworkingV1().NetworkPolicies(namespace).Watch(context.Background(), o) }, ) - npcoll := krt.NewInformer[*v1.NetworkPolicy](c) + npcoll := krt.NewInformer[*v1.NetworkPolicy](c, opts.WithName("NetworkPolicies")...) c.RunAndWait(test.NewStop(t)) assert.Equal(t, npcoll.List(), []*v1.NetworkPolicy{np}) } diff --git a/pkg/kube/krt/internal.go b/pkg/kube/krt/internal.go index 5a4cf1c463fc..8e1699d462e8 100644 --- a/pkg/kube/krt/internal.go +++ b/pkg/kube/krt/internal.go @@ -21,11 +21,9 @@ import ( "go.uber.org/atomic" "google.golang.org/protobuf/proto" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/cache" "istio.io/api/type/v1beta1" "istio.io/istio/pkg/config" - "istio.io/istio/pkg/kube/controllers" "istio.io/istio/pkg/ptr" ) @@ -71,6 +69,12 @@ type collectionOptions struct { name string augmentation func(o any) any stop <-chan struct{} + debugger *DebugHandler +} + +type indexedDependency struct { + id collectionUID + key string } // dependency is a specific thing that can be depended on @@ -87,36 +91,10 @@ type erasedEventHandler = func(o []Event[any], initialSync bool) // This is called from Fetch to Collections, generally. type registerDependency interface { // Registers a dependency, returning true if it is finalized - registerDependency(*dependency, Syncer, func(f erasedEventHandler)) + registerDependency(*dependency, Syncer, func(f erasedEventHandler) Syncer) name() string } -// tryGetKey returns the Key for an object. If not possible, returns false -func tryGetKey[O any](a O) (Key[O], bool) { - as, ok := any(a).(string) - if ok { - return Key[O](as), true - } - ao, ok := any(a).(controllers.Object) - if ok { - k, _ := cache.MetaNamespaceKeyFunc(ao) - return Key[O](k), true - } - ac, ok := any(a).(config.Config) - if ok { - return Key[O](keyFunc(ac.Name, ac.Namespace)), true - } - arn, ok := any(a).(ResourceNamer) - if ok { - return Key[O](arn.ResourceName()), true - } - ack := GetApplyConfigKey(a) - if ack != nil { - return *ack, true - } - return "", false -} - // getLabels returns the labels for an object, if possible. // Warning: this will panic if the labels is not available. func getLabels(a any) map[string]string { diff --git a/pkg/kube/krt/join.go b/pkg/kube/krt/join.go index eac8d6eda63d..6ff2371326fa 100644 --- a/pkg/kube/krt/join.go +++ b/pkg/kube/krt/join.go @@ -30,7 +30,7 @@ type join[T any] struct { synced <-chan struct{} } -func (j *join[T]) GetKey(k Key[T]) *T { +func (j *join[T]) GetKey(k string) *T { for _, c := range j.collections { if r := c.GetKey(k); r != nil { return r @@ -41,7 +41,7 @@ func (j *join[T]) GetKey(k Key[T]) *T { func (j *join[T]) List() []T { res := []T{} - found := sets.New[Key[T]]() + found := sets.New[string]() for _, c := range j.collections { for _, i := range c.List() { key := GetKey(i) @@ -79,12 +79,10 @@ func (j *join[T]) name() string { return j.collectionName } func (j *join[T]) uid() collectionUID { return j.id } // nolint: unused // (not true, its to implement an interface) -func (j *join[I]) dump() { - log.Errorf("> BEGIN DUMP (join %v)", j.collectionName) - for _, c := range j.collections { - c.dump() - } - log.Errorf("< END DUMP (join %v)", j.collectionName) +func (j *join[I]) dump() CollectionDump { + // Dump should not be used on join; instead its preferred to enroll each individual collection. Maybe reconsider + // in the future if there is a need + return CollectionDump{} } // nolint: unused // (not true) diff --git a/pkg/kube/krt/join_test.go b/pkg/kube/krt/join_test.go index 5e37a1eda3f1..49db7134bcc2 100644 --- a/pkg/kube/krt/join_test.go +++ b/pkg/kube/krt/join_test.go @@ -69,25 +69,27 @@ func TestJoinCollection(t *testing.T) { } func TestCollectionJoin(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} c := kube.NewFakeClient() - pods := krt.NewInformer[*corev1.Pod](c) - services := krt.NewInformer[*corev1.Service](c) - serviceEntries := krt.NewInformer[*istioclient.ServiceEntry](c) - c.RunAndWait(test.NewStop(t)) + pods := krt.NewInformer[*corev1.Pod](c, opts.WithName("Pods")...) + services := krt.NewInformer[*corev1.Service](c, opts.WithName("Services")...) + serviceEntries := krt.NewInformer[*istioclient.ServiceEntry](c, opts.WithName("ServiceEntrys")...) + c.RunAndWait(stop) pc := clienttest.Wrap(t, kclient.New[*corev1.Pod](c)) sc := clienttest.Wrap(t, kclient.New[*corev1.Service](c)) sec := clienttest.Wrap(t, kclient.New[*istioclient.ServiceEntry](c)) - SimplePods := SimplePodCollection(pods) + SimplePods := SimplePodCollection(pods, opts) ExtraSimplePods := krt.NewStatic(&SimplePod{ Named: Named{"namespace", "name-static"}, Labeled: Labeled{map[string]string{"app": "foo"}}, IP: "9.9.9.9", }, true) - SimpleServices := SimpleServiceCollection(services) - SimpleServiceEntries := SimpleServiceCollectionFromEntries(serviceEntries) + SimpleServices := SimpleServiceCollection(services, opts) + SimpleServiceEntries := SimpleServiceCollectionFromEntries(serviceEntries, opts) AllServices := krt.JoinCollection([]krt.Collection[SimpleService]{SimpleServices, SimpleServiceEntries}) AllPods := krt.JoinCollection([]krt.Collection[SimplePod]{SimplePods, ExtraSimplePods.AsCollection()}) - SimpleEndpoints := SimpleEndpointsCollection(AllPods, AllServices) + SimpleEndpoints := SimpleEndpointsCollection(AllPods, AllServices, opts) fetch := func() []SimpleEndpoint { return slices.SortBy(SimpleEndpoints.List(), func(s SimpleEndpoint) string { return s.ResourceName() }) @@ -165,6 +167,8 @@ func TestCollectionJoin(t *testing.T) { } func TestCollectionJoinSync(t *testing.T) { + stop := test.NewStop(t) + opts := KrtOptions{stop} c := kube.NewFakeClient(&corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: "name", @@ -173,10 +177,9 @@ func TestCollectionJoinSync(t *testing.T) { }, Status: corev1.PodStatus{PodIP: "1.2.3.4"}, }) - pods := krt.NewInformer[*corev1.Pod](c) - stop := test.NewStop(t) + pods := krt.NewInformer[*corev1.Pod](c, opts.WithName("Pods")...) c.RunAndWait(stop) - SimplePods := SimplePodCollection(pods) + SimplePods := SimplePodCollection(pods, opts) ExtraSimplePods := krt.NewStatic(&SimplePod{ Named: Named{"namespace", "name-static"}, Labeled: Labeled{map[string]string{"app": "foo"}}, diff --git a/pkg/kube/krt/processor.go b/pkg/kube/krt/processor.go new file mode 100644 index 000000000000..057f07e09ed3 --- /dev/null +++ b/pkg/kube/krt/processor.go @@ -0,0 +1,235 @@ +// Copyright Istio Authors +// +// Licensed 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 krt + +import ( + "sync" + "sync/atomic" + + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/utils/buffer" + + "istio.io/istio/pkg/slices" +) + +// handlerSet tracks a set of handlers. Handlers can be added at any time. +type handlerSet[O any] struct { + mu sync.RWMutex + handlers []*processorListener[O] + wg wait.Group +} + +func (o *handlerSet[O]) Insert(f func(o []Event[O], initialSync bool), parentSynced Syncer, initialEvents []Event[O], stopCh <-chan struct{}) Syncer { + o.mu.Lock() + l := newProcessListener(f, parentSynced, stopCh) + o.handlers = append(o.handlers, l) + o.wg.Start(l.run) + o.wg.Start(l.pop) + o.mu.Unlock() + l.send(initialEvents, true) + return l.Synced() +} + +func (o *handlerSet[O]) Distribute(events []Event[O], initialSync bool) { + o.mu.RLock() + defer o.mu.RUnlock() + for _, listener := range o.handlers { + listener.send(slices.Clone(events), initialSync) + } +} + +// Synced returns a Syncer that will wait for all registered handlers (at the time of the call!) are synced. +func (o *handlerSet[O]) Synced() Syncer { + o.mu.RLock() + syncer := multiSyncer{syncers: make([]Syncer, 0, len(o.handlers))} + for _, listener := range o.handlers { + syncer.syncers = append(syncer.syncers, listener.Synced()) + } + o.mu.RUnlock() + return syncer +} + +// processorListener is a fork of the upstream Kubernetes one. It has minimal tweaks to fit into +// our use case better, but the most important one being that processorListener is private in Kubernetes. +// +// processorListener relays notifications from a sharedProcessor to +// one ResourceEventHandler --- using two goroutines, two unbuffered +// channels, and an unbounded ring buffer. The `add(notification)` +// function sends the given notification to `addCh`. One goroutine +// runs `pop()`, which pumps notifications from `addCh` to `nextCh` +// using storage in the ring buffer while `nextCh` is not keeping up. +// Another goroutine runs `run()`, which receives notifications from +// `nextCh` and synchronously invokes the appropriate handler method. +// +// processorListener also keeps track of the adjusted requested resync +// period of the listener. +type processorListener[O any] struct { + nextCh chan any + addCh chan eventSet[O] + stop <-chan struct{} + + handler func(o []Event[O], initialSync bool) + + syncTracker *countingTracker + + // pendingNotifications is an unbounded ring buffer that holds all notifications not yet distributed. + // There is one per listener, but a failing/stalled listener will have infinite pendingNotifications + // added until we OOM. + // TODO: This is no worse than before, since reflectors were backed by unbounded DeltaFIFOs, but + // we should try to do something better. + pendingNotifications buffer.RingGrowing +} + +func newProcessListener[O any]( + handler func(o []Event[O], initialSync bool), + upstreamSyncer Syncer, + stop <-chan struct{}, +) *processorListener[O] { + bufferSize := 1024 + ret := &processorListener[O]{ + nextCh: make(chan any), + addCh: make(chan eventSet[O]), + stop: stop, + handler: handler, + syncTracker: &countingTracker{upstreamHasSynced: upstreamSyncer, synced: make(chan struct{})}, + pendingNotifications: *buffer.NewRingGrowing(bufferSize), + } + + return ret +} + +type eventSet[O any] struct { + event []Event[O] + isInInitialList bool +} + +func (p *processorListener[O]) send(event []Event[O], isInInitialList bool) { + if isInInitialList { + // The initial sync had no items to process, so we would never call syncTracker.Finish(). + // Just directly mark it as done here + if len(event) == 0 { + close(p.syncTracker.synced) + return + } + // Otherwise, mark how many items we have left to process + p.syncTracker.Start(len(event)) + } + select { + case <-p.stop: + return + case p.addCh <- eventSet[O]{event: event, isInInitialList: isInInitialList}: + } +} + +func (p *processorListener[O]) pop() { + defer utilruntime.HandleCrash() + defer close(p.nextCh) // Tell .run() to stop + + var nextCh chan<- any + var notification any + for { + select { + case <-p.stop: + return + case nextCh <- notification: + // Notification dispatched + var ok bool + notification, ok = p.pendingNotifications.ReadOne() + if !ok { // Nothing to pop + nextCh = nil // Disable this select case + } + case notificationToAdd, ok := <-p.addCh: + if !ok { + return + } + if notification == nil { // No notification to pop (and pendingNotifications is empty) + // Optimize the case - skip adding to pendingNotifications + notification = notificationToAdd + nextCh = p.nextCh + } else { // There is already a notification waiting to be dispatched + p.pendingNotifications.WriteOne(notificationToAdd) + } + } + } +} + +func (p *processorListener[O]) run() { + for { + select { + case <-p.stop: + return + case nextr, ok := <-p.nextCh: + if !ok { + return + } + next := nextr.(eventSet[O]) + p.handler(next.event, next.isInInitialList) + if next.isInInitialList { + p.syncTracker.Finished(len(next.event)) + } + } + } +} + +func (p *processorListener[O]) Synced() Syncer { + return p.syncTracker.Synced() +} + +// countingTracker helps propagate HasSynced when events are processed in +// order (i.e. via a queue). +type countingTracker struct { + count int64 + + upstreamHasSynced Syncer + synced chan struct{} +} + +// Start should be called prior to processing each key which is part of the +// initial list. +func (t *countingTracker) Start(count int) { + atomic.AddInt64(&t.count, int64(count)) +} + +// Finished should be called when finished processing a key which was part of +// the initial list. You must never call Finished() before (or without) its +// corresponding Start(), that is a logic error that could cause HasSynced to +// return a wrong value. To help you notice this should it happen, Finished() +// will panic if the internal counter goes negative. +func (t *countingTracker) Finished(count int) { + result := atomic.AddInt64(&t.count, -int64(count)) + if result < 0 { + panic("synctrack: negative counter; this logic error means HasSynced may return incorrect value") + } + if result == 0 { + close(t.synced) + } +} + +// Synced returns a syncer that responds as "Synced" when the underlying collection is synced, and the +// initial list has been processed. This relies on the source not considering +// itself synced until *after* it has delivered the notification for the last +// key, and that notification handler must have called Start. +func (t *countingTracker) Synced() Syncer { + // Call UpstreamHasSynced first: it might take a lock, which might take + // a significant amount of time, and we don't want to then act on a + // stale count value. + return multiSyncer{ + syncers: []Syncer{ + t.upstreamHasSynced, + channelSyncer{synced: t.synced, name: "tracker"}, + }, + } +} diff --git a/pkg/kube/krt/recomputetrigger.go b/pkg/kube/krt/recomputetrigger.go index 223f396ae162..51c0114e7465 100644 --- a/pkg/kube/krt/recomputetrigger.go +++ b/pkg/kube/krt/recomputetrigger.go @@ -34,8 +34,8 @@ type RecomputeTrigger struct { i *atomic.Int32 } -func NewRecomputeTrigger(startSynced bool) *RecomputeTrigger { - inner := NewStatic[int32](ptr.Of(int32(0)), startSynced) +func NewRecomputeTrigger(startSynced bool, opts ...CollectionOption) *RecomputeTrigger { + inner := NewStatic[int32](ptr.Of(int32(0)), startSynced, opts...) return &RecomputeTrigger{inner: inner, i: atomic.NewInt32(0)} } diff --git a/pkg/kube/krt/recomputetrigger_test.go b/pkg/kube/krt/recomputetrigger_test.go index 9dba2911f6fe..1bf22531b8f4 100644 --- a/pkg/kube/krt/recomputetrigger_test.go +++ b/pkg/kube/krt/recomputetrigger_test.go @@ -17,6 +17,8 @@ package krt_test import ( "testing" + "go.uber.org/atomic" + "istio.io/istio/pkg/kube/krt" "istio.io/istio/pkg/ptr" "istio.io/istio/pkg/test" @@ -26,11 +28,11 @@ import ( func TestRecomputeTrigger(t *testing.T) { rt := krt.NewRecomputeTrigger(false) col1 := krt.NewStatic(ptr.Of("foo"), true).AsCollection() - response := "foo" + response := atomic.NewString("foo") col2 := krt.NewCollection(col1, func(ctx krt.HandlerContext, i string) *string { rt.MarkDependant(ctx) - return ptr.Of(response) - }) + return ptr.Of(response.Load()) + }, krt.WithStop(test.NewStop(t))) assert.Equal(t, col2.Synced().HasSynced(), false) rt.MarkSynced() @@ -40,11 +42,11 @@ func TestRecomputeTrigger(t *testing.T) { col2.Register(TrackerHandler[string](tt)) tt.WaitOrdered("add/foo") - response = "bar" + response.Store("bar") rt.TriggerRecomputation() tt.WaitUnordered("delete/foo", "add/bar") - response = "baz" + response.Store("baz") rt.TriggerRecomputation() tt.WaitUnordered("delete/bar", "add/baz") } diff --git a/pkg/kube/krt/singleton.go b/pkg/kube/krt/singleton.go index 2fd0f2603162..f15ba28a9bb6 100644 --- a/pkg/kube/krt/singleton.go +++ b/pkg/kube/krt/singleton.go @@ -15,11 +15,13 @@ package krt import ( + "fmt" "sync/atomic" "istio.io/istio/pkg/kube/controllers" "istio.io/istio/pkg/kube/kclient" "istio.io/istio/pkg/ptr" + "istio.io/istio/pkg/slices" ) // dummyValue is a placeholder value for use with dummyCollection. @@ -35,7 +37,7 @@ type StaticSingleton[T any] interface { MarkSynced() } -func NewStatic[T any](initial *T, startSynced bool) StaticSingleton[T] { +func NewStatic[T any](initial *T, startSynced bool, opts ...CollectionOption) StaticSingleton[T] { val := new(atomic.Pointer[T]) val.Store(initial) x := &static[T]{ @@ -45,18 +47,25 @@ func NewStatic[T any](initial *T, startSynced bool) StaticSingleton[T] { eventHandlers: &handlers[T]{}, } x.synced.Store(startSynced) + o := buildCollectionOptions(opts...) + if o.name == "" { + o.name = fmt.Sprintf("Static[%v]", ptr.TypeName[T]()) + } + x.collectionName = o.name + maybeRegisterCollectionForDebugging(x, o.debugger) return collectionAdapter[T]{x} } // static represents a Collection of a single static value. This can be explicitly Set() to override it type static[T any] struct { - val *atomic.Pointer[T] - synced *atomic.Bool - id collectionUID - eventHandlers *handlers[T] + val *atomic.Pointer[T] + synced *atomic.Bool + id collectionUID + eventHandlers *handlers[T] + collectionName string } -func (d *static[T]) GetKey(k Key[T]) *T { +func (d *static[T]) GetKey(k string) *T { return d.val.Load() } @@ -88,7 +97,7 @@ func (d *static[T]) RegisterBatch(f func(o []Event[T], initialSync bool), runExi func (d *static[T]) Synced() Syncer { return pollSyncer{ - name: "static", + name: d.collectionName, f: func() bool { return d.synced.Load() }, @@ -106,8 +115,12 @@ func (d *static[T]) Set(now *T) { } // nolint: unused // (not true, its to implement an interface) -func (d *static[T]) dump() { - log.Errorf(">>> static[%v]: %+v<<<", ptr.TypeName[T](), d.val.Load()) +func (d *static[T]) dump() CollectionDump { + return CollectionDump{ + Outputs: map[string]any{ + "static": d.val.Load(), + }, + } } // nolint: unused // (not true, its to implement an interface) @@ -118,7 +131,7 @@ func (d *static[T]) augment(a any) any { // nolint: unused // (not true, its to implement an interface) func (d *static[T]) name() string { - return "static" + return d.collectionName } // nolint: unused // (not true, its to implement an interface) @@ -188,7 +201,10 @@ func NewSingleton[O any](hf TransformationEmpty[O], opts ...CollectionOption) Si // This is an internal construct exclusively for implementing the "Singleton" pattern. // This is so we can represent a singleton (a func() *O) as a collection (a func(I) *O). // dummyCollection just returns a single "I" that is ignored. - dummyCollection := NewStatic[dummyValue](&dummyValue{}, true).AsCollection() + + // Disable debugging on the internal static collection, else we end up with duplicates + staticOpts := append(slices.Clone(opts), WithDebugging(nil)) + dummyCollection := NewStatic[dummyValue](&dummyValue{}, true, staticOpts...).AsCollection() col := NewCollection[dummyValue, O](dummyCollection, func(ctx HandlerContext, _ dummyValue) *O { return hf(ctx) }, opts...) @@ -198,7 +214,9 @@ func NewSingleton[O any](hf TransformationEmpty[O], opts ...CollectionOption) Si // NewManyFromNothing is a niche Collection type that doesn't have any input dependencies. This is useful where things // only rely on out-of-band data via RecomputeTrigger, for instance. func NewManyFromNothing[O any](hf TransformationEmptyToMulti[O], opts ...CollectionOption) Collection[O] { - dummyCollection := NewStatic[dummyValue](&dummyValue{}, true).AsCollection() + // Disable debugging on the internal static collection, else we end up with duplicates + staticOpts := append(slices.Clone(opts), WithDebugging(nil)) + dummyCollection := NewStatic[dummyValue](&dummyValue{}, true, staticOpts...).AsCollection() col := NewManyCollection[dummyValue, O](dummyCollection, func(ctx HandlerContext, _ dummyValue) []O { return hf(ctx) }, opts...) diff --git a/pkg/kube/krt/singleton_test.go b/pkg/kube/krt/singleton_test.go index fce909685806..1809bc012e01 100644 --- a/pkg/kube/krt/singleton_test.go +++ b/pkg/kube/krt/singleton_test.go @@ -32,9 +32,9 @@ import ( ) func TestSingleton(t *testing.T) { - c := kube.NewFakeClient() - ConfigMaps := krt.NewInformer[*corev1.ConfigMap](c) stop := test.NewStop(t) + c := kube.NewFakeClient() + ConfigMaps := krt.NewInformer[*corev1.ConfigMap](c, krt.WithStop(stop)) c.RunAndWait(stop) cmt := clienttest.NewWriter[*corev1.ConfigMap](t, c) ConfigMapNames := krt.NewSingleton[string]( @@ -43,7 +43,7 @@ func TestSingleton(t *testing.T) { return ptr.Of(slices.Join(",", slices.Map(cms, func(c *corev1.ConfigMap) string { return config.NamespacedName(c).String() })...)) - }, + }, krt.WithStop(stop), ) ConfigMapNames.AsCollection().Synced().WaitUntilSynced(stop) tt := assert.NewTracker[string](t) diff --git a/pkg/kube/krt/static.go b/pkg/kube/krt/static.go index 3dba71d4f65e..e28dd6855e63 100644 --- a/pkg/kube/krt/static.go +++ b/pkg/kube/krt/static.go @@ -15,29 +15,110 @@ package krt import ( + "fmt" + "sync" + "istio.io/istio/pkg/kube/controllers" "istio.io/istio/pkg/kube/kclient" "istio.io/istio/pkg/maps" + "istio.io/istio/pkg/ptr" "istio.io/istio/pkg/slices" ) +type StaticCollection[T any] struct { + *staticList[T] +} + type staticList[T any] struct { - vals map[Key[T]]T - id collectionUID + mu sync.RWMutex + vals map[string]T + eventHandlers *handlerSet[T] + id collectionUID + stop <-chan struct{} + collectionName string } -func NewStaticCollection[T any](vals []T) Collection[T] { - res := map[Key[T]]T{} +func NewStaticCollection[T any](vals []T, opts ...CollectionOption) StaticCollection[T] { + o := buildCollectionOptions(opts...) + if o.name == "" { + o.name = fmt.Sprintf("Static[%v]", ptr.TypeName[T]()) + } + + res := make(map[string]T, len(vals)) for _, v := range vals { res[GetKey(v)] = v } - return &staticList[T]{ - vals: res, - id: nextUID(), + + sl := &staticList[T]{ + eventHandlers: &handlerSet[T]{}, + vals: res, + id: nextUID(), + stop: o.stop, + collectionName: o.name, + } + + return StaticCollection[T]{ + staticList: sl, + } +} + +// DeleteObject deletes an object from the collection. +func (s *staticList[T]) DeleteObject(k string) { + s.mu.Lock() + defer s.mu.Unlock() + old, f := s.vals[k] + if f { + delete(s.vals, k) + s.eventHandlers.Distribute([]Event[T]{{ + Old: &old, + Event: controllers.EventDelete, + }}, false) + } +} + +// DeleteObjects deletes all objects matching the provided filter +func (s StaticCollection[T]) DeleteObjects(filter func(obj T) bool) { + s.mu.Lock() + defer s.mu.Unlock() + var removed []Event[T] + for k, v := range s.vals { + if filter(v) { + delete(s.vals, k) + removed = append(removed, Event[T]{ + Old: &v, + Event: controllers.EventDelete, + }) + } + } + if len(removed) > 0 { + s.eventHandlers.Distribute(removed, false) } } -func (s *staticList[T]) GetKey(k Key[T]) *T { +// UpdateObject adds or updates an object into the collection. +func (s *staticList[T]) UpdateObject(obj T) { + s.mu.Lock() + defer s.mu.Unlock() + k := GetKey(obj) + old, f := s.vals[k] + s.vals[k] = obj + if f { + s.eventHandlers.Distribute([]Event[T]{{ + Old: &old, + New: &obj, + Event: controllers.EventUpdate, + }}, false) + } else { + s.eventHandlers.Distribute([]Event[T]{{ + New: &obj, + Event: controllers.EventAdd, + }}, false) + } +} + +func (s *staticList[T]) GetKey(k string) *T { + s.mu.RLock() + defer s.mu.RUnlock() if o, f := s.vals[k]; f { return &o } @@ -46,7 +127,7 @@ func (s *staticList[T]) GetKey(k Key[T]) *T { // nolint: unused // (not true, its to implement an interface) func (s *staticList[T]) name() string { - return "staticList" + return s.collectionName } // nolint: unused // (not true, its to implement an interface) @@ -55,7 +136,10 @@ func (s *staticList[T]) uid() collectionUID { } // nolint: unused // (not true, its to implement an interface) -func (s *staticList[T]) dump() { +func (s *staticList[T]) dump() CollectionDump { + return CollectionDump{ + Outputs: eraseMap(slices.GroupUnique(s.List(), getTypedKey)), + } } // nolint: unused // (not true, its to implement an interface) @@ -72,6 +156,8 @@ type staticListIndex[T any] struct { // nolint: unused // (not true) func (s staticListIndex[T]) Lookup(key string) []any { var res []any + s.parent.mu.RLock() + defer s.parent.mu.RUnlock() for _, v := range s.parent.vals { have := s.extract(v) if slices.Contains(have, key) { @@ -90,6 +176,8 @@ func (s *staticList[T]) index(extract func(o T) []string) kclient.RawIndexer { } func (s *staticList[T]) List() []T { + s.mu.RLock() + defer s.mu.RUnlock() return maps.Values(s.vals) } @@ -98,19 +186,23 @@ func (s *staticList[T]) Register(f func(o Event[T])) Syncer { } func (s *staticList[T]) Synced() Syncer { + // We are always synced in the static collection since the initial state must be provided upfront return alwaysSynced{} } func (s *staticList[T]) RegisterBatch(f func(o []Event[T], initialSync bool), runExistingState bool) Syncer { + s.mu.Lock() + defer s.mu.Unlock() + var objs []Event[T] if runExistingState { - f(slices.Map(s.List(), func(e T) Event[T] { - return Event[T]{ - New: &e, + for _, v := range s.vals { + objs = append(objs, Event[T]{ + New: &v, Event: controllers.EventAdd, - } - }), true) + }) + } } - return alwaysSynced{} + return s.eventHandlers.Insert(f, s.Synced(), objs, s.stop) } var _ internalCollection[any] = &staticList[any]{} diff --git a/pkg/kube/krt/static_test.go b/pkg/kube/krt/static_test.go new file mode 100644 index 000000000000..ceec4ceeb380 --- /dev/null +++ b/pkg/kube/krt/static_test.go @@ -0,0 +1,47 @@ +// Copyright Istio Authors +// +// Licensed 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 krt_test + +import ( + "testing" + + "istio.io/istio/pkg/kube/krt" + "istio.io/istio/pkg/test" + "istio.io/istio/pkg/test/util/assert" +) + +func TestStaticCollection(t *testing.T) { + stop := test.NewStop(t) + c := krt.NewStaticCollection[Named]([]Named{{"ns", "a"}}, krt.WithStop(stop)) + assert.Equal(t, c.Synced().HasSynced(), true, "should start synced") + assert.Equal(t, c.List(), []Named{{"ns", "a"}}) + + tracker := assert.NewTracker[string](t) + c.RegisterBatch(BatchedTrackerHandler[Named](tracker), true) + tracker.WaitOrdered("add/ns/a") + + c.UpdateObject(Named{"ns", "b"}) + tracker.WaitOrdered("add/ns/b") + + c.UpdateObject(Named{"ns", "b"}) + tracker.WaitOrdered("update/ns/b") + + tracker2 := assert.NewTracker[string](t) + c.RegisterBatch(BatchedTrackerHandler[Named](tracker2), true) + tracker2.WaitCompare(CompareUnordered("add/ns/a", "add/ns/b")) + + c.DeleteObject("ns/b") + tracker.WaitOrdered("delete/ns/b") +} diff --git a/pkg/kube/krt/sync.go b/pkg/kube/krt/sync.go index 31131f8b474f..aa7fa0eb3779 100644 --- a/pkg/kube/krt/sync.go +++ b/pkg/kube/krt/sync.go @@ -24,6 +24,7 @@ type Syncer interface { var ( _ Syncer = channelSyncer{} _ Syncer = pollSyncer{} + _ Syncer = multiSyncer{} ) type channelSyncer struct { diff --git a/pkg/kube/krt/testing.go b/pkg/kube/krt/testing.go index 6bce96f1005b..bc7c258efc2c 100644 --- a/pkg/kube/krt/testing.go +++ b/pkg/kube/krt/testing.go @@ -14,17 +14,12 @@ package krt -// Dump is a *testing* helper to dump the state of a collection, if possible, into logs. -func Dump[O any](c Collection[O]) { - c.(internalCollection[O]).dump() -} - type TestingDummyContext struct{} func (t TestingDummyContext) _internalHandler() { } -func (t TestingDummyContext) registerDependency(d *dependency, s Syncer, f func(f erasedEventHandler)) { +func (t TestingDummyContext) registerDependency(d *dependency, s Syncer, f func(f erasedEventHandler) Syncer) { } func (t TestingDummyContext) name() string { diff --git a/pkg/kube/labels/labels.go b/pkg/kube/labels/labels.go index 172dc7515696..a338ace0e830 100644 --- a/pkg/kube/labels/labels.go +++ b/pkg/kube/labels/labels.go @@ -16,7 +16,11 @@ // from Kubernetes resources. package labels -import "istio.io/istio/pkg/model" +import ( + "istio.io/api/annotation" + "istio.io/api/label" + "istio.io/istio/pkg/model" +) var ( // These are the labels that are checked for canonical service name and revision. @@ -33,6 +37,17 @@ var ( } ) +// WorkloadNameFromWorkloadEntry derives the workload name from a WorkloadEntry +func WorkloadNameFromWorkloadEntry(name string, annos map[string]string, labels map[string]string) string { + if arg, f := annos[annotation.IoIstioAutoRegistrationGroup.Name]; f { + return arg + } + if wn, f := labels[label.ServiceWorkloadName.Name]; f { + return wn + } + return name +} + // CanonicalService returns the values of the following labels from the supplied map: // - service.istio.io/canonical-name // - service.istio.io/canonical-revision diff --git a/pkg/kube/namespace/filter.go b/pkg/kube/namespace/filter.go index 9d4402b01c89..606a234174d8 100644 --- a/pkg/kube/namespace/filter.go +++ b/pkg/kube/namespace/filter.go @@ -69,12 +69,12 @@ func NewDiscoveryNamespacesFilter( f.notifyHandlers(sets.New(ns.Name), nil) } }, - UpdateFunc: func(old, new *corev1.Namespace) { + UpdateFunc: func(oldObj, newObj *corev1.Namespace) { f.lock.Lock() - membershipChanged, namespaceAdded := f.namespaceUpdatedLocked(old.ObjectMeta, new.ObjectMeta) + membershipChanged, namespaceAdded := f.namespaceUpdatedLocked(oldObj.ObjectMeta, newObj.ObjectMeta) f.lock.Unlock() if membershipChanged { - added := sets.New(new.Name) + added := sets.New(newObj.Name) var removed sets.String if !namespaceAdded { removed = added diff --git a/pkg/kube/util.go b/pkg/kube/util.go index aa3f255f1966..3b46265472a1 100644 --- a/pkg/kube/util.go +++ b/pkg/kube/util.go @@ -34,6 +34,7 @@ import ( "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd/api" + "istio.io/api/label" "istio.io/istio/pilot/pkg/config/kube/crd" "istio.io/istio/pilot/pkg/features" "istio.io/istio/pkg/config" @@ -209,7 +210,7 @@ func SetRestDefaults(config *rest.Config) *rest.Config { return config } -// CheckPodTermina returns true if the pod's phase is terminal (succeeded || failed) +// CheckPodTerminal returns true if the pod's phase is terminal (succeeded || failed) // usually used to filter cron jobs. func CheckPodTerminal(pod *corev1.Pod) bool { return pod.Status.Phase == corev1.PodFailed || pod.Status.Phase == corev1.PodSucceeded @@ -256,6 +257,19 @@ func CheckPodReady(pod *corev1.Pod) error { } } +// GetWorkloadMetaFromPod heuristically derives workload name and type metadata from the pod spec. +// This respects the workload-name override; to just use heuristics only use GetDeployMetaFromPod. +func GetWorkloadMetaFromPod(pod *corev1.Pod) (types.NamespacedName, metav1.TypeMeta) { + name, meta := GetDeployMetaFromPod(pod) + if pod == nil { + return name, meta + } + if wn, f := pod.Labels[label.ServiceWorkloadName.Name]; f { + name.Name = wn + } + return name, meta +} + // GetDeployMetaFromPod heuristically derives deployment metadata from the pod spec. func GetDeployMetaFromPod(pod *corev1.Pod) (types.NamespacedName, metav1.TypeMeta) { if pod == nil { diff --git a/pkg/log/options.go b/pkg/log/options.go index 49c69c06deef..f04a49f24243 100644 --- a/pkg/log/options.go +++ b/pkg/log/options.go @@ -187,7 +187,7 @@ func convertScopedLevel(sl string) (string, Level, error) { level, ok := stringToLevel[l] if !ok { - return "", NoneLevel, fmt.Errorf("invalid output level '%s'", sl) + return "", NoneLevel, fmt.Errorf("invalid output level '%s'", l) } return s, level, nil diff --git a/pkg/proto/merge/merge.go b/pkg/proto/merge/merge.go index 6e00addcbd09..319cd89b75cc 100644 --- a/pkg/proto/merge/merge.go +++ b/pkg/proto/merge/merge.go @@ -32,7 +32,7 @@ import ( ) type ( - MergeFunction func(dst, src protoreflect.Message) + MergeFunction func(dst, src protoreflect.Message) protoreflect.Message mergeOptions struct { customMergeFn map[protoreflect.FullName]MergeFunction } @@ -46,16 +46,10 @@ func MergeFunctionOptionFn(name protoreflect.FullName, function MergeFunction) O } } -// ReplaceMergeFn instead of merging all subfields one by one, takes src and set it to dest -var ReplaceMergeFn MergeFunction = func(dst, src protoreflect.Message) { - dst.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - dst.Clear(fd) - return true - }) - src.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - dst.Set(fd, v) - return true - }) +// ReplaceMergeFn instead of merging all subfields one by one, returns src +var ReplaceMergeFn MergeFunction = func(dst, src protoreflect.Message) protoreflect.Message { + // we can return src directly because this is a replace + return src } var options = []OptionFn{ @@ -99,7 +93,8 @@ func (o mergeOptions) mergeMessage(dst, src protoreflect.Message) { case fd.Message() != nil: mergeFn, exists := o.customMergeFn[fd.Message().FullName()] if exists { - mergeFn(dst.Mutable(fd).Message(), v.Message()) + dstV := mergeFn(dst.Mutable(fd).Message(), v.Message()) + dst.Set(fd, protoreflect.ValueOf(dstV)) } else { o.mergeMessage(dst.Mutable(fd).Message(), v.Message()) } diff --git a/pkg/proto/merge/merge_test.go b/pkg/proto/merge/merge_test.go new file mode 100644 index 000000000000..da5880aeb71e --- /dev/null +++ b/pkg/proto/merge/merge_test.go @@ -0,0 +1,39 @@ +// Copyright Istio Authors +// +// Licensed 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 merge + +import ( + "testing" + + listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" + "google.golang.org/protobuf/types/known/durationpb" + + "istio.io/istio/pkg/test/util/assert" +) + +func TestMerge(t *testing.T) { + src := &durationpb.Duration{Seconds: 123, Nanos: 456} + dst := &durationpb.Duration{Seconds: 789, Nanos: 999} + + srcListener := &listener.Listener{ListenerFiltersTimeout: src} + dstListener := &listener.Listener{ListenerFiltersTimeout: dst} + + Merge(dstListener, srcListener) + + assert.Equal(t, dstListener.ListenerFiltersTimeout, src) + + // dst duration not changed after merge + assert.Equal(t, dst, &durationpb.Duration{Seconds: 789, Nanos: 999}) +} diff --git a/pkg/queue/instance.go b/pkg/queue/instance.go index 9375fb664cfc..bb831ff39fa3 100644 --- a/pkg/queue/instance.go +++ b/pkg/queue/instance.go @@ -58,9 +58,10 @@ type queueImpl struct { closed chan struct{} closeOnce *sync.Once // initialSync indicates the queue has initially "synced". - initialSync *atomic.Bool - id string - metrics *queueMetrics + initialSync *atomic.Bool + id string + metrics *queueMetrics + syncCallback func() } // NewQueue instantiates a queue with a processing function @@ -68,6 +69,13 @@ func NewQueue(errorDelay time.Duration) Instance { return NewQueueWithID(errorDelay, rand.String(10)) } +// NewQueue instantiates a queue with a processing function +func NewWithSync(f func(), name string) Instance { + q := NewQueueWithID(time.Second, name) + q.(*queueImpl).syncCallback = f + return q +} + func NewQueueWithID(errorDelay time.Duration, name string) Instance { return &queueImpl{ delay: errorDelay, @@ -164,6 +172,9 @@ func (q *queueImpl) Run(stop <-chan struct{}) { q.Push(func() error { q.initialSync.Store(true) + if q.syncCallback != nil { + q.syncCallback() + } return nil }) for q.processNextItem() { diff --git a/pkg/queue/instance_test.go b/pkg/queue/instance_test.go index e9c55508ea6a..bea41cfe3e81 100644 --- a/pkg/queue/instance_test.go +++ b/pkg/queue/instance_test.go @@ -38,8 +38,6 @@ func TestOrdering(t *testing.T) { mu := sync.Mutex{} out := make([]int, 0) for i := 0; i < numValues; i++ { - i := i - q.Push(func() error { mu.Lock() out = append(out, i) diff --git a/pkg/revisions/tag_watcher.go b/pkg/revisions/tag_watcher.go index 167da30e6962..bddc4c2e795e 100644 --- a/pkg/revisions/tag_watcher.go +++ b/pkg/revisions/tag_watcher.go @@ -62,7 +62,7 @@ func NewTagWatcher(client kube.Client, revision string) TagWatcher { p.index = kclient.CreateStringIndex(p.webhooks, func(o *admissionregistrationv1.MutatingWebhookConfiguration) []string { rev := o.GetLabels()[label.IoIstioRev.Name] - if rev == "" { + if rev == "" || !isTagWebhook(o) { return nil } return []string{rev} diff --git a/pkg/revisions/tag_watcher_test.go b/pkg/revisions/tag_watcher_test.go index 4f1375804f44..99f1a9e45e17 100644 --- a/pkg/revisions/tag_watcher_test.go +++ b/pkg/revisions/tag_watcher_test.go @@ -44,6 +44,7 @@ func TestTagWatcher(t *testing.T) { track.WaitOrdered("revision") assert.Equal(t, tw.GetMyTags(), sets.New("revision")) + whs.Create(makeRevision("revision")) whs.Create(makeTag("revision", "tag-foo")) track.WaitOrdered("revision,tag-foo") assert.Equal(t, tw.GetMyTags(), sets.New("revision", "tag-foo")) @@ -77,3 +78,15 @@ func makeTag(revision string, tg string) *admissionregistrationv1.MutatingWebhoo }, } } + +func makeRevision(revision string) *admissionregistrationv1.MutatingWebhookConfiguration { + return &admissionregistrationv1.MutatingWebhookConfiguration{ + TypeMeta: metav1.TypeMeta{}, + ObjectMeta: metav1.ObjectMeta{ + Name: revision, + Labels: map[string]string{ + label.IoIstioRev.Name: revision, + }, + }, + } +} diff --git a/pkg/slices/slices.go b/pkg/slices/slices.go index a65dc3737ae4..eb6be069b676 100644 --- a/pkg/slices/slices.go +++ b/pkg/slices/slices.go @@ -178,6 +178,18 @@ func FilterInPlace[E any](s []E, keep func(E) bool) []E { return s[:i] } +func FilterDuplicates[E comparable](s []E) []E { + seen := make(map[E]struct{}) + result := make([]E, 0) + for _, item := range s { + if _, ok := seen[item]; !ok { + result = append(result, item) + seen[item] = struct{}{} + } + } + return result +} + // FilterDuplicatesPresorted retains all unique elements in []E. // The slices MUST be pre-sorted. func FilterDuplicatesPresorted[E comparable](s []E) []E { @@ -253,7 +265,6 @@ func MapFilter[E any, O any](s []E, f func(E) *O) []O { func Reference[E any](s []E) []*E { res := make([]*E, 0, len(s)) for _, v := range s { - v := v res = append(res, &v) } return res diff --git a/pkg/test/echo/proto/echo.pb.go b/pkg/test/echo/proto/echo.pb.go index c899112c2ae3..915eac6955c3 100644 --- a/pkg/test/echo/proto/echo.pb.go +++ b/pkg/test/echo/proto/echo.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc (unknown) // source: test/echo/proto/echo.proto diff --git a/pkg/test/echo/server/forwarder/http.go b/pkg/test/echo/server/forwarder/http.go index 73beac1765e7..c3e0302505b4 100644 --- a/pkg/test/echo/server/forwarder/http.go +++ b/pkg/test/echo/server/forwarder/http.go @@ -74,13 +74,13 @@ func (c *httpProtocol) ForwardEcho(ctx context.Context, cfg *Config) (*proto.For } func newHTTP3TransportGetter(cfg *Config) (httpTransportGetter, func()) { - newConn := func() *http3.RoundTripper { - return &http3.RoundTripper{ + newConn := func() *http3.Transport { + return &http3.Transport{ TLSClientConfig: cfg.tlsConfig, QUICConfig: &quic.Config{}, } } - closeFn := func(conn *http3.RoundTripper) func() { + closeFn := func(conn *http3.Transport) func() { return func() { _ = conn.Close() } diff --git a/pkg/test/echo/server/forwarder/util.go b/pkg/test/echo/server/forwarder/util.go index 7a0d797769c7..66aa5584c7df 100644 --- a/pkg/test/echo/server/forwarder/util.go +++ b/pkg/test/echo/server/forwarder/util.go @@ -134,7 +134,6 @@ func doForward(ctx context.Context, cfg *Config, e *executor, doReq func(context g := e.NewGroup() for index := 0; index < cfg.count; index++ { - index := index workFn := func() error { st := time.Now() resp, err := doReq(ctx, cfg, index) diff --git a/pkg/test/framework/components/authz/kube.go b/pkg/test/framework/components/authz/kube.go index 2ad4b76663f4..936864a3e1f8 100644 --- a/pkg/test/framework/components/authz/kube.go +++ b/pkg/test/framework/components/authz/kube.go @@ -188,7 +188,6 @@ func (s *serverImpl) deploy(ctx resource.Context) error { // Wait for the endpoints to be ready. var g multierror.Group for _, c := range ctx.Clusters() { - c := c g.Go(func() error { _, _, err := kube.WaitUntilServiceEndpointsAreReady(c.Kube(), s.ns.Name(), "ext-authz") return err diff --git a/pkg/test/framework/components/echo/common/deployment/echos.go b/pkg/test/framework/components/echo/common/deployment/echos.go index 927c45e34645..140d666fec99 100644 --- a/pkg/test/framework/components/echo/common/deployment/echos.go +++ b/pkg/test/framework/components/echo/common/deployment/echos.go @@ -147,7 +147,6 @@ func (c *Config) fillDefaults(ctx resource.Context) error { }) } else { for i := 0; i < c.NamespaceCount; i++ { - i := i g.Go(func() error { ns, err := namespace.New(ctx, namespace.Config{ Prefix: fmt.Sprintf("echo%d", i+1), @@ -501,7 +500,6 @@ func New(ctx resource.Context, cfg Config) (*Echos, error) { g := multierror.Group{} for i := 0; i < len(apps.NS); i++ { - i := i g.Go(func() error { return apps.NS[i].loadValues(ctx, echos, apps) }) diff --git a/pkg/test/framework/components/echo/echotest/filters_test.go b/pkg/test/framework/components/echo/echotest/filters_test.go index 9342fb53f93f..a0a741f9fed9 100644 --- a/pkg/test/framework/components/echo/echotest/filters_test.go +++ b/pkg/test/framework/components/echo/echotest/filters_test.go @@ -199,7 +199,6 @@ func TestFilters(t *testing.T) { }, } for n, tc := range tests { - n, tc := n, tc t.Run(n, func(t *testing.T) { compare(t, tc.filter(all), tc.expect) }) @@ -328,7 +327,6 @@ func TestRun(t *testing.T) { } for name, tt := range tests { - tt := tt t.NewSubTest(name).Run(func(t framework.TestContext) { testTopology := map[string]map[string]int{} tt.run(t, testTopology) diff --git a/pkg/test/framework/components/echo/echotest/run.go b/pkg/test/framework/components/echo/echotest/run.go index 7ab0d520106e..95fa5e29aa32 100644 --- a/pkg/test/framework/components/echo/echotest/run.go +++ b/pkg/test/framework/components/echo/echotest/run.go @@ -121,7 +121,6 @@ func (t *T) RunFromClusters(testFn oneClusterOneTest) { // fromEachCluster runs test from each cluster without requiring source deployment. func (t *T) fromEachCluster(ctx framework.TestContext, testFn perClusterTest) { for _, fromCluster := range t.sources.Clusters() { - fromCluster := fromCluster ctx.NewSubTestf("from %s", fromCluster.StableName()).Run(func(ctx framework.TestContext) { testFn(ctx, fromCluster) }) @@ -246,7 +245,6 @@ func (t *T) fromEachDeployment(ctx framework.TestContext, testFn perDeploymentTe includeNS := t.isMultipleNamespaces() for _, from := range t.sources.Services() { - from := from subtestName := from.Config().Service if includeNS { subtestName += "." + from.Config().Namespace.Prefix() @@ -263,7 +261,6 @@ func (t *T) toEachDeployment(ctx framework.TestContext, testFn perDeploymentTest includeNS := t.isMultipleNamespaces() for _, to := range t.destinations.Services() { - to := to subtestName := to.Config().Service if includeNS { subtestName += "." + to.Config().Namespace.Prefix() @@ -276,7 +273,6 @@ func (t *T) toEachDeployment(ctx framework.TestContext, testFn perDeploymentTest func (t *T) fromEachWorkloadCluster(ctx framework.TestContext, from echo.Instances, testFn perInstanceTest) { for _, fromInstance := range from { - fromInstance := fromInstance if len(ctx.Clusters()) == 1 && len(from) == 1 { testFn(ctx, fromInstance) } else { @@ -310,8 +306,6 @@ func (t *T) toNDeployments(ctx framework.TestContext, n int, from echo.Instances // combination filters should be run again for individual sources filteredTargets := t.destinations.Services().MatchFQDNs(commonTargets...) for _, svc := range nDestinations(ctx, n, filteredTargets) { - svc := svc - namespacedNames := svc.NamespacedNames() var toNames []string if includeNS { diff --git a/pkg/test/framework/components/echo/instances.go b/pkg/test/framework/components/echo/instances.go index 19c1a5e12501..63627b356c86 100644 --- a/pkg/test/framework/components/echo/instances.go +++ b/pkg/test/framework/components/echo/instances.go @@ -194,7 +194,6 @@ func (i Instances) Append(instances Instances) Instances { func (i Instances) Restart() error { g := multierror.Group{} for _, app := range i { - app := app g.Go(app.Restart) } return g.Wait().ErrorOrNil() diff --git a/pkg/test/framework/components/echo/kube/builder.go b/pkg/test/framework/components/echo/kube/builder.go index 47fbc4950db7..82996623c892 100644 --- a/pkg/test/framework/components/echo/kube/builder.go +++ b/pkg/test/framework/components/echo/kube/builder.go @@ -26,7 +26,6 @@ func Build(ctx resource.Context, configs []echo.Config) (echo.Instances, error) g := multierror.Group{} for i, cfg := range configs { - i, cfg := i, cfg g.Go(func() (err error) { instances[i], err = newInstance(ctx, cfg) return diff --git a/pkg/test/framework/components/istio/cleanup.go b/pkg/test/framework/components/istio/cleanup.go index 55becc42ac2b..234c1c5275c5 100644 --- a/pkg/test/framework/components/istio/cleanup.go +++ b/pkg/test/framework/components/istio/cleanup.go @@ -16,6 +16,8 @@ package istio import ( "context" + "errors" + "fmt" "regexp" "time" @@ -27,9 +29,15 @@ import ( "istio.io/istio/pkg/test/framework/resource" kube2 "istio.io/istio/pkg/test/kube" "istio.io/istio/pkg/test/scopes" + "istio.io/istio/pkg/test/util/retry" "istio.io/istio/pkg/test/util/yml" ) +const ( + RetryDelay = 2 * time.Second + RetryTimeOut = 5 * time.Minute +) + func (i *istioImpl) Close() error { t0 := time.Now() scopes.Framework.Infof("=== BEGIN: Cleanup Istio [Suite=%s] ===", i.ctx.Settings().TestID) @@ -82,7 +90,6 @@ func (i *istioImpl) Dump(ctx resource.Context) { return nil }) for _, c := range ctx.Clusters().Primaries() { - c := c g.Go(func() error { kube2.DumpDebug(ctx, c, d, "configz", ns) return nil @@ -96,15 +103,38 @@ func (i *istioImpl) Dump(ctx resource.Context) { return nil }) } - // Dump istio-cni. + // Dump kube-system as well. g.Go(func() error { - kube2.DumpPods(ctx, d, "kube-system", []string{"k8s-app=istio-cni-node"}) + kube2.DumpPods(ctx, d, "kube-system", []string{}) return nil }) } func (i *istioImpl) cleanupCluster(c cluster.Cluster, errG *multierror.Group) { scopes.Framework.Infof("clean up cluster %s", c.Name()) + + // Tail `istio-cni` termination/shutdown logs, if any such pods present + // in the system namespace + label := "k8s-app=istio-cni-node" + + fetchFunc := kube2.NewPodFetch(c, i.cfg.SystemNamespace, label) + + fetched, e := fetchFunc() + if e != nil { + scopes.Framework.Infof("Failed retrieving pods: %v", e) + } + + if len(fetched) != 0 { + workDir, err := i.ctx.CreateTmpDirectory("istio-state") + if err != nil { + scopes.Framework.Errorf("Unable to create directory for dumping istio-cni termlogs: %v", err) + return + } + for _, pod := range fetched { + go kube2.DumpTerminationLogs(context.Background(), c, workDir, pod, "install-cni") + } + } + errG.Go(func() (err error) { if e := i.installer.Close(c); e != nil { err = multierror.Append(err, e) @@ -132,6 +162,38 @@ func (i *istioImpl) cleanupCluster(c cluster.Cluster, errG *multierror.Group) { context.Background(), metav1.DeleteOptions{}, metav1.ListOptions{}); e != nil { err = multierror.Append(err, e) } + + // We deleted all resources, but don't report cleanup finished until all Istio pods + // in the system namespace have actually terminated. + cleanErr := retry.UntilSuccess(func() error { + label := "app.kubernetes.io/part-of=istio" + + fetchPodFunc := kube2.NewPodFetch(c, i.cfg.SystemNamespace, label) + + fetchedPod, e := fetchPodFunc() + if e != nil { + scopes.Framework.Infof("Failed retrieving pods: %v", e) + } + + // In Openshift if takes time to cleanup the services. + // Lets check for the services cleanup as well. + fetchSvcFunc := kube2.NewServiceFetch(c, i.cfg.SystemNamespace, label) + + fetchedSvc, e := fetchSvcFunc() + if e != nil { + scopes.Framework.Infof("Failed retrieving services: %v", e) + } + + if len(fetchedPod) == 0 && len(fetchedSvc) == 0 { + return nil + } + res := fmt.Sprintf("Still waiting for %d pods and %d services to terminate in %s ", len(fetchedPod), len(fetchedSvc), i.cfg.SystemNamespace) + scopes.Framework.Infof(res) + return errors.New(res) + }, retry.Timeout(RetryTimeOut), retry.Delay(RetryDelay)) + + err = multierror.Append(err, cleanErr) + return }) } diff --git a/pkg/test/framework/components/istio/configmap.go b/pkg/test/framework/components/istio/configmap.go index e3d5dcb1d021..78ef1890ddeb 100644 --- a/pkg/test/framework/components/istio/configmap.go +++ b/pkg/test/framework/components/istio/configmap.go @@ -110,7 +110,6 @@ func (ic *injectConfig) UpdateInjectionConfig(t resource.Context, update func(*i mu := sync.RWMutex{} for _, c := range ic.ctx.AllClusters() { - c := c errG.Go(func() error { cfgMap, err := ic.getConfigMap(c, ic.configMapName()) if err != nil { @@ -166,7 +165,6 @@ func (ic *injectConfig) UpdateInjectionConfig(t resource.Context, update func(*i mu.RLock() defer mu.RUnlock() for cn, mcYAML := range origCfg { - cn, mcYAML := cn, mcYAML c := ic.ctx.AllClusters().GetByName(cn) errG.Go(func() error { cfgMap, err := ic.getConfigMap(c, ic.configMapName()) @@ -291,7 +289,6 @@ func (mc *meshConfig) UpdateMeshConfig(t resource.Context, update func(*meshconf mu := sync.RWMutex{} for _, c := range mc.ctx.AllClusters() { - c := c errG.Go(func() error { cfgMapName, err := mc.configMapName() if err != nil { @@ -356,7 +353,6 @@ func (mc *meshConfig) UpdateMeshConfig(t resource.Context, update func(*meshconf mu.RLock() defer mu.RUnlock() for cn, mcYAML := range origCfg { - cn, mcYAML := cn, mcYAML c := mc.ctx.AllClusters().GetByName(cn) errG.Go(func() error { cfgMapName, err := mc.configMapName() diff --git a/pkg/test/framework/components/istio/installer.go b/pkg/test/framework/components/istio/installer.go index 2ac7d1866ddf..0846130bdb47 100644 --- a/pkg/test/framework/components/istio/installer.go +++ b/pkg/test/framework/components/istio/installer.go @@ -142,6 +142,7 @@ func (i *installer) Close(c cluster.Cluster) error { if len(manifests) > 0 { return i.ctx.ConfigKube(c).YAML("", removeCRDsSlice(manifests)).Delete() } + scopes.Framework.Debugf("Deleting yaml on cluster %s: %+v", c.Name(), manifests) return nil } diff --git a/pkg/test/framework/components/istio/kube.go b/pkg/test/framework/components/istio/kube.go index b5aaa130aa43..037ff964bffa 100644 --- a/pkg/test/framework/components/istio/kube.go +++ b/pkg/test/framework/components/istio/kube.go @@ -302,7 +302,6 @@ func newKube(ctx resource.Context, cfg Config) (Instance, error) { // Install control plane clusters (can be external or primary). errG := multierror.Group{} for _, c := range ctx.AllClusters().Primaries() { - c := c errG.Go(func() error { return i.installControlPlaneCluster(c) }) @@ -322,7 +321,6 @@ func newKube(ctx resource.Context, cfg Config) (Instance, error) { // Install (non-config) remote clusters. errG = multierror.Group{} for _, c := range ctx.Clusters().Remotes(ctx.Clusters().Configs()...) { - c := c errG.Go(func() error { if err := i.installRemoteCluster(c); err != nil { return fmt.Errorf("failed installing remote cluster %s: %v", c.Name(), err) @@ -357,7 +355,6 @@ func newKube(ctx resource.Context, cfg Config) (Instance, error) { // Configure gateways for remote clusters. for _, c := range ctx.Clusters().Remotes() { - c := c if i.externalControlPlane || cfg.IstiodlessRemotes { // Install ingress and egress gateways // These need to be installed as a separate step for external control planes because config clusters are installed diff --git a/pkg/test/framework/components/jwt/kube.go b/pkg/test/framework/components/jwt/kube.go index 6b41471f2b98..0e284fabcfde 100644 --- a/pkg/test/framework/components/jwt/kube.go +++ b/pkg/test/framework/components/jwt/kube.go @@ -119,7 +119,6 @@ func (s *serverImpl) deploy(ctx resource.Context) error { // Wait for the endpoints to be ready. var g multierror.Group for _, c := range ctx.AllClusters() { - c := c g.Go(func() error { fetchFn := kube.NewPodFetch(c, s.ns.Name(), "app=jwt-server") _, err := kube.WaitUntilPodsAreReady(fetchFn) diff --git a/pkg/test/framework/components/namespace/kube.go b/pkg/test/framework/components/namespace/kube.go index ab7601121852..537aeb4cc390 100644 --- a/pkg/test/framework/components/namespace/kube.go +++ b/pkg/test/framework/components/namespace/kube.go @@ -262,7 +262,6 @@ func (n *kubeNamespace) createInCluster(c cluster.Cluster, cfg Config) error { func (n *kubeNamespace) forEachCluster(fn func(i int, c cluster.Cluster) error) error { errG := multierror.Group{} for i, c := range n.ctx.AllClusters() { - i, c := i, c errG.Go(func() error { return fn(i, c) }) diff --git a/pkg/test/framework/components/zipkin/kube.go b/pkg/test/framework/components/zipkin/kube.go index eccf2f721230..937174db9777 100644 --- a/pkg/test/framework/components/zipkin/kube.go +++ b/pkg/test/framework/components/zipkin/kube.go @@ -15,6 +15,7 @@ package zipkin import ( + "context" "encoding/json" "errors" "fmt" @@ -37,9 +38,10 @@ import ( ) const ( - appName = "zipkin" - tracesAPI = "/api/v2/traces?limit=%d&spanName=%s&annotationQuery=%s" - zipkinPort = 9411 + appName = "zipkin" + tracesAPI = "/api/v2/traces?limit=%d&spanName=%s&annotationQuery=%s" + zipkinPort = 9411 + httpTimeout = 5 * time.Second remoteZipkinEntry = ` apiVersion: networking.istio.io/v1 @@ -232,33 +234,80 @@ func (c *kubeComponent) ID() resource.ID { return c.id } -func (c *kubeComponent) QueryTraces(limit int, spanName, annotationQuery string) ([]Trace, error) { - // Get 100 most recent traces - client := http.Client{ - Timeout: 5 * time.Second, +func (c *kubeComponent) QueryTraces(limit int, spanName, annotationQuery, hostDomain string) ([]Trace, error) { + url, client, err := c.createHTTPClient(limit, spanName, annotationQuery, hostDomain) + if err != nil { + return nil, fmt.Errorf("failed to create HTTP client: %w", err) } - scopes.Framework.Debugf("make get call to zipkin api %v", c.address+fmt.Sprintf(tracesAPI, limit, spanName, annotationQuery)) - resp, err := client.Get(c.address + fmt.Sprintf(tracesAPI, limit, spanName, annotationQuery)) + + req, err := http.NewRequest("GET", url, nil) if err != nil { - scopes.Framework.Debugf("zipking err %v", err) - return nil, err + return nil, fmt.Errorf("failed to create request: %w", err) } - if resp.StatusCode != http.StatusOK { - scopes.Framework.Debugf("response err %v", resp.StatusCode) - return nil, fmt.Errorf("zipkin api returns non-ok: %v", resp.StatusCode) + + // Set Host header to specific domain resolution, like Openshift + if hostDomain != "" { + req.Host = fmt.Sprintf("tracing.%s", hostDomain) + scopes.Framework.Debugf("Request created with Host header: %s", req.Host) + } + + resp, err := client.Do(req) + if err != nil { + scopes.Framework.Debugf("Error performing request to Zipkin API: %v", err) + return nil, fmt.Errorf("http request failed: %w", err) } defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + scopes.Framework.Debugf("Received non-OK response: %d", resp.StatusCode) + return nil, fmt.Errorf("zipkin API returned status code: %d", resp.StatusCode) + } body, err := io.ReadAll(resp.Body) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to read response body: %w", err) } traces, err := extractTraces(body) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to extract traces: %w", err) } + return traces, nil } +func (c *kubeComponent) createHTTPClient(limit int, spanName, annotationQuery, hostDomain string) (string, http.Client, error) { + baseURL := fmt.Sprintf(tracesAPI, limit, spanName, annotationQuery) + if hostDomain == "" { + url := c.address + baseURL + scopes.Framework.Debugf("Making GET call to Zipkin API: %s", url) + return url, http.Client{Timeout: httpTimeout}, nil + } + + ip, err := resolveHostDomainToIP(hostDomain) + if err != nil { + return "", http.Client{}, fmt.Errorf("failed to resolve host domain %s: %w", hostDomain, err) + } + + transport := &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + _, port, err := net.SplitHostPort(addr) + if err != nil { + return nil, fmt.Errorf("invalid address: %s: %w", addr, err) + } + + resolvedAddr := net.JoinHostPort(ip, port) + return (&net.Dialer{}).DialContext(ctx, network, resolvedAddr) + }, + } + + url := fmt.Sprintf("http://%s%s", ip, baseURL) + scopes.Framework.Debugf("Making GET call to Zipkin API: %s with resolve override: %s", url, hostDomain) + + return url, http.Client{ + Timeout: httpTimeout, + Transport: transport, + }, nil +} + // Close implements io.Closer. func (c *kubeComponent) Close() error { if c.forwarder != nil { @@ -322,3 +371,17 @@ func buildSpan(obj any) Span { } return s } + +func resolveHostDomainToIP(hostDomain string) (string, error) { + ips, err := net.LookupIP(hostDomain) + if err != nil { + return "", err + } + // Use the first resolved IP address + for _, ip := range ips { + if ipv4 := ip.To4(); ipv4 != nil { + return ipv4.String(), nil + } + } + return "", fmt.Errorf("no IPv4 address found for hostname: %s", hostDomain) +} diff --git a/pkg/test/framework/components/zipkin/zipkin.go b/pkg/test/framework/components/zipkin/zipkin.go index 2036e316b80c..af232b90472d 100644 --- a/pkg/test/framework/components/zipkin/zipkin.go +++ b/pkg/test/framework/components/zipkin/zipkin.go @@ -27,7 +27,7 @@ type Instance interface { // QueryTraces gets at most number of limit most recent available traces from zipkin. // spanName filters that only trace with the given span name will be included. - QueryTraces(limit int, spanName, annotationQuery string) ([]Trace, error) + QueryTraces(limit int, spanName, annotationQuery, hostDomain string) ([]Trace, error) } type Config struct { diff --git a/pkg/test/framework/config.go b/pkg/test/framework/config.go index 093962f63359..a395be6a44ca 100644 --- a/pkg/test/framework/config.go +++ b/pkg/test/framework/config.go @@ -95,7 +95,6 @@ func (c *configFactory) applyYAML(cleanupStrategy cleanup.Strategy, ns string, y g, _ := errgroup.WithContext(context.TODO()) for _, cl := range c.clusters { - cl := cl g.Go(func() error { scopes.Framework.Debugf("Applying to %s to namespace %v: %s", cl.StableName(), ns, strings.Join(yamlFiles, ", ")) if err := cl.ApplyYAMLFiles(ns, yamlFiles...); err != nil { @@ -126,7 +125,6 @@ func (c *configFactory) deleteYAML(ns string, yamlText ...string) error { g, _ := errgroup.WithContext(context.TODO()) for _, c := range c.clusters { - c := c g.Go(func() error { if err := c.DeleteYAMLFiles(ns, yamlFiles...); err != nil { return fmt.Errorf("failed deleting YAML from cluster %s: %v", c.Name(), err) @@ -146,8 +144,6 @@ func (c *configFactory) WaitForConfig(ctx resource.Context, ns string, yamlText } for _, cfg := range yamlText { - cfg := cfg - // TODO(https://github.com/istio/istio/issues/37324): It's currently unsafe // to call istioctl concurrently since it relies on the istioctl library // (rather than calling the binary from the command line) which uses a number @@ -242,7 +238,6 @@ func (c *configPlan) Apply(opts ...apply.Option) error { // Apply for each namespace concurrently. g, _ := errgroup.WithContext(context.TODO()) for ns, y := range c.yamlText { - ns, y := ns, y g.Go(func() error { return c.applyYAML(options.Cleanup, ns, y...) }) @@ -277,7 +272,6 @@ func (c *configPlan) Delete() error { // Delete for each namespace concurrently. g, _ := errgroup.WithContext(context.TODO()) for ns, y := range c.yamlText { - ns, y := ns, y g.Go(func() error { return c.deleteYAML(ns, y...) }) diff --git a/pkg/test/framework/resource/version_test.go b/pkg/test/framework/resource/version_test.go index b5edd3b86928..f5fb7f6c7f26 100644 --- a/pkg/test/framework/resource/version_test.go +++ b/pkg/test/framework/resource/version_test.go @@ -88,7 +88,7 @@ func TestMinimumIstioVersion(t *testing.T) { { "three versions", IstioVersions([]IstioVersion{ - "1.9", "1.24", "1.10", + "1.9", "1.25", "1.10", }), IstioVersion("1.9"), }, diff --git a/pkg/test/framework/suite.go b/pkg/test/framework/suite.go index 4b7549e9d8c9..8dd859d5138f 100644 --- a/pkg/test/framework/suite.go +++ b/pkg/test/framework/suite.go @@ -362,7 +362,6 @@ func (s *suiteImpl) SetupParallel(fns ...resource.SetupFn) Suite { s.setupFns = append(s.setupFns, func(ctx resource.Context) error { g := multierror.Group{} for _, fn := range fns { - fn := fn g.Go(func() error { return fn(ctx) }) diff --git a/pkg/test/kube/dump.go b/pkg/test/kube/dump.go index 03584b317d93..4edc07ad675c 100644 --- a/pkg/test/kube/dump.go +++ b/pkg/test/kube/dump.go @@ -91,7 +91,6 @@ func DumpDeployments(ctx resource.Context, workDir, namespace string) { return } for _, deployment := range deps.Items { - deployment := deployment errG.Go(func() error { out, err := yaml.Marshal(deployment) if err != nil { @@ -113,7 +112,6 @@ func DumpWebhooks(ctx resource.Context, workDir string) { return } for _, mwh := range mwhs.Items { - mwh := mwh errG.Go(func() error { out, err := yaml.Marshal(mwh) if err != nil { @@ -128,7 +126,6 @@ func DumpWebhooks(ctx resource.Context, workDir string) { return } for _, vwh := range vwhs.Items { - vwh := vwh errG.Go(func() error { out, err := yaml.Marshal(vwh) if err != nil { @@ -167,7 +164,6 @@ func DumpPods(ctx resource.Context, workDir, namespace string, selectors []strin continue } for _, dump := range dumpers { - c, dump := c, dump wg.Add(1) go func() { dump(ctx, c, workDir, namespace, pods.Items...) @@ -429,7 +425,6 @@ func DumpPodEnvoy(ctx resource.Context, c cluster.Cluster, workDir, namespace st pods = podsOrFetch(c, pods, namespace) g := errgroup.Group{} for _, pod := range pods { - pod := pod if !hasEnvoy(pod) { continue } @@ -627,7 +622,6 @@ func DumpDebug(ctx resource.Context, c cluster.Cluster, workDir, endpoint, names func DumpPodAgent(ctx resource.Context, c cluster.Cluster, workDir string, _ string, pods ...corev1.Pod) { g := errgroup.Group{} for _, pod := range pods { - pod := pod g.Go(func() error { fw, err := newPortForward(c, pod, 15020) if err != nil { @@ -643,3 +637,18 @@ func DumpPodAgent(ctx resource.Context, c cluster.Cluster, workDir string, _ str scopes.Framework.Errorf("failed to dump ndsz: %v", err) } } + +// Will capture pod logs until target pod/container terminates, and then will write them to file. +// Generally should be run in a goroutine while deletion happens +func DumpTerminationLogs(ctx context.Context, c cluster.Cluster, workDir string, pod corev1.Pod, containerName string) { + fname := podOutputPath(workDir, c, pod, fmt.Sprintf("%s.termination.log", containerName)) + l, err := c.PodLogsFollow(ctx, pod.Name, pod.Namespace, containerName) + if err != nil && len(l) == 0 { + scopes.Framework.Warnf("Unable to capture termination logs for cluster/pod/container: %s/%s/%s/%s: %v", + c.Name(), pod.Namespace, pod.Name, containerName, err) + } + if err = os.WriteFile(fname, []byte(l), os.ModePerm); err != nil { + scopes.Framework.Warnf("Unable to write termination logs for cluster/pod/container: %s/%s/%s/%s: %v", + c.Name(), pod.Namespace, pod.Name, containerName, err) + } +} diff --git a/pkg/test/kube/util.go b/pkg/test/kube/util.go index df9eab2071bf..784ecfcf2928 100644 --- a/pkg/test/kube/util.go +++ b/pkg/test/kube/util.go @@ -39,8 +39,13 @@ var ( ErrNoPodsFetched = fmt.Errorf("no pods fetched") ) -// PodFetchFunc fetches pods from a k8s Client. -type PodFetchFunc func() ([]corev1.Pod, error) +type ( + // PodFetchFunc fetches pods from a k8s Client. + PodFetchFunc func() ([]corev1.Pod, error) + + // SvcFetchFunc fetches services from a k8s Client. + SvcFetchFunc func() ([]corev1.Service, error) +) // NewPodFetch creates a new PodFetchFunction that fetches all pods matching the namespace and label selectors. func NewPodFetch(a istioKube.CLIClient, namespace string, selectors ...string) PodFetchFunc { @@ -119,6 +124,17 @@ func CheckPodsAreReady(fetchFunc PodFetchFunc) ([]corev1.Pod, error) { return fetched, nil } +// NewServiceFetch creates a new ServiceFetchFunction that fetches all services matching the namespace and label selectors. +func NewServiceFetch(a istioKube.CLIClient, namespace string, selectors ...string) SvcFetchFunc { + return func() ([]corev1.Service, error) { + services, err := a.ServicesForSelector(context.TODO(), namespace, selectors...) + if err != nil { + return nil, err + } + return services.Items, nil + } +} + // DeleteOptionsForeground creates new delete options that will block until the operation completes. func DeleteOptionsForeground() metav1.DeleteOptions { propagationPolicy := metav1.DeletePropagationForeground diff --git a/pkg/test/util/assert/assert.go b/pkg/test/util/assert/assert.go index 283984c4b095..6693b3521c83 100644 --- a/pkg/test/util/assert/assert.go +++ b/pkg/test/util/assert/assert.go @@ -149,3 +149,16 @@ func ChannelIsEmpty[T any](t test.Failer, c <-chan T) { case <-time.After(time.Millisecond * 20): } } + +// ChannelIsClosed asserts a channel is closed +func ChannelIsClosed[T any](t test.Failer, c <-chan T) { + t.Helper() + select { + case obj, ok := <-c: + if ok { + t.Fatalf("channel had element, expected closed: %v", obj) + } + default: + t.Fatalf("channel was not closed") + } +} diff --git a/pkg/wasm/convert.go b/pkg/wasm/convert.go index 6d10118cbdf8..8ec3012b1e61 100644 --- a/pkg/wasm/convert.go +++ b/pkg/wasm/convert.go @@ -22,7 +22,10 @@ import ( udpa "github.com/cncf/xds/go/udpa/type/v1" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + rbacv3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" + httprbac "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3" httpwasm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/wasm/v3" + networkrbac "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/rbac/v3" networkwasm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/wasm/v3" wasmextensions "github.com/envoyproxy/go-control-plane/envoy/extensions/wasm/v3" "github.com/envoyproxy/go-control-plane/pkg/conversion" @@ -37,24 +40,48 @@ import ( var ( allowHTTPTypedConfig = &anypb.Any{ TypeUrl: "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + // no rules mean allow all. } - allowNetworkTypedConfig = &anypb.Any{ - TypeUrl: "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - } + denyHTTPTypedConfig, _ = anypb.New(&httprbac.RBAC{ + // empty rule means deny all. + Rules: &rbacv3.RBAC{}, + }) + + allowNetworkTypeConfig, _ = anypb.New(&networkrbac.RBAC{ + // no rules mean allow all. + StatPrefix: "wasm-default-allow", + }) + denyNetworkTypedConfig, _ = anypb.New(&networkrbac.RBAC{ + // empty rule means deny all. + Rules: &rbacv3.RBAC{}, + StatPrefix: "wasm-default-deny", + }) ) -func createHTTPAllowAllFilter(name string) (*anypb.Any, error) { +func createHTTPDefaultFilter(name string, failOpen bool) (*anypb.Any, error) { + var tc *anypb.Any + if failOpen { + tc = allowHTTPTypedConfig + } else { + tc = denyHTTPTypedConfig + } ec := &core.TypedExtensionConfig{ Name: name, - TypedConfig: allowHTTPTypedConfig, + TypedConfig: tc, } return anypb.New(ec) } -func createNetworkAllowAllFilter(name string) (*anypb.Any, error) { +func createNetworkDefaultFilter(name string, failOpen bool) (*anypb.Any, error) { + var tc *anypb.Any + if failOpen { + tc = allowNetworkTypeConfig + } else { + tc = denyNetworkTypedConfig + } ec := &core.TypedExtensionConfig{ Name: name, - TypedConfig: allowNetworkTypedConfig, + TypedConfig: tc, } return anypb.New(ec) } @@ -96,12 +123,9 @@ func MaybeConvertWasmExtensionConfig(resources []*anypb.Any, cache Cache) error if wasmHTTPConfig != nil { newExtensionConfig, err := convertHTTPWasmConfigFromRemoteToLocal(extConfig, wasmHTTPConfig, cache) if err != nil { - if !wasmHTTPConfig.GetConfig().GetFailOpen() { - convertErrs[i] = err - return - } // Use NOOP filter because the download failed. - newExtensionConfig, err = createHTTPAllowAllFilter(extConfig.GetName()) + // nolint: staticcheck // FailOpen deprecated + newExtensionConfig, err = createHTTPDefaultFilter(extConfig.GetName(), wasmHTTPConfig.GetConfig().GetFailOpen()) if err != nil { // If the fallback is failing, send the Nack regardless of fail_open. err = fmt.Errorf("failed to create allow-all filter as a fallback of %s Wasm Module: %w", extConfig.GetName(), err) @@ -113,12 +137,9 @@ func MaybeConvertWasmExtensionConfig(resources []*anypb.Any, cache Cache) error } else { newExtensionConfig, err := convertNetworkWasmConfigFromRemoteToLocal(extConfig, wasmNetworkConfig, cache) if err != nil { - if !wasmNetworkConfig.GetConfig().GetFailOpen() { - convertErrs[i] = err - return - } // Use NOOP filter because the download failed. - newExtensionConfig, err = createNetworkAllowAllFilter(extConfig.GetName()) + // nolint: staticcheck // FailOpen deprecated + newExtensionConfig, err = createNetworkDefaultFilter(extConfig.GetName(), wasmNetworkConfig.GetConfig().GetFailOpen()) if err != nil { // If the fallback is failing, send the Nack regardless of fail_open. err = fmt.Errorf("failed to create allow-all filter as a fallback of %s Wasm Module: %w", extConfig.GetName(), err) diff --git a/pkg/wasm/convert_test.go b/pkg/wasm/convert_test.go index 5efbb36b24d8..3722c4e10eab 100644 --- a/pkg/wasm/convert_test.go +++ b/pkg/wasm/convert_test.go @@ -23,6 +23,7 @@ import ( udpa "github.com/cncf/xds/go/udpa/type/v1" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + rbacv3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" rbac "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/rbac/v3" wasm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/wasm/v3" v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/wasm/v3" @@ -224,27 +225,17 @@ func TestWasmConvert(t *testing.T) { }, wantErr: false, }, - { - name: "remote load fail", - input: []*core.TypedExtensionConfig{ - extensionConfigMap["remote-load-fail"], - }, - wantOutput: []*core.TypedExtensionConfig{ - extensionConfigMap["remote-load-fail"], - }, - wantErr: true, - }, { name: "mix", input: []*core.TypedExtensionConfig{ - extensionConfigMap["remote-load-fail"], + extensionConfigMap["remote-load-fail-close"], extensionConfigMap["remote-load-success"], }, wantOutput: []*core.TypedExtensionConfig{ - extensionConfigMap["remote-load-fail"], + extensionConfigMap["remote-load-deny"], extensionConfigMap["remote-load-success-local-file"], }, - wantErr: true, + wantErr: false, }, { name: "remote load fail open", @@ -256,6 +247,16 @@ func TestWasmConvert(t *testing.T) { }, wantErr: false, }, + { + name: "remote load fail close", + input: []*core.TypedExtensionConfig{ + extensionConfigMap["remote-load-fail-close"], + }, + wantOutput: []*core.TypedExtensionConfig{ + extensionConfigMap["remote-load-deny"], + }, + wantErr: false, + }, { name: "no typed struct", input: []*core.TypedExtensionConfig{ @@ -292,9 +293,9 @@ func TestWasmConvert(t *testing.T) { extensionConfigMap["no-http-uri"], }, wantOutput: []*core.TypedExtensionConfig{ - extensionConfigMap["no-http-uri"], + extensionConfigMap["remote-load-deny"], }, - wantErr: true, + wantErr: false, }, { name: "secret", @@ -391,7 +392,7 @@ var extensionConfigMap = map[string]*core.TypedExtensionConfig{ }, }, }), - "no-http-uri": buildTypedStructExtensionConfig("no-remote-load", &wasm.Wasm{ + "no-http-uri": buildTypedStructExtensionConfig("remote-load-fail", &wasm.Wasm{ Config: &v3.PluginConfig{ Vm: &v3.PluginConfig_VmConfig{ VmConfig: &v3.VmConfig{ @@ -447,7 +448,7 @@ var extensionConfigMap = map[string]*core.TypedExtensionConfig{ }, }, }), - "remote-load-fail": buildTypedStructExtensionConfig("remote-load-fail", &wasm.Wasm{ + "remote-load-fail-close": buildTypedStructExtensionConfig("remote-load-fail", &wasm.Wasm{ Config: &v3.PluginConfig{ Vm: &v3.PluginConfig_VmConfig{ VmConfig: &v3.VmConfig{ @@ -479,6 +480,9 @@ var extensionConfigMap = map[string]*core.TypedExtensionConfig{ }, }), "remote-load-allow": buildAnyExtensionConfig("remote-load-fail", &rbac.RBAC{}), + "remote-load-deny": buildAnyExtensionConfig("remote-load-fail", &rbac.RBAC{ + Rules: &rbacv3.RBAC{}, + }), "remote-load-secret": buildTypedStructExtensionConfig("remote-load-success", &wasm.Wasm{ Config: &v3.PluginConfig{ Vm: &v3.PluginConfig_VmConfig{ diff --git a/pkg/workloadapi/security/authorization.pb.go b/pkg/workloadapi/security/authorization.pb.go index cbacd3a6e9a1..06d2193dec56 100644 --- a/pkg/workloadapi/security/authorization.pb.go +++ b/pkg/workloadapi/security/authorization.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc (unknown) // source: workloadapi/security/authorization.proto @@ -228,7 +228,7 @@ type Group struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Rules are OR-ed (e.g. ANY rule can match) + // Rules are AND-ed // This is a generic form of the authz policy's to, from and when Rules []*Rules `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"` } diff --git a/pkg/workloadapi/security/authorization.proto b/pkg/workloadapi/security/authorization.proto index 5235b129d4f1..35e5f2e70cad 100644 --- a/pkg/workloadapi/security/authorization.proto +++ b/pkg/workloadapi/security/authorization.proto @@ -37,7 +37,7 @@ message Authorization { } message Group { - // Rules are OR-ed (e.g. ANY rule can match) + // Rules are AND-ed // This is a generic form of the authz policy's to, from and when repeated Rules rules = 1; } diff --git a/pkg/workloadapi/security/authorization_json.gen.go b/pkg/workloadapi/security/authorization_json.gen.go new file mode 100644 index 000000000000..14c1b8ae73e3 --- /dev/null +++ b/pkg/workloadapi/security/authorization_json.gen.go @@ -0,0 +1,78 @@ +// Code generated by protoc-gen-jsonshim. DO NOT EDIT. +package security + +import ( + bytes "bytes" + jsonpb "github.com/golang/protobuf/jsonpb" +) + +// MarshalJSON is a custom marshaler for Authorization +func (this *Authorization) MarshalJSON() ([]byte, error) { + str, err := AuthorizationMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Authorization +func (this *Authorization) UnmarshalJSON(b []byte) error { + return AuthorizationUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for Group +func (this *Group) MarshalJSON() ([]byte, error) { + str, err := AuthorizationMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Group +func (this *Group) UnmarshalJSON(b []byte) error { + return AuthorizationUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for Rules +func (this *Rules) MarshalJSON() ([]byte, error) { + str, err := AuthorizationMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Rules +func (this *Rules) UnmarshalJSON(b []byte) error { + return AuthorizationUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for Match +func (this *Match) MarshalJSON() ([]byte, error) { + str, err := AuthorizationMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Match +func (this *Match) UnmarshalJSON(b []byte) error { + return AuthorizationUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for Address +func (this *Address) MarshalJSON() ([]byte, error) { + str, err := AuthorizationMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Address +func (this *Address) UnmarshalJSON(b []byte) error { + return AuthorizationUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for StringMatch +func (this *StringMatch) MarshalJSON() ([]byte, error) { + str, err := AuthorizationMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for StringMatch +func (this *StringMatch) UnmarshalJSON(b []byte) error { + return AuthorizationUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +var ( + AuthorizationMarshaler = &jsonpb.Marshaler{} + AuthorizationUnmarshaler = &jsonpb.Unmarshaler{AllowUnknownFields: true} +) diff --git a/pkg/workloadapi/workload.pb.go b/pkg/workloadapi/workload.pb.go index 5f7dd55b9024..06d8f09836e1 100644 --- a/pkg/workloadapi/workload.pb.go +++ b/pkg/workloadapi/workload.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc (unknown) // source: workloadapi/workload.proto @@ -23,6 +23,7 @@ package workloadapi import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" reflect "reflect" sync "sync" ) @@ -656,6 +657,8 @@ type Service struct { LoadBalancing *LoadBalancing `protobuf:"bytes,8,opt,name=load_balancing,json=loadBalancing,proto3" json:"load_balancing,omitempty"` // IP families provides configuration about the IP families this service supports. IpFamilies IPFamilies `protobuf:"varint,9,opt,name=ip_families,json=ipFamilies,proto3,enum=istio.workload.IPFamilies" json:"ip_families,omitempty"` + // Extension provides a mechanism to attach arbitrary additional configuration to an object. + Extensions []*Extension `protobuf:"bytes,10,rep,name=extensions,proto3" json:"extensions,omitempty"` } func (x *Service) Reset() { @@ -751,6 +754,13 @@ func (x *Service) GetIpFamilies() IPFamilies { return IPFamilies_AUTOMATIC } +func (x *Service) GetExtensions() []*Extension { + if x != nil { + return x.Extensions + } + return nil +} + type LoadBalancing struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -907,6 +917,8 @@ type Workload struct { // The Locality defines information about where a workload is geographically deployed Locality *Locality `protobuf:"bytes,24,opt,name=locality,proto3" json:"locality,omitempty"` NetworkMode NetworkMode `protobuf:"varint,25,opt,name=network_mode,json=networkMode,proto3,enum=istio.workload.NetworkMode" json:"network_mode,omitempty"` + // Extension provides a mechanism to attach arbitrary additional configuration to an object. + Extensions []*Extension `protobuf:"bytes,26,rep,name=extensions,proto3" json:"extensions,omitempty"` } func (x *Workload) Reset() { @@ -1107,6 +1119,13 @@ func (x *Workload) GetNetworkMode() NetworkMode { return NetworkMode_STANDARD } +func (x *Workload) GetExtensions() []*Extension { + if x != nil { + return x.Extensions + } + return nil +} + type Locality struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1530,196 +1549,268 @@ func (x *NamespacedHostname) GetHostname() string { return "" } +// Extension provides a mechanism to attach arbitrary additional configuration to an object. +type Extension struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name provides an opaque name for the extension. + // This may have semantic meaning or used for debugging. + // This should be unique amongst all extensions attached to an item. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // config provides some opaque configuration. + Config *anypb.Any `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` +} + +func (x *Extension) Reset() { + *x = Extension{} + mi := &file_workloadapi_workload_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Extension) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Extension) ProtoMessage() {} + +func (x *Extension) ProtoReflect() protoreflect.Message { + mi := &file_workloadapi_workload_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Extension.ProtoReflect.Descriptor instead. +func (*Extension) Descriptor() ([]byte, []int) { + return file_workloadapi_workload_proto_rawDescGZIP(), []int{11} +} + +func (x *Extension) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Extension) GetConfig() *anypb.Any { + if x != nil { + return x.Config + } + return nil +} + var File_workloadapi_workload_proto protoreflect.FileDescriptor var file_workloadapi_workload_proto_rawDesc = []byte{ 0x0a, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x61, 0x70, 0x69, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x69, 0x73, - 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x7e, 0x0a, 0x07, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x6c, - 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x69, 0x73, 0x74, 0x69, - 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, - 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, - 0x33, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, - 0x64, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xac, 0x03, 0x0a, - 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, - 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, - 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, - 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, - 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x6c, 0x74, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x08, - 0x77, 0x61, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x1a, 0x19, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7e, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, + 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x33, 0x0a, 0x07, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x69, 0x73, + 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x48, 0x00, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, + 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xe7, 0x03, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x3c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, + 0x2a, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, - 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x08, - 0x77, 0x61, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x44, 0x0a, 0x0e, 0x6c, 0x6f, 0x61, 0x64, - 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, - 0x64, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, - 0x0d, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x3b, - 0x0a, 0x0b, 0x69, 0x70, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, - 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x49, 0x50, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x52, - 0x0a, 0x69, 0x70, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x22, 0xbc, 0x03, 0x0a, 0x0d, - 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x52, 0x0a, - 0x12, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x69, 0x73, 0x74, 0x69, - 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x11, - 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x36, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x22, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, - 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x2e, 0x4d, - 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x4f, 0x0a, 0x0d, 0x68, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x2a, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, - 0x64, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x2e, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0c, 0x68, 0x65, - 0x61, 0x6c, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x65, 0x0a, 0x05, 0x53, 0x63, - 0x6f, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, - 0x47, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x4f, 0x4e, 0x45, 0x10, 0x02, - 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x42, 0x5a, 0x4f, 0x4e, 0x45, 0x10, 0x03, 0x12, 0x08, 0x0a, - 0x04, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4c, 0x55, 0x53, 0x54, - 0x45, 0x52, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x10, - 0x06, 0x22, 0x36, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, - 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x46, - 0x41, 0x49, 0x4c, 0x4f, 0x56, 0x45, 0x52, 0x10, 0x02, 0x22, 0x2f, 0x0a, 0x0c, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x4e, 0x4c, - 0x59, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, - 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x22, 0xaa, 0x09, 0x0a, 0x08, 0x57, - 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x14, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, - 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, - 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, - 0x47, 0x0a, 0x0f, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, - 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x0e, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x77, 0x61, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, - 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x08, 0x77, 0x61, 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x12, 0x47, 0x0a, 0x0f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, + 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x61, 0x6c, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x41, + 0x6c, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x08, 0x77, 0x61, 0x79, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x0e, 0x6e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, - 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x0a, - 0x0e, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, - 0x6c, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x11, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x65, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x69, 0x73, 0x74, + 0x61, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x08, 0x77, 0x61, 0x79, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x12, 0x44, 0x0a, 0x0e, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x69, 0x73, + 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4c, 0x6f, 0x61, + 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x0d, 0x6c, 0x6f, 0x61, 0x64, + 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x3b, 0x0a, 0x0b, 0x69, 0x70, 0x5f, + 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, + 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, + 0x49, 0x50, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x52, 0x0a, 0x69, 0x70, 0x46, 0x61, + 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x69, 0x73, 0x74, + 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0xbc, 0x03, 0x0a, 0x0d, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x69, 0x6e, 0x67, 0x12, 0x52, 0x0a, 0x12, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, + 0x23, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, + 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x2e, 0x53, + 0x63, 0x6f, 0x70, 0x65, 0x52, 0x11, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, + 0x4f, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, + 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x42, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x52, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x22, 0x65, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x53, 0x43, 0x4f, 0x50, 0x45, 0x10, 0x00, + 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x47, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, + 0x5a, 0x4f, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x42, 0x5a, 0x4f, 0x4e, + 0x45, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x04, 0x12, 0x0b, 0x0a, + 0x07, 0x43, 0x4c, 0x55, 0x53, 0x54, 0x45, 0x52, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x45, + 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x10, 0x06, 0x22, 0x36, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, + 0x14, 0x0a, 0x10, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x4d, + 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x10, + 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x46, 0x41, 0x49, 0x4c, 0x4f, 0x56, 0x45, 0x52, 0x10, 0x02, 0x22, + 0x2f, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x10, 0x0a, 0x0c, 0x4f, 0x4e, 0x4c, 0x59, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, + 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x01, + 0x22, 0xe5, 0x09, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, + 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x47, 0x0a, 0x0f, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, + 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, + 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x0e, + 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x21, + 0x0a, 0x0c, 0x74, 0x72, 0x75, 0x73, 0x74, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x72, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x77, 0x61, + 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, + 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x47, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x08, 0x77, 0x61, + 0x79, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x47, 0x0a, 0x0f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, + 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, + 0x0e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x6f, 0x64, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x61, 0x6e, + 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x61, + 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, + 0x6c, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0d, 0x77, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x1c, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, + 0x64, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, + 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, + 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x75, 0x6e, 0x6e, + 0x65, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x50, 0x0a, 0x12, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, + 0x6f, 0x61, 0x64, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x42, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x18, 0x16, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x57, 0x6f, 0x72, 0x6b, - 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, - 0x61, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, - 0x61, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, - 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6e, - 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0c, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, - 0x12, 0x50, 0x0a, 0x12, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x69, - 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x41, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x52, - 0x11, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x75, 0x6e, 0x6e, - 0x65, 0x6c, 0x12, 0x42, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x16, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, - 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x16, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x36, 0x0a, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, - 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x57, - 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, - 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, - 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, - 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0c, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x1b, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, - 0x64, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0b, 0x6e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x1a, 0x55, 0x0a, 0x0d, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x69, - 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x6f, - 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x10, 0x22, 0x50, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x6c, - 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x7a, - 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x73, 0x75, 0x62, 0x7a, 0x6f, 0x6e, 0x65, 0x22, 0x36, 0x0a, 0x08, 0x50, 0x6f, 0x72, - 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, - 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x22, 0x4a, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, 0x0b, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x90, 0x01, - 0x0a, 0x11, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x75, 0x6e, - 0x6e, 0x65, 0x6c, 0x12, 0x46, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, - 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, - 0x1f, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x4e, - 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x10, 0x01, - 0x22, 0xe2, 0x01, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x40, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, - 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x64, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x48, 0x00, 0x52, 0x08, 0x68, 0x6f, 0x73, - 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, - 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x68, 0x62, 0x6f, 0x6e, 0x65, 0x5f, 0x6d, 0x74, 0x6c, 0x73, 0x5f, - 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x68, 0x62, 0x6f, 0x6e, - 0x65, 0x4d, 0x74, 0x6c, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x52, 0x15, - 0x68, 0x62, 0x6f, 0x6e, 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x74, 0x6c, 0x73, - 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x44, 0x0a, 0x0e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x4e, 0x0a, 0x12, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x2a, 0x43, 0x0a, 0x0a, 0x49, + 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x16, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, + 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x08, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x69, + 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4c, 0x6f, + 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x12, 0x3e, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6d, 0x6f, 0x64, 0x65, + 0x18, 0x19, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, + 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4d, + 0x6f, 0x64, 0x65, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4d, 0x6f, 0x64, 0x65, + 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x1a, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, + 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x55, 0x0a, 0x0d, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, + 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x10, 0x22, 0x50, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, + 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x7a, 0x6f, 0x6e, 0x65, 0x22, 0x36, 0x0a, 0x08, 0x50, 0x6f, + 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x22, 0x4a, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x90, + 0x01, 0x0a, 0x11, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x46, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, + 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, + 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, + 0x22, 0x1f, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x08, 0x0a, 0x04, + 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x10, + 0x01, 0x22, 0xe2, 0x01, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x40, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, 0x77, + 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x48, 0x00, 0x52, 0x08, 0x68, 0x6f, + 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x69, 0x73, 0x74, 0x69, 0x6f, 0x2e, + 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x68, 0x62, 0x6f, 0x6e, 0x65, 0x5f, 0x6d, 0x74, 0x6c, 0x73, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x68, 0x62, 0x6f, + 0x6e, 0x65, 0x4d, 0x74, 0x6c, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x52, + 0x15, 0x68, 0x62, 0x6f, 0x6e, 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x5f, 0x74, 0x6c, + 0x73, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x44, 0x0a, 0x0e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x4e, 0x0a, 0x12, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x4d, 0x0a, 0x09, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x41, 0x6e, 0x79, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2a, 0x43, 0x0a, 0x0a, 0x49, 0x50, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x55, 0x54, 0x4f, 0x4d, 0x41, 0x54, 0x49, 0x43, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x50, 0x56, 0x34, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x50, 0x56, 0x36, 0x5f, @@ -1753,7 +1844,7 @@ func file_workloadapi_workload_proto_rawDescGZIP() []byte { } var file_workloadapi_workload_proto_enumTypes = make([]protoimpl.EnumInfo, 9) -var file_workloadapi_workload_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_workloadapi_workload_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_workloadapi_workload_proto_goTypes = []any{ (IPFamilies)(0), // 0: istio.workload.IPFamilies (NetworkMode)(0), // 1: istio.workload.NetworkMode @@ -1775,7 +1866,9 @@ var file_workloadapi_workload_proto_goTypes = []any{ (*GatewayAddress)(nil), // 17: istio.workload.GatewayAddress (*NetworkAddress)(nil), // 18: istio.workload.NetworkAddress (*NamespacedHostname)(nil), // 19: istio.workload.NamespacedHostname - nil, // 20: istio.workload.Workload.ServicesEntry + (*Extension)(nil), // 20: istio.workload.Extension + nil, // 21: istio.workload.Workload.ServicesEntry + (*anypb.Any)(nil), // 22: google.protobuf.Any } var file_workloadapi_workload_proto_depIdxs = []int32{ 12, // 0: istio.workload.Address.workload:type_name -> istio.workload.Workload @@ -1785,28 +1878,31 @@ var file_workloadapi_workload_proto_depIdxs = []int32{ 17, // 4: istio.workload.Service.waypoint:type_name -> istio.workload.GatewayAddress 11, // 5: istio.workload.Service.load_balancing:type_name -> istio.workload.LoadBalancing 0, // 6: istio.workload.Service.ip_families:type_name -> istio.workload.IPFamilies - 5, // 7: istio.workload.LoadBalancing.routing_preference:type_name -> istio.workload.LoadBalancing.Scope - 6, // 8: istio.workload.LoadBalancing.mode:type_name -> istio.workload.LoadBalancing.Mode - 7, // 9: istio.workload.LoadBalancing.health_policy:type_name -> istio.workload.LoadBalancing.HealthPolicy - 4, // 10: istio.workload.Workload.tunnel_protocol:type_name -> istio.workload.TunnelProtocol - 17, // 11: istio.workload.Workload.waypoint:type_name -> istio.workload.GatewayAddress - 17, // 12: istio.workload.Workload.network_gateway:type_name -> istio.workload.GatewayAddress - 3, // 13: istio.workload.Workload.workload_type:type_name -> istio.workload.WorkloadType - 16, // 14: istio.workload.Workload.application_tunnel:type_name -> istio.workload.ApplicationTunnel - 20, // 15: istio.workload.Workload.services:type_name -> istio.workload.Workload.ServicesEntry - 2, // 16: istio.workload.Workload.status:type_name -> istio.workload.WorkloadStatus - 13, // 17: istio.workload.Workload.locality:type_name -> istio.workload.Locality - 1, // 18: istio.workload.Workload.network_mode:type_name -> istio.workload.NetworkMode - 15, // 19: istio.workload.PortList.ports:type_name -> istio.workload.Port - 8, // 20: istio.workload.ApplicationTunnel.protocol:type_name -> istio.workload.ApplicationTunnel.Protocol - 19, // 21: istio.workload.GatewayAddress.hostname:type_name -> istio.workload.NamespacedHostname - 18, // 22: istio.workload.GatewayAddress.address:type_name -> istio.workload.NetworkAddress - 14, // 23: istio.workload.Workload.ServicesEntry.value:type_name -> istio.workload.PortList - 24, // [24:24] is the sub-list for method output_type - 24, // [24:24] is the sub-list for method input_type - 24, // [24:24] is the sub-list for extension type_name - 24, // [24:24] is the sub-list for extension extendee - 0, // [0:24] is the sub-list for field type_name + 20, // 7: istio.workload.Service.extensions:type_name -> istio.workload.Extension + 5, // 8: istio.workload.LoadBalancing.routing_preference:type_name -> istio.workload.LoadBalancing.Scope + 6, // 9: istio.workload.LoadBalancing.mode:type_name -> istio.workload.LoadBalancing.Mode + 7, // 10: istio.workload.LoadBalancing.health_policy:type_name -> istio.workload.LoadBalancing.HealthPolicy + 4, // 11: istio.workload.Workload.tunnel_protocol:type_name -> istio.workload.TunnelProtocol + 17, // 12: istio.workload.Workload.waypoint:type_name -> istio.workload.GatewayAddress + 17, // 13: istio.workload.Workload.network_gateway:type_name -> istio.workload.GatewayAddress + 3, // 14: istio.workload.Workload.workload_type:type_name -> istio.workload.WorkloadType + 16, // 15: istio.workload.Workload.application_tunnel:type_name -> istio.workload.ApplicationTunnel + 21, // 16: istio.workload.Workload.services:type_name -> istio.workload.Workload.ServicesEntry + 2, // 17: istio.workload.Workload.status:type_name -> istio.workload.WorkloadStatus + 13, // 18: istio.workload.Workload.locality:type_name -> istio.workload.Locality + 1, // 19: istio.workload.Workload.network_mode:type_name -> istio.workload.NetworkMode + 20, // 20: istio.workload.Workload.extensions:type_name -> istio.workload.Extension + 15, // 21: istio.workload.PortList.ports:type_name -> istio.workload.Port + 8, // 22: istio.workload.ApplicationTunnel.protocol:type_name -> istio.workload.ApplicationTunnel.Protocol + 19, // 23: istio.workload.GatewayAddress.hostname:type_name -> istio.workload.NamespacedHostname + 18, // 24: istio.workload.GatewayAddress.address:type_name -> istio.workload.NetworkAddress + 22, // 25: istio.workload.Extension.config:type_name -> google.protobuf.Any + 14, // 26: istio.workload.Workload.ServicesEntry.value:type_name -> istio.workload.PortList + 27, // [27:27] is the sub-list for method output_type + 27, // [27:27] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name } func init() { file_workloadapi_workload_proto_init() } @@ -1828,7 +1924,7 @@ func file_workloadapi_workload_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_workloadapi_workload_proto_rawDesc, NumEnums: 9, - NumMessages: 12, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/workloadapi/workload.proto b/pkg/workloadapi/workload.proto index 7ca8270ecbdd..c66b9bb55628 100644 --- a/pkg/workloadapi/workload.proto +++ b/pkg/workloadapi/workload.proto @@ -15,6 +15,9 @@ syntax = "proto3"; package istio.workload; + +import "google/protobuf/any.proto"; + option go_package="pkg/workloadapi"; // Address represents a unique address. @@ -82,6 +85,9 @@ message Service { // IP families provides configuration about the IP families this service supports. IPFamilies ip_families = 9; + + // Extension provides a mechanism to attach arbitrary additional configuration to an object. + repeated Extension extensions = 10; } enum IPFamilies { @@ -258,6 +264,9 @@ message Workload { NetworkMode network_mode = 25; + // Extension provides a mechanism to attach arbitrary additional configuration to an object. + repeated Extension extensions = 26; + // Reservations for deleted fields. reserved 15; } @@ -355,3 +364,13 @@ message NamespacedHostname { // hostname (ex: gateway.example.com) string hostname = 2; } + +// Extension provides a mechanism to attach arbitrary additional configuration to an object. +message Extension { + // name provides an opaque name for the extension. + // This may have semantic meaning or used for debugging. + // This should be unique amongst all extensions attached to an item. + string name = 1; + // config provides some opaque configuration. + google.protobuf.Any config = 2; +} diff --git a/pkg/workloadapi/workload_json.gen.go b/pkg/workloadapi/workload_json.gen.go new file mode 100644 index 000000000000..f5d2ca4949a2 --- /dev/null +++ b/pkg/workloadapi/workload_json.gen.go @@ -0,0 +1,144 @@ +// Code generated by protoc-gen-jsonshim. DO NOT EDIT. +package workloadapi + +import ( + bytes "bytes" + jsonpb "github.com/golang/protobuf/jsonpb" +) + +// MarshalJSON is a custom marshaler for Address +func (this *Address) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Address +func (this *Address) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for Service +func (this *Service) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Service +func (this *Service) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for LoadBalancing +func (this *LoadBalancing) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for LoadBalancing +func (this *LoadBalancing) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for Workload +func (this *Workload) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Workload +func (this *Workload) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for Locality +func (this *Locality) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Locality +func (this *Locality) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for PortList +func (this *PortList) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for PortList +func (this *PortList) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for Port +func (this *Port) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Port +func (this *Port) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for ApplicationTunnel +func (this *ApplicationTunnel) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for ApplicationTunnel +func (this *ApplicationTunnel) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for GatewayAddress +func (this *GatewayAddress) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for GatewayAddress +func (this *GatewayAddress) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for NetworkAddress +func (this *NetworkAddress) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for NetworkAddress +func (this *NetworkAddress) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for NamespacedHostname +func (this *NamespacedHostname) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for NamespacedHostname +func (this *NamespacedHostname) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +// MarshalJSON is a custom marshaler for Extension +func (this *Extension) MarshalJSON() ([]byte, error) { + str, err := WorkloadMarshaler.MarshalToString(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for Extension +func (this *Extension) UnmarshalJSON(b []byte) error { + return WorkloadUnmarshaler.Unmarshal(bytes.NewReader(b), this) +} + +var ( + WorkloadMarshaler = &jsonpb.Marshaler{} + WorkloadUnmarshaler = &jsonpb.Unmarshaler{AllowUnknownFields: true} +) diff --git a/pkg/zdsapi/zds.pb.go b/pkg/zdsapi/zds.pb.go index 8d1b9b9c36ea..8643e307a7f3 100644 --- a/pkg/zdsapi/zds.pb.go +++ b/pkg/zdsapi/zds.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc (unknown) // source: zdsapi/zds.proto diff --git a/prow/integ-suite-kind.sh b/prow/integ-suite-kind.sh index a744d0f11460..594988ade3dc 100755 --- a/prow/integ-suite-kind.sh +++ b/prow/integ-suite-kind.sh @@ -37,7 +37,7 @@ setup_and_export_git_sha source "${ROOT}/common/scripts/kind_provisioner.sh" TOPOLOGY=SINGLE_CLUSTER -NODE_IMAGE="gcr.io/istio-testing/kind-node:v1.31.0" +NODE_IMAGE="gcr.io/istio-testing/kind-node:v1.32.0" KIND_CONFIG="" CLUSTER_TOPOLOGY_CONFIG_FILE="${ROOT}/prow/config/topology/multicluster.json" diff --git a/prow/release-commit.sh b/prow/release-commit.sh index 903c564f448b..5b71754b565a 100755 --- a/prow/release-commit.sh +++ b/prow/release-commit.sh @@ -67,7 +67,7 @@ ${DEPENDENCIES:-$(cat <bool 10)","format":"time_series","intervalFactor":1,"legendFormat":"istio-proxy","refId":"B"}],"title":"vCPU / 1k rps","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":8},"id":7,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[1m]))","format":"time_series","intervalFactor":1,"legendFormat":"istio-ingressgateway","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[1m]))","format":"time_series","intervalFactor":1,"legendFormat":"istio-proxy","refId":"B"}],"title":"vCPU","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":16},"id":13,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Memory and Data Rates","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":17},"id":902,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{pod=~\"istio-ingressgateway-.*\"}) / count(container_memory_working_set_bytes{pod=~\"istio-ingressgateway-.*\",container!=\"POD\"})","format":"time_series","intervalFactor":1,"legendFormat":"per istio-ingressgateway","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{namespace!=\"istio-system\",container=\"istio-proxy\"}) / count(container_memory_working_set_bytes{namespace!=\"istio-system\",container=\"istio-proxy\"})","format":"time_series","intervalFactor":1,"legendFormat":"per istio proxy","refId":"B"}],"title":"Memory Usage","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"Bps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":17},"id":11,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(irate(istio_response_bytes_sum{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[1m]))","format":"time_series","intervalFactor":1,"legendFormat":"istio-ingressgateway","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(irate(istio_response_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[1m])) + sum(irate(istio_request_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[1m]))","format":"time_series","intervalFactor":1,"legendFormat":"istio-proxy","refId":"B"}],"title":"Bytes transferred / sec","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":25},"id":17,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Istio Component Versions","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":24,"x":0,"y":26},"id":15,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(istio_build) by (component, tag)","format":"time_series","intervalFactor":1,"legendFormat":"{{ component }}: {{ tag }}","refId":"A"}],"title":"Istio Components by Version","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":34},"id":71,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Proxy Resource Usage","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":0,"y":35},"id":72,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{container=\"istio-proxy\"})","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"Memory","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":6,"y":35},"id":73,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[1m]))","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"vCPU","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":12,"y":35},"id":702,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_fs_usage_bytes{container=\"istio-proxy\"})","format":"time_series","intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"Disk","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":42},"id":69,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Istiod Resource Usage","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":0,"y":43},"id":5,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"process_virtual_memory_bytes{app=\"istiod\"}","format":"time_series","instant":false,"intervalFactor":2,"legendFormat":"Virtual Memory","refId":"I","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"process_resident_memory_bytes{app=\"istiod\"}","format":"time_series","intervalFactor":2,"legendFormat":"Resident Memory","refId":"H","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_heap_sys_bytes{app=\"istiod\"}","format":"time_series","hide":true,"intervalFactor":2,"legendFormat":"heap sys","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_heap_alloc_bytes{app=\"istiod\"}","format":"time_series","hide":true,"intervalFactor":2,"legendFormat":"heap alloc","refId":"D"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_alloc_bytes{app=\"istiod\"}","format":"time_series","intervalFactor":2,"legendFormat":"Alloc","refId":"F","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_heap_inuse_bytes{app=\"istiod\"}","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Heap in-use","refId":"E","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_stack_inuse_bytes{app=\"istiod\"}","format":"time_series","intervalFactor":2,"legendFormat":"Stack in-use","refId":"G","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"})","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"C","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"container_memory_working_set_bytes{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"{{ container }} (k8s)","refId":"B","step":2}],"title":"Memory","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":6,"y":43},"id":602,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[1m]))","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[1m])) by (container)","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"{{ container }} (k8s)","refId":"B","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"irate(process_cpu_seconds_total{app=\"istiod\"}[1m])","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"pilot (self-reported)","refId":"C","step":2}],"title":"vCPU","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":12,"y":43},"id":74,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"process_open_fds{app=\"istiod\"}","format":"time_series","hide":true,"instant":false,"interval":"","intervalFactor":2,"legendFormat":"Open FDs (pilot)","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"container_fs_usage_bytes{ container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}","format":"time_series","intervalFactor":2,"legendFormat":"{{ container }}","refId":"B","step":2}],"title":"Disk","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":18,"y":43},"id":402,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":false},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_goroutines{app=\"istiod\"}","format":"time_series","intervalFactor":2,"legendFormat":"Number of Goroutines","refId":"A","step":2}],"title":"Goroutines","type":"timeseries"}],"refresh":"","schemaVersion":38,"style":"dark","tags":[],"templating":{"list":[{"hide":0,"includeAll":false,"multi":false,"name":"datasource","options":[],"query":"prometheus","queryValue":"","refresh":1,"regex":"","skipUrlSync":false,"type":"datasource"}]},"time":{"from":"now-30m","to":"now"},"timepicker":{"refresh_intervals":["30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone":"","title":"Istio Performance Dashboard","version":1,"weekStart":""} + {"annotations":{"list":[{"builtIn":1,"datasource":{"type":"datasource","uid":"grafana"},"enable":true,"hide":true,"iconColor":"rgba(0, 211, 255, 1)","name":"Annotations & Alerts","type":"dashboard"}]},"editable":true,"fiscalYearStartMonth":0,"graphTooltip":0,"links":[],"liveNow":false,"panels":[{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":0},"id":21,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Performance Dashboard Notes","type":"row"},{"gridPos":{"h":6,"w":24,"x":0,"y":1},"id":19,"links":[],"options":{"code":{"language":"plaintext","showLineNumbers":false,"showMiniMap":false},"content":"The charts on this dashboard are intended to show Istio main components cost in terms of resources utilization under steady load.\n\n- **vCPU / 1k rps:** shows vCPU utilization by the main Istio components normalized by 1000 requests/second. When idle or low traffic, this chart will be blank. The curve for istio-proxy refers to the services sidecars only.\n- **vCPU:** vCPU utilization by Istio components, not normalized.\n- **Memory:** memory footprint for the components. Telemetry and policy are normalized by 1k rps, and no data is shown when there is no traffic. For ingress and istio-proxy, the data is per instance.\n- **Bytes transferred / sec:** shows the number of bytes flowing through each Istio component.\n\n\n","mode":"markdown"},"pluginVersion":"10.1.5","title":"Performance Dashboard README","transparent":true,"type":"text"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":7},"id":6,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"vCPU Usage","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":8},"id":4,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"(sum(irate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[$__rate_interval])) / (round(sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[$__rate_interval])), 0.001)/1000))","format":"time_series","hide":false,"intervalFactor":1,"legendFormat":"istio-ingressgateway","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"(sum(irate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[$__rate_interval]))/ (round(sum(irate(istio_requests_total[$__rate_interval])), 0.001)/1000))/ (sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\"}[$__rate_interval])) >bool 10)","format":"time_series","intervalFactor":1,"legendFormat":"istio-proxy","refId":"B"}],"title":"vCPU / 1k rps","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":8},"id":7,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[$__rate_interval]))","format":"time_series","intervalFactor":1,"legendFormat":"istio-ingressgateway","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[$__rate_interval]))","format":"time_series","intervalFactor":1,"legendFormat":"istio-proxy","refId":"B"}],"title":"vCPU","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":16},"id":13,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Memory and Data Rates","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":17},"id":902,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{pod=~\"istio-ingressgateway-.*\"}) / count(container_memory_working_set_bytes{pod=~\"istio-ingressgateway-.*\",container!=\"POD\"})","format":"time_series","intervalFactor":1,"legendFormat":"per istio-ingressgateway","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{namespace!=\"istio-system\",container=\"istio-proxy\"}) / count(container_memory_working_set_bytes{namespace!=\"istio-system\",container=\"istio-proxy\"})","format":"time_series","intervalFactor":1,"legendFormat":"per istio proxy","refId":"B"}],"title":"Memory Usage","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"Bps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":17},"id":11,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(irate(istio_response_bytes_sum{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[$__rate_interval]))","format":"time_series","intervalFactor":1,"legendFormat":"istio-ingressgateway","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(irate(istio_response_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[$__rate_interval])) + sum(irate(istio_request_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[$__rate_interval]))","format":"time_series","intervalFactor":1,"legendFormat":"istio-proxy","refId":"B"}],"title":"Bytes transferred / sec","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":25},"id":17,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Istio Component Versions","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":24,"x":0,"y":26},"id":15,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(istio_build) by (component, tag)","format":"time_series","intervalFactor":1,"legendFormat":"{{ component }}: {{ tag }}","refId":"A"}],"title":"Istio Components by Version","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":34},"id":71,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Proxy Resource Usage","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":0,"y":35},"id":72,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{container=\"istio-proxy\"})","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"Memory","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":6,"y":35},"id":73,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[$__rate_interval]))","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"vCPU","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":12,"y":35},"id":702,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_fs_usage_bytes{container=\"istio-proxy\"})","format":"time_series","intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"Disk","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":42},"id":69,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Istiod Resource Usage","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":0,"y":43},"id":5,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"process_virtual_memory_bytes{app=\"istiod\"}","format":"time_series","instant":false,"intervalFactor":2,"legendFormat":"Virtual Memory","refId":"I","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"process_resident_memory_bytes{app=\"istiod\"}","format":"time_series","intervalFactor":2,"legendFormat":"Resident Memory","refId":"H","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_heap_sys_bytes{app=\"istiod\"}","format":"time_series","hide":true,"intervalFactor":2,"legendFormat":"heap sys","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_heap_alloc_bytes{app=\"istiod\"}","format":"time_series","hide":true,"intervalFactor":2,"legendFormat":"heap alloc","refId":"D"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_alloc_bytes{app=\"istiod\"}","format":"time_series","intervalFactor":2,"legendFormat":"Alloc","refId":"F","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_heap_inuse_bytes{app=\"istiod\"}","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Heap in-use","refId":"E","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_memstats_stack_inuse_bytes{app=\"istiod\"}","format":"time_series","intervalFactor":2,"legendFormat":"Stack in-use","refId":"G","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"})","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"C","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"container_memory_working_set_bytes{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"{{ container }} (k8s)","refId":"B","step":2}],"title":"Memory","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":6,"y":43},"id":602,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[$__rate_interval]))","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[$__rate_interval])) by (container)","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"{{ container }} (k8s)","refId":"B","step":2},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"irate(process_cpu_seconds_total{app=\"istiod\"}[$__rate_interval])","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"pilot (self-reported)","refId":"C","step":2}],"title":"vCPU","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":12,"y":43},"id":74,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"process_open_fds{app=\"istiod\"}","format":"time_series","hide":true,"instant":false,"interval":"","intervalFactor":2,"legendFormat":"Open FDs (pilot)","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"container_fs_usage_bytes{ container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}","format":"time_series","intervalFactor":2,"legendFormat":"{{ container }}","refId":"B","step":2}],"title":"Disk","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":7,"w":6,"x":18,"y":43},"id":402,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":false},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"go_goroutines{app=\"istiod\"}","format":"time_series","intervalFactor":2,"legendFormat":"Number of Goroutines","refId":"A","step":2}],"title":"Goroutines","type":"timeseries"}],"refresh":"","schemaVersion":38,"style":"dark","tags":[],"templating":{"list":[{"hide":0,"includeAll":false,"multi":false,"name":"datasource","options":[],"query":"prometheus","queryValue":"","refresh":1,"regex":"","skipUrlSync":false,"type":"datasource"}]},"time":{"from":"now-30m","to":"now"},"timepicker":{"refresh_intervals":["30s","1m","5m","15m","30m","1h","2h","1d"],"time_options":["5m","15m","1h","6h","12h","24h","2d","7d","30d"]},"timezone":"","title":"Istio Performance Dashboard","version":1,"weekStart":""} pilot-dashboard.json: | {"graphTooltip":1,"panels":[{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":0},"id":1,"panels":[],"title":"Deployed Versions","type":"row"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Version number of each running instance","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"}}},"gridPos":{"h":5,"w":24,"x":0,"y":1},"id":2,"interval":"5s","options":{"legend":{"calcs":[],"displayMode":"list"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (tag) (istio_build{component=\"pilot\"})","legendFormat":"Version ({{tag}})"}],"title":"Pilot Versions","type":"timeseries"},{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":1},"id":3,"panels":[],"title":"Resource Usage","type":"row"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Memory usage of each running instance","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"},"unit":"bytes"}},"gridPos":{"h":10,"w":6,"x":0,"y":2},"id":4,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (pod) (container_memory_working_set_bytes{container=\"discovery\",pod=~\"istiod-.*\"})","legendFormat":"Container ({{pod}})"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (pod) (go_memstats_stack_inuse_bytes{app=\"istiod\"})","legendFormat":"Stack ({{pod}})"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (pod) (go_memstats_heap_inuse_bytes{app=\"istiod\"})","legendFormat":"Heap (In Use) ({{pod}})"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (pod) (go_memstats_heap_alloc_bytes{app=\"istiod\"})","legendFormat":"Heap (Allocated) ({{pod}})"}],"title":"Memory Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Details about memory allocations","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"},"unit":"Bps"},"overrides":[{"matcher":{"id":"byFrameRefID","options":"B"},"properties":[{"id":"custom.axisPlacement","value":"right"},{"id":"unit","value":"c/s"}]}]},"gridPos":{"h":10,"w":6,"x":6,"y":2},"id":5,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (pod) (rate(go_memstats_alloc_bytes_total{app=\"istiod\"}[$__rate_interval]))","legendFormat":"Bytes ({{pod}})"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (pod) (rate(go_memstats_mallocs_total{app=\"istiod\"}[$__rate_interval]))","legendFormat":"Objects ({{pod}})"}],"title":"Memory Allocations","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"CPU usage of each running instance","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"}}},"gridPos":{"h":10,"w":6,"x":12,"y":2},"id":6,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (pod) (irate(container_cpu_usage_seconds_total{container=\"discovery\",pod=~\"istiod-.*\"}[$__rate_interval]))","legendFormat":"Container ({{pod}})"}],"title":"CPU Usage","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Goroutine count for each running instance","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"}}},"gridPos":{"h":10,"w":6,"x":18,"y":2},"id":7,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (pod) (go_goroutines{app=\"istiod\"})","legendFormat":"Goroutines ({{pod}})"}],"title":"Goroutines","type":"timeseries"},{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":3},"id":8,"panels":[],"title":"Push Information","type":"row"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"fieldConfig":{"defaults":{"custom":{"drawStyle":"bars","fillOpacity":100,"gradientMode":"none","showPoints":"never","stacking":{"mode":"normal"}},"unit":"ops"},"overrides":[{"matcher":{"id":"byName","options":"cds"},"properties":[{"id":"displayName","value":"Clusters"}]},{"matcher":{"id":"byName","options":"eds"},"properties":[{"id":"displayName","value":"Endpoints"}]},{"matcher":{"id":"byName","options":"lds"},"properties":[{"id":"displayName","value":"Listeners"}]},{"matcher":{"id":"byName","options":"rds"},"properties":[{"id":"displayName","value":"Routes"}]},{"matcher":{"id":"byName","options":"nds"},"properties":[{"id":"displayName","value":"DNS Tables"}]},{"matcher":{"id":"byName","options":"istio.io/debug"},"properties":[{"id":"displayName","value":"Debug"}]},{"matcher":{"id":"byName","options":"istio.io/debug/syncz"},"properties":[{"id":"displayName","value":"Debug"}]},{"matcher":{"id":"byName","options":"wads"},"properties":[{"id":"displayName","value":"Authorization"}]},{"matcher":{"id":"byName","options":"wds"},"properties":[{"id":"displayName","value":"Workloads"}]},{"matcher":{"id":"byName","options":"type.googleapis.com/istio.security.Authorization"},"properties":[{"id":"displayName","value":"Authorizations"}]},{"matcher":{"id":"byName","options":"type.googleapis.com/istio.workload.Address"},"properties":[{"id":"displayName","value":"Addresses"}]}]},"gridPos":{"h":10,"w":8,"x":0,"y":4},"id":9,"interval":"15s","options":{"legend":{"calcs":[],"displayMode":"list"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (type) (irate(pilot_xds_pushes[$__rate_interval]))","legendFormat":"{{type}}"}],"title":"XDS Pushes","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Size of each xDS push.\n","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"}}},"gridPos":{"h":10,"w":8,"x":8,"y":4},"id":10,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (type,event) (rate(pilot_k8s_reg_events[$__rate_interval]))","legendFormat":"{{event}} {{type}}"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (type,event) (rate(pilot_k8s_cfg_events[$__rate_interval]))","legendFormat":"{{event}} {{type}}"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (type) (rate(pilot_push_triggers[$__rate_interval]))","legendFormat":"Push {{type}}"}],"title":"Events","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Total number of XDS connections\n","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"}}},"gridPos":{"h":10,"w":8,"x":16,"y":4},"id":11,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum(envoy_cluster_upstream_cx_active{cluster_name=\"xds-grpc\"})","legendFormat":"Connections (client reported)"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum (pilot_xds)","legendFormat":"Connections (server reported)"}],"title":"Connections","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Number of push errors. Many of these are at least potentional fatal and should be explored in-depth via Istiod logs.\nNote: metrics here do not use rate() to avoid missing transition from \"No series\"; series are not reported if there are no errors at all.\n","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"}}},"gridPos":{"h":10,"w":8,"x":0,"y":14},"id":12,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (type) (pilot_total_xds_rejects)","legendFormat":"Rejected Config ({{type}})"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"pilot_total_xds_internal_errors","legendFormat":"Internal Errors"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"pilot_xds_push_context_errors","legendFormat":"Push Context Errors"}],"title":"Push Errors","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Count of active and pending proxies managed by each instance.\nPending is expected to converge to zero.\n","gridPos":{"h":10,"w":8,"x":8,"y":14},"id":13,"interval":"1m","options":{"calculation":{"xBuckets":{"mode":"size","value":"1min"}},"cellGap":0,"color":{"mode":"scheme","scheme":"Spectral","steps":128},"yAxis":{"decimals":0,"unit":"s"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum(rate(pilot_xds_push_time_bucket{}[1m])) by (le)","format":"heatmap","legendFormat":"{{le}}"}],"title":"Push Time","type":"heatmap"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Size of each xDS push.\n","gridPos":{"h":10,"w":8,"x":16,"y":14},"id":14,"interval":"1m","options":{"calculation":{"xBuckets":{"mode":"size","value":"1min"}},"cellGap":0,"color":{"mode":"scheme","scheme":"Spectral","steps":128},"yAxis":{"decimals":0,"unit":"bytes"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum(rate(pilot_xds_config_size_bytes_bucket{}[1m])) by (le)","format":"heatmap","legendFormat":"{{le}}"}],"title":"Push Size","type":"heatmap"},{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":100},"id":15,"panels":[],"title":"Webhooks","type":"row"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Rate of XDS push operations, by type. This is incremented on a per-proxy basis.\n","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"}}},"gridPos":{"h":8,"w":12,"x":0,"y":101},"id":16,"interval":"5s","options":{"legend":{"calcs":[],"displayMode":"list"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum (rate(galley_validation_passed[$__rate_interval]))","legendFormat":"Success"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum (rate(galley_validation_failed[$__rate_interval]))","legendFormat":"Failure"}],"title":"Validation","type":"timeseries"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Size of each xDS push.\n","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"}}},"gridPos":{"h":8,"w":12,"x":12,"y":101},"id":17,"interval":"5s","options":{"legend":{"calcs":[],"displayMode":"list"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum (rate(sidecar_injection_success_total[$__rate_interval]))","legendFormat":"Success"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum (rate(sidecar_injection_failure_total[$__rate_interval]))","legendFormat":"Failure"}],"title":"Injection","type":"timeseries"}],"refresh":"15s","schemaVersion":39,"templating":{"list":[{"name":"datasource","query":"prometheus","type":"datasource"}]},"time":{"from":"now-30m","to":"now"},"timezone":"utc","title":"Istio Control Plane Dashboard","uid":"1813f692a8e4ac77155348d4c7d2fba8"} ztunnel-dashboard.json: | @@ -244,7 +242,7 @@ metadata: apiVersion: v1 data: istio-extension-dashboard.json: | - {"annotations":{"list":[{"builtIn":1,"datasource":{"type":"datasource","uid":"grafana"},"enable":true,"hide":true,"iconColor":"rgba(0, 211, 255, 1)","name":"Annotations & Alerts","type":"dashboard"}]},"editable":true,"fiscalYearStartMonth":0,"graphTooltip":0,"links":[],"liveNow":false,"panels":[{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":0},"id":3,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Wasm VMs","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"description":"","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":1},"id":2,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_envoy_wasm_runtime_null_active)","interval":"","legendFormat":"native","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_envoy_wasm_runtime_v8_active)","interval":"","legendFormat":"v8","refId":"B"}],"title":"Active","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":1},"id":6,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_envoy_wasm_runtime_null_created)","interval":"","legendFormat":"native","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_envoy_wasm_runtime_v8_created)","interval":"","legendFormat":"v8","refId":"B"}],"title":"Created","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":9},"id":7,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Wasm Module Remote Load","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":8,"x":0,"y":10},"id":11,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_cache_entries)","interval":"","legendFormat":"entries","refId":"A"}],"title":"Cache Entry","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":8,"x":8,"y":10},"id":8,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_cache_hits)","interval":"","legendFormat":"hits","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_cache_misses)","interval":"","legendFormat":"misses","refId":"B"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_cache_negative_hits)","interval":"","legendFormat":"negative hits","refId":"C"}],"title":"Cache Visit","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":8,"x":16,"y":10},"id":10,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_fetch_failures)","interval":"","legendFormat":"failures","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_fetch_successes)","interval":"","legendFormat":"successes","refId":"B"}],"title":"Remote Fetch","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":18},"id":71,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Proxy Resource Usage","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":19},"id":72,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{container=\"istio-proxy\"})","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"Memory","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":19},"id":73,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[1m]))","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"vCPU","type":"timeseries"}],"refresh":"","schemaVersion":38,"style":"dark","tags":[],"templating":{"list":[{"current":{"selected":false,"text":"default","value":"default"},"hide":0,"includeAll":false,"multi":false,"name":"datasource","options":[],"query":"prometheus","queryValue":"","refresh":1,"regex":"","skipUrlSync":false,"type":"datasource"}]},"time":{"from":"now-5m","to":"now"},"timepicker":{"refresh_intervals":["30s","1m","5m","15m","30m","1h","2h","1d"]},"timezone":"","title":"Istio Wasm Extension Dashboard","version":1,"weekStart":""} + {"annotations":{"list":[{"builtIn":1,"datasource":{"type":"datasource","uid":"grafana"},"enable":true,"hide":true,"iconColor":"rgba(0, 211, 255, 1)","name":"Annotations & Alerts","type":"dashboard"}]},"editable":true,"fiscalYearStartMonth":0,"graphTooltip":0,"links":[],"liveNow":false,"panels":[{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":0},"id":3,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Wasm VMs","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"description":"","fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":1},"id":2,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_envoy_wasm_runtime_null_active)","interval":"","legendFormat":"native","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_envoy_wasm_runtime_v8_active)","interval":"","legendFormat":"v8","refId":"B"}],"title":"Active","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":1},"id":6,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_envoy_wasm_runtime_null_created)","interval":"","legendFormat":"native","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_envoy_wasm_runtime_v8_created)","interval":"","legendFormat":"v8","refId":"B"}],"title":"Created","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":9},"id":7,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Wasm Module Remote Load","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":8,"x":0,"y":10},"id":11,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_cache_entries)","interval":"","legendFormat":"entries","refId":"A"}],"title":"Cache Entry","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":8,"x":8,"y":10},"id":8,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_cache_hits)","interval":"","legendFormat":"hits","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_cache_misses)","interval":"","legendFormat":"misses","refId":"B"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_cache_negative_hits)","interval":"","legendFormat":"negative hits","refId":"C"}],"title":"Cache Visit","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"links":[],"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":8,"x":16,"y":10},"id":10,"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_fetch_failures)","interval":"","legendFormat":"failures","refId":"A"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"avg(envoy_wasm_remote_load_fetch_successes)","interval":"","legendFormat":"successes","refId":"B"}],"title":"Remote Fetch","type":"timeseries"},{"collapsed":false,"datasource":{"type":"prometheus","uid":"${datasource}"},"gridPos":{"h":1,"w":24,"x":0,"y":18},"id":71,"panels":[],"targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"refId":"A"}],"title":"Proxy Resource Usage","type":"row"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"bytes"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":19},"id":72,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(container_memory_working_set_bytes{container=\"istio-proxy\"})","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"Memory","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"${datasource}"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"never","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"short"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":19},"id":73,"links":[],"options":{"legend":{"calcs":[],"displayMode":"list","placement":"bottom","showLegend":true},"tooltip":{"mode":"multi","sort":"none"}},"pluginVersion":"10.1.5","targets":[{"datasource":{"type":"prometheus","uid":"${datasource}"},"expr":"sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[$__rate_interval]))","format":"time_series","hide":false,"intervalFactor":2,"legendFormat":"Total (k8s)","refId":"A","step":2}],"title":"vCPU","type":"timeseries"}],"refresh":"","schemaVersion":38,"style":"dark","tags":[],"templating":{"list":[{"current":{"selected":false,"text":"default","value":"default"},"hide":0,"includeAll":false,"multi":false,"name":"datasource","options":[],"query":"prometheus","queryValue":"","refresh":1,"regex":"","skipUrlSync":false,"type":"datasource"}]},"time":{"from":"now-5m","to":"now"},"timepicker":{"refresh_intervals":["30s","1m","5m","15m","30m","1h","2h","1d"]},"timezone":"","title":"Istio Wasm Extension Dashboard","version":1,"weekStart":""} istio-mesh-dashboard.json: | {"graphTooltip":1,"panels":[{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":0},"id":1,"panels":[],"title":"Global Traffic","type":"row"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Total requests in the cluster","fieldConfig":{"defaults":{"color":{"fixedColor":"blue","mode":"fixed"},"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"},"unit":"reqps"}},"gridPos":{"h":5,"w":6,"x":0,"y":1},"id":2,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"round(sum (rate(istio_requests_total{reporter=~\"source|waypoint\"}[$__rate_interval])), 0.01)"}],"title":"Traffic Volume","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Total success rate of requests in the cluster","fieldConfig":{"defaults":{"color":{"fixedColor":"blue","mode":"fixed"},"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"},"unit":"percentunit"}},"gridPos":{"h":5,"w":6,"x":6,"y":1},"id":3,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum (rate(istio_requests_total{reporter=~\"source|waypoint\",response_code!~\"5..\"}[$__rate_interval])) / sum (rate(istio_requests_total{reporter=~\"source|waypoint\"}[$__rate_interval]))"}],"title":"Success Rate","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Total 4xx requests in in the cluster","fieldConfig":{"defaults":{"color":{"fixedColor":"blue","mode":"fixed"},"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"},"unit":"reqps"}},"gridPos":{"h":5,"w":6,"x":12,"y":1},"id":4,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"round(sum (rate(istio_requests_total{reporter=~\"source|waypoint\",response_code=~\"4..\"}[$__rate_interval])), 0.01)or vector(0)"}],"title":"4xxs","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Total 5xx requests in in the cluster","fieldConfig":{"defaults":{"color":{"fixedColor":"blue","mode":"fixed"},"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"},"unit":"reqps"}},"gridPos":{"h":5,"w":6,"x":18,"y":1},"id":5,"interval":"5s","options":{"legend":{"calcs":["last","max"],"displayMode":"table"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"round(sum (rate(istio_requests_total{reporter=~\"source|waypoint\",response_code=~\"5..\"}[$__rate_interval])), 0.01)or vector(0)"}],"title":"5xxs","type":"stat"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Request information for HTTP services","fieldConfig":{"overrides":[{"matcher":{"id":"byName","options":"Value #requests"},"properties":[{"id":"displayName","value":"Requests"},{"id":"decimals","value":2},{"id":"unit","value":"reqps"}]},{"matcher":{"id":"byName","options":"Value #p50"},"properties":[{"id":"displayName","value":"P50 Latency"},{"id":"decimals","value":2},{"id":"unit","value":"ms"}]},{"matcher":{"id":"byName","options":"Value #p90"},"properties":[{"id":"displayName","value":"P90 Latency"},{"id":"decimals","value":2},{"id":"unit","value":"ms"}]},{"matcher":{"id":"byName","options":"Value #p99"},"properties":[{"id":"displayName","value":"P99 Latency"},{"id":"decimals","value":2},{"id":"unit","value":"ms"}]},{"matcher":{"id":"byName","options":"Value #success"},"properties":[{"id":"displayName","value":"Success Rate"},{"id":"decimals","value":2},{"id":"unit","value":"percentunit"},{"id":"custom.cellOptions","value":{"type":"color-background"}},{"id":"thresholds","value":{"mode":"absolute","steps":[{"color":"red","value":null},{"color":"yellow","value":"0.95"},{"color":"green","value":1}]}}]},{"matcher":{"id":"byName","options":"destination_workload_var"},"properties":[{"id":"displayName","value":"Workload"}]},{"matcher":{"id":"byName","options":"destination_service"},"properties":[{"id":"displayName","value":"Service"},{"id":"custom.minWidth","value":400}]},{"matcher":{"id":"byName","options":"destination_workload_namespace"},"properties":[{"id":"custom.hidden","value":true}]},{"matcher":{"id":"byName","options":"destination_workload"},"properties":[{"id":"custom.hidden","value":true}]},{"matcher":{"id":"byName","options":"Time"},"properties":[{"id":"custom.hidden","value":true}]}]},"gridPos":{"h":16,"w":24,"y":10},"id":6,"interval":"5s","pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"label_join(sum by (destination_workload,destination_workload_namespace,destination_service) (rate(istio_requests_total{reporter=~\"source|waypoint\"}[$__rate_interval])), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")","format":"table","instant":true,"legendFormat":"{{ destination_workload}}.{{ destination_workload_namespace }}","refId":"requests"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"label_join(histogram_quantile(0.5, sum by (le,destination_workload,destination_workload_namespace) (rate(istio_request_duration_milliseconds_bucket{reporter=~\"source|waypoint\"}[$__rate_interval]))), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")","format":"table","instant":true,"legendFormat":"{{ destination_workload}}.{{ destination_workload_namespace }}","refId":"p50"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"label_join(histogram_quantile(0.9, sum by (le,destination_workload,destination_workload_namespace) (rate(istio_request_duration_milliseconds_bucket{reporter=~\"source|waypoint\"}[$__rate_interval]))), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")","format":"table","instant":true,"legendFormat":"{{ destination_workload}}.{{ destination_workload_namespace }}","refId":"p90"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"label_join(histogram_quantile(0.99, sum by (le,destination_workload,destination_workload_namespace) (rate(istio_request_duration_milliseconds_bucket{reporter=~\"source|waypoint\"}[$__rate_interval]))), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")","format":"table","instant":true,"legendFormat":"{{ destination_workload}}.{{ destination_workload_namespace }}","refId":"p99"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"label_join(sum by (destination_workload,destination_workload_namespace) (rate(istio_requests_total{reporter=~\"source|waypoint\",response_code!~\"5..\"}[$__rate_interval]))/sum by (destination_workload,destination_workload_namespace) (rate(istio_requests_total{reporter=~\"source|waypoint\"}[$__rate_interval])), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")","format":"table","instant":true,"legendFormat":"{{ destination_workload}}.{{ destination_workload_namespace }}","refId":"success"}],"title":"HTTP/gRPC Workloads","transformations":[{"id":"merge"}],"type":"table"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Bytes sent and recieived information for TCP services","fieldConfig":{"overrides":[{"matcher":{"id":"byName","options":"Value #recv"},"properties":[{"id":"displayName","value":"Bytes Received"},{"id":"decimals","value":2},{"id":"unit","value":"bps"}]},{"matcher":{"id":"byName","options":"Value #sent"},"properties":[{"id":"displayName","value":"Bytes Sent"},{"id":"decimals","value":2},{"id":"unit","value":"bps"}]},{"matcher":{"id":"byName","options":"destination_workload_var"},"properties":[{"id":"displayName","value":"Workload"}]},{"matcher":{"id":"byName","options":"destination_service"},"properties":[{"id":"displayName","value":"Service"},{"id":"custom.minWidth","value":400}]},{"matcher":{"id":"byName","options":"destination_workload_namespace"},"properties":[{"id":"custom.hidden","value":true}]},{"matcher":{"id":"byName","options":"destination_workload"},"properties":[{"id":"custom.hidden","value":true}]},{"matcher":{"id":"byName","options":"Time"},"properties":[{"id":"custom.hidden","value":true}]}]},"gridPos":{"h":16,"w":24,"y":26},"id":7,"interval":"5s","pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"label_join(sum by (destination_workload,destination_workload_namespace,destination_service) (rate(istio_tcp_received_bytes_total{reporter=~\"source|waypoint\"}[$__rate_interval])), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")","format":"table","instant":true,"legendFormat":"{{ destination_workload}}.{{ destination_workload_namespace }}","refId":"recv"},{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"label_join(sum by (destination_workload,destination_workload_namespace,destination_service) (rate(istio_tcp_sent_bytes_total{reporter=~\"source|waypoint\"}[$__rate_interval])), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")","format":"table","instant":true,"legendFormat":"{{ destination_workload}}.{{ destination_workload_namespace }}","refId":"sent"}],"title":"TCP Workloads","transformations":[{"id":"merge"}],"type":"table"},{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":42},"id":8,"panels":[],"title":"Istio Component Versions","type":"row"},{"datasource":{"type":"datasource","uid":"-- Mixed --"},"description":"Version number of each running instance","fieldConfig":{"defaults":{"custom":{"fillOpacity":10,"gradientMode":"hue","showPoints":"never"}}},"gridPos":{"h":8,"w":24,"x":0,"y":43},"id":9,"interval":"5s","options":{"legend":{"calcs":[],"displayMode":"list"}},"pluginVersion":"v11.0.0","targets":[{"datasource":{"type":"prometheus","uid":"$datasource"},"expr":"sum by (component,tag) (istio_build)","legendFormat":"{{component}} ({{tag}})"}],"title":"Istio Component Versions","type":"timeseries"}],"refresh":"15s","schemaVersion":39,"templating":{"list":[{"name":"datasource","query":"prometheus","type":"datasource"}]},"time":{"from":"now-30m","to":"now"},"timezone":"utc","title":"Istio Mesh Dashboard","uid":"1a9a8ea49444aae205c7737573e894f9"} istio-service-dashboard.json: "{\"annotations\":{\"list\":[{\"builtIn\":1,\"datasource\":{\"type\":\"datasource\",\"uid\":\"grafana\"},\"enable\":true,\"hide\":true,\"iconColor\":\"rgba(0, @@ -628,20 +626,20 @@ data: destination_workload }}.{{ destination_workload_namespace }} P99\",\"refId\":\"H\",\"step\":2}],\"title\":\"Response Size By Service Workload\",\"type\":\"timeseries\"},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"fieldConfig\":{\"defaults\":{\"color\":{\"mode\":\"palette-classic\"},\"custom\":{\"axisCenteredZero\":false,\"axisColorMode\":\"text\",\"axisLabel\":\"\",\"axisPlacement\":\"auto\",\"barAlignment\":0,\"drawStyle\":\"line\",\"fillOpacity\":10,\"gradientMode\":\"none\",\"hideFrom\":{\"legend\":false,\"tooltip\":false,\"viz\":false},\"insertNulls\":false,\"lineInterpolation\":\"linear\",\"lineWidth\":1,\"pointSize\":5,\"scaleDistribution\":{\"type\":\"linear\"},\"showPoints\":\"never\",\"spanNulls\":false,\"stacking\":{\"group\":\"A\",\"mode\":\"none\"},\"thresholdsStyle\":{\"mode\":\"off\"}},\"mappings\":[],\"min\":0,\"thresholds\":{\"mode\":\"absolute\",\"steps\":[{\"color\":\"green\",\"value\":null},{\"color\":\"red\",\"value\":80}]},\"unit\":\"Bps\"},\"overrides\":[]},\"gridPos\":{\"h\":6,\"w\":12,\"x\":0,\"y\":50},\"id\":92,\"links\":[],\"options\":{\"legend\":{\"calcs\":[],\"displayMode\":\"list\",\"placement\":\"bottom\",\"showLegend\":true},\"tooltip\":{\"mode\":\"multi\",\"sort\":\"none\"}},\"pluginVersion\":\"10.1.5\",\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"destination\\\", connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\", - destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m])) + destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[$__rate_interval])) by (destination_workload, destination_workload_namespace), 0.001)\",\"format\":\"time_series\",\"hide\":false,\"intervalFactor\":1,\"legendFormat\":\"{{ destination_workload }}.{{ destination_workload_namespace}} (\U0001F510mTLS)\",\"refId\":\"A\",\"step\":2},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"destination\\\", connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\", - destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m])) + destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[$__rate_interval])) by (destination_workload, destination_workload_namespace), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ destination_workload }}.{{ destination_workload_namespace}}\",\"refId\":\"B\",\"step\":2}],\"title\":\"Bytes Received from Incoming TCP Connection\",\"type\":\"timeseries\"},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"fieldConfig\":{\"defaults\":{\"color\":{\"mode\":\"palette-classic\"},\"custom\":{\"axisCenteredZero\":false,\"axisColorMode\":\"text\",\"axisLabel\":\"\",\"axisPlacement\":\"auto\",\"barAlignment\":0,\"drawStyle\":\"line\",\"fillOpacity\":10,\"gradientMode\":\"none\",\"hideFrom\":{\"legend\":false,\"tooltip\":false,\"viz\":false},\"insertNulls\":false,\"lineInterpolation\":\"linear\",\"lineWidth\":1,\"pointSize\":5,\"scaleDistribution\":{\"type\":\"linear\"},\"showPoints\":\"never\",\"spanNulls\":false,\"stacking\":{\"group\":\"A\",\"mode\":\"none\"},\"thresholdsStyle\":{\"mode\":\"off\"}},\"mappings\":[],\"min\":0,\"thresholds\":{\"mode\":\"absolute\",\"steps\":[{\"color\":\"green\",\"value\":null},{\"color\":\"red\",\"value\":80}]},\"unit\":\"Bps\"},\"overrides\":[]},\"gridPos\":{\"h\":6,\"w\":12,\"x\":12,\"y\":50},\"id\":93,\"links\":[],\"options\":{\"legend\":{\"calcs\":[],\"displayMode\":\"list\",\"placement\":\"bottom\",\"showLegend\":true},\"tooltip\":{\"mode\":\"multi\",\"sort\":\"none\"}},\"pluginVersion\":\"10.1.5\",\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\\\"mutual_tls\\\", reporter=\\\"destination\\\", destination_service=~\\\"$service\\\", destination_workload=~\\\"$dstwl\\\", - destination_workload_namespace=~\\\"$dstns\\\"}[1m])) by (destination_workload, + destination_workload_namespace=~\\\"$dstns\\\"}[$__rate_interval])) by (destination_workload, destination_workload_namespace), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ destination_workload }}.{{destination_workload_namespace }} (\U0001F510mTLS)\",\"refId\":\"A\",\"step\":2},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\\\"mutual_tls\\\", reporter=\\\"destination\\\", destination_service=~\\\"$service\\\", destination_workload=~\\\"$dstwl\\\", - destination_workload_namespace=~\\\"$dstns\\\"}[1m])) by (destination_workload, + destination_workload_namespace=~\\\"$dstns\\\"}[$__rate_interval])) by (destination_workload, destination_workload_namespace), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ destination_workload }}.{{destination_workload_namespace }}\",\"refId\":\"B\",\"step\":2}],\"title\":\"Bytes Sent to Incoming TCP Connection\",\"type\":\"timeseries\"}],\"refresh\":\"1m\",\"schemaVersion\":38,\"style\":\"dark\",\"tags\":[],\"templating\":{\"list\":[{\"hide\":0,\"includeAll\":false,\"multi\":false,\"name\":\"datasource\",\"options\":[],\"query\":\"prometheus\",\"queryValue\":\"\",\"refresh\":1,\"regex\":\"\",\"skipUrlSync\":false,\"type\":\"datasource\"},{\"current\":{\"selected\":false,\"text\":\"details.default.svc.cluster.local\",\"value\":\"details.default.svc.cluster.local\"},\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"definition\":\"\",\"hide\":0,\"includeAll\":false,\"label\":\"Service\",\"multi\":false,\"name\":\"service\",\"options\":[],\"query\":\"query_result(sum(istio_requests_total{}) @@ -696,14 +694,14 @@ data: destination_workload_namespace=~\\\"$namespace\\\"}[1m])) by (le))\",\"format\":\"time_series\",\"hide\":false,\"intervalFactor\":1,\"legendFormat\":\"P99\",\"refId\":\"C\"}],\"title\":\"Request Duration\",\"type\":\"timeseries\"},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"fieldConfig\":{\"defaults\":{\"color\":{\"fixedColor\":\"rgb(31, 120, 193)\",\"mode\":\"fixed\"},\"mappings\":[{\"options\":{\"match\":\"null\",\"result\":{\"text\":\"N/A\"}},\"type\":\"special\"}],\"thresholds\":{\"mode\":\"absolute\",\"steps\":[{\"color\":\"green\",\"value\":null},{\"color\":\"red\",\"value\":80}]},\"unit\":\"Bps\"},\"overrides\":[]},\"gridPos\":{\"h\":4,\"w\":12,\"x\":0,\"y\":8},\"id\":84,\"links\":[],\"maxDataPoints\":100,\"options\":{\"colorMode\":\"none\",\"graphMode\":\"area\",\"justifyMode\":\"auto\",\"orientation\":\"horizontal\",\"reduceOptions\":{\"calcs\":[\"mean\"],\"fields\":\"\",\"values\":false},\"textMode\":\"auto\"},\"pluginVersion\":\"10.1.5\",\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"sum(irate(istio_tcp_sent_bytes_total{reporter=~\\\"$qrep\\\", - destination_workload_namespace=~\\\"$namespace\\\", destination_workload=~\\\"$workload\\\"}[1m])) + destination_workload_namespace=~\\\"$namespace\\\", destination_workload=~\\\"$workload\\\"}[$__rate_interval])) + sum(irate(istio_tcp_received_bytes_total{reporter=~\\\"$qrep\\\", destination_workload_namespace=~\\\"$namespace\\\", - destination_workload=~\\\"$workload\\\"}[1m]))\",\"format\":\"time_series\",\"hide\":false,\"intervalFactor\":1,\"legendFormat\":\"\",\"refId\":\"A\"}],\"title\":\"TCP + destination_workload=~\\\"$workload\\\"}[$__rate_interval]))\",\"format\":\"time_series\",\"hide\":false,\"intervalFactor\":1,\"legendFormat\":\"\",\"refId\":\"A\"}],\"title\":\"TCP Server Traffic\",\"type\":\"stat\"},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"fieldConfig\":{\"defaults\":{\"color\":{\"fixedColor\":\"rgb(31, 120, 193)\",\"mode\":\"fixed\"},\"mappings\":[{\"options\":{\"match\":\"null\",\"result\":{\"text\":\"N/A\"}},\"type\":\"special\"}],\"thresholds\":{\"mode\":\"absolute\",\"steps\":[{\"color\":\"green\",\"value\":null},{\"color\":\"red\",\"value\":80}]},\"unit\":\"Bps\"},\"overrides\":[]},\"gridPos\":{\"h\":4,\"w\":12,\"x\":12,\"y\":8},\"id\":85,\"links\":[],\"maxDataPoints\":100,\"options\":{\"colorMode\":\"none\",\"graphMode\":\"area\",\"justifyMode\":\"auto\",\"orientation\":\"horizontal\",\"reduceOptions\":{\"calcs\":[\"mean\"],\"fields\":\"\",\"values\":false},\"textMode\":\"auto\"},\"pluginVersion\":\"10.1.5\",\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"sum(irate(istio_tcp_sent_bytes_total{reporter=~\\\"$qrep\\\", - source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\"}[1m])) + source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\"}[$__rate_interval])) + sum(irate(istio_tcp_received_bytes_total{reporter=~\\\"$qrep\\\", source_workload_namespace=~\\\"$namespace\\\", - source_workload=~\\\"$workload\\\"}[1m]))\",\"format\":\"time_series\",\"hide\":false,\"intervalFactor\":1,\"legendFormat\":\"\",\"refId\":\"A\"}],\"title\":\"TCP + source_workload=~\\\"$workload\\\"}[$__rate_interval]))\",\"format\":\"time_series\",\"hide\":false,\"intervalFactor\":1,\"legendFormat\":\"\",\"refId\":\"A\"}],\"title\":\"TCP Client Traffic\",\"type\":\"stat\"},{\"collapsed\":false,\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"gridPos\":{\"h\":1,\"w\":24,\"x\":0,\"y\":12},\"id\":93,\"panels\":[],\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"refId\":\"A\"}],\"title\":\"Inbound Workloads\",\"type\":\"row\"},{\"gridPos\":{\"h\":3,\"w\":24,\"x\":0,\"y\":13},\"id\":45,\"links\":[],\"options\":{\"code\":{\"language\":\"plaintext\",\"showLineNumbers\":false,\"showMiniMap\":false},\"content\":\"
\\nINBOUND WORKLOADS\\n
\",\"mode\":\"html\"},\"pluginVersion\":\"10.1.5\",\"transparent\":true,\"type\":\"text\"},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"fieldConfig\":{\"defaults\":{\"color\":{\"mode\":\"palette-classic\"},\"custom\":{\"axisCenteredZero\":false,\"axisColorMode\":\"text\",\"axisLabel\":\"\",\"axisPlacement\":\"auto\",\"barAlignment\":0,\"drawStyle\":\"line\",\"fillOpacity\":0,\"gradientMode\":\"none\",\"hideFrom\":{\"legend\":false,\"tooltip\":false,\"viz\":false},\"insertNulls\":false,\"lineInterpolation\":\"linear\",\"lineWidth\":1,\"pointSize\":5,\"scaleDistribution\":{\"type\":\"linear\"},\"showPoints\":\"never\",\"spanNulls\":false,\"stacking\":{\"group\":\"A\",\"mode\":\"none\"},\"thresholdsStyle\":{\"mode\":\"off\"}},\"mappings\":[],\"min\":0,\"thresholds\":{\"mode\":\"absolute\",\"steps\":[{\"color\":\"green\",\"value\":null},{\"color\":\"red\",\"value\":80}]},\"unit\":\"ops\"},\"overrides\":[{\"matcher\":{\"id\":\"byValue\",\"options\":{\"op\":\"gte\",\"reducer\":\"allIsNull\",\"value\":0}},\"properties\":[{\"id\":\"custom.hideFrom\",\"value\":{\"legend\":true,\"tooltip\":true,\"viz\":false}}]}]},\"gridPos\":{\"h\":6,\"w\":12,\"x\":0,\"y\":16},\"id\":25,\"links\":[],\"options\":{\"legend\":{\"calcs\":[],\"displayMode\":\"list\",\"placement\":\"bottom\",\"showLegend\":true},\"tooltip\":{\"mode\":\"single\",\"sort\":\"none\"}},\"pluginVersion\":\"10.1.5\",\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_requests_total{connection_security_policy=\\\"mutual_tls\\\", @@ -894,20 +892,20 @@ data: by (source_workload, source_workload_namespace, le))\",\"format\":\"time_series\",\"hide\":false,\"intervalFactor\":1,\"legendFormat\":\"{{source_workload}}.{{source_workload_namespace}} P99\",\"refId\":\"H\",\"step\":2}],\"title\":\"Response Size By Source\",\"type\":\"timeseries\"},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"fieldConfig\":{\"defaults\":{\"color\":{\"mode\":\"palette-classic\"},\"custom\":{\"axisCenteredZero\":false,\"axisColorMode\":\"text\",\"axisLabel\":\"\",\"axisPlacement\":\"auto\",\"barAlignment\":0,\"drawStyle\":\"line\",\"fillOpacity\":10,\"gradientMode\":\"none\",\"hideFrom\":{\"legend\":false,\"tooltip\":false,\"viz\":false},\"insertNulls\":false,\"lineInterpolation\":\"linear\",\"lineWidth\":1,\"pointSize\":5,\"scaleDistribution\":{\"type\":\"linear\"},\"showPoints\":\"never\",\"spanNulls\":false,\"stacking\":{\"group\":\"A\",\"mode\":\"none\"},\"thresholdsStyle\":{\"mode\":\"off\"}},\"mappings\":[],\"min\":0,\"thresholds\":{\"mode\":\"absolute\",\"steps\":[{\"color\":\"green\",\"value\":null},{\"color\":\"red\",\"value\":80}]},\"unit\":\"Bps\"},\"overrides\":[]},\"gridPos\":{\"h\":6,\"w\":12,\"x\":0,\"y\":28},\"id\":80,\"links\":[],\"options\":{\"legend\":{\"calcs\":[],\"displayMode\":\"list\",\"placement\":\"bottom\",\"showLegend\":true},\"tooltip\":{\"mode\":\"multi\",\"sort\":\"none\"}},\"pluginVersion\":\"10.1.5\",\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_received_bytes_total{reporter=~\\\"$qrep\\\", connection_security_policy=\\\"mutual_tls\\\", destination_workload_namespace=~\\\"$namespace\\\", - destination_workload=~\\\"$workload\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m])) + destination_workload=~\\\"$workload\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[$__rate_interval])) by (source_workload, source_workload_namespace), 0.001)\",\"format\":\"time_series\",\"hide\":false,\"intervalFactor\":1,\"legendFormat\":\"{{ source_workload }}.{{ source_workload_namespace}} (\U0001F510mTLS)\",\"refId\":\"A\",\"step\":2},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_received_bytes_total{reporter=~\\\"$qrep\\\", connection_security_policy!=\\\"mutual_tls\\\", destination_workload_namespace=~\\\"$namespace\\\", - destination_workload=~\\\"$workload\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m])) + destination_workload=~\\\"$workload\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[$__rate_interval])) by (source_workload, source_workload_namespace), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ source_workload }}.{{ source_workload_namespace}}\",\"refId\":\"B\",\"step\":2}],\"title\":\"Bytes Received from Incoming TCP Connection\",\"type\":\"timeseries\"},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"fieldConfig\":{\"defaults\":{\"color\":{\"mode\":\"palette-classic\"},\"custom\":{\"axisCenteredZero\":false,\"axisColorMode\":\"text\",\"axisLabel\":\"\",\"axisPlacement\":\"auto\",\"barAlignment\":0,\"drawStyle\":\"line\",\"fillOpacity\":10,\"gradientMode\":\"none\",\"hideFrom\":{\"legend\":false,\"tooltip\":false,\"viz\":false},\"insertNulls\":false,\"lineInterpolation\":\"linear\",\"lineWidth\":1,\"pointSize\":5,\"scaleDistribution\":{\"type\":\"linear\"},\"showPoints\":\"never\",\"spanNulls\":false,\"stacking\":{\"group\":\"A\",\"mode\":\"none\"},\"thresholdsStyle\":{\"mode\":\"off\"}},\"mappings\":[],\"min\":0,\"thresholds\":{\"mode\":\"absolute\",\"steps\":[{\"color\":\"green\",\"value\":null},{\"color\":\"red\",\"value\":80}]},\"unit\":\"Bps\"},\"overrides\":[]},\"gridPos\":{\"h\":6,\"w\":12,\"x\":12,\"y\":28},\"id\":82,\"links\":[],\"options\":{\"legend\":{\"calcs\":[],\"displayMode\":\"list\",\"placement\":\"bottom\",\"showLegend\":true},\"tooltip\":{\"mode\":\"multi\",\"sort\":\"none\"}},\"pluginVersion\":\"10.1.5\",\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\\\"mutual_tls\\\", reporter=~\\\"$qrep\\\", destination_workload_namespace=~\\\"$namespace\\\", destination_workload=~\\\"$workload\\\", - source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m])) + source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[$__rate_interval])) by (source_workload, source_workload_namespace), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ source_workload }}.{{ source_workload_namespace}} (\U0001F510mTLS)\",\"refId\":\"A\",\"step\":2},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\\\"mutual_tls\\\", reporter=~\\\"$qrep\\\", destination_workload_namespace=~\\\"$namespace\\\", destination_workload=~\\\"$workload\\\", - source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m])) + source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[$__rate_interval])) by (source_workload, source_workload_namespace), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ source_workload }}.{{ source_workload_namespace}}\",\"refId\":\"B\",\"step\":2}],\"title\":\"Bytes Sent to Incoming TCP Connection\",\"type\":\"timeseries\"},{\"collapsed\":false,\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"gridPos\":{\"h\":1,\"w\":24,\"x\":0,\"y\":34},\"id\":91,\"panels\":[],\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"refId\":\"A\"}],\"title\":\"Outbound @@ -1069,18 +1067,20 @@ data: destination_service }} P99\",\"refId\":\"H\",\"step\":2}],\"title\":\"Response Size By Destination\",\"type\":\"timeseries\"},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"fieldConfig\":{\"defaults\":{\"color\":{\"mode\":\"palette-classic\"},\"custom\":{\"axisCenteredZero\":false,\"axisColorMode\":\"text\",\"axisLabel\":\"\",\"axisPlacement\":\"auto\",\"barAlignment\":0,\"drawStyle\":\"line\",\"fillOpacity\":10,\"gradientMode\":\"none\",\"hideFrom\":{\"legend\":false,\"tooltip\":false,\"viz\":false},\"insertNulls\":false,\"lineInterpolation\":\"linear\",\"lineWidth\":1,\"pointSize\":5,\"scaleDistribution\":{\"type\":\"linear\"},\"showPoints\":\"never\",\"spanNulls\":false,\"stacking\":{\"group\":\"A\",\"mode\":\"none\"},\"thresholdsStyle\":{\"mode\":\"off\"}},\"mappings\":[],\"min\":0,\"thresholds\":{\"mode\":\"absolute\",\"steps\":[{\"color\":\"green\",\"value\":null},{\"color\":\"red\",\"value\":80}]},\"unit\":\"Bps\"},\"overrides\":[]},\"gridPos\":{\"h\":6,\"w\":12,\"x\":0,\"y\":50},\"id\":76,\"links\":[],\"options\":{\"legend\":{\"calcs\":[],\"displayMode\":\"list\",\"placement\":\"bottom\",\"showLegend\":true},\"tooltip\":{\"mode\":\"multi\",\"sort\":\"none\"}},\"pluginVersion\":\"10.1.5\",\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_received_bytes_total{connection_security_policy=\\\"mutual_tls\\\", reporter=\\\"source\\\", source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\", - destination_service=~\\\"$dstsvc\\\"}[1m])) by (destination_service), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ + destination_service=~\\\"$dstsvc\\\"}[$__rate_interval])) by (destination_service), + 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ destination_service }} (\U0001F510mTLS)\",\"refId\":\"A\",\"step\":2},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_received_bytes_total{connection_security_policy!=\\\"mutual_tls\\\", reporter=\\\"source\\\", source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\", - destination_service=~\\\"$dstsvc\\\"}[1m])) by (destination_service), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ + destination_service=~\\\"$dstsvc\\\"}[$__rate_interval])) by (destination_service), + 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ destination_service }}\",\"refId\":\"B\",\"step\":2}],\"title\":\"Bytes Sent on Outgoing TCP Connection\",\"type\":\"timeseries\"},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"fieldConfig\":{\"defaults\":{\"color\":{\"mode\":\"palette-classic\"},\"custom\":{\"axisCenteredZero\":false,\"axisColorMode\":\"text\",\"axisLabel\":\"\",\"axisPlacement\":\"auto\",\"barAlignment\":0,\"drawStyle\":\"line\",\"fillOpacity\":10,\"gradientMode\":\"none\",\"hideFrom\":{\"legend\":false,\"tooltip\":false,\"viz\":false},\"insertNulls\":false,\"lineInterpolation\":\"linear\",\"lineWidth\":1,\"pointSize\":5,\"scaleDistribution\":{\"type\":\"linear\"},\"showPoints\":\"never\",\"spanNulls\":false,\"stacking\":{\"group\":\"A\",\"mode\":\"none\"},\"thresholdsStyle\":{\"mode\":\"off\"}},\"mappings\":[],\"min\":0,\"thresholds\":{\"mode\":\"absolute\",\"steps\":[{\"color\":\"green\",\"value\":null},{\"color\":\"red\",\"value\":80}]},\"unit\":\"Bps\"},\"overrides\":[]},\"gridPos\":{\"h\":6,\"w\":12,\"x\":12,\"y\":50},\"id\":78,\"links\":[],\"options\":{\"legend\":{\"calcs\":[],\"displayMode\":\"list\",\"placement\":\"bottom\",\"showLegend\":true},\"tooltip\":{\"mode\":\"multi\",\"sort\":\"none\"}},\"pluginVersion\":\"10.1.5\",\"targets\":[{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_sent_bytes_total{reporter=\\\"source\\\", connection_security_policy=\\\"mutual_tls\\\", source_workload_namespace=~\\\"$namespace\\\", - source_workload=~\\\"$workload\\\", destination_service=~\\\"$dstsvc\\\"}[1m])) + source_workload=~\\\"$workload\\\", destination_service=~\\\"$dstsvc\\\"}[$__rate_interval])) by (destination_service), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ destination_service }} (\U0001F510mTLS)\",\"refId\":\"A\",\"step\":2},{\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"expr\":\"round(sum(irate(istio_tcp_sent_bytes_total{reporter=\\\"source\\\", connection_security_policy!=\\\"mutual_tls\\\", source_workload_namespace=~\\\"$namespace\\\", - source_workload=~\\\"$workload\\\", destination_service=~\\\"$dstsvc\\\"}[1m])) + source_workload=~\\\"$workload\\\", destination_service=~\\\"$dstsvc\\\"}[$__rate_interval])) by (destination_service), 0.001)\",\"format\":\"time_series\",\"intervalFactor\":1,\"legendFormat\":\"{{ destination_service }}\",\"refId\":\"B\",\"step\":2}],\"title\":\"Bytes Received from Outgoing TCP Connection\",\"type\":\"timeseries\"}],\"refresh\":\"1m\",\"schemaVersion\":38,\"style\":\"dark\",\"tags\":[],\"templating\":{\"list\":[{\"hide\":0,\"includeAll\":false,\"multi\":false,\"name\":\"datasource\",\"options\":[],\"query\":\"prometheus\",\"queryValue\":\"\",\"refresh\":1,\"regex\":\"\",\"skipUrlSync\":false,\"type\":\"datasource\"},{\"current\":{\"selected\":true,\"text\":\"default\",\"value\":\"default\"},\"datasource\":{\"type\":\"prometheus\",\"uid\":\"${datasource}\"},\"definition\":\"\",\"hide\":0,\"includeAll\":false,\"label\":\"Namespace\",\"multi\":false,\"name\":\"namespace\",\"options\":[],\"query\":\"query_result(sum(istio_requests_total) diff --git a/samples/addons/jaeger.yaml b/samples/addons/jaeger.yaml index 6cc1358742b1..89d46f7b1bc9 100644 --- a/samples/addons/jaeger.yaml +++ b/samples/addons/jaeger.yaml @@ -20,7 +20,7 @@ spec: spec: containers: - name: jaeger - image: "docker.io/jaegertracing/all-in-one:1.58" + image: "docker.io/jaegertracing/all-in-one:1.63.0" env: - name: BADGER_EPHEMERAL value: "false" diff --git a/samples/addons/kiali.yaml b/samples/addons/kiali.yaml index f899a633b176..0dbcdec40432 100644 --- a/samples/addons/kiali.yaml +++ b/samples/addons/kiali.yaml @@ -6,13 +6,12 @@ metadata: name: kiali namespace: "istio-system" labels: - helm.sh/chart: kiali-server-2.0.0 + helm.sh/chart: kiali-server-2.2.0 app: kiali app.kubernetes.io/name: kiali app.kubernetes.io/instance: kiali - version: "v2.0.0" - app.kubernetes.io/version: "v2.0.0" - app.kubernetes.io/managed-by: Helm + version: "v2.2.0" + app.kubernetes.io/version: "v2.2.0" app.kubernetes.io/part-of: "kiali" ... --- @@ -23,13 +22,12 @@ metadata: name: kiali namespace: "istio-system" labels: - helm.sh/chart: kiali-server-2.0.0 + helm.sh/chart: kiali-server-2.2.0 app: kiali app.kubernetes.io/name: kiali app.kubernetes.io/instance: kiali - version: "v2.0.0" - app.kubernetes.io/version: "v2.0.0" - app.kubernetes.io/managed-by: Helm + version: "v2.2.0" + app.kubernetes.io/version: "v2.2.0" app.kubernetes.io/part-of: "kiali" data: config.yaml: | @@ -68,7 +66,7 @@ data: image_name: quay.io/kiali/kiali image_pull_policy: IfNotPresent image_pull_secrets: [] - image_version: v2.0 + image_version: v2.2 ingress: additional_labels: {} class_name: nginx @@ -87,6 +85,18 @@ data: pod_labels: sidecar.istio.io/inject: "false" priority_class_name: "" + probes: + liveness: + initial_delay_seconds: 5 + period_seconds: 30 + readiness: + initial_delay_seconds: 5 + period_seconds: 30 + startup: + failure_threshold: 6 + initial_delay_seconds: 30 + period_seconds: 10 + remote_cluster_resources_only: false replicas: 1 resources: limits: @@ -99,7 +109,7 @@ data: service_annotations: {} service_type: "" tolerations: [] - version_label: v2.0.0 + version_label: v2.2.0 view_only_mode: false external_services: custom_dashboards: @@ -134,13 +144,12 @@ kind: ClusterRole metadata: name: kiali labels: - helm.sh/chart: kiali-server-2.0.0 + helm.sh/chart: kiali-server-2.2.0 app: kiali app.kubernetes.io/name: kiali app.kubernetes.io/instance: kiali - version: "v2.0.0" - app.kubernetes.io/version: "v2.0.0" - app.kubernetes.io/managed-by: Helm + version: "v2.2.0" + app.kubernetes.io/version: "v2.2.0" app.kubernetes.io/part-of: "kiali" rules: - apiGroups: [""] @@ -248,13 +257,12 @@ kind: ClusterRoleBinding metadata: name: kiali labels: - helm.sh/chart: kiali-server-2.0.0 + helm.sh/chart: kiali-server-2.2.0 app: kiali app.kubernetes.io/name: kiali app.kubernetes.io/instance: kiali - version: "v2.0.0" - app.kubernetes.io/version: "v2.0.0" - app.kubernetes.io/managed-by: Helm + version: "v2.2.0" + app.kubernetes.io/version: "v2.2.0" app.kubernetes.io/part-of: "kiali" roleRef: apiGroup: rbac.authorization.k8s.io @@ -273,13 +281,12 @@ metadata: name: kiali namespace: "istio-system" labels: - helm.sh/chart: kiali-server-2.0.0 + helm.sh/chart: kiali-server-2.2.0 app: kiali app.kubernetes.io/name: kiali app.kubernetes.io/instance: kiali - version: "v2.0.0" - app.kubernetes.io/version: "v2.0.0" - app.kubernetes.io/managed-by: Helm + version: "v2.2.0" + app.kubernetes.io/version: "v2.2.0" app.kubernetes.io/part-of: "kiali" annotations: spec: @@ -304,13 +311,12 @@ metadata: name: kiali namespace: "istio-system" labels: - helm.sh/chart: kiali-server-2.0.0 + helm.sh/chart: kiali-server-2.2.0 app: kiali app.kubernetes.io/name: kiali app.kubernetes.io/instance: kiali - version: "v2.0.0" - app.kubernetes.io/version: "v2.0.0" - app.kubernetes.io/managed-by: Helm + version: "v2.2.0" + app.kubernetes.io/version: "v2.2.0" app.kubernetes.io/part-of: "kiali" spec: replicas: 1 @@ -327,30 +333,30 @@ spec: metadata: name: kiali labels: - helm.sh/chart: kiali-server-2.0.0 + helm.sh/chart: kiali-server-2.2.0 app: kiali app.kubernetes.io/name: kiali app.kubernetes.io/instance: kiali - version: "v2.0.0" - app.kubernetes.io/version: "v2.0.0" - app.kubernetes.io/managed-by: Helm + version: "v2.2.0" + app.kubernetes.io/version: "v2.2.0" app.kubernetes.io/part-of: "kiali" sidecar.istio.io/inject: "false" annotations: - checksum/config: 03a677accc379d7d5b7b3c74464dc72867b31f794e5beaa98221ba19c5735016 + checksum/config: 6193c1858cb3618b8f65ae27ed8e8b194c478e059f08cd7e99fe4231314a6661 prometheus.io/scrape: "true" prometheus.io/port: "9090" kiali.io/dashboards: go,kiali spec: serviceAccountName: kiali containers: - - image: "quay.io/kiali/kiali:v2.0" + - image: "quay.io/kiali/kiali:v2.2" imagePullPolicy: IfNotPresent name: kiali command: - "/opt/kiali/kiali" - "-config" - "/kiali-configuration/config.yaml" + terminationMessagePolicy: FallbackToLogsOnError securityContext: allowPrivilegeEscalation: false privileged: false @@ -378,6 +384,14 @@ spec: scheme: HTTP initialDelaySeconds: 5 periodSeconds: 30 + startupProbe: + httpGet: + path: /kiali/healthz + port: api-port + scheme: HTTP + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 env: - name: ACTIVE_NAMESPACE valueFrom: diff --git a/samples/addons/loki.yaml b/samples/addons/loki.yaml index 2bc77414af82..291414c664c3 100644 --- a/samples/addons/loki.yaml +++ b/samples/addons/loki.yaml @@ -6,11 +6,10 @@ metadata: name: loki namespace: istio-system labels: - helm.sh/chart: loki-6.18.0 + helm.sh/chart: loki-6.24.0 app.kubernetes.io/name: loki app.kubernetes.io/instance: loki - app.kubernetes.io/version: "3.2.0" - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: "3.3.2" automountServiceAccountToken: true --- # Source: loki/templates/config.yaml @@ -20,11 +19,10 @@ metadata: name: loki namespace: istio-system labels: - helm.sh/chart: loki-6.18.0 + helm.sh/chart: loki-6.24.0 app.kubernetes.io/name: loki app.kubernetes.io/instance: loki - app.kubernetes.io/version: "3.2.0" - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: "3.3.2" data: config.yaml: | @@ -69,6 +67,8 @@ data: ruler: storage: type: local + wal: + dir: /var/loki/ruler-wal runtime_config: file: /etc/loki/runtime-config/runtime-config.yaml schema_config: @@ -108,11 +108,10 @@ metadata: name: loki-runtime namespace: istio-system labels: - helm.sh/chart: loki-6.18.0 + helm.sh/chart: loki-6.24.0 app.kubernetes.io/name: loki app.kubernetes.io/instance: loki - app.kubernetes.io/version: "3.2.0" - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: "3.3.2" data: runtime-config.yaml: | {} @@ -122,11 +121,10 @@ kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: - helm.sh/chart: loki-6.18.0 + helm.sh/chart: loki-6.24.0 app.kubernetes.io/name: loki app.kubernetes.io/instance: loki - app.kubernetes.io/version: "3.2.0" - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: "3.3.2" name: loki-clusterrole rules: - apiGroups: [""] # "" indicates the core API group @@ -139,11 +137,10 @@ apiVersion: rbac.authorization.k8s.io/v1 metadata: name: loki-clusterrolebinding labels: - helm.sh/chart: loki-6.18.0 + helm.sh/chart: loki-6.24.0 app.kubernetes.io/name: loki app.kubernetes.io/instance: loki - app.kubernetes.io/version: "3.2.0" - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: "3.3.2" subjects: - kind: ServiceAccount name: loki @@ -160,11 +157,10 @@ metadata: name: loki-memberlist namespace: istio-system labels: - helm.sh/chart: loki-6.18.0 + helm.sh/chart: loki-6.24.0 app.kubernetes.io/name: loki app.kubernetes.io/instance: loki - app.kubernetes.io/version: "3.2.0" - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: "3.3.2" annotations: spec: type: ClusterIP @@ -186,11 +182,10 @@ metadata: name: loki-headless namespace: istio-system labels: - helm.sh/chart: loki-6.18.0 + helm.sh/chart: loki-6.24.0 app.kubernetes.io/name: loki app.kubernetes.io/instance: loki - app.kubernetes.io/version: "3.2.0" - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: "3.3.2" variant: headless prometheus.io/service-monitor: "false" annotations: @@ -212,11 +207,10 @@ metadata: name: loki namespace: istio-system labels: - helm.sh/chart: loki-6.18.0 + helm.sh/chart: loki-6.24.0 app.kubernetes.io/name: loki app.kubernetes.io/instance: loki - app.kubernetes.io/version: "3.2.0" - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: "3.3.2" annotations: spec: type: ClusterIP @@ -241,11 +235,10 @@ metadata: name: loki namespace: istio-system labels: - helm.sh/chart: loki-6.18.0 + helm.sh/chart: loki-6.24.0 app.kubernetes.io/name: loki app.kubernetes.io/instance: loki - app.kubernetes.io/version: "3.2.0" - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: "3.3.2" app.kubernetes.io/component: single-binary app.kubernetes.io/part-of: memberlist spec: @@ -268,7 +261,7 @@ spec: template: metadata: annotations: - checksum/config: 33763d92c95bb565c019078f0419bddedd9febff7743044c8a329dfe84d4d218 + checksum/config: 65f45e07d0596b0b96b33e41e6d153bd55f4f5da04824b4f0a4f7b2937f5b3f0 labels: app.kubernetes.io/name: loki app.kubernetes.io/instance: loki @@ -287,7 +280,7 @@ spec: terminationGracePeriodSeconds: 30 containers: - name: loki-sc-rules - image: "kiwigrid/k8s-sidecar:1.27.5" + image: "kiwigrid/k8s-sidecar:1.28.0" imagePullPolicy: IfNotPresent env: - name: METHOD @@ -308,7 +301,7 @@ spec: - name: sc-rules-volume mountPath: "/rules" - name: loki - image: docker.io/grafana/loki:3.2.0 + image: docker.io/grafana/loki:3.3.2 imagePullPolicy: IfNotPresent args: - -config.file=/etc/loki/config/config.yaml diff --git a/samples/addons/prometheus.yaml b/samples/addons/prometheus.yaml index 78f92228eb1e..aafdaf7fec52 100644 --- a/samples/addons/prometheus.yaml +++ b/samples/addons/prometheus.yaml @@ -7,9 +7,8 @@ metadata: app.kubernetes.io/component: server app.kubernetes.io/name: prometheus app.kubernetes.io/instance: prometheus - app.kubernetes.io/version: v2.54.1 - helm.sh/chart: prometheus-25.27.0 - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: v3.0.1 + helm.sh/chart: prometheus-26.0.1 app.kubernetes.io/part-of: prometheus name: prometheus namespace: istio-system @@ -24,9 +23,8 @@ metadata: app.kubernetes.io/component: server app.kubernetes.io/name: prometheus app.kubernetes.io/instance: prometheus - app.kubernetes.io/version: v2.54.1 - helm.sh/chart: prometheus-25.27.0 - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: v3.0.1 + helm.sh/chart: prometheus-26.0.1 app.kubernetes.io/part-of: prometheus name: prometheus namespace: istio-system @@ -359,9 +357,8 @@ metadata: app.kubernetes.io/component: server app.kubernetes.io/name: prometheus app.kubernetes.io/instance: prometheus - app.kubernetes.io/version: v2.54.1 - helm.sh/chart: prometheus-25.27.0 - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: v3.0.1 + helm.sh/chart: prometheus-26.0.1 app.kubernetes.io/part-of: prometheus name: prometheus rules: @@ -411,9 +408,8 @@ metadata: app.kubernetes.io/component: server app.kubernetes.io/name: prometheus app.kubernetes.io/instance: prometheus - app.kubernetes.io/version: v2.54.1 - helm.sh/chart: prometheus-25.27.0 - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: v3.0.1 + helm.sh/chart: prometheus-26.0.1 app.kubernetes.io/part-of: prometheus name: prometheus subjects: @@ -433,9 +429,8 @@ metadata: app.kubernetes.io/component: server app.kubernetes.io/name: prometheus app.kubernetes.io/instance: prometheus - app.kubernetes.io/version: v2.54.1 - helm.sh/chart: prometheus-25.27.0 - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: v3.0.1 + helm.sh/chart: prometheus-26.0.1 app.kubernetes.io/part-of: prometheus name: prometheus namespace: istio-system @@ -460,9 +455,8 @@ metadata: app.kubernetes.io/component: server app.kubernetes.io/name: prometheus app.kubernetes.io/instance: prometheus - app.kubernetes.io/version: v2.54.1 - helm.sh/chart: prometheus-25.27.0 - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: v3.0.1 + helm.sh/chart: prometheus-26.0.1 app.kubernetes.io/part-of: prometheus name: prometheus namespace: istio-system @@ -483,9 +477,8 @@ spec: app.kubernetes.io/component: server app.kubernetes.io/name: prometheus app.kubernetes.io/instance: prometheus - app.kubernetes.io/version: v2.54.1 - helm.sh/chart: prometheus-25.27.0 - app.kubernetes.io/managed-by: Helm + app.kubernetes.io/version: v3.0.1 + helm.sh/chart: prometheus-26.0.1 app.kubernetes.io/part-of: prometheus sidecar.istio.io/inject: "false" @@ -494,7 +487,7 @@ spec: serviceAccountName: prometheus containers: - name: prometheus-server-configmap-reload - image: "ghcr.io/prometheus-operator/prometheus-config-reloader:v0.76.0" + image: "ghcr.io/prometheus-operator/prometheus-config-reloader:v0.78.2" imagePullPolicy: "IfNotPresent" args: - --watched-dir=/etc/config @@ -522,7 +515,7 @@ spec: readOnly: true - name: prometheus-server - image: "prom/prometheus:v2.54.1" + image: "prom/prometheus:v3.0.1" imagePullPolicy: "IfNotPresent" args: - --storage.tsdb.retention.time=15d diff --git a/samples/httpbin/httpbin-nodeport.yaml b/samples/httpbin/httpbin-nodeport.yaml index 11f00f59dc93..4344939452ca 100644 --- a/samples/httpbin/httpbin-nodeport.yaml +++ b/samples/httpbin/httpbin-nodeport.yaml @@ -48,7 +48,7 @@ spec: version: v1 spec: containers: - - image: docker.io/mccutchen/go-httpbin:v2.5.0 + - image: docker.io/mccutchen/go-httpbin:v2.15.0 imagePullPolicy: IfNotPresent name: httpbin ports: diff --git a/samples/ratelimit/rate-limit-service.yaml b/samples/ratelimit/rate-limit-service.yaml index 1045482b0be4..f9695820ba6a 100644 --- a/samples/ratelimit/rate-limit-service.yaml +++ b/samples/ratelimit/rate-limit-service.yaml @@ -113,7 +113,7 @@ spec: app: ratelimit spec: containers: - - image: envoyproxy/ratelimit:9d8d70a8 # 2022/08/16 + - image: envoyproxy/ratelimit:30a4ce1a # 2024/08/01 imagePullPolicy: IfNotPresent name: ratelimit command: ["/bin/ratelimit"] diff --git a/security/pkg/credentialfetcher/fetcher_test.go b/security/pkg/credentialfetcher/fetcher_test.go index 28412ddf14e5..cfb4a54bf0cd 100644 --- a/security/pkg/credentialfetcher/fetcher_test.go +++ b/security/pkg/credentialfetcher/fetcher_test.go @@ -63,7 +63,6 @@ func TestNewCredFetcher(t *testing.T) { // Disable token refresh for GCE VM credential fetcher. plugin.SetTokenRotation(false) for id, tc := range testCases { - id, tc := id, tc t.Run(id, func(t *testing.T) { t.Parallel() cf, err := NewCredFetcher( diff --git a/tests/binary/binaries_test.go b/tests/binary/binaries_test.go index 5bf955c081a0..c5265f0b7128 100644 --- a/tests/binary/binaries_test.go +++ b/tests/binary/binaries_test.go @@ -107,8 +107,8 @@ func TestBinarySizes(t *testing.T) { // TODO: shrink the ranges here once the active work to reduce binary size is complete // For now, having two small a range will result in lots of "merge conflicts" "istioctl": {60, 90}, - "pilot-agent": {20, 24}, - "pilot-discovery": {60, 90}, + "pilot-agent": {20, 25}, + "pilot-discovery": {60, 91}, "bug-report": {60, 80}, "client": {15, 30}, "server": {15, 30}, diff --git a/tests/binary/dependencies_test.go b/tests/binary/dependencies_test.go index 6c167cc7e9c0..da56ef1ef631 100644 --- a/tests/binary/dependencies_test.go +++ b/tests/binary/dependencies_test.go @@ -57,6 +57,8 @@ func TestDependencies(t *testing.T) { `envoy/extensions/filters/(http|network)/wasm/`, `github.com/envoyproxy/protoc-gen-validate/validate`, `github.com/envoyproxy/go-control-plane/pkg/conversion`, + `github.com/envoyproxy/go-control-plane/envoy/config`, + `github.com/envoyproxy/go-control-plane/envoy/extensions/filters`, `contrib/envoy/extensions/private_key_providers/`, `^istio\.io/api/(annotation|label|mcp|mesh|networking|type)`, `^istio\.io/api/analysis/v1alpha1`, diff --git a/tests/integration/README.md b/tests/integration/README.md index ecfad13395c6..e5b6184cf057 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -516,26 +516,26 @@ The test framework supports the following command-line flags: | Name | Type | Description | |------|------|-------------| -| -istio.test.work_dir | string | Local working directory for creating logs/temp files. If left empty, os.TempDir() is used. | -| -istio.test.ci | bool | Enable CI Mode. Additional logging and state dumping will be enabled. | -| -istio.test.nocleanup | bool | Do not cleanup resources after test completion. | -| -istio.test.select | string | Comma separated list of labels for selecting tests to run (e.g. 'foo,+bar-baz'). | -| -istio.test.hub | string | Container registry hub to use (default HUB environment variable). | -| -istio.test.tag | string | Common Container tag to use when deploying container images (default TAG environment variable). | -| -istio.test.pullpolicy | string | Common image pull policy to use when deploying container images. | -| -istio.test.kube.config | string | A comma-separated list of paths to kube config files for cluster environments. (default ~/.kube/config). | -| -istio.test.kube.deploy | bool | Deploy Istio into the target Kubernetes environment. (default true). | -| -istio.test.kube.deployEastWestGW | bool | Deploy Istio east west gateway into the target Kubernetes environment. (default true). | -| -istio.test.kube.systemNamespace | string | The namespace where the Istio components reside in a typical deployment. (default "istio-system"). | -| -istio.test.kube.helm.values | string | Manual overrides for Helm values file. Only valid when deploying Istio. | -| -istio.test.kube.helm.iopFile | string | IstioOperator spec file. This can be an absolute path or relative to the repository root. Defaults to "tests/integration/iop-integration-test-defaults.yaml". | -| -istio.test.kube.loadbalancer | bool | Used to obtain the right IP address for ingress gateway. This should be false for any environment that doesn't support a LoadBalancer type. | -| -istio.test.revision | string | Overwrite the default namespace label (istio-enabled=true) with revision lable (istio.io/rev=XXX). (default is no overwrite). | -| -istio.test.skip | []string | Skip tests matching the regular expression. This follows the semantics of -test.run. | -| -istio.test.skipVM | bool | Skip all the VM related parts in all the tests. (default is "false"). | -| -istio.test.helmRepo | string | Overwrite the default helm Repo used for the tests. | -| -istio.test.ambient | bool | Indicate the use of ambient mesh. | -| -istio.test.openshift | bool | Set to `true` when running the tests in an OpenShift cluster, rather than in KinD. | +| --istio.test.work_dir | string | Local working directory for creating logs/temp files. If left empty, os.TempDir() is used. | +| --istio.test.ci | bool | Enable CI Mode. Additional logging and state dumping will be enabled. | +| --istio.test.nocleanup | bool | Do not cleanup resources after test completion. | +| --istio.test.select | string | Comma separated list of labels for selecting tests to run (e.g. 'foo,+bar-baz'). | +| --istio.test.hub | string | Container registry hub to use (default HUB environment variable). | +| --istio.test.tag | string | Common Container tag to use when deploying container images (default TAG environment variable). | +| --istio.test.pullpolicy | string | Common image pull policy to use when deploying container images. | +| --istio.test.kube.config | string | A comma-separated list of paths to kube config files for cluster environments. (default ~/.kube/config). | +| --istio.test.kube.deploy | bool | Deploy Istio into the target Kubernetes environment. (default true). | +| --istio.test.kube.deployEastWestGW | bool | Deploy Istio east west gateway into the target Kubernetes environment. (default true). | +| --istio.test.kube.systemNamespace | string | The namespace where the Istio components reside in a typical deployment. (default "istio-system"). | +| --istio.test.kube.helm.values | string | Manual overrides for Helm values file. Only valid when deploying Istio. | +| --istio.test.kube.helm.iopFile | string | IstioOperator spec file. This can be an absolute path or relative to the repository root. Defaults to "tests/integration/iop-integration-test-defaults.yaml". | +| --istio.test.kube.loadbalancer | bool | Used to obtain the right IP address for ingress gateway. This should be false for any environment that doesn't support a LoadBalancer type. | +| --istio.test.revision | string | Overwrite the default namespace label (istio-enabled=true) with revision lable (istio.io/rev=XXX). (default is no overwrite). | +| --istio.test.skip | []string | Skip tests matching the regular expression. This follows the semantics of -test.run. | +| --istio.test.skipVM | bool | Skip all the VM related parts in all the tests. (default is "false"). | +| --istio.test.helmRepo | string | Overwrite the default helm Repo used for the tests. | +| --istio.test.ambient | bool | Indicate the use of ambient mesh. | +| --istio.test.openshift | bool | Set to `true` when running the tests in an OpenShift cluster, rather than in KinD. | ## Notes diff --git a/tests/integration/ambient/baseline_test.go b/tests/integration/ambient/baseline_test.go index e47dc4856c05..dd60910e2a33 100644 --- a/tests/integration/ambient/baseline_test.go +++ b/tests/integration/ambient/baseline_test.go @@ -206,7 +206,6 @@ func TestPodIP(t *testing.T) { framework.NewTest(t).Run(func(t framework.TestContext) { for _, src := range apps.All { for _, srcWl := range src.WorkloadsOrFail(t) { - srcWl := srcWl t.NewSubTestf("from %v %v", src.Config().Service, srcWl.Address()).Run(func(t framework.TestContext) { for _, dst := range apps.All { for _, dstWl := range dst.WorkloadsOrFail(t) { @@ -769,8 +768,9 @@ spec: } src.CallOrFail(t, opt) }) - // globally peerauth == STRICT, but we have a port-specific allowlist that is PERMISSIVE, - // so anything hitting that port should not be rejected + // general workload peerauth == STRICT, but we have a port-specific allowlist that is PERMISSIVE, + // so anything hitting that port should not be rejected. + // NOTE: Using port 18080 since that's the http port for the echo deployment t.NewSubTest("strict-permissive-ports").Run(func(t framework.TestContext) { t.ConfigIstio().Eval(apps.Namespace.Name(), map[string]string{ "Destination": dst.Config().Service, @@ -788,13 +788,85 @@ spec: mtls: mode: STRICT portLevelMtls: - 8080: + 18080: mode: PERMISSIVE `).ApplyOrFail(t) opt = opt.DeepCopy() // Should pass for all workloads, in or out of mesh, targeting this port src.CallOrFail(t, opt) }) + + // global peer auth is strict, but we have a permissive port-level rule + t.NewSubTest("global-strict-permissive-workload-ports").Run(func(t framework.TestContext) { + t.ConfigIstio().YAML(i.Settings().SystemNamespace, ` +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: global-strict +spec: + mtls: + mode: STRICT + `).ApplyOrFail(t) + t.ConfigIstio().Eval(apps.Namespace.Name(), map[string]string{ + "Destination": dst.Config().Service, + "Source": src.Config().Service, + "Namespace": apps.Namespace.Name(), + }, ` +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: local-port-override +spec: + selector: + matchLabels: + app: "{{ .Destination }}" + portLevelMtls: + 18080: + mode: PERMISSIVE + 19090: + mode: STRICT + `).ApplyOrFail(t) + opt = opt.DeepCopy() + // Should pass for all workloads, in or out of mesh, targeting this port + src.CallOrFail(t, opt) + }) + + t.NewSubTest("global-permissive-strict-workload-ports").Run(func(t framework.TestContext) { + t.ConfigIstio().YAML(i.Settings().SystemNamespace, ` +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: global-strict +spec: + mtls: + mode: PERMISSIVE + `).ApplyOrFail(t) + t.ConfigIstio().Eval(apps.Namespace.Name(), map[string]string{ + "Destination": dst.Config().Service, + "Namespace": apps.Namespace.Name(), + }, ` +apiVersion: security.istio.io/v1 +kind: PeerAuthentication +metadata: + name: local-port-override +spec: + selector: + matchLabels: + app: "{{ .Destination }}" + portLevelMtls: + 18080: + mode: STRICT + 19090: + mode: STRICT + + `).ApplyOrFail(t) + opt = opt.DeepCopy() + if !src.Config().HasProxyCapabilities() && dst.Config().HasProxyCapabilities() { + // Expect deny if the dest is in the mesh (enforcing mTLS) but src is not (not sending mTLS) + opt.Check = CheckDeny + } + src.CallOrFail(t, opt) + }) }) }) } @@ -1888,7 +1960,6 @@ spec: ips, ports := istio.DefaultIngressOrFail(t, t).HTTPAddresses() for _, tc := range testCases { - tc := tc for i, ip := range ips { t.NewSubTestf("%s %s %d", tc.location, tc.resolution, i).Run(func(t framework.TestContext) { echotest. @@ -2023,7 +2094,6 @@ spec: ips, ports := istio.DefaultIngressOrFail(t, t).HTTPAddresses() for _, tc := range testCases { - tc := tc for i, ip := range ips { t.NewSubTestf("%s %s %d", tc.location, tc.resolution, i).Run(func(t framework.TestContext) { echotest. @@ -2050,7 +2120,6 @@ spec: }) }) } - } }) } @@ -2101,7 +2170,6 @@ spec: WithParams(param.Params{}.SetWellKnown(param.Namespace, apps.Namespace)) for _, tc := range testCases { - tc := tc t.NewSubTestf("%s %s", tc.location, tc.resolution).Run(func(t framework.TestContext) { echotest. New(t, apps.All). @@ -2233,13 +2301,10 @@ func RunReachability(testCases []reachability.TestCase, t framework.TestContext) runTest := func(t framework.TestContext, f func(t framework.TestContext, src echo.Instance, dst echo.Instance, opt echo.CallOptions)) { svcs := apps.All for _, src := range svcs { - src := src t.NewSubTestf("from %v", src.Config().Service).RunParallel(func(t framework.TestContext) { for _, dst := range svcs { - dst := dst t.NewSubTestf("to %v", dst.Config().Service).RunParallel(func(t framework.TestContext) { for _, opt := range callOptions { - opt := opt t.NewSubTestf("%v", opt.Scheme).RunParallel(func(t framework.TestContext) { opt = opt.DeepCopy() opt.To = dst @@ -2253,8 +2318,6 @@ func RunReachability(testCases []reachability.TestCase, t framework.TestContext) } } for _, c := range testCases { - // Create a copy to avoid races, as tests are run in parallel - c := c testName := strings.TrimSuffix(c.ConfigFile, filepath.Ext(c.ConfigFile)) t.NewSubTest(testName).Run(func(t framework.TestContext) { // Apply the policy. @@ -2440,7 +2503,6 @@ func runTestContext(t framework.TestContext, f func(t framework.TestContext, src for _, dst := range svcs { t.NewSubTestf("to %v", dst.Config().Service).Run(func(t framework.TestContext) { for _, opt := range callOptions { - src, dst, opt := src, dst, opt t.NewSubTestf("%v", opt.Scheme).Run(func(t framework.TestContext) { opt = opt.DeepCopy() opt.To = dst @@ -2546,7 +2608,7 @@ spec: - match: metric: REQUEST_COUNT tagOverrides: - custom_dimension: + custom_dimension: value: "'test'" source_principal: operation: REMOVE @@ -2729,7 +2791,6 @@ func TestMetadataServer(t *testing.T) { } svcs := apps.All for _, src := range svcs { - src := src t.NewSubTestf("from %v", src.Config().Service).Run(func(t framework.TestContext) { // curl -H "Metadata-Flavor: Google" 169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity opts := echo.CallOptions{ @@ -2764,7 +2825,6 @@ func TestAPIServer(t *testing.T) { assert.NoError(t, err) for _, src := range svcs { - src := src t.NewSubTestf("from %v", src.Config().Service).Run(func(t framework.TestContext) { opts := echo.CallOptions{ Address: "kubernetes.default.svc", @@ -3161,6 +3221,45 @@ func daemonsetsetComplete(ds *appsv1.DaemonSet) bool { ds.Status.ObservedGeneration >= ds.Generation } +func TestWaypointWithInvalidBackend(t *testing.T) { + framework.NewTest(t). + Run(func(t framework.TestContext) { + // We should expect a 500 error since the backend is invalid. + t.ConfigIstio(). + Eval(apps.Namespace.Name(), apps.Namespace.Name(), `apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: add-header +spec: + parentRefs: + - name: sidecar + kind: Service + group: "" + port: 80 + rules: + - filters: + - type: RequestHeaderModifier + requestHeaderModifier: + add: + - name: greeting + value: "hello world!" + backendRefs: + - name: invalid + port: 80 +`). + ApplyOrFail(t) + SetWaypoint(t, Sidecar, "waypoint") + client := apps.Captured + client[0].CallOrFail(t, echo.CallOptions{ + To: apps.Sidecar, + Port: ports.HTTP, + Check: check.And( + check.Status(500), + ), + }) + }) +} + func TestWaypointWithSidecarBackend(t *testing.T) { framework.NewTest(t). Run(func(t framework.TestContext) { diff --git a/tests/integration/ambient/cni/main_test.go b/tests/integration/ambient/cni/main_test.go index ba8d35ef2b76..c54b4efd93ac 100644 --- a/tests/integration/ambient/cni/main_test.go +++ b/tests/integration/ambient/cni/main_test.go @@ -18,21 +18,13 @@ package cni import ( - "context" - "errors" "fmt" "testing" "time" - appsv1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "istio.io/api/label" "istio.io/istio/pkg/config/constants" - istioKube "istio.io/istio/pkg/kube" "istio.io/istio/pkg/test/framework" - "istio.io/istio/pkg/test/framework/components/cluster" "istio.io/istio/pkg/test/framework/components/echo" common_deploy "istio.io/istio/pkg/test/framework/components/echo/common/deployment" "istio.io/istio/pkg/test/framework/components/echo/common/ports" @@ -46,6 +38,7 @@ import ( "istio.io/istio/pkg/test/scopes" "istio.io/istio/pkg/test/shell" "istio.io/istio/pkg/test/util/retry" + util "istio.io/istio/tests/integration/ambient" "istio.io/istio/tests/integration/pilot/common" "istio.io/istio/tests/integration/security/util/cert" ) @@ -192,7 +185,7 @@ func TestTrafficWithEstablishedPodsIfCNIMissing(t *testing.T) { c := t.Clusters().Default() t.Log("Getting current daemonset") // mostly a correctness check - to make sure it's actually there - origDS := getCNIDaemonSet(t, c) + origDS := util.GetCNIDaemonSet(t, c, i.Settings().SystemNamespace) ns := apps.SingleNamespaceView().EchoNamespace.Namespace fetchFn := testKube.NewPodFetch(c, ns.Name()) @@ -203,14 +196,14 @@ func TestTrafficWithEstablishedPodsIfCNIMissing(t *testing.T) { t.Log("Deleting current daemonset") // Delete JUST the daemonset - ztunnel + workloads remain in place - deleteCNIDaemonset(t, c) + util.DeleteCNIDaemonset(t, c, i.Settings().SystemNamespace) // Our echo instances have already been deployed/configured by the CNI, // so the CNI being removed should not disrupt them. common.RunAllTrafficTests(t, i, apps.SingleNamespaceView()) // put it back - deployCNIDaemonset(t, c, origDS) + util.DeployCNIDaemonset(t, c, origDS) }) } @@ -228,7 +221,7 @@ func TestCNIMisconfigHealsOnRestart(t *testing.T) { // I don't think we have a good way to solve this ATM so doing stuff like this is as // good as it gets, short of creating an entirely new suite for every possibly-cluster-destructive op. retry.UntilSuccessOrFail(t, func() error { - ensureCNIDS := getCNIDaemonSet(t, c) + ensureCNIDS := util.GetCNIDaemonSet(t, c, i.Settings().SystemNamespace) if ensureCNIDS.Status.NumberReady == ensureCNIDS.Status.DesiredNumberScheduled { return nil } @@ -240,21 +233,24 @@ func TestCNIMisconfigHealsOnRestart(t *testing.T) { volPatch := []byte(fmt.Sprintf(`{"spec":{"template":{"spec":{"volumes":[{"name":"cni-net-dir","hostPath":{"path": "%s", "type": ""}}]}}}}`, "/etc/cni/nope.d")) t.Log("Patching the CNI Daemonset") - _ = patchCNIDaemonSet(t, c, volPatch) + _ = util.PatchCNIDaemonSet(t, c, i.Settings().SystemNamespace, volPatch) - rolloutCmd := fmt.Sprintf("kubectl rollout restart daemonset/%s -n %s", "istio-cni-node", i.Settings().SystemNamespace) + // Why not use `rollout restart` here? It waits for each node's pod to go healthy, + // so if we intentionally break the DS, we'll never finish breaking all the nodes. + // So, delete all the pods at once by label + restartDSPodsCmd := fmt.Sprintf("kubectl delete pods -l k8s-app=istio-cni-node -n %s", i.Settings().SystemNamespace) retry.UntilSuccessOrFail(t, func() error { - t.Log("Rollout restart CNI daemonset to get a fixed instance") + t.Log("Restart CNI daemonset pods to get broken instances on every node") // depending on timing it can actually take little bit for the patch to be applied and // to get all pods to enter a broken state break - so rely on the retry delay to sort that for us - if _, err := shell.Execute(true, rolloutCmd); err != nil { - t.Fatalf("failed to rollout restart deployments %v", err) + if _, err := shell.Execute(true, restartDSPodsCmd); err != nil { + t.Fatalf("failed to restart daemonset pods %v", err) } time.Sleep(1 * time.Second) - brokenCNIDS := getCNIDaemonSet(t, c) + brokenCNIDS := util.GetCNIDaemonSet(t, c, i.Settings().SystemNamespace) t.Log("Checking for broken DS") if brokenCNIDS.Status.NumberReady == 0 { return nil @@ -272,22 +268,22 @@ func TestCNIMisconfigHealsOnRestart(t *testing.T) { fixedVolPatch := []byte(fmt.Sprintf(`{"spec":{"template":{"spec":{"volumes":[{"name":"cni-net-dir","hostPath":{"path": "%s", "type": ""}}]}}}}`, "/etc/cni/net.d")) t.Log("Re-patching the CNI Daemonset") - _ = patchCNIDaemonSet(t, c, fixedVolPatch) + _ = util.PatchCNIDaemonSet(t, c, i.Settings().SystemNamespace, fixedVolPatch) // Need to sleep a bit to make sure this takes, - // and also to avoid `rollout restart`-ing too fast, which can give an error like + // and also to avoid `restart`-ing too fast, which can give an error like // `if restart has already been triggered within the past second, please wait before attempting to trigger another` time.Sleep(1 * time.Second) - // Rollout restart CNI pods so they get the fixed config. + // Restart CNI pods so they get the fixed config. // to _fix_ the pods we should only have to do this *once* - t.Log("Rollout restart CNI daemonset to get a fixed instance") - if _, err := shell.Execute(true, rolloutCmd); err != nil { - t.Fatalf("failed to rollout restart deployments %v", err) + t.Log("Restart CNI daemonset to get a fixed instance on every node") + if _, err := shell.Execute(true, restartDSPodsCmd); err != nil { + t.Fatalf("failed to restart daemonset %v", err) } retry.UntilSuccessOrFail(t, func() error { - fixedCNIDaemonSet := getCNIDaemonSet(t, c) + fixedCNIDaemonSet := util.GetCNIDaemonSet(t, c, i.Settings().SystemNamespace) t.Log("Checking for happy DS") if fixedCNIDaemonSet.Status.NumberReady == fixedCNIDaemonSet.Status.DesiredNumberScheduled { return nil @@ -296,66 +292,3 @@ func TestCNIMisconfigHealsOnRestart(t *testing.T) { }, retry.Delay(1*time.Second), retry.Timeout(80*time.Second)) }) } - -func patchCNIDaemonSet(ctx framework.TestContext, c cluster.Cluster, patch []byte) *appsv1.DaemonSet { - cniDaemonSet, err := c.(istioKube.CLIClient). - Kube().AppsV1().DaemonSets(i.Settings().SystemNamespace). - Patch(context.Background(), "istio-cni-node", types.StrategicMergePatchType, patch, metav1.PatchOptions{}) - if err != nil { - ctx.Fatalf("failed to patch CNI Daemonset %v from ns %s", err, i.Settings().SystemNamespace) - } - if cniDaemonSet == nil { - ctx.Fatal("cannot find CNI Daemonset") - } - return cniDaemonSet -} - -func getCNIDaemonSet(ctx framework.TestContext, c cluster.Cluster) *appsv1.DaemonSet { - cniDaemonSet, err := c.(istioKube.CLIClient). - Kube().AppsV1().DaemonSets(i.Settings().SystemNamespace). - Get(context.Background(), "istio-cni-node", metav1.GetOptions{}) - if err != nil { - ctx.Fatalf("failed to get CNI Daemonset %v from ns %s", err, i.Settings().SystemNamespace) - } - if cniDaemonSet == nil { - ctx.Fatal("cannot find CNI Daemonset") - } - return cniDaemonSet -} - -func deleteCNIDaemonset(ctx framework.TestContext, c cluster.Cluster) { - if err := c.(istioKube.CLIClient). - Kube().AppsV1().DaemonSets(i.Settings().SystemNamespace). - Delete(context.Background(), "istio-cni-node", metav1.DeleteOptions{}); err != nil { - ctx.Fatalf("failed to delete CNI Daemonset %v", err) - } - - // Wait until the CNI Daemonset pod cannot be fetched anymore - retry.UntilSuccessOrFail(ctx, func() error { - scopes.Framework.Infof("Checking if CNI Daemonset pods are deleted...") - pods, err := c.PodsForSelector(context.TODO(), i.Settings().SystemNamespace, "k8s-app=istio-cni-node") - if err != nil { - return err - } - if len(pods.Items) > 0 { - return errors.New("CNI Daemonset pod still exists after deletion") - } - return nil - }, retry.Delay(1*time.Second), retry.Timeout(80*time.Second)) -} - -func deployCNIDaemonset(ctx framework.TestContext, c cluster.Cluster, cniDaemonSet *appsv1.DaemonSet) { - deployDaemonSet := appsv1.DaemonSet{} - deployDaemonSet.Spec = cniDaemonSet.Spec - deployDaemonSet.ObjectMeta = metav1.ObjectMeta{ - Name: cniDaemonSet.ObjectMeta.Name, - Namespace: cniDaemonSet.ObjectMeta.Namespace, - Labels: cniDaemonSet.ObjectMeta.Labels, - Annotations: cniDaemonSet.ObjectMeta.Annotations, - } - _, err := c.(istioKube.CLIClient).Kube().AppsV1().DaemonSets(cniDaemonSet.ObjectMeta.Namespace). - Create(context.Background(), &deployDaemonSet, metav1.CreateOptions{}) - if err != nil { - ctx.Fatalf("failed to deploy CNI Daemonset %v", err) - } -} diff --git a/tests/integration/ambient/cniupgrade/main_test.go b/tests/integration/ambient/cniupgrade/main_test.go new file mode 100644 index 000000000000..1b3a0f1512cf --- /dev/null +++ b/tests/integration/ambient/cniupgrade/main_test.go @@ -0,0 +1,231 @@ +//go:build integ +// +build integ + +// Copyright Istio Authors +// +// Licensed 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 cniupgrade + +import ( + "fmt" + "testing" + + "istio.io/api/label" + "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/test/framework" + "istio.io/istio/pkg/test/framework/components/echo" + common_deploy "istio.io/istio/pkg/test/framework/components/echo/common/deployment" + "istio.io/istio/pkg/test/framework/components/echo/common/ports" + "istio.io/istio/pkg/test/framework/components/echo/deployment" + "istio.io/istio/pkg/test/framework/components/echo/match" + "istio.io/istio/pkg/test/framework/components/istio" + "istio.io/istio/pkg/test/framework/components/namespace" + testlabel "istio.io/istio/pkg/test/framework/label" + "istio.io/istio/pkg/test/framework/resource" + "istio.io/istio/pkg/test/scopes" + "istio.io/istio/pkg/test/shell" + util "istio.io/istio/tests/integration/ambient" + "istio.io/istio/tests/integration/pilot/common" + "istio.io/istio/tests/integration/security/util/cert" +) + +var ( + i istio.Instance + + // Below are various preconfigured echo deployments. Whenever possible, tests should utilize these + // to avoid excessive creation/tear down of deployments. In general, a test should only deploy echo if + // its doing something unique to that specific test. + apps = &EchoDeployments{} +) + +type EchoDeployments struct { + // Namespace echo apps will be deployed + Namespace namespace.Instance + // Captured echo service + Captured echo.Instances + // Uncaptured echo Service + Uncaptured echo.Instances + + // All echo services + All echo.Instances +} + +// TestMain defines the entrypoint for pilot tests using a standard Istio installation. +// If a test requires a custom install it should go into its own package, otherwise it should go +// here to reuse a single install across tests. +func TestMain(m *testing.M) { + // nolint: staticcheck + framework. + NewSuite(m). + RequireMinVersion(24). + Label(testlabel.IPv4). // https://github.com/istio/istio/issues/41008 + Setup(func(t resource.Context) error { + t.Settings().Ambient = true + return nil + }). + Setup(istio.Setup(&i, func(ctx resource.Context, cfg *istio.Config) { + // can't deploy VMs without eastwest gateway + ctx.Settings().SkipVMs() + cfg.EnableCNI = true + cfg.DeployEastWestGW = false + cfg.ControlPlaneValues = ` +values: + cni: + repair: + enabled: true + ztunnel: + terminationGracePeriodSeconds: 5 + env: + SECRET_TTL: 5m +` + }, cert.CreateCASecretAlt)). + Setup(func(t resource.Context) error { + return SetupApps(t, i, apps) + }). + Run() +} + +const ( + Captured = "captured" + Uncaptured = "uncaptured" +) + +func SetupApps(t resource.Context, i istio.Instance, apps *EchoDeployments) error { + var err error + apps.Namespace, err = namespace.New(t, namespace.Config{ + Prefix: "echo", + Inject: false, + Labels: map[string]string{ + label.IoIstioDataplaneMode.Name: "ambient", + }, + }) + if err != nil { + return err + } + + builder := deployment.New(t). + WithClusters(t.Clusters()...). + WithConfig(echo.Config{ + Service: Captured, + Namespace: apps.Namespace, + Ports: ports.All(), + ServiceAccount: true, + Subsets: []echo.SubsetConfig{ + { + Replicas: 1, + Version: "v1", + }, + { + Replicas: 1, + Version: "v2", + }, + }, + }). + WithConfig(echo.Config{ + Service: Uncaptured, + Namespace: apps.Namespace, + Ports: ports.All(), + ServiceAccount: true, + Subsets: []echo.SubsetConfig{ + { + Replicas: 1, + Version: "v1", + Labels: map[string]string{label.IoIstioDataplaneMode.Name: constants.DataplaneModeNone}, + }, + { + Replicas: 1, + Version: "v2", + Labels: map[string]string{label.IoIstioDataplaneMode.Name: constants.DataplaneModeNone}, + }, + }, + }) + + // Build the applications + echos, err := builder.Build() + if err != nil { + return err + } + for _, b := range echos { + scopes.Framework.Infof("built %v", b.Config().Service) + } + + apps.All = echos + apps.Uncaptured = match.ServiceName(echo.NamespacedName{Name: Uncaptured, Namespace: apps.Namespace}).GetMatches(echos) + apps.Captured = match.ServiceName(echo.NamespacedName{Name: Captured, Namespace: apps.Namespace}).GetMatches(echos) + + return nil +} + +func TestTrafficWithCNIUpgrade(t *testing.T) { + framework.NewTest(t). + TopLevel(). + Run(func(t framework.TestContext) { + apps := common_deploy.NewOrFail(t, common_deploy.Config{ + NoExternalNamespace: true, + IncludeExtAuthz: false, + }) + + c := t.Clusters().Default() + ns := apps.SingleNamespaceView().EchoNamespace.Namespace + + // We need to simulate a Daemonset that exists, but has zero pods backing it. + // + // This is to simulate the backing pods terminating while the DS remains + // (as would be the case for a short period during upgrade) + // This is tricky to orchestrate in a test flow as by-design DSes don't scale to 0. + // But, we can hack the DS selector to mimic this. + t.Log("Updating CNI Daemonset") + origCNIDaemonSet := util.GetCNIDaemonSet(t, c, i.Settings().SystemNamespace) + + // Leave the DS in place, but cause all its backing pods to terminate. + util.ScaleCNIDaemonsetToZeroPods(t, c, i.Settings().SystemNamespace) + + // Rollout restart app instances in the echo namespace, and wait for a broken instance. + // Because the CNI daemonset was not marked for deleting when the CNI daemonset pods shut down, + // the CNI daemonset pods we just removed should have left the CNI plugin in place on the nodes, + // which will stall new pods being scheduled. + t.Log("Rollout restart echo instance to get broken app instances") + rolloutCmd := fmt.Sprintf("kubectl rollout restart deployment -n %s", ns.Name()) + if _, err := shell.Execute(true, rolloutCmd); err != nil { + t.Fatalf("failed to rollout restart deployments %v", err) + } + + // Since the CNI plugin is in place but no agent is there, pods should stall infinitely + util.WaitForStalledPodOrFail(t, c, ns) + + t.Log("Redeploy CNI") + // The only thing left is the raw DS with no backing pods, so just delete it + util.DeleteCNIDaemonset(t, c, i.Settings().SystemNamespace) + // Now bring back the original CNI Daemonset, which should recreate backing pods + util.DeployCNIDaemonset(t, c, origCNIDaemonSet) + + // Rollout restart app instances in the echo namespace, which should schedule now + // that the CNI daemonset is back + // NOTE - technically we don't need to forcibly restart the app pods, they will + // (eventually) reschedule naturally now that the node agent is back. + // Doing an explicit rollout restart is typically just faster and also helps keep tests reliable. + t.Log("Rollout restart echo instance to get a fixed instance") + if _, err := shell.Execute(true, rolloutCmd); err != nil { + t.Fatalf("failed to rollout restart deployments %v", err) + } + rolloutStatusCmd := fmt.Sprintf("kubectl rollout status deployment -n %s", ns.Name()) + t.Log("wait for rollouts to finish") + if _, err := shell.Execute(true, rolloutStatusCmd); err != nil { + t.Fatalf("failed to rollout status deployments %v", err) + } + + // Everyone should be happy + common.RunAllTrafficTests(t, i, apps.SingleNamespaceView()) + }) +} diff --git a/tests/integration/ambient/util.go b/tests/integration/ambient/util.go new file mode 100644 index 000000000000..541844cf136f --- /dev/null +++ b/tests/integration/ambient/util.go @@ -0,0 +1,181 @@ +//go:build integ +// +build integ + +// Copyright Istio Authors +// +// Licensed 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 ambient + +import ( + "context" + "errors" + "fmt" + "strings" + "time" + + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + + istioKube "istio.io/istio/pkg/kube" + "istio.io/istio/pkg/test/framework" + "istio.io/istio/pkg/test/framework/components/cluster" + "istio.io/istio/pkg/test/framework/components/namespace" + "istio.io/istio/pkg/test/scopes" + "istio.io/istio/pkg/test/util/retry" +) + +const ( + RetryDelay = 2 * time.Second + RetryTimeOut = 5 * time.Minute + Timeout = 2 * time.Minute +) + +func DeployCNIDaemonset(ctx framework.TestContext, c cluster.Cluster, cniDaemonSet *appsv1.DaemonSet) { + deployDaemonSet := appsv1.DaemonSet{} + deployDaemonSet.Spec = cniDaemonSet.Spec + deployDaemonSet.ObjectMeta = metav1.ObjectMeta{ + Name: cniDaemonSet.ObjectMeta.Name, + Namespace: cniDaemonSet.ObjectMeta.Namespace, + Labels: cniDaemonSet.ObjectMeta.Labels, + Annotations: cniDaemonSet.ObjectMeta.Annotations, + } + _, err := c.(istioKube.CLIClient).Kube().AppsV1().DaemonSets(cniDaemonSet.ObjectMeta.Namespace). + Create(context.Background(), &deployDaemonSet, metav1.CreateOptions{}) + if err != nil { + ctx.Fatalf("failed to deploy CNI Daemonset %v", err) + } + + // Wait for the DS backing pods to ready up + retry.UntilSuccessOrFail(ctx, func() error { + ensureCNIDS := GetCNIDaemonSet(ctx, c, cniDaemonSet.ObjectMeta.Namespace) + if ensureCNIDS.Status.NumberReady == ensureCNIDS.Status.DesiredNumberScheduled { + return nil + } + return fmt.Errorf("still waiting for CNI pods to become ready before proceeding") + }, retry.Delay(RetryDelay), retry.Timeout(RetryTimeOut)) +} + +func DeleteCNIDaemonset(ctx framework.TestContext, c cluster.Cluster, systemNamespace string) { + if err := c.(istioKube.CLIClient). + Kube().AppsV1().DaemonSets(systemNamespace). + Delete(context.Background(), "istio-cni-node", metav1.DeleteOptions{}); err != nil { + ctx.Fatalf("failed to delete CNI Daemonset %v", err) + } + + // Wait until the CNI Daemonset pods cannot be fetched anymore + retry.UntilSuccessOrFail(ctx, func() error { + scopes.Framework.Infof("Checking if CNI Daemonset pods are deleted...") + pods, err := c.PodsForSelector(context.TODO(), systemNamespace, "k8s-app=istio-cni-node") + if err != nil { + return err + } + if len(pods.Items) > 0 { + return errors.New("CNI Daemonset pod still exists after deletion") + } + return nil + }, retry.Delay(1*time.Second), retry.Timeout(80*time.Second)) +} + +func GetCNIDaemonSet(ctx framework.TestContext, c cluster.Cluster, systemNamespace string) *appsv1.DaemonSet { + cniDaemonSet, err := c.(istioKube.CLIClient). + Kube().AppsV1().DaemonSets(systemNamespace). + Get(context.Background(), "istio-cni-node", metav1.GetOptions{}) + if err != nil { + ctx.Fatalf("failed to get CNI Daemonset %v from ns %s", err, systemNamespace) + } + if cniDaemonSet == nil { + ctx.Fatal("cannot find CNI Daemonset") + } + return cniDaemonSet +} + +// ScaleCNIDaemonsetToZeroPods patches the DS with a non-existing node selector. +// This will cause the DS to "scale down" to 0 pods, while leaving the +// actual DS resource in-place for our test (important for CNI upgrade flow test) +func ScaleCNIDaemonsetToZeroPods(ctx framework.TestContext, c cluster.Cluster, systemNamespace string) { + patchData := `{ + "spec": { + "template": { + "spec": { + "nodeSelector": { + "non-existing": "true" + } + } + } + } + }` + + PatchCNIDaemonSet(ctx, c, systemNamespace, []byte(patchData)) + + // Wait until the CNI Daemonset pod cannot be fetched anymore + retry.UntilSuccessOrFail(ctx, func() error { + scopes.Framework.Infof("Checking if CNI Daemonset pods are deleted...") + pods, err := c.PodsForSelector(context.TODO(), systemNamespace, "k8s-app=istio-cni-node") + if err != nil { + return err + } + if len(pods.Items) > 0 { + return errors.New("CNI Daemonset pod still exists after deletion") + } + return nil + }, retry.Delay(1*time.Second), retry.Timeout(80*time.Second)) +} + +func WaitForStalledPodOrFail(t framework.TestContext, cluster cluster.Cluster, ns namespace.Instance) { + retry.UntilSuccessOrFail(t, func() error { + pods, err := cluster.Kube().CoreV1().Pods(ns.Name()).List(context.TODO(), metav1.ListOptions{}) + if err != nil { + return err + } + if len(pods.Items) == 0 { + return fmt.Errorf("still waiting the pod in namespace %v to start", ns.Name()) + } + // Verify that every pod is in broken state due to CNI plugin failure. + for _, p := range pods.Items { + for _, cState := range p.Status.ContainerStatuses { + waiting := cState.State.Waiting + + scopes.Framework.Infof("checking pod status for stall") + if waiting != nil && waiting.Reason == "ContainerCreating" { + scopes.Framework.Infof("checking pod events") + events, err := cluster.Kube().CoreV1().Events(ns.Name()).List(context.TODO(), metav1.ListOptions{}) + if err != nil { + return err + } + for _, ev := range events.Items { + if ev.InvolvedObject.Name == p.Name && strings.Contains(ev.Message, "Failed to create pod sandbox") { + return nil + } + } + } + + } + } + return fmt.Errorf("cannot find any pod with wanted failure status") + }, retry.Delay(1*time.Second), retry.Timeout(80*time.Second)) +} + +func PatchCNIDaemonSet(ctx framework.TestContext, c cluster.Cluster, systemNamespace string, patch []byte) *appsv1.DaemonSet { + cniDaemonSet, err := c.(istioKube.CLIClient). + Kube().AppsV1().DaemonSets(systemNamespace). + Patch(context.Background(), "istio-cni-node", types.StrategicMergePatchType, patch, metav1.PatchOptions{}) + if err != nil { + ctx.Fatalf("failed to patch CNI Daemonset %v from ns %s", err, systemNamespace) + } + if cniDaemonSet == nil { + ctx.Fatal("cannot find CNI Daemonset") + } + return cniDaemonSet +} diff --git a/tests/integration/ambient/wasm_test.go b/tests/integration/ambient/wasm_test.go index 7034f1c99b79..8bf99b3a7341 100644 --- a/tests/integration/ambient/wasm_test.go +++ b/tests/integration/ambient/wasm_test.go @@ -227,10 +227,6 @@ func TestWasmPluginConfigurations(t *testing.T) { } for _, tc := range testCases { - if tc.name == "service-wasm-test" { - t.Skip("https://github.com/istio/istio/issues/51288/") - } - if tc.name == "gateway-wasm-test" { crd.DeployGatewayAPIOrSkip(t) args := map[string]any{ diff --git a/tests/integration/ambient/waypoint_test.go b/tests/integration/ambient/waypoint_test.go index 24b2cb2805c4..c01466806477 100644 --- a/tests/integration/ambient/waypoint_test.go +++ b/tests/integration/ambient/waypoint_test.go @@ -325,7 +325,6 @@ spec: // ensure HTTP traffic works with all hostname variants for _, src := range apps.All { - src := src if !hboneClient(src) { // TODO if we hairpinning, don't skip here continue @@ -335,7 +334,6 @@ spec: t.Skip("TODO: sidecars don't properly handle use-waypoint") } for _, host := range apps.Captured.Config().HostnameVariants() { - host := host t.NewSubTestf("to %s", host).Run(func(t framework.TestContext) { src.CallOrFail(t, echo.CallOptions{ To: apps.Captured, @@ -396,7 +394,6 @@ func setWaypointInternal(t framework.TestContext, name, ns string, waypoint stri func TestWaypointDNS(t *testing.T) { runTest := func(t framework.TestContext, c echo.Checker) { for _, src := range apps.All { - src := src if !hboneClient(src) { continue } @@ -459,7 +456,6 @@ func TestWaypointAsEgressGateway(t *testing.T) { t.ConfigIstio().YAML(apps.Namespace.Name(), config).ApplyOrFail(t) } for _, src := range apps.All { - src := src if !hboneClient(src) { continue } diff --git a/tests/integration/iop-ambient-test-defaults.yaml b/tests/integration/iop-ambient-test-defaults.yaml index 9b232364c945..280c779e9189 100644 --- a/tests/integration/iop-ambient-test-defaults.yaml +++ b/tests/integration/iop-ambient-test-defaults.yaml @@ -16,9 +16,6 @@ spec: # For that, DNS capture must be enabled in the CNI # and DNS proxying must be enabled in ztunnel dnsCapture: true - pilot: - env: - PILOT_ENABLE_IP_AUTOALLOCATE: "true" ztunnel: meshConfig: defaultConfig: diff --git a/tests/integration/pilot/analyze_test.go b/tests/integration/pilot/analyze_test.go index d20d371cf7b8..6fab35655abc 100644 --- a/tests/integration/pilot/analyze_test.go +++ b/tests/integration/pilot/analyze_test.go @@ -101,7 +101,7 @@ func TestFileOnly(t *testing.T) { }) } -func TestDirectoryWithoutRecursion(t *testing.T) { +func TestDirectory(t *testing.T) { // nolint: staticcheck framework. NewTest(t). @@ -116,33 +116,8 @@ func TestDirectoryWithoutRecursion(t *testing.T) { istioCtl := istioctl.NewOrFail(t, istioctl.Config{}) - // Recursive is false, so we should only analyze - // testdata/some-dir/missing-gateway.yaml and get a - // SchemaValidationError (if we did recurse, we'd get a - // UnknownAnnotation as well). - output, err := istioctlSafe(t, istioCtl, ns.Name(), false, "--recursive=false", dirWithConfig) - expectMessages(t, g, output, msg.SchemaValidationError) - g.Expect(err).To(BeIdenticalTo(analyzerFoundIssuesError)) - }) -} - -func TestDirectoryWithRecursion(t *testing.T) { - // nolint: staticcheck - framework. - NewTest(t). - RequiresSingleCluster(). - Run(func(t framework.TestContext) { - g := NewWithT(t) - - ns := namespace.NewOrFail(t, namespace.Config{ - Prefix: "istioctl-analyze", - Inject: true, - }) - - istioCtl := istioctl.NewOrFail(t, istioctl.Config{}) - - // Recursive is true, so we should see one error (SchemaValidationError). - output, err := istioctlSafe(t, istioCtl, ns.Name(), false, "--recursive=true", dirWithConfig) + // Hardcore recursive to true, so we should see one error (SchemaValidationError). + output, err := istioctlSafe(t, istioCtl, ns.Name(), false, dirWithConfig) expectMessages(t, g, output, msg.SchemaValidationError) g.Expect(err).To(BeIdenticalTo(analyzerFoundIssuesError)) }) diff --git a/tests/integration/pilot/cni_race_test.go b/tests/integration/pilot/cni_race_test.go index 95549f112ebf..403eeaca5ff2 100644 --- a/tests/integration/pilot/cni_race_test.go +++ b/tests/integration/pilot/cni_race_test.go @@ -24,19 +24,17 @@ import ( "testing" "time" - appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - istioKube "istio.io/istio/pkg/kube" "istio.io/istio/pkg/test/framework" "istio.io/istio/pkg/test/framework/components/cluster" "istio.io/istio/pkg/test/framework/components/echo" "istio.io/istio/pkg/test/framework/components/echo/common/ports" "istio.io/istio/pkg/test/framework/components/echo/deployment" "istio.io/istio/pkg/test/framework/components/namespace" - "istio.io/istio/pkg/test/scopes" "istio.io/istio/pkg/test/shell" "istio.io/istio/pkg/test/util/retry" + util "istio.io/istio/tests/integration/ambient" "istio.io/istio/tools/istio-iptables/pkg/constants" ) @@ -66,8 +64,8 @@ func TestCNIRaceRepair(t *testing.T) { // To begin with, delete CNI Daemonset to simulate a CNI race condition. // Temporarily store CNI DaemonSet, which will be deployed again later. t.Log("Delete CNI Daemonset temporarily to simulate race condition") - cniDaemonSet := getCNIDaemonSet(t, c) - deleteCNIDaemonset(t, c) + cniDaemonSet := util.GetCNIDaemonSet(t, c, i.Settings().SystemNamespace) + util.DeleteCNIDaemonset(t, c, i.Settings().SystemNamespace) // Rollout restart instances in the echo namespace, and wait for a broken instance. t.Log("Rollout restart echo instance to get a broken instance") @@ -79,61 +77,11 @@ func TestCNIRaceRepair(t *testing.T) { t.Log("Redeploy CNI and verify repair takes effect by evicting the broken pod") // Now bring back CNI Daemonset, and pod in the echo namespace should be repaired. - deployCNIDaemonset(t, c, cniDaemonSet) + util.DeployCNIDaemonset(t, c, cniDaemonSet) waitForRepairOrFail(t, c, ns) }) } -func getCNIDaemonSet(ctx framework.TestContext, c cluster.Cluster) *appsv1.DaemonSet { - cniDaemonSet, err := c.(istioKube.CLIClient). - Kube().AppsV1().DaemonSets(i.Settings().SystemNamespace). - Get(context.Background(), "istio-cni-node", metav1.GetOptions{}) - if err != nil { - ctx.Fatalf("failed to get CNI Daemonset %v", err) - } - if cniDaemonSet == nil { - ctx.Fatal("cannot find CNI Daemonset") - } - return cniDaemonSet -} - -func deleteCNIDaemonset(ctx framework.TestContext, c cluster.Cluster) { - if err := c.(istioKube.CLIClient). - Kube().AppsV1().DaemonSets(i.Settings().SystemNamespace). - Delete(context.Background(), "istio-cni-node", metav1.DeleteOptions{}); err != nil { - ctx.Fatalf("failed to delete CNI Daemonset %v", err) - } - - // Wait until the CNI Daemonset pod cannot be fetched anymore - retry.UntilSuccessOrFail(ctx, func() error { - scopes.Framework.Infof("Checking if CNI Daemonset pods are deleted...") - pods, err := c.PodsForSelector(context.TODO(), i.Settings().SystemNamespace, "k8s-app=istio-cni-node") - if err != nil { - return err - } - if len(pods.Items) > 0 { - return errors.New("CNI Daemonset pod still exists after deletion") - } - return nil - }, retry.Delay(1*time.Second), retry.Timeout(80*time.Second)) -} - -func deployCNIDaemonset(ctx framework.TestContext, c cluster.Cluster, cniDaemonSet *appsv1.DaemonSet) { - deployDaemonSet := appsv1.DaemonSet{} - deployDaemonSet.Spec = cniDaemonSet.Spec - deployDaemonSet.ObjectMeta = metav1.ObjectMeta{ - Name: cniDaemonSet.ObjectMeta.Name, - Namespace: cniDaemonSet.ObjectMeta.Namespace, - Labels: cniDaemonSet.ObjectMeta.Labels, - Annotations: cniDaemonSet.ObjectMeta.Annotations, - } - _, err := c.(istioKube.CLIClient).Kube().AppsV1().DaemonSets(i.Settings().SystemNamespace). - Create(context.Background(), &deployDaemonSet, metav1.CreateOptions{}) - if err != nil { - ctx.Fatalf("failed to deploy CNI Daemonset %v", err) - } -} - func waitForBrokenPodOrFail(t framework.TestContext, cluster cluster.Cluster, ns namespace.Instance) { retry.UntilSuccessOrFail(t, func() error { pods, err := cluster.Kube().CoreV1().Pods(ns.Name()).List(context.TODO(), metav1.ListOptions{}) diff --git a/tests/integration/pilot/common/routing.go b/tests/integration/pilot/common/routing.go index 3fc01c24004c..9a553e8d87f1 100644 --- a/tests/integration/pilot/common/routing.go +++ b/tests/integration/pilot/common/routing.go @@ -909,7 +909,6 @@ spec: } } for _, split := range splits { - split := split t.RunTraffic(TrafficTestCase{ name: fmt.Sprintf("shifting-%d", split[0]), skip: skipAmbient(t, "https://github.com/istio/istio/issues/44948"), @@ -1282,9 +1281,6 @@ spec: } for _, c := range t.Apps.A { for _, e := range expects { - c := c - e := e - tc.children = append(tc.children, TrafficCall{ name: fmt.Sprintf("%s: %s", c.Config().Cluster.StableName(), e.alpn), opts: echo.CallOptions{ @@ -1347,9 +1343,6 @@ spec: } for _, c := range t.Apps.A { for _, e := range expects { - c := c - e := e - tc.children = append(tc.children, TrafficCall{ name: fmt.Sprintf("%s: %s", c.Config().Cluster.StableName(), e.alpn), opts: echo.CallOptions{ @@ -1436,9 +1429,6 @@ spec: } for _, c := range t.Apps.A { for _, e := range expects { - c := c - e := e - tc.children = append(tc.children, TrafficCall{ name: fmt.Sprintf("%s: %s", c.Config().Cluster.StableName(), e.alpn), opts: echo.CallOptions{ @@ -1535,7 +1525,6 @@ func trafficLoopCases(t TrafficContext) { for _, c := range t.Apps.A { for _, d := range t.Apps.B { for _, port := range []int{15001, 15006} { - c, d, port := c, d, port t.RunTraffic(TrafficTestCase{ name: fmt.Sprint(port), call: c.CallOrFail, @@ -1577,7 +1566,6 @@ func autoPassthroughCases(t TrafficContext) { var childs []TrafficCall for _, sni := range snis { for _, alpn := range alpns { - alpn, sni, mode := alpn, sni, mode al := []string{alpn} if alpn == "" { al = nil @@ -2150,7 +2138,6 @@ spec: for _, port := range []echo.Port{ports.AutoHTTP, ports.HTTP, ports.HTTP2} { for _, h2 := range []bool{true, false} { - port, h2 := port, h2 protoName := "http1" expectedProto := "HTTP/1.1" if h2 { @@ -2211,7 +2198,7 @@ spec: } for _, proto := range []protocol.Instance{protocol.HTTP, protocol.HTTPS} { - proto, secret := proto, "" + secret := "" if proto.IsTLS() { secret = ingressutil.IngressKubeSecretYAML("cred", "{{.IngressNamespace}}", ingressutil.TLS, ingressutil.IngressCredentialA) } @@ -2290,7 +2277,6 @@ func ProxyProtocolFilterAppliedGatewayCase(apps *deployment.SingleNamespaceView, } for _, d := range destinationSets { - d := d if len(d) == 0 { continue } @@ -2368,7 +2354,6 @@ func XFFGatewayCase(apps *deployment.SingleNamespaceView, gateway string) []Traf } for _, d := range destinationSets { - d := d if len(d) == 0 { continue } @@ -2649,8 +2634,6 @@ func hostCases(t TrafficContext) { // 4. Another service, B', with P' -> T'. There is no conflicts here at all. func serviceCases(t TrafficContext) { for _, c := range t.Apps.A { - c := c - // Case 1 // Identical to port "http" or service B, just behind another service name svc := fmt.Sprintf(`apiVersion: v1 @@ -2773,7 +2756,6 @@ func externalNameCases(t TrafficContext) { ch := []TrafficCall{} for _, c := range t.Apps.A { for _, port := range []echo.Port{ports.HTTP, ports.AutoHTTP, ports.TCP, ports.HTTPS} { - c, port := c, port ch = append(ch, TrafficCall{ name: port.Name, call: c.CallOrFail, @@ -2914,10 +2896,7 @@ func consistentHashCases(t TrafficContext) { t.Skip("multi-network is not supported") } for _, app := range []echo.Instances{t.Apps.A, t.Apps.B} { - app := app for _, c := range app { - c := c - // First setup a service selecting a few services. This is needed to ensure we can load balance across many pods. svcName := "consistent-hash" if nw := c.Config().Cluster.NetworkName(); nw != "" { @@ -3238,7 +3217,6 @@ func protocolSniffingCases(t TrafficContext) { // so we can check all clusters are hit for _, call := range protocols { - call := call t.RunTraffic(TrafficTestCase{ skip: skip{ skip: call.scheme == scheme.TCP, @@ -3457,8 +3435,6 @@ func instanceIPTests(t TrafficContext) { } for _, ipCase := range ipCases { for _, client := range t.Apps.A { - ipCase := ipCase - client := client to := t.Apps.B var config string if !ipCase.disableSidecar { @@ -3535,30 +3511,11 @@ spec: for _, client := range flatten(t.Apps.VM, t.Apps.A, t.Apps.Tproxy) { v4, v6 := getSupportedIPFamilies(t, client) - var expectedIPv4, expectedIPv6 []string - if v4 && v6 { - expectedIPv4 = ipv4 - expectedIPv6 = ipv6 - } else if v4 { - expectedIPv4 = ipv4 - expectedIPv6 = ipv6[:1] - } else { - expectedIPv4 = ipv4[:1] - expectedIPv6 = ipv6 - } - // If a client is deployed in a remote cluster, which is not a config cluster, i.e. Istio resources - // are not created in that cluster, it will resolve only the default address, because the ServiceEntry - // created in this test is internally assigned to the config cluster, so function GetAllAddressesForProxy(remote), - // will only return the default address for that service. - remotes := client.Clusters().Remotes() - if len(remotes) > 0 && len(remotes.Configs()) == 0 { - if v4 { - expectedIPv4 = []string{"1.2.3.4"} - } - if v6 { - expectedIPv6 = []string{"1234:1234:1234::1234:1234:1234"} - } - } + log := scopes.Framework.WithLabels("client", client.ServiceName()) + + expectedIPv4 := ipv4 + expectedIPv6 := ipv6 + log.Infof("v4=%v v6=%v wantv4=%v wantv6=%v", v4, v6, expectedIPv4, expectedIPv6) cases := []struct { name string ips []string @@ -3616,7 +3573,6 @@ spec: if tt.skipCNI && t.Istio.Settings().EnableCNI { continue } - tt, client := tt, client address := "fake.service.local?" if tt.protocol != "" { address += "&protocol=" + tt.protocol @@ -3625,8 +3581,11 @@ spec: address += "&server=" + tt.server } var checker echo.Checker = func(result echo.CallResult, _ error) error { + if len(result.Responses) == 0 { + return fmt.Errorf("no responses") + } for _, r := range result.Responses { - if !reflect.DeepEqual(r.Body(), tt.expected) { + if !sets.New(r.Body()...).Equals(sets.New(tt.expected...)) { return fmt.Errorf("unexpected dns response: wanted %v, got %v", tt.expected, r.Body()) } } @@ -3664,7 +3623,6 @@ spec: } for _, client := range flatten(t.Apps.VM, t.Apps.A, t.Apps.Tproxy) { for _, tt := range svcCases { - tt, client := tt, client aInCluster := match.Cluster(client.Config().Cluster).GetMatches(t.Apps.A) if len(aInCluster) == 0 { // The cluster doesn't contain A, but connects to a cluster containing A @@ -3776,7 +3734,6 @@ func VMTestCases(vms echo.Instances) func(t TrafficContext) { }) } for _, c := range testCases { - c := c checker := check.OK() if !match.Headless.Any(c.to) { // headless load-balancing can be inconsistent @@ -3856,8 +3813,8 @@ spec: statusCode: http.StatusOK, from: t.Apps.A, to: fakeExternalAddress, - protocol: protocol.HTTPS, - port: 443, + protocol: protocol.HTTP, + port: 80, }, // TC3: Test connectivity to external service from outboundTrafficPolicy=PASS_THROUGH pod. // Traffic should go through without the need for any explicit ServiceEntry @@ -4076,7 +4033,6 @@ func serverFirstTestCases(t TrafficContext) { } for _, client := range from { for _, c := range configs { - client, c := client, c t.RunTraffic(TrafficTestCase{ name: fmt.Sprintf("%v:%v/%v", c.port, c.dest, c.auth), skip: skip{ diff --git a/tests/integration/pilot/ingress_test.go b/tests/integration/pilot/ingress_test.go index 498c4fa2d659..52e9d2236ba5 100644 --- a/tests/integration/pilot/ingress_test.go +++ b/tests/integration/pilot/ingress_test.go @@ -287,10 +287,8 @@ spec: } for _, ingr := range istio.IngressesOrFail(t, t) { - ingr := ingr t.NewSubTestf("from %s", ingr.Cluster().StableName()).Run(func(t framework.TestContext) { for _, c := range cases { - c := c t.NewSubTest(c.name).Run(func(t framework.TestContext) { if err := t.ConfigIstio().YAML(apps.Namespace.Name(), ingressClassConfig, fmt.Sprintf(ingressConfigTemplate, "ingress", "istio-test", c.path, c.path, c.prefixPath)). @@ -435,7 +433,6 @@ spec: } for _, c := range ingressUpdateCases { - c := c updatedIngress := fmt.Sprintf(ingressConfigTemplate, updateIngressName, c.ingressClass, c.path, c.path, c.path) t.ConfigIstio().YAML(apps.Namespace.Name(), updatedIngress).ApplyOrFail(t) t.NewSubTest(c.name).Run(func(t framework.TestContext) { diff --git a/tests/integration/pilot/istioctl_test.go b/tests/integration/pilot/istioctl_test.go index d0f1536b7334..3e62067dc874 100644 --- a/tests/integration/pilot/istioctl_test.go +++ b/tests/integration/pilot/istioctl_test.go @@ -444,7 +444,6 @@ func TestRemoteClusters(t *testing.T) { framework.NewTest(t).RequiresMinClusters(2). Run(func(t framework.TestContext) { for _, cluster := range t.Clusters().Primaries() { - cluster := cluster t.NewSubTest(cluster.StableName()).Run(func(t framework.TestContext) { istioCtl := istioctl.NewOrFail(t, istioctl.Config{Cluster: cluster}) var output string diff --git a/tests/integration/pilot/mcs/autoexport/autoexport_test.go b/tests/integration/pilot/mcs/autoexport/autoexport_test.go index 5b544f81c5f9..e051ceee114d 100644 --- a/tests/integration/pilot/mcs/autoexport/autoexport_test.go +++ b/tests/integration/pilot/mcs/autoexport/autoexport_test.go @@ -64,7 +64,6 @@ func TestAutoExport(t *testing.T) { func(ctx framework.TestContext) { serviceB := match.ServiceName(echo.NamespacedName{Name: common.ServiceB, Namespace: echos.Namespace}) for _, cluster := range serviceB.GetMatches(echos.Instances).Clusters() { - cluster := cluster ctx.NewSubTest(cluster.StableName()).RunParallel(func(ctx framework.TestContext) { // Verify that the ServiceExport was created. ctx.NewSubTest("create").Run(func(ctx framework.TestContext) { @@ -118,7 +117,6 @@ func TestAutoExport(t *testing.T) { ctx.NewSubTest("non-exported").RunParallel(func(ctx framework.TestContext) { ns := "kube-system" for i, cluster := range ctx.Clusters() { - cluster := cluster ctx.NewSubTest(strconv.Itoa(i)).RunParallel(func(ctx framework.TestContext) { services, err := cluster.Dynamic().Resource(serviceExportGVR).Namespace(ns).List( context.TODO(), metav1.ListOptions{}) diff --git a/tests/integration/pilot/mcs/discoverability/discoverability_test.go b/tests/integration/pilot/mcs/discoverability/discoverability_test.go index 7cacf467fe27..66d993f3c932 100644 --- a/tests/integration/pilot/mcs/discoverability/discoverability_test.go +++ b/tests/integration/pilot/mcs/discoverability/discoverability_test.go @@ -153,7 +153,6 @@ func TestServiceExportedInOneCluster(t *testing.T) { // Test exporting service B exclusively in each cluster. for _, exportCluster := range bClusters { - exportCluster := exportCluster t.NewSubTestf("b exported in %s", exportCluster.StableName()). Run(func(t framework.TestContext) { // Export service B in the export cluster. @@ -374,7 +373,6 @@ func createAndCleanupServiceExport(t framework.TestContext, service string, expo // Create the ServiceExports in each cluster concurrently. g := errgroup.Group{} for _, c := range exportClusters { - c := c g.Go(func() error { _, err := c.Dynamic().Resource(serviceExportGVR).Namespace(echos.Namespace.Name()).Create(context.TODO(), &unstructured.Unstructured{Object: u}, metav1.CreateOptions{}) @@ -393,7 +391,6 @@ func createAndCleanupServiceExport(t framework.TestContext, service string, expo if common.IsMCSControllerEnabled(t) { scopes.Framework.Infof("Waiting for the MCS Controller to create ServiceImport in each cluster") for _, c := range importClusters { - c := c serviceImports := c.Dynamic().Resource(serviceImportGVR).Namespace(echos.Namespace.Name()) g.Go(func() error { @@ -416,7 +413,6 @@ func createAndCleanupServiceExport(t framework.TestContext, service string, expo } else { scopes.Framework.Infof("No MCS Controller running. Manually creating ServiceImport in each cluster") for _, c := range importClusters { - c := c g.Go(func() error { // Generate a dummy service in the cluster to reserve the ClusterSet VIP. clusterSetIPSvc, err := genClusterSetIPService(c) @@ -446,7 +442,6 @@ func createAndCleanupServiceExport(t framework.TestContext, service string, expo t.Cleanup(func() { wg := sync.WaitGroup{} for _, c := range exportClusters { - c := c wg.Add(1) go func() { defer wg.Done() diff --git a/tests/integration/pilot/mirror_test.go b/tests/integration/pilot/mirror_test.go index 78fc84030541..22f74cd0a2ca 100644 --- a/tests/integration/pilot/mirror_test.go +++ b/tests/integration/pilot/mirror_test.go @@ -141,7 +141,6 @@ func runMirrorTest(t *testing.T, options mirrorTestOptions) { ApplyOrFail(t) for _, podA := range apps.A { - podA := podA t.NewSubTest(fmt.Sprintf("from %s", podA.Config().Cluster.StableName())).Run(func(t framework.TestContext) { for _, proto := range mirrorProtocols { t.NewSubTest(string(proto)).Run(func(t framework.TestContext) { diff --git a/tests/integration/pilot/multicluster_test.go b/tests/integration/pilot/multicluster_test.go index d5f8350e762e..f11288fce771 100644 --- a/tests/integration/pilot/multicluster_test.go +++ b/tests/integration/pilot/multicluster_test.go @@ -108,11 +108,9 @@ spec: } for _, test := range tests { - test := test t.NewSubTest(test.name).Run(func(t framework.TestContext) { test.setup(t) for _, source := range sources { - source := source t.NewSubTest(source.Config().Cluster.StableName()).RunParallel(func(t framework.TestContext) { source.CallOrFail(t, echo.CallOptions{ To: to, @@ -135,7 +133,6 @@ spec: // this runs in a separate test context - confirms the cluster local config was cleaned up t.NewSubTest("cross cluster").Run(func(t framework.TestContext) { for _, source := range sources { - source := source t.NewSubTest(source.Config().Cluster.StableName()).Run(func(t framework.TestContext) { source.CallOrFail(t, echo.CallOptions{ To: to, diff --git a/tests/integration/pilot/multiplecontrolplanes/main_test.go b/tests/integration/pilot/multiplecontrolplanes/main_test.go index 34f89c8f56f7..a38a62883a05 100644 --- a/tests/integration/pilot/multiplecontrolplanes/main_test.go +++ b/tests/integration/pilot/multiplecontrolplanes/main_test.go @@ -60,7 +60,7 @@ func TestMain(m *testing.M) { Label(label.CustomSetup). // We are deploying two isolated environments, which CNI doesn't support. // We could deploy one of the usergroups as the CNI owner, but for now we skip - SkipIf("CNI is not suppored", func(ctx resource.Context) bool { + SkipIf("CNI is not supported", func(ctx resource.Context) bool { c, _ := istio.DefaultConfig(ctx) return c.EnableCNI }). diff --git a/tests/integration/pilot/proxyconfig/proxyconfig_test.go b/tests/integration/pilot/proxyconfig/proxyconfig_test.go index fcd306ad0306..60eda22186dd 100644 --- a/tests/integration/pilot/proxyconfig/proxyconfig_test.go +++ b/tests/integration/pilot/proxyconfig/proxyconfig_test.go @@ -169,7 +169,6 @@ func TestProxyConfig(t *testing.T) { func checkInjectedValues(t framework.TestContext, instances echo.Instances, values map[string]string) { t.Helper() for _, i := range instances { - i := i attempts := 0 retry.UntilSuccessOrFail(t, func() error { // to avoid sleeping for ProxyConfig propagation, we @@ -182,7 +181,6 @@ func checkInjectedValues(t framework.TestContext, instances echo.Instances, valu } attempts++ for _, w := range i.WorkloadsOrFail(t) { - w := w for k, v := range values { // can we rely on printenv being in the container once distroless is default? out, _, err := i.Config().Cluster.PodExec(w.PodName(), i.Config().Namespace.Name(), diff --git a/tests/integration/pilot/testdata/gateway-api-crd.yaml b/tests/integration/pilot/testdata/gateway-api-crd.yaml index 0b7c920de869..fc4a43f41bcf 100644 --- a/tests/integration/pilot/testdata/gateway-api-crd.yaml +++ b/tests/integration/pilot/testdata/gateway-api-crd.yaml @@ -1,10 +1,10 @@ -# Generated with `kubectl kustomize "https://github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v1.2.0"` +# Generated with `kubectl kustomize "https://github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v1.2.1"` apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null labels: @@ -502,7 +502,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null labels: @@ -1128,7 +1128,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: gatewayclasses.gateway.networking.k8s.io @@ -1645,7 +1645,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: gateways.gateway.networking.k8s.io @@ -4058,7 +4058,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: grpcroutes.gateway.networking.k8s.io @@ -6293,7 +6293,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: httproutes.gateway.networking.k8s.io @@ -12452,7 +12452,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: referencegrants.gateway.networking.k8s.io @@ -12642,7 +12642,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tcproutes.gateway.networking.k8s.io @@ -13384,7 +13384,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: tlsroutes.gateway.networking.k8s.io @@ -14189,7 +14189,7 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 - gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/bundle-version: v1.2.1 gateway.networking.k8s.io/channel: experimental creationTimestamp: null name: udproutes.gateway.networking.k8s.io diff --git a/tests/integration/pilot/vm_test.go b/tests/integration/pilot/vm_test.go index 5dcce302405c..a5731d080c61 100644 --- a/tests/integration/pilot/vm_test.go +++ b/tests/integration/pilot/vm_test.go @@ -82,7 +82,6 @@ func TestVmOSPost(t *testing.T) { instances := b.BuildOrFail(t) for idx, image := range images { - idx, image := idx, image t.NewSubTest(image).RunParallel(func(t framework.TestContext) { tc := common.TrafficContext{ TestContext: t, diff --git a/tests/integration/pilot/workloadentry_test.go b/tests/integration/pilot/workloadentry_test.go index 4c45be44187d..d12f15cdb328 100644 --- a/tests/integration/pilot/workloadentry_test.go +++ b/tests/integration/pilot/workloadentry_test.go @@ -186,7 +186,6 @@ spec: } for _, tc := range testCases { - tc := tc t.NewSubTest(tc.name).Run(func(t framework.TestContext) { for network, networkClusters := range t.Clusters().ByNetwork() { weClusters := t.Clusters().Configs(networkClusters...) @@ -203,7 +202,6 @@ spec: } for _, src := range apps.A.Instances() { - src := src // TODO possibly can run parallel t.NewSubTestf("from %s", src.Clusters().Default().Name()).Run(func(t framework.TestContext) { src.CallOrFail(t, echo.CallOptions{ diff --git a/tests/integration/security/authz_test.go b/tests/integration/security/authz_test.go index a067f8e58457..f12ee25cb6ac 100644 --- a/tests/integration/security/authz_test.go +++ b/tests/integration/security/authz_test.go @@ -458,7 +458,6 @@ func TestAuthz_NotHost(t *testing.T) { } for _, c := range cases { - c := c testName := fmt.Sprintf("%s(%s)/http", c.host, c.allow) t.NewSubTest(testName).Run(func(t framework.TestContext) { wantCode := http.StatusOK @@ -1056,10 +1055,17 @@ func TestAuthz_PathTemplating(t *testing.T) { path: "/store/cart", allow: false, }, + { + path: "/store/foo/cart", + allow: true, + }, + { + path: "/store/foo/bar/cart", + allow: true, + }, } for _, c := range cases { - c := c testName := fmt.Sprintf("%s(%s)/http", c.path, c.allow) t.NewSubTest(testName).Run(func(t framework.TestContext) { newAuthzTest(). @@ -1214,7 +1220,6 @@ func TestAuthz_IngressGateway(t *testing.T) { } for _, c := range cases { - c := c testName := fmt.Sprintf("%s%s(%s)/http", c.host, c.path, c.allow) if len(c.ip) > 0 { testName = c.ip + "->" + testName @@ -1317,7 +1322,6 @@ func TestAuthz_EgressGateway(t *testing.T) { } for _, c := range cases { - c := c testName := fmt.Sprintf("%s%s(%s)/http", c.host, c.path, c.allow) t.NewSubTest(testName).Run(func(t framework.TestContext) { wantCode := http.StatusOK @@ -1501,7 +1505,6 @@ func TestAuthz_Conditions(t *testing.T) { } for _, c := range cases { - c := c xfooHeader := "" if c.headers != nil { xfooHeader = "?x-foo=" + c.headers.Get("x-foo") @@ -1599,7 +1602,6 @@ func TestAuthz_PathNormalization(t *testing.T) { } for _, c := range cases { - c := c testName := fmt.Sprintf("%s(%s)/http", c.path, c.allow) t.NewSubTest(testName).Run(func(t framework.TestContext) { newAuthzTest(). @@ -1707,7 +1709,6 @@ func TestAuthz_CustomServer(t *testing.T) { } for _, c := range cases { - c := c if c.skip { continue } @@ -1722,7 +1723,6 @@ func TestAuthz_CustomServer(t *testing.T) { return provider.IsProtocolSupported(tst.opts.Port.Protocol) }) for _, tst := range tsts { - tst := tst params := "" if c.headers != nil { params = fmt.Sprintf("?%s=%s", authz.XExtAuthz, c.headers.Get(authz.XExtAuthz)) @@ -1919,7 +1919,6 @@ func (tsts authzTests) RunAll(t framework.TestContext) { outerTestName := fmt.Sprintf("%s%s(%s)", firstTest.prefix, firstTest.opts.HTTP.Path, firstTest.allow) t.NewSubTest(outerTestName).Run(func(t framework.TestContext) { for _, tst := range tsts { - tst := tst t.NewSubTest(tst.opts.Port.Name).Run(func(t framework.TestContext) { tst.BuildAndRun(t) }) @@ -1947,7 +1946,6 @@ func (tsts authzTests) RunInSerial(t framework.TestContext) { outerTestName := fmt.Sprintf("%s%s(%s)", firstTest.prefix, firstTest.opts.HTTP.Path, firstTest.allow) t.NewSubTest(outerTestName).Run(func(t framework.TestContext) { for _, tst := range tsts { - tst := tst t.NewSubTest(tst.opts.Port.Name).Run(func(t framework.TestContext) { tst.BuildAndRun(t) }) diff --git a/tests/integration/security/filebased_tls_origination/destination_rule_tls_test.go b/tests/integration/security/filebased_tls_origination/destination_rule_tls_test.go index 578214107f0b..bae36cb39419 100644 --- a/tests/integration/security/filebased_tls_origination/destination_rule_tls_test.go +++ b/tests/integration/security/filebased_tls_origination/destination_rule_tls_test.go @@ -53,7 +53,6 @@ spec: `).ApplyOrFail(t) for _, portName := range []string{"grpc", "http", "tcp"} { - portName := portName t.NewSubTest(portName).Run(func(t framework.TestContext) { opts := echo.CallOptions{ To: server, diff --git a/tests/integration/security/jwt_test.go b/tests/integration/security/jwt_test.go index 7a1c8bf1e3c1..d623462c244a 100644 --- a/tests/integration/security/jwt_test.go +++ b/tests/integration/security/jwt_test.go @@ -473,6 +473,16 @@ func TestIngressRequestAuthentication(t *testing.T) { name string customizeCall func(opts *echo.CallOptions, to echo.Target) }{ + { + name: "allow healthz", + customizeCall: func(opts *echo.CallOptions, to echo.Target) { + opts.HTTP.Path = "/healthz" + opts.HTTP.Headers = headers.New(). + WithHost(fmt.Sprintf("example.%s.com", to.ServiceName())). + Build() + opts.Check = check.OK() + }, + }, { name: "deny without token", customizeCall: func(opts *echo.CallOptions, to echo.Target) { @@ -559,16 +569,6 @@ func TestIngressRequestAuthentication(t *testing.T) { opts.Check = check.Status(http.StatusForbidden) }, }, - { - name: "allow healthz", - customizeCall: func(opts *echo.CallOptions, to echo.Target) { - opts.HTTP.Path = "/healthz" - opts.HTTP.Headers = headers.New(). - WithHost(fmt.Sprintf("example.%s.com", to.ServiceName())). - Build() - opts.Check = check.OK() - }, - }, } newTrafficTest(t, apps.Ns1.All.Instances()). @@ -613,6 +613,16 @@ func TestGatewayAPIRequestAuthentication(t *testing.T) { name string customizeCall func(opts *echo.CallOptions, to echo.Target) }{ + { + name: "allow healthz", + customizeCall: func(opts *echo.CallOptions, to echo.Target) { + opts.HTTP.Path = "/healthz" + opts.HTTP.Headers = headers.New(). + WithHost(fmt.Sprintf("example.%s.com", to.ServiceName())). + Build() + opts.Check = check.OK() + }, + }, { name: "deny without token", customizeCall: func(opts *echo.CallOptions, to echo.Target) { @@ -710,16 +720,6 @@ func TestGatewayAPIRequestAuthentication(t *testing.T) { opts.Check = check.Status(http.StatusForbidden) }, }, - { - name: "allow healthz", - customizeCall: func(opts *echo.CallOptions, to echo.Target) { - opts.HTTP.Path = "/healthz" - opts.HTTP.Headers = headers.New(). - WithHost(fmt.Sprintf("example.%s.com", to.ServiceName())). - Build() - opts.Check = check.OK() - }, - }, } newTrafficTest(t, apps.Ns1.A.Append(apps.Ns1.B)). diff --git a/tests/integration/security/normalization_test.go b/tests/integration/security/normalization_test.go index b87b9a89038c..1d60750cff62 100644 --- a/tests/integration/security/normalization_test.go +++ b/tests/integration/security/normalization_test.go @@ -232,7 +232,6 @@ pathNormalization: FromMatch(match.ServiceName(apps.Ns1.A.NamespacedName())). Run(func(t framework.TestContext, from echo.Instance, to echo.Target) { for _, expected := range tt.expectations { - expected := expected t.NewSubTest(expected.in).Run(func(t framework.TestContext) { checker := check.URL(expected.out) if expected.out == "400" { diff --git a/tests/integration/security/pass_through_filter_chain_test.go b/tests/integration/security/pass_through_filter_chain_test.go index a546920a8797..aca8e80bdf17 100644 --- a/tests/integration/security/pass_through_filter_chain_test.go +++ b/tests/integration/security/pass_through_filter_chain_test.go @@ -331,7 +331,6 @@ spec: } for _, tc := range cases { - tc := tc t.NewSubTest(tc.name).Run(func(t framework.TestContext) { // Create the PeerAuthentication for the test case. config.New(t). @@ -394,9 +393,8 @@ spec: // TODO(nmittler): Why does passthrough not work? ConditionallyTo(echotest.SameNetwork). Run(func(t framework.TestContext, from echo.Instance, to echo.Target) { - for _, expect := range tc.expected { - expect := expect - p := expect.port + for _, exp := range tc.expected { + p := exp.port opts := echo.CallOptions{ // Do not set To, otherwise fillInCallOptions() will // complain with port does not match. @@ -412,9 +410,9 @@ spec: Count: echo.DefaultCallsPerWorkload() * to.WorkloadsOrFail(t).Len(), } - allow := allowValue(expect.mtlsSucceeds) + allow := allowValue(exp.mtlsSucceeds) if from.Config().IsNaked() { - allow = allowValue(expect.plaintextSucceeds) + allow = allowValue(exp.plaintextSucceeds) } if allow { diff --git a/tests/integration/security/reachability_test.go b/tests/integration/security/reachability_test.go index 5c3773140b21..52f477ebd5b0 100644 --- a/tests/integration/security/reachability_test.go +++ b/tests/integration/security/reachability_test.go @@ -453,8 +453,6 @@ func TestReachability(t *testing.T) { } for _, c := range cases { - c := c - t.NewSubTest(c.name).Run(func(t framework.TestContext) { if c.minIstioVersion != "" { skipMV := !t.Settings().Revisions.AtLeast(resource.IstioVersion(c.minIstioVersion)) @@ -493,8 +491,6 @@ func TestReachability(t *testing.T) { // This is to workaround a known bug (https://github.com/istio/istio/issues/38982) causing // connection resets when sending traffic to multiple ports at once for _, opts := range allOpts { - opts := opts - schemeStr := string(opts.Scheme) if len(schemeStr) == 0 { schemeStr = opts.Port.Name diff --git a/tests/integration/security/sds_ingress/util/util.go b/tests/integration/security/sds_ingress/util/util.go index 6e2d23d4ec9e..0fb501f3c434 100644 --- a/tests/integration/security/sds_ingress/util/util.go +++ b/tests/integration/security/sds_ingress/util/util.go @@ -150,7 +150,6 @@ func CreateIngressKubeSecretInNamespace(t framework.TestContext, credName string clusters = t.Clusters() } for _, c := range clusters { - c := c wg.Go(func() error { secret := createSecret(ingressType, credName, ns, ingressCred, isCompoundAndNotGeneric) _, err := c.Kube().CoreV1().Secrets(ns).Create(context.TODO(), secret, metav1.CreateOptions{}) diff --git a/tests/integration/security/util/reachability/context.go b/tests/integration/security/util/reachability/context.go index ddb644e76e76..2483db36563a 100644 --- a/tests/integration/security/util/reachability/context.go +++ b/tests/integration/security/util/reachability/context.go @@ -128,8 +128,6 @@ func Run(testCases []TestCase, t framework.TestContext) { } for _, c := range testCases { - // Create a copy to avoid races, as tests are run in parallel - c := c testName := strings.TrimSuffix(c.ConfigFile, filepath.Ext(c.ConfigFile)) t.NewSubTest(testName).Run(func(t framework.TestContext) { // Apply the policy. @@ -141,7 +139,6 @@ func Run(testCases []TestCase, t framework.TestContext) { }) for _, clients := range []echo.Instances{A, B, Headless, Naked, HeadlessNaked} { for _, from := range clients { - from := from t.NewSubTest(fmt.Sprintf("%s in %s", from.Config().Service, from.Config().Cluster.StableName())).Run(func(t framework.TestContext) { destinationSets := []echo.Instances{ @@ -157,7 +154,6 @@ func Run(testCases []TestCase, t framework.TestContext) { } for _, to := range destinationSets { - to := to if c.ExpectDestinations != nil { to = c.ExpectDestinations(from, to) } @@ -177,9 +173,6 @@ func Run(testCases []TestCase, t framework.TestContext) { copts = &c.CallOpts } for _, opts := range *copts { - // Copy the loop variables so they won't change for the subtests. - opts := opts - // Set the target on the call options. opts.To = to if len(toClusters) == 1 { diff --git a/tests/integration/telemetry/api/accesslogs_test.go b/tests/integration/telemetry/api/accesslogs_test.go index 3661b9225b05..d6503e59c1d9 100644 --- a/tests/integration/telemetry/api/accesslogs_test.go +++ b/tests/integration/telemetry/api/accesslogs_test.go @@ -1,17 +1,3 @@ -// Copyright Istio Authors -// -// Licensed 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. - //go:build integ // +build integ @@ -32,6 +18,7 @@ package api import ( + "errors" "fmt" "strings" "testing" @@ -123,6 +110,44 @@ defaultProviders: }) } +func TestAccessLogWithFilterState(t *testing.T) { + framework.NewTest(t). + Run(func(t framework.TestContext) { + t.ConfigIstio().File(apps.Namespace.Name(), "./testdata/accesslog/enable-filter-state-log.yaml").ApplyOrFail(t) + to := GetTarget() + from := GetClientInstances()[0] + err := retry.UntilSuccess(func() error { + from.CallOrFail(t, echo.CallOptions{ + To: to, + Port: echo.Port{ + Name: "http", + }, + HTTP: echo.HTTP{ + Path: "/filter-state-test", + }, + }) + lines := logs(t, to, "filter-state-test") + if len(lines) == 0 { + return errors.New("no logs found") + } + // if FILTER_STATE is not working, then the log will look like this: + // `/filter-state-test - -` + target := fmt.Sprintf("/%s - -", "filter-state-test") + for _, line := range lines { + t.Logf("line: %s", line) + if line == target { + t.Logf("FILTER_STATE is not working, logs: %s", line) + return errors.New("FILTER_STATE is not working") + } + } + return nil + }, retry.Timeout(framework.TelemetryRetryTimeout)) + if err != nil { + t.Fatalf("expected FILTER_STATE but got nil, err: %v", err) + } + }) +} + func applyTelemetryResourceWithTargetRef(t framework.TestContext, enableLogs bool) { args := map[string]any{ "TargetGatewayName": GetTarget().ServiceName() + "-gateway", @@ -247,6 +272,24 @@ func runAccessLogsTests(t framework.TestContext, expectLogs bool, hasTargetRef b } } +func logs(t test.Failer, to echo.Target, testID string) []string { + var result []string + for _, w := range to.WorkloadsOrFail(t) { + l, err := w.Sidecar().Logs() + if err != nil { + t.Fatalf("failed getting logs: %v", err) + } + split := strings.Split(l, "\n") + for _, line := range split { + if c := float64(strings.Count(line, testID)); c > 0 { + result = append(result, line) + } + } + } + + return result +} + func logCount(t test.Failer, to echo.Target, testID string) float64 { counts := map[string]float64{} for _, w := range to.WorkloadsOrFail(t) { diff --git a/tests/integration/telemetry/api/customize_metrics_test.go b/tests/integration/telemetry/api/customize_metrics_test.go index cab303b04288..d6702d116f07 100644 --- a/tests/integration/telemetry/api/customize_metrics_test.go +++ b/tests/integration/telemetry/api/customize_metrics_test.go @@ -111,7 +111,19 @@ spec: } func setupWasmExtension(t framework.TestContext) { - attrGenImageURL := fmt.Sprintf("oci://%v/istio-testing/wasm/attributegen:0.0.1", registry.Address()) + isKind, err := IsKindCluster() + if err != nil { + t.Errorf("failed to identify cluster type: %v", err) + } + + // By default, for any platform, the test will pull the test image from public "gcr.io" registry. + // For "Kind" environment, it will pull the images from the "kind-registry". + // For "Kind", this is due to DNS issues in IPv6 cluster + attrGenImageTag := "359dcd3a19f109c50e97517fe6b1e2676e870c4d" + if isKind { + attrGenImageTag = "0.0.1" + } + attrGenImageURL := fmt.Sprintf("oci://%v/istio-testing/wasm/attributegen:%v", registry.Address(), attrGenImageTag) args := map[string]any{ "AttributeGenURL": attrGenImageURL, } diff --git a/tests/integration/telemetry/api/dashboard_test.go b/tests/integration/telemetry/api/dashboard_test.go index d032920117b5..d7c7d1233c47 100644 --- a/tests/integration/telemetry/api/dashboard_test.go +++ b/tests/integration/telemetry/api/dashboard_test.go @@ -156,7 +156,6 @@ func TestDashboard(t *testing.T) { // all in a single scrape which can lead to `rate()` not behaving correctly. go setupDashboardTest(c.Done()) for _, d := range dashboards { - d := d t.NewSubTest(d.name).Run(func(t framework.TestContext) { for _, cl := range t.Clusters() { if !cl.IsPrimary() && d.requirePrimary { diff --git a/tests/integration/telemetry/api/registry_setup_test.go b/tests/integration/telemetry/api/registry_setup_test.go index ab4eee0979aa..29858c3b3bb0 100644 --- a/tests/integration/telemetry/api/registry_setup_test.go +++ b/tests/integration/telemetry/api/registry_setup_test.go @@ -34,11 +34,25 @@ const ( ) func testRegistrySetup(ctx resource.Context) (err error) { - registry, err = registryredirector.New(ctx, registryredirector.Config{ - Cluster: ctx.AllClusters().Default(), - TargetRegistry: "kind-registry:5000", - Scheme: "http", - }) + var config registryredirector.Config + + isKind, err := IsKindCluster() + if err != nil { + return + } + + // By default, for any platform, the test will pull the test image from public "gcr.io" registry. + // For "Kind" environment, it will pull the images from the "kind-registry". + // For "Kind", this is due to DNS issues in IPv6 cluster + if isKind { + config = registryredirector.Config{ + Cluster: ctx.AllClusters().Default(), + TargetRegistry: "kind-registry:5000", + Scheme: "http", + } + } + + registry, err = registryredirector.New(ctx, config) if err != nil { return } diff --git a/tests/integration/telemetry/api/setup_test.go b/tests/integration/telemetry/api/setup_test.go index 2e7bd1ae125c..29c8d7e46f56 100644 --- a/tests/integration/telemetry/api/setup_test.go +++ b/tests/integration/telemetry/api/setup_test.go @@ -20,8 +20,11 @@ package api import ( "encoding/base64" "fmt" + "os" "testing" + "k8s.io/client-go/tools/clientcmd" + "istio.io/api/annotation" "istio.io/istio/pkg/test/echo/common" "istio.io/istio/pkg/test/framework" @@ -81,6 +84,12 @@ func setupConfig(_ resource.Context, cfg *istio.Config) { cfg.ControlPlaneValues = ` meshConfig: accessLogFile: "" # disable from install, we will enable via Telemetry layer + extensionProviders: + - name: filter-state-log + envoyFileAccessLog: + path: /dev/stdout + logFormat: + text: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %FILTER_STATE(upstream_peer)% %FILTER_STATE(downstream_peer)%\n" ` cfg.RemoteClusterValues = cfg.ControlPlaneValues cfg.Values["global.logging.level"] = "xdsproxy:debug,wasm:debug" @@ -129,9 +138,6 @@ proxyMetadata: return err } - if err != nil { - return err - } for _, c := range ctx.Clusters() { ingr = append(ingr, ist.IngressFor(c)) } @@ -151,3 +157,23 @@ proxyMetadata: } return nil } + +// The function validates if the cluster is a "Kind" cluster, +// By looking into a context name. Expects "kind-" prefix. +// That is required by some tests for specific actions on "Kind". +func IsKindCluster() (bool, error) { + kubeconfig := os.Getenv("KUBECONFIG") + if kubeconfig == "" { + kubeconfig = clientcmd.RecommendedHomeFile + } + + config, err := clientcmd.LoadFromFile(kubeconfig) + if err != nil { + if os.IsNotExist(err) { + return false, fmt.Errorf("kubeconfig file not found: %s", kubeconfig) + } + return false, err + } + currentContext := config.CurrentContext + return currentContext == "kind-kind" || len(currentContext) > 5 && currentContext[:5] == "kind-", nil +} diff --git a/tests/integration/telemetry/api/stats_test.go b/tests/integration/telemetry/api/stats_test.go index 265ce1b7e9ba..fa5a72bfea1a 100644 --- a/tests/integration/telemetry/api/stats_test.go +++ b/tests/integration/telemetry/api/stats_test.go @@ -28,6 +28,7 @@ import ( "golang.org/x/sync/errgroup" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/test" "istio.io/istio/pkg/test/echo/common/scheme" "istio.io/istio/pkg/test/env" @@ -75,7 +76,6 @@ func TestStatsFilter(t *testing.T) { t.ConfigIstio().YAML(ist.Settings().SystemNamespace, PeerAuthenticationConfig).ApplyOrFail(t) g, _ := errgroup.WithContext(context.Background()) for _, cltInstance := range GetClientInstances() { - cltInstance := cltInstance g.Go(func() error { err := retry.UntilSuccess(func() error { if err := SendTraffic(cltInstance); err != nil { @@ -157,7 +157,6 @@ func TestStatsTCPFilter(t *testing.T) { Run(func(t framework.TestContext) { g, _ := errgroup.WithContext(context.Background()) for _, cltInstance := range GetClientInstances() { - cltInstance := cltInstance g.Go(func() error { err := retry.UntilSuccess(func() error { if err := SendTCPTraffic(cltInstance); err != nil { @@ -211,7 +210,6 @@ func TestStatsGatewayServerTCPFilter(t *testing.T) { g, _ := errgroup.WithContext(context.Background()) for _, cltInstance := range GetClientInstances() { - cltInstance := cltInstance g.Go(func() error { err := retry.UntilSuccess(func() error { if _, err := cltInstance.Call(echo.CallOptions{ @@ -299,6 +297,35 @@ func SendTrafficOrFail(t test.Failer, from echo.Instance) { }) } +func SendTrafficOrFailExpectForbidden(t test.Failer, from echo.Instance) { + from.CallOrFail(t, echo.CallOptions{ + To: GetTarget(), + Port: echo.Port{ + Name: "http", + }, + Retry: echo.Retry{ + Options: []retry.Option{ + retry.Delay(framework.TelemetryRetryDelay), + retry.MaxAttempts(10), + }, + }, + Check: check.Forbidden(protocol.HTTP), + }) + from.CallOrFail(t, echo.CallOptions{ + To: apps.Naked, + Port: echo.Port{ + Name: "http", + }, + Retry: echo.Retry{ + Options: []retry.Option{ + retry.Delay(framework.TelemetryRetryDelay), + retry.MaxAttempts(10), + }, + }, + Check: check.Forbidden(protocol.HTTP), + }) +} + // SendTCPTraffic makes a client call to the "server" service on the tcp port. func SendTCPTraffic(from echo.Instance) error { _, err := from.Call(echo.CallOptions{ @@ -509,8 +536,6 @@ func buildGRPCQuery(metric string) (destinationQuery prometheus.Query) { func SendGRPCTraffic() error { for _, cltInstance := range GetClientInstances() { - cltInstance := cltInstance - _, err := cltInstance.Call(echo.CallOptions{ To: GetTarget(), Port: echo.Port{ diff --git a/tests/integration/telemetry/api/testdata/accesslog/enable-filter-state-log.yaml b/tests/integration/telemetry/api/testdata/accesslog/enable-filter-state-log.yaml new file mode 100644 index 000000000000..5bfd9e1af081 --- /dev/null +++ b/tests/integration/telemetry/api/testdata/accesslog/enable-filter-state-log.yaml @@ -0,0 +1,8 @@ +apiVersion: telemetry.istio.io/v1 +kind: Telemetry +metadata: + name: filter-state-log +spec: + accessLogging: + - providers: + - name: filter-state-log diff --git a/tests/integration/telemetry/api/wasmplugin_test.go b/tests/integration/telemetry/api/wasmplugin_test.go index b1727db73efc..7801cc817b9f 100644 --- a/tests/integration/telemetry/api/wasmplugin_test.go +++ b/tests/integration/telemetry/api/wasmplugin_test.go @@ -339,7 +339,8 @@ func TestBadWasmRemoteLoad(t *testing.T) { Run(func(t framework.TestContext) { // Enable logging for debugging applyTelemetryResource(t, true) - badWasmTestHelper(t, "testdata/bad-filter.yaml", false, true) + // if wasm image is not ready, a deny-all rbac filter while be added instead. ecds is not rejected. + badWasmTestHelper(t, "testdata/bad-filter.yaml", false, false, true) }) } @@ -355,11 +356,11 @@ func TestBadWasmWithFailOpen(t *testing.T) { // Enable logging for debugging applyTelemetryResource(t, true) // since this case is for "fail_open=true", ecds is not rejected. - badWasmTestHelper(t, "testdata/bad-wasm-envoy-filter-fail-open.yaml", true, false) + badWasmTestHelper(t, "testdata/bad-wasm-envoy-filter-fail-open.yaml", true, false, false) }) } -func badWasmTestHelper(t framework.TestContext, filterConfigPath string, restartTarget bool, ecdsShouldReject bool) { +func badWasmTestHelper(t framework.TestContext, filterConfigPath string, restartTarget bool, ecdsShouldReject bool, forbiddenAfterConfig bool) { t.Helper() // Test bad wasm remote load in only one cluster. // There is no need to repeat the same testing logic in multiple clusters. @@ -405,8 +406,11 @@ func badWasmTestHelper(t framework.TestContext, filterConfigPath string, restart t.Log("got istio_agent_wasm_remote_fetch_count metric in prometheus, bad wasm filter is applied, send request to echo server again.") - // Verify that echo server could still return 200 - SendTrafficOrFail(t, to) - - t.Log("echo server still returns ok after bad wasm filter is applied.") + if forbiddenAfterConfig { + SendTrafficOrFailExpectForbidden(t, to) + t.Log("echo server returns 403 after bad wasm(FAIL_CLOSE) filter is applied.") + } else { + SendTrafficOrFail(t, to) + t.Log("echo server still returns ok after bad wasm(FAIL_OPEN) filter is applied.") + } } diff --git a/tests/integration/telemetry/tracing/otelcollector/tracing_test.go b/tests/integration/telemetry/tracing/otelcollector/tracing_test.go index 5e5024346cd0..99f54fe5a759 100644 --- a/tests/integration/telemetry/tracing/otelcollector/tracing_test.go +++ b/tests/integration/telemetry/tracing/otelcollector/tracing_test.go @@ -94,16 +94,20 @@ func TestProxyTracingOpenTelemetryProvider(t *testing.T) { // TODO fix tracing tests in multi-network https://github.com/istio/istio/issues/28890 for _, cluster := range ctx.Clusters().ByNetwork()[ctx.Clusters().Default().NetworkName()] { - cluster := cluster ctx.NewSubTest(cluster.StableName()).Run(func(ctx framework.TestContext) { retry.UntilSuccessOrFail(ctx, func() error { err := tracing.SendTraffic(ctx, nil, cluster) if err != nil { return fmt.Errorf("cannot send traffic from cluster %s: %v", cluster.Name(), err) } + hostDomain := "" + if ctx.Settings().OpenShift { + ingressAddr, _ := tracing.GetIngressInstance().HTTPAddresses() + hostDomain = ingressAddr[0] + } // the OTel collector exports to Zipkin - traces, err := tracing.GetZipkinInstance().QueryTraces(300, "", tc.customAttribute) + traces, err := tracing.GetZipkinInstance().QueryTraces(300, "", tc.customAttribute, hostDomain) t.Logf("got traces %v from %s", traces, cluster) if err != nil { return fmt.Errorf("cannot get traces from zipkin: %v", err) diff --git a/tests/integration/telemetry/tracing/zipkin/client_tracing_test.go b/tests/integration/telemetry/tracing/zipkin/client_tracing_test.go index d468d78bb5af..3dd541be1241 100644 --- a/tests/integration/telemetry/tracing/zipkin/client_tracing_test.go +++ b/tests/integration/telemetry/tracing/zipkin/client_tracing_test.go @@ -39,7 +39,6 @@ func TestClientTracing(t *testing.T) { Run(func(t framework.TestContext) { appNsInst := tracing.GetAppNamespace() for _, cluster := range t.Clusters().ByNetwork()[t.Clusters().Default().NetworkName()] { - cluster := cluster t.NewSubTest(cluster.StableName()).Run(func(ctx framework.TestContext) { retry.UntilSuccessOrFail(ctx, func() error { // Send test traffic with a trace header. @@ -51,8 +50,13 @@ func TestClientTracing(t *testing.T) { if err != nil { return fmt.Errorf("cannot send traffic from cluster %s: %v", cluster.Name(), err) } + hostDomain := "" + if t.Settings().OpenShift { + ingressAddr, _ := tracing.GetIngressInstance().HTTPAddresses() + hostDomain = ingressAddr[0] + } traces, err := tracing.GetZipkinInstance().QueryTraces(100, - fmt.Sprintf("server.%s.svc.cluster.local:80/*", appNsInst.Name()), "") + fmt.Sprintf("server.%s.svc.cluster.local:80/*", appNsInst.Name()), "", hostDomain) if err != nil { return fmt.Errorf("cannot get traces from zipkin: %v", err) } @@ -62,7 +66,6 @@ func TestClientTracing(t *testing.T) { return nil }, retry.Delay(3*time.Second), retry.Timeout(80*time.Second)) }) - } }) } diff --git a/tests/integration/telemetry/tracing/zipkin/server_tracing_test.go b/tests/integration/telemetry/tracing/zipkin/server_tracing_test.go index 454068112cdf..ecfb969b92c7 100644 --- a/tests/integration/telemetry/tracing/zipkin/server_tracing_test.go +++ b/tests/integration/telemetry/tracing/zipkin/server_tracing_test.go @@ -44,8 +44,13 @@ func TestServerTracing(t *testing.T) { if err != nil { return fmt.Errorf("cannot send traffic from cluster %s: %v", cluster.Name(), err) } + hostDomain := "" + if t.Settings().OpenShift { + ingressAddr, _ := tracing.GetIngressInstance().HTTPAddresses() + hostDomain = ingressAddr[0] + } traces, err := tracing.GetZipkinInstance().QueryTraces(300, - fmt.Sprintf("server.%s.svc.cluster.local:80/*", appNsInst.Name()), "") + fmt.Sprintf("server.%s.svc.cluster.local:80/*", appNsInst.Name()), "", hostDomain) if err != nil { return fmt.Errorf("cannot get traces from zipkin: %v", err) } diff --git a/tools/build-kind-image.sh b/tools/build-kind-image.sh index 5ddb5cd36b0e..7179a874ac14 100755 --- a/tools/build-kind-image.sh +++ b/tools/build-kind-image.sh @@ -16,11 +16,12 @@ # This script builds a multi-arch kind node image # Largely copied from https://github.com/kubernetes-sigs/kind/blob/2a1e9df91fd22d6ae5b91648b6c1a606ab4cdf30/hack/release/build/push-node.sh +# Example usage, without building (preferred): `tools/build-kind-image.sh v1.23.4 gcr.io/istio-testing/kind-node:v1.23.4` # Example usage: `tools/build-kind-image.sh ~/go/src/k8s.io/kubernetes gcr.io/istio-testing/kind-node:v1.23.4` set -uex -kdir="${1:?Kubernetes directory}" +kdir="${1:?Kubernetes directory OR version}" registry="${2:?registry}" ARCHES="${ARCHES:-amd64 arm64}" diff --git a/tools/docker-builder/builder/crane.go b/tools/docker-builder/builder/crane.go index 73240215322f..1a21936d1c3f 100644 --- a/tools/docker-builder/builder/crane.go +++ b/tools/docker-builder/builder/crane.go @@ -100,7 +100,6 @@ func WarmBase(ctx context.Context, architectures []string, baseImages ...string) t0 := time.Now() for i, b := range keys { - b, i := b, i go func() { defer wg.Done() ref, err := name.ParseReference(b.name) diff --git a/tools/docker-builder/crane.go b/tools/docker-builder/crane.go index 6e2e797e3c22..591c8a9ff028 100644 --- a/tools/docker-builder/crane.go +++ b/tools/docker-builder/crane.go @@ -119,7 +119,6 @@ func RunCrane(ctx context.Context, a Args) error { // Finally, construct images and push them dockerStart := time.Now() for _, b := range builds { - b := b g.Go(func() error { if err := builder.Build(ctx, b); err != nil { return fmt.Errorf("build %v: %v", b.Name, err) diff --git a/tools/docker-builder/docker.go b/tools/docker-builder/docker.go index 9fc6a9a1d50e..9116ecd5cf84 100644 --- a/tools/docker-builder/docker.go +++ b/tools/docker-builder/docker.go @@ -291,7 +291,6 @@ func ConstructBakeFile(a Args) (map[string]string, error) { if strings.HasSuffix(i, ":latest") { // Allow clobbering of latest - don't verify existence continue } - i := i e.Go(func() error { exists, err := image.Exists(i) if err != nil { diff --git a/tools/istio-clean-iptables/pkg/cmd/cleanup.go b/tools/istio-clean-iptables/pkg/cmd/cleanup.go deleted file mode 100644 index 680233b64064..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/cleanup.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright Istio Authors -// -// Licensed 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 cmd - -import ( - "fmt" - "net/netip" - "os" - - "istio.io/istio/tools/istio-clean-iptables/pkg/config" - "istio.io/istio/tools/istio-iptables/pkg/builder" - common "istio.io/istio/tools/istio-iptables/pkg/capture" - types "istio.io/istio/tools/istio-iptables/pkg/config" - "istio.io/istio/tools/istio-iptables/pkg/constants" - dep "istio.io/istio/tools/istio-iptables/pkg/dependencies" -) - -func NewDependencies(cfg *config.Config) dep.Dependencies { - if cfg.DryRun { - return &dep.DependenciesStub{} - } - return &dep.RealDependencies{} -} - -type IptablesCleaner struct { - ext dep.Dependencies - cfg *config.Config - iptV *dep.IptablesVersion - ipt6V *dep.IptablesVersion -} - -type NetworkRange struct { - IsWildcard bool - CIDRs []netip.Prefix - HasLoopBackIP bool -} - -func separateV4V6(cidrList string) (NetworkRange, NetworkRange, error) { - if cidrList == "*" { - return NetworkRange{IsWildcard: true}, NetworkRange{IsWildcard: true}, nil - } - ipv6Ranges := NetworkRange{} - ipv4Ranges := NetworkRange{} - for _, ipRange := range types.Split(cidrList) { - ipp, err := netip.ParsePrefix(ipRange) - if err != nil { - _, err = fmt.Fprintf(os.Stderr, "Ignoring error for bug compatibility with istio-iptables: %s\n", err.Error()) - if err != nil { - return ipv4Ranges, ipv6Ranges, err - } - continue - } - if ipp.Addr().Is4() { - ipv4Ranges.CIDRs = append(ipv4Ranges.CIDRs, ipp) - if ipp.Addr().IsLoopback() { - ipv4Ranges.HasLoopBackIP = true - } - } else { - ipv6Ranges.CIDRs = append(ipv6Ranges.CIDRs, ipp) - if ipp.Addr().IsLoopback() { - ipv6Ranges.HasLoopBackIP = true - } - } - } - return ipv4Ranges, ipv6Ranges, nil -} - -func NewIptablesCleaner(cfg *config.Config, iptV, ipt6V *dep.IptablesVersion, ext dep.Dependencies) *IptablesCleaner { - return &IptablesCleaner{ - ext: ext, - cfg: cfg, - iptV: iptV, - ipt6V: ipt6V, - } -} - -// TODO BML why are these not on the type? -func flushAndDeleteChains(ext dep.Dependencies, iptV *dep.IptablesVersion, table string, chains []string) { - for _, chain := range chains { - ext.RunQuietlyAndIgnore(constants.IPTables, iptV, nil, "-t", table, "-F", chain) - ext.RunQuietlyAndIgnore(constants.IPTables, iptV, nil, "-t", table, "-X", chain) - } -} - -func DeleteRule(ext dep.Dependencies, iptV *dep.IptablesVersion, table string, chain string, rulespec ...string) { - args := append([]string{"-t", table, "-D", chain}, rulespec...) - ext.RunQuietlyAndIgnore(constants.IPTables, iptV, nil, args...) -} - -func removeOldChains(cfg *config.Config, ext dep.Dependencies, iptV *dep.IptablesVersion) { - // Remove the old TCP rules - for _, table := range []string{constants.NAT, constants.MANGLE} { - ext.RunQuietlyAndIgnore(constants.IPTables, iptV, nil, "-t", table, "-D", constants.PREROUTING, "-p", constants.TCP, "-j", constants.ISTIOINBOUND) - } - ext.RunQuietlyAndIgnore(constants.IPTables, iptV, nil, "-t", constants.NAT, "-D", constants.OUTPUT, "-p", constants.TCP, "-j", constants.ISTIOOUTPUT) - - // Flush and delete the istio chains from NAT table. - chains := []string{constants.ISTIOOUTPUT, constants.ISTIOINBOUND} - flushAndDeleteChains(ext, iptV, constants.NAT, chains) - // Flush and delete the istio chains from MANGLE table. - chains = []string{constants.ISTIOINBOUND, constants.ISTIODIVERT, constants.ISTIOTPROXY} - flushAndDeleteChains(ext, iptV, constants.MANGLE, chains) - - if cfg.InboundInterceptionMode == constants.TPROXY { - DeleteRule(ext, iptV, constants.MANGLE, constants.PREROUTING, - "-p", constants.TCP, "-m", "mark", "--mark", cfg.InboundTProxyMark, "-j", "CONNMARK", "--save-mark") - DeleteRule(ext, iptV, constants.MANGLE, constants.OUTPUT, - "-p", constants.TCP, "-m", "connmark", "--mark", cfg.InboundTProxyMark, "-j", "CONNMARK", "--restore-mark") - } - - // Must be last, the others refer to it - chains = []string{constants.ISTIOREDIRECT, constants.ISTIOINREDIRECT, constants.ISTIOOUTPUT} - flushAndDeleteChains(ext, iptV, constants.NAT, chains) -} - -func cleanupKubeVirt(cfg *config.Config, ext dep.Dependencies, iptV *dep.IptablesVersion, iptV6 *dep.IptablesVersion) { - cleanupFunc := func(iptVer *dep.IptablesVersion, rangeInclude NetworkRange) { - if rangeInclude.IsWildcard { - // Wildcard specified. Redirect all remaining outbound traffic to Envoy. - for _, internalInterface := range types.Split(cfg.KubeVirtInterfaces) { - DeleteRule(ext, iptVer, constants.PREROUTING, constants.NAT, "-i", internalInterface, "-j", constants.ISTIOREDIRECT) - } - } else if len(rangeInclude.CIDRs) > 0 { - // User has specified a non-empty list of cidrs to be redirected to Envoy. - for _, cidr := range rangeInclude.CIDRs { - for _, internalInterface := range types.Split(cfg.KubeVirtInterfaces) { - DeleteRule(ext, iptVer, constants.PREROUTING, constants.PREROUTING, constants.NAT, "-i", internalInterface, - "-d", cidr.String(), "-j", constants.ISTIOREDIRECT) - } - } - } - // cleanup short circuit - for _, internalInterface := range types.Split(cfg.KubeVirtInterfaces) { - DeleteRule(ext, iptVer, constants.PREROUTING, constants.NAT, "-i", internalInterface, "-j", constants.RETURN) - } - } - - ipv4RangesInclude, ipv6RangesInclude, err := separateV4V6(cfg.OutboundIPRangesInclude) - if err == nil { - cleanupFunc(iptV, ipv4RangesInclude) - cleanupFunc(iptV6, ipv6RangesInclude) - } -} - -// cleanupDNSUDP removes any IPv4/v6 UDP rules. -// TODO BML drop `HandleDSNUDP` and friends, no real need to tread UDP rules specially -// or create unique abstractions for them -func cleanupDNSUDP(cfg *config.Config, ext dep.Dependencies, iptV, ipt6V *dep.IptablesVersion) { - // Remove UDP jumps from OUTPUT chain to ISTIOOUTPUT chain - ext.RunQuietlyAndIgnore(constants.IPTables, iptV, nil, "-t", constants.NAT, "-D", constants.OUTPUT, "-p", constants.UDP, "-j", constants.ISTIOOUTPUT) - ext.RunQuietlyAndIgnore(constants.IPTables, iptV, nil, "-t", constants.RAW, "-D", constants.OUTPUT, "-p", constants.UDP, "-j", constants.ISTIOOUTPUT) - ext.RunQuietlyAndIgnore(constants.IPTables, ipt6V, nil, "-t", constants.NAT, "-D", constants.OUTPUT, "-p", constants.UDP, "-j", constants.ISTIOOUTPUT) - ext.RunQuietlyAndIgnore(constants.IPTables, ipt6V, nil, "-t", constants.RAW, "-D", constants.OUTPUT, "-p", constants.UDP, "-j", constants.ISTIOOUTPUT) - - // Remove the old DNS UDP rules - if cfg.RedirectDNS { - ownerGroupsFilter := types.ParseInterceptFilter(cfg.OwnerGroupsInclude, cfg.OwnerGroupsExclude) - - common.HandleDNSUDP(common.DeleteOps, builder.NewIptablesRuleBuilder(nil), ext, iptV, ipt6V, cfg.ProxyUID, cfg.ProxyGID, - cfg.DNSServersV4, cfg.DNSServersV6, cfg.CaptureAllDNS, ownerGroupsFilter) - } - - // Drop the ISTIO_OUTPUT chain - chains := []string{constants.ISTIOOUTPUT} - flushAndDeleteChains(ext, iptV, constants.RAW, chains) - flushAndDeleteChains(ext, iptV, constants.NAT, chains) -} - -func (c *IptablesCleaner) Run() { - defer func() { - _ = c.ext.Run(constants.IPTablesSave, c.iptV, nil) - _ = c.ext.Run(constants.IPTablesSave, c.ipt6V, nil) - }() - - // clean v4/v6 - // cleanup kube-virt-related jumps - cleanupKubeVirt(c.cfg, c.ext, c.iptV, c.ipt6V) - // Remove chains (run once per v4/v6) - removeOldChains(c.cfg, c.ext, c.iptV) - removeOldChains(c.cfg, c.ext, c.ipt6V) - - // Remove DNS UDP (runs for both v4 and v6 at the same time) - cleanupDNSUDP(c.cfg, c.ext, c.iptV, c.ipt6V) -} diff --git a/tools/istio-clean-iptables/pkg/cmd/cleanup_test.go b/tools/istio-clean-iptables/pkg/cmd/cleanup_test.go deleted file mode 100644 index 73f20542978d..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/cleanup_test.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright Istio Authors -// -// Licensed 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 cmd - -import ( - "path/filepath" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - - testutil "istio.io/istio/pilot/test/util" - "istio.io/istio/tools/istio-clean-iptables/pkg/config" - "istio.io/istio/tools/istio-iptables/pkg/constants" - dep "istio.io/istio/tools/istio-iptables/pkg/dependencies" -) - -func constructTestConfig() *config.Config { - return &config.Config{ - ProxyUID: constants.DefaultProxyUID, - ProxyGID: constants.DefaultProxyUID, - OwnerGroupsInclude: constants.OwnerGroupsInclude.DefaultValue, - } -} - -func TestIptables(t *testing.T) { - cases := []struct { - name string - config func(cfg *config.Config) - }{ - { - "empty", - func(*config.Config) {}, - }, - { - "dns", - func(cfg *config.Config) { - cfg.RedirectDNS = true - }, - }, - { - "dns-uid-gid", - func(cfg *config.Config) { - cfg.RedirectDNS = true - cfg.DNSServersV4 = []string{"127.0.0.53"} - cfg.DNSServersV6 = []string{"::127.0.0.53"} - cfg.ProxyGID = "1,2" - cfg.ProxyUID = "3,4" - }, - }, - { - "outbound-owner-groups", - func(cfg *config.Config) { - cfg.RedirectDNS = true - cfg.OwnerGroupsInclude = "java,202" - }, - }, - { - "outbound-owner-groups-exclude", - func(cfg *config.Config) { - cfg.RedirectDNS = true - cfg.OwnerGroupsExclude = "888,ftp" - }, - }, - { - "ipnets-with-kube-virt-interfaces", - func(cfg *config.Config) { - cfg.KubeVirtInterfaces = "eth1,eth2" - cfg.OutboundIPRangesInclude = "10.0.0.0/8" - }, - }, - { - "kube-virt-interfaces", - func(cfg *config.Config) { - cfg.KubeVirtInterfaces = "eth1,eth2" - cfg.OutboundIPRangesInclude = "*" - }, - }, - { - "inbound-interception-mode", - func(cfg *config.Config) { - cfg.InboundInterceptionMode = "TPROXY" - cfg.InboundTProxyMark = "1337" - }, - }, - } - for _, tt := range cases { - t.Run(tt.name, func(t *testing.T) { - cfg := constructTestConfig() - tt.config(cfg) - - ext := &dep.DependenciesStub{} - iptStub, _ := ext.DetectIptablesVersion(false) - ip6tStub, _ := ext.DetectIptablesVersion(true) - cleaner := NewIptablesCleaner(cfg, &iptStub, &ip6tStub, ext) - - cleaner.Run() - - compareToGolden(t, tt.name, ext.ExecutedAll) - - expectedExecutedNormally := []string{"iptables-save", "ip6tables-save"} - if diff := cmp.Diff(ext.ExecutedNormally, expectedExecutedNormally); diff != "" { - t.Fatalf("Executed normally commands: got\n%v\nwant\n%vdiff %v", - ext.ExecutedNormally, expectedExecutedNormally, diff) - } - - expectedExecutedQuietly := ext.ExecutedAll[:len(ext.ExecutedAll)-len(expectedExecutedNormally)] - if diff := cmp.Diff(ext.ExecutedQuietly, expectedExecutedQuietly); diff != "" { - t.Fatalf("Executed quietly commands: got\n%v\nwant\n%vdiff %v", - ext.ExecutedQuietly, expectedExecutedQuietly, diff) - } - }) - } -} - -func compareToGolden(t *testing.T, name string, actual []string) { - t.Helper() - gotBytes := []byte(strings.Join(actual, "\n")) - goldenFile := filepath.Join("testdata", name+".golden") - testutil.CompareContent(t, gotBytes, goldenFile) -} diff --git a/tools/istio-clean-iptables/pkg/cmd/root.go b/tools/istio-clean-iptables/pkg/cmd/root.go deleted file mode 100644 index dc907f572bcd..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/root.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright Istio Authors -// -// Licensed 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 cmd - -import ( - "github.com/spf13/cobra" - - "istio.io/istio/pkg/flag" - "istio.io/istio/pkg/log" - "istio.io/istio/tools/istio-clean-iptables/pkg/config" - "istio.io/istio/tools/istio-iptables/pkg/constants" -) - -func bindCmdlineFlags(cfg *config.Config, cmd *cobra.Command) { - fs := cmd.Flags() - flag.BindEnv(fs, constants.DryRun, "n", "Do not call any external dependencies like iptables.", - &cfg.DryRun) - - flag.BindEnv(fs, constants.ProxyUID, "u", - "Specify the UID of the user for which the redirection is not applied. Typically, this is the UID of the proxy container.", - &cfg.ProxyUID) - - flag.BindEnv(fs, constants.ProxyGID, "g", - "Specify the GID of the user for which the redirection is not applied (same default value as -u param).", - &cfg.ProxyGID) - - flag.BindEnv(fs, constants.RedirectDNS, "", "Enable capture of dns traffic by istio-agent.", &cfg.RedirectDNS) - // Allow binding to a different var, for consistency with other components - flag.AdditionalEnv(fs, constants.RedirectDNS, "ISTIO_META_DNS_CAPTURE") - - flag.BindEnv(fs, constants.CaptureAllDNS, "", - "Instead of only capturing DNS traffic to DNS server IP, capture all DNS traffic at port 53. This setting is only effective when redirect dns is enabled.", - &cfg.CaptureAllDNS) - - flag.BindEnv(fs, constants.InboundInterceptionMode, "m", - "The mode used to redirect inbound connections to Envoy, either \"REDIRECT\" or \"TPROXY\".", - &cfg.InboundInterceptionMode) - - flag.BindEnv(fs, constants.InboundTProxyMark, "t", "", &cfg.InboundTProxyMark) -} - -func GetCommand(logOpts *log.Options) *cobra.Command { - cfg := config.DefaultConfig() - cmd := &cobra.Command{ - Use: "istio-clean-iptables", - Short: "Clean up iptables rules for Istio Sidecar", - Long: "Script responsible for cleaning up iptables rules", - PreRunE: func(cmd *cobra.Command, args []string) error { - if err := log.Configure(logOpts); err != nil { - return err - } - return nil - }, - RunE: func(cmd *cobra.Command, args []string) error { - cfg.FillConfigFromEnvironment() - if err := cfg.Validate(); err != nil { - return err - } - ext := NewDependencies(cfg) - - iptVer, err := ext.DetectIptablesVersion(false) - if err != nil { - return err - } - ipt6Ver, err := ext.DetectIptablesVersion(true) - if err != nil { - return err - } - - cleaner := NewIptablesCleaner(cfg, &iptVer, &ipt6Ver, ext) - cleaner.Run() - return nil - }, - } - bindCmdlineFlags(cfg, cmd) - return cmd -} diff --git a/tools/istio-clean-iptables/pkg/cmd/testdata/dns-uid-gid.golden b/tools/istio-clean-iptables/pkg/cmd/testdata/dns-uid-gid.golden deleted file mode 100644 index 5009822aa906..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/testdata/dns-uid-gid.golden +++ /dev/null @@ -1,78 +0,0 @@ -iptables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_INBOUND -iptables -t nat -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_INBOUND -iptables -t mangle -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_DIVERT -iptables -t mangle -X ISTIO_DIVERT -iptables -t mangle -F ISTIO_TPROXY -iptables -t mangle -X ISTIO_TPROXY -iptables -t nat -F ISTIO_REDIRECT -iptables -t nat -X ISTIO_REDIRECT -iptables -t nat -F ISTIO_IN_REDIRECT -iptables -t nat -X ISTIO_IN_REDIRECT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_INBOUND -ip6tables -t nat -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_INBOUND -ip6tables -t mangle -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_DIVERT -ip6tables -t mangle -X ISTIO_DIVERT -ip6tables -t mangle -F ISTIO_TPROXY -ip6tables -t mangle -X ISTIO_TPROXY -ip6tables -t nat -F ISTIO_REDIRECT -ip6tables -t nat -X ISTIO_REDIRECT -ip6tables -t nat -F ISTIO_IN_REDIRECT -ip6tables -t nat -X ISTIO_IN_REDIRECT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -iptables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 3 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 3 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 4 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 4 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 2 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 2 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -d 127.0.0.53/32 -j REDIRECT --to-port 15053 -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -d ::127.0.0.53/128 -j REDIRECT --to-port 15053 -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 3 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 3 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 3 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 3 -j CT --zone 2 -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 4 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 4 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 4 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 4 -j CT --zone 2 -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 1 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 1 -j CT --zone 2 -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 2 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 2 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 2 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 2 -j CT --zone 2 -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -d 127.0.0.53/32 -j CT --zone 2 -iptables -t raw -D PREROUTING -p udp --sport 53 -s 127.0.0.53/32 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -d ::127.0.0.53/128 -j CT --zone 2 -ip6tables -t raw -D PREROUTING -p udp --sport 53 -s ::127.0.0.53/128 -j CT --zone 1 -iptables -t raw -F ISTIO_OUTPUT -iptables -t raw -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables-save -ip6tables-save \ No newline at end of file diff --git a/tools/istio-clean-iptables/pkg/cmd/testdata/dns.golden b/tools/istio-clean-iptables/pkg/cmd/testdata/dns.golden deleted file mode 100644 index 64ac6578047c..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/testdata/dns.golden +++ /dev/null @@ -1,60 +0,0 @@ -iptables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_INBOUND -iptables -t nat -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_INBOUND -iptables -t mangle -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_DIVERT -iptables -t mangle -X ISTIO_DIVERT -iptables -t mangle -F ISTIO_TPROXY -iptables -t mangle -X ISTIO_TPROXY -iptables -t nat -F ISTIO_REDIRECT -iptables -t nat -X ISTIO_REDIRECT -iptables -t nat -F ISTIO_IN_REDIRECT -iptables -t nat -X ISTIO_IN_REDIRECT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_INBOUND -ip6tables -t nat -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_INBOUND -ip6tables -t mangle -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_DIVERT -ip6tables -t mangle -X ISTIO_DIVERT -ip6tables -t mangle -F ISTIO_TPROXY -ip6tables -t mangle -X ISTIO_TPROXY -ip6tables -t nat -F ISTIO_REDIRECT -ip6tables -t nat -X ISTIO_REDIRECT -ip6tables -t nat -F ISTIO_IN_REDIRECT -ip6tables -t nat -X ISTIO_IN_REDIRECT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -iptables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j RETURN -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 1337 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 1337 -j CT --zone 2 -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 1337 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 1337 -j CT --zone 2 -iptables -t raw -F ISTIO_OUTPUT -iptables -t raw -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables-save -ip6tables-save \ No newline at end of file diff --git a/tools/istio-clean-iptables/pkg/cmd/testdata/empty.golden b/tools/istio-clean-iptables/pkg/cmd/testdata/empty.golden deleted file mode 100644 index c53e9527917b..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/testdata/empty.golden +++ /dev/null @@ -1,48 +0,0 @@ -iptables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_INBOUND -iptables -t nat -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_INBOUND -iptables -t mangle -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_DIVERT -iptables -t mangle -X ISTIO_DIVERT -iptables -t mangle -F ISTIO_TPROXY -iptables -t mangle -X ISTIO_TPROXY -iptables -t nat -F ISTIO_REDIRECT -iptables -t nat -X ISTIO_REDIRECT -iptables -t nat -F ISTIO_IN_REDIRECT -iptables -t nat -X ISTIO_IN_REDIRECT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_INBOUND -ip6tables -t nat -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_INBOUND -ip6tables -t mangle -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_DIVERT -ip6tables -t mangle -X ISTIO_DIVERT -ip6tables -t mangle -F ISTIO_TPROXY -ip6tables -t mangle -X ISTIO_TPROXY -ip6tables -t nat -F ISTIO_REDIRECT -ip6tables -t nat -X ISTIO_REDIRECT -ip6tables -t nat -F ISTIO_IN_REDIRECT -ip6tables -t nat -X ISTIO_IN_REDIRECT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -iptables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -F ISTIO_OUTPUT -iptables -t raw -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables-save -ip6tables-save \ No newline at end of file diff --git a/tools/istio-clean-iptables/pkg/cmd/testdata/inbound-interception-mode.golden b/tools/istio-clean-iptables/pkg/cmd/testdata/inbound-interception-mode.golden deleted file mode 100644 index fb4a74fae6aa..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/testdata/inbound-interception-mode.golden +++ /dev/null @@ -1,52 +0,0 @@ -iptables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_INBOUND -iptables -t nat -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_INBOUND -iptables -t mangle -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_DIVERT -iptables -t mangle -X ISTIO_DIVERT -iptables -t mangle -F ISTIO_TPROXY -iptables -t mangle -X ISTIO_TPROXY -iptables -t mangle -D PREROUTING -p tcp -m mark --mark 1337 -j CONNMARK --save-mark -iptables -t mangle -D OUTPUT -p tcp -m connmark --mark 1337 -j CONNMARK --restore-mark -iptables -t nat -F ISTIO_REDIRECT -iptables -t nat -X ISTIO_REDIRECT -iptables -t nat -F ISTIO_IN_REDIRECT -iptables -t nat -X ISTIO_IN_REDIRECT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_INBOUND -ip6tables -t nat -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_INBOUND -ip6tables -t mangle -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_DIVERT -ip6tables -t mangle -X ISTIO_DIVERT -ip6tables -t mangle -F ISTIO_TPROXY -ip6tables -t mangle -X ISTIO_TPROXY -ip6tables -t mangle -D PREROUTING -p tcp -m mark --mark 1337 -j CONNMARK --save-mark -ip6tables -t mangle -D OUTPUT -p tcp -m connmark --mark 1337 -j CONNMARK --restore-mark -ip6tables -t nat -F ISTIO_REDIRECT -ip6tables -t nat -X ISTIO_REDIRECT -ip6tables -t nat -F ISTIO_IN_REDIRECT -ip6tables -t nat -X ISTIO_IN_REDIRECT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -iptables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -F ISTIO_OUTPUT -iptables -t raw -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables-save -ip6tables-save \ No newline at end of file diff --git a/tools/istio-clean-iptables/pkg/cmd/testdata/ipnets-with-kube-virt-interfaces.golden b/tools/istio-clean-iptables/pkg/cmd/testdata/ipnets-with-kube-virt-interfaces.golden deleted file mode 100644 index 1ca3ff0fdc11..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/testdata/ipnets-with-kube-virt-interfaces.golden +++ /dev/null @@ -1,54 +0,0 @@ -iptables -t PREROUTING -D PREROUTING nat -i eth1 -d 10.0.0.0/8 -j ISTIO_REDIRECT -iptables -t PREROUTING -D PREROUTING nat -i eth2 -d 10.0.0.0/8 -j ISTIO_REDIRECT -iptables -t PREROUTING -D nat -i eth1 -j RETURN -iptables -t PREROUTING -D nat -i eth2 -j RETURN -ip6tables -t PREROUTING -D nat -i eth1 -j RETURN -ip6tables -t PREROUTING -D nat -i eth2 -j RETURN -iptables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_INBOUND -iptables -t nat -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_INBOUND -iptables -t mangle -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_DIVERT -iptables -t mangle -X ISTIO_DIVERT -iptables -t mangle -F ISTIO_TPROXY -iptables -t mangle -X ISTIO_TPROXY -iptables -t nat -F ISTIO_REDIRECT -iptables -t nat -X ISTIO_REDIRECT -iptables -t nat -F ISTIO_IN_REDIRECT -iptables -t nat -X ISTIO_IN_REDIRECT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_INBOUND -ip6tables -t nat -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_INBOUND -ip6tables -t mangle -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_DIVERT -ip6tables -t mangle -X ISTIO_DIVERT -ip6tables -t mangle -F ISTIO_TPROXY -ip6tables -t mangle -X ISTIO_TPROXY -ip6tables -t nat -F ISTIO_REDIRECT -ip6tables -t nat -X ISTIO_REDIRECT -ip6tables -t nat -F ISTIO_IN_REDIRECT -ip6tables -t nat -X ISTIO_IN_REDIRECT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -iptables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -F ISTIO_OUTPUT -iptables -t raw -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables-save -ip6tables-save \ No newline at end of file diff --git a/tools/istio-clean-iptables/pkg/cmd/testdata/kube-virt-interfaces.golden b/tools/istio-clean-iptables/pkg/cmd/testdata/kube-virt-interfaces.golden deleted file mode 100644 index 0215b6efc82e..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/testdata/kube-virt-interfaces.golden +++ /dev/null @@ -1,56 +0,0 @@ -iptables -t PREROUTING -D nat -i eth1 -j ISTIO_REDIRECT -iptables -t PREROUTING -D nat -i eth2 -j ISTIO_REDIRECT -iptables -t PREROUTING -D nat -i eth1 -j RETURN -iptables -t PREROUTING -D nat -i eth2 -j RETURN -ip6tables -t PREROUTING -D nat -i eth1 -j ISTIO_REDIRECT -ip6tables -t PREROUTING -D nat -i eth2 -j ISTIO_REDIRECT -ip6tables -t PREROUTING -D nat -i eth1 -j RETURN -ip6tables -t PREROUTING -D nat -i eth2 -j RETURN -iptables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_INBOUND -iptables -t nat -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_INBOUND -iptables -t mangle -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_DIVERT -iptables -t mangle -X ISTIO_DIVERT -iptables -t mangle -F ISTIO_TPROXY -iptables -t mangle -X ISTIO_TPROXY -iptables -t nat -F ISTIO_REDIRECT -iptables -t nat -X ISTIO_REDIRECT -iptables -t nat -F ISTIO_IN_REDIRECT -iptables -t nat -X ISTIO_IN_REDIRECT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_INBOUND -ip6tables -t nat -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_INBOUND -ip6tables -t mangle -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_DIVERT -ip6tables -t mangle -X ISTIO_DIVERT -ip6tables -t mangle -F ISTIO_TPROXY -ip6tables -t mangle -X ISTIO_TPROXY -ip6tables -t nat -F ISTIO_REDIRECT -ip6tables -t nat -X ISTIO_REDIRECT -ip6tables -t nat -F ISTIO_IN_REDIRECT -ip6tables -t nat -X ISTIO_IN_REDIRECT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -iptables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -F ISTIO_OUTPUT -iptables -t raw -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables-save -ip6tables-save \ No newline at end of file diff --git a/tools/istio-clean-iptables/pkg/cmd/testdata/outbound-owner-groups-exclude.golden b/tools/istio-clean-iptables/pkg/cmd/testdata/outbound-owner-groups-exclude.golden deleted file mode 100644 index bef8177d34c3..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/testdata/outbound-owner-groups-exclude.golden +++ /dev/null @@ -1,64 +0,0 @@ -iptables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_INBOUND -iptables -t nat -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_INBOUND -iptables -t mangle -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_DIVERT -iptables -t mangle -X ISTIO_DIVERT -iptables -t mangle -F ISTIO_TPROXY -iptables -t mangle -X ISTIO_TPROXY -iptables -t nat -F ISTIO_REDIRECT -iptables -t nat -X ISTIO_REDIRECT -iptables -t nat -F ISTIO_IN_REDIRECT -iptables -t nat -X ISTIO_IN_REDIRECT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_INBOUND -ip6tables -t nat -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_INBOUND -ip6tables -t mangle -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_DIVERT -ip6tables -t mangle -X ISTIO_DIVERT -ip6tables -t mangle -F ISTIO_TPROXY -ip6tables -t mangle -X ISTIO_TPROXY -ip6tables -t nat -F ISTIO_REDIRECT -ip6tables -t nat -X ISTIO_REDIRECT -ip6tables -t nat -F ISTIO_IN_REDIRECT -ip6tables -t nat -X ISTIO_IN_REDIRECT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -iptables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 888 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 888 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner ftp -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner ftp -j RETURN -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 1337 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 1337 -j CT --zone 2 -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 1337 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 1337 -j CT --zone 2 -iptables -t raw -F ISTIO_OUTPUT -iptables -t raw -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables-save -ip6tables-save \ No newline at end of file diff --git a/tools/istio-clean-iptables/pkg/cmd/testdata/outbound-owner-groups.golden b/tools/istio-clean-iptables/pkg/cmd/testdata/outbound-owner-groups.golden deleted file mode 100644 index 07ef22a8e347..000000000000 --- a/tools/istio-clean-iptables/pkg/cmd/testdata/outbound-owner-groups.golden +++ /dev/null @@ -1,62 +0,0 @@ -iptables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -iptables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_INBOUND -iptables -t nat -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_INBOUND -iptables -t mangle -X ISTIO_INBOUND -iptables -t mangle -F ISTIO_DIVERT -iptables -t mangle -X ISTIO_DIVERT -iptables -t mangle -F ISTIO_TPROXY -iptables -t mangle -X ISTIO_TPROXY -iptables -t nat -F ISTIO_REDIRECT -iptables -t nat -X ISTIO_REDIRECT -iptables -t nat -F ISTIO_IN_REDIRECT -iptables -t nat -X ISTIO_IN_REDIRECT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t mangle -D PREROUTING -p tcp -j ISTIO_INBOUND -ip6tables -t nat -D OUTPUT -p tcp -j ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -ip6tables -t nat -F ISTIO_INBOUND -ip6tables -t nat -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_INBOUND -ip6tables -t mangle -X ISTIO_INBOUND -ip6tables -t mangle -F ISTIO_DIVERT -ip6tables -t mangle -X ISTIO_DIVERT -ip6tables -t mangle -F ISTIO_TPROXY -ip6tables -t mangle -X ISTIO_TPROXY -ip6tables -t nat -F ISTIO_REDIRECT -ip6tables -t nat -X ISTIO_REDIRECT -ip6tables -t nat -F ISTIO_IN_REDIRECT -ip6tables -t nat -X ISTIO_IN_REDIRECT -ip6tables -t nat -F ISTIO_OUTPUT -ip6tables -t nat -X ISTIO_OUTPUT -iptables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t nat -D OUTPUT -p udp -j ISTIO_OUTPUT -ip6tables -t raw -D OUTPUT -p udp -j ISTIO_OUTPUT -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j RETURN -iptables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner ! --gid-owner java -m owner ! --gid-owner 202 -j RETURN -ip6tables -t nat -D ISTIO_OUTPUT -p udp --dport 53 -m owner ! --gid-owner java -m owner ! --gid-owner 202 -j RETURN -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --uid-owner 1337 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 1337 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --uid-owner 1337 -j CT --zone 2 -iptables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j CT --zone 1 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --dport 53 -m owner --gid-owner 1337 -j CT --zone 1 -iptables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 1337 -j CT --zone 2 -ip6tables -t raw -D ISTIO_OUTPUT -p udp --sport 15053 -m owner --gid-owner 1337 -j CT --zone 2 -iptables -t raw -F ISTIO_OUTPUT -iptables -t raw -X ISTIO_OUTPUT -iptables -t nat -F ISTIO_OUTPUT -iptables -t nat -X ISTIO_OUTPUT -iptables-save -ip6tables-save \ No newline at end of file diff --git a/tools/istio-clean-iptables/pkg/config/config.go b/tools/istio-clean-iptables/pkg/config/config.go deleted file mode 100644 index 192aaa68d9be..000000000000 --- a/tools/istio-clean-iptables/pkg/config/config.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright Istio Authors -// -// Licensed 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 config - -import ( - "encoding/json" - "fmt" - "os/user" - - "github.com/miekg/dns" - - "istio.io/istio/pkg/env" - "istio.io/istio/pkg/log" - netutil "istio.io/istio/pkg/util/net" - types "istio.io/istio/tools/istio-iptables/pkg/config" - "istio.io/istio/tools/istio-iptables/pkg/constants" -) - -func DefaultConfig() *Config { - return &Config{ - OwnerGroupsInclude: constants.OwnerGroupsInclude.DefaultValue, - OwnerGroupsExclude: constants.OwnerGroupsExclude.DefaultValue, - } -} - -// Command line options -// nolint: maligned -type Config struct { - DryRun bool `json:"DRY_RUN"` - ProxyUID string `json:"PROXY_UID"` - ProxyGID string `json:"PROXY_GID"` - RedirectDNS bool `json:"REDIRECT_DNS"` - DNSServersV4 []string `json:"DNS_SERVERS_V4"` - DNSServersV6 []string `json:"DNS_SERVERS_V6"` - CaptureAllDNS bool `json:"CAPTURE_ALL_DNS"` - OwnerGroupsInclude string `json:"OUTBOUND_OWNER_GROUPS_INCLUDE"` - OwnerGroupsExclude string `json:"OUTBOUND_OWNER_GROUPS_EXCLUDE"` - InboundInterceptionMode string `json:"INBOUND_INTERCEPTION_MODE"` - InboundTProxyMark string `json:"INBOUND_TPROXY_MARK"` - OutboundIPRangesInclude string `json:"OUTBOUND_IPRANGES_INCLUDE"` - KubeVirtInterfaces string `json:"KUBE_VIRT_INTERFACES"` -} - -func (c *Config) String() string { - output, err := json.MarshalIndent(c, "", "\t") - if err != nil { - log.Fatalf("Unable to marshal config object: %v", err) - } - return string(output) -} - -func (c *Config) Print() { - fmt.Println("Variables:") - fmt.Println("----------") - fmt.Printf("PROXY_UID=%s\n", c.ProxyUID) - fmt.Printf("PROXY_GID=%s\n", c.ProxyGID) - fmt.Printf("DNS_CAPTURE=%t\n", c.RedirectDNS) - fmt.Printf("CAPTURE_ALL_DNS=%t\n", c.CaptureAllDNS) - fmt.Printf("DNS_SERVERS=%s,%s\n", c.DNSServersV4, c.DNSServersV6) - fmt.Printf("OUTBOUND_OWNER_GROUPS_INCLUDE=%s\n", c.OwnerGroupsInclude) - fmt.Printf("OUTBOUND_OWNER_GROUPS_EXCLUDE=%s\n", c.OwnerGroupsExclude) - fmt.Printf("OUTBOUND_IP_RANGES_INCLUDE=%s\n", c.OutboundIPRangesInclude) - fmt.Printf("KUBE_VIRT_INTERFACES=%s\n", c.KubeVirtInterfaces) - fmt.Println("") -} - -func (c *Config) Validate() error { - return types.ValidateOwnerGroups(c.OwnerGroupsInclude, c.OwnerGroupsExclude) -} - -var envoyUserVar = env.Register(constants.EnvoyUser, "istio-proxy", "Envoy proxy username") - -func (c *Config) FillConfigFromEnvironment() { - // Fill in env-var only options - c.OwnerGroupsInclude = constants.OwnerGroupsInclude.Get() - c.OwnerGroupsExclude = constants.OwnerGroupsExclude.Get() - c.InboundInterceptionMode = constants.IstioInboundInterceptionMode.Get() - c.InboundTProxyMark = constants.IstioInboundTproxyMark.Get() - // TODO: Make this more configurable, maybe with an allowlist of users to be captured for output instead of a denylist. - if c.ProxyUID == "" { - usr, err := user.Lookup(envoyUserVar.Get()) - var userID string - // Default to the UID of ENVOY_USER - if err != nil { - userID = constants.DefaultProxyUID - } else { - userID = usr.Uid - } - c.ProxyUID = userID - } - - // For TPROXY as its uid and gid are same. - if c.ProxyGID == "" { - c.ProxyGID = c.ProxyUID - } - // Lookup DNS nameservers. We only do this if DNS is enabled in case of some obscure theoretical - // case where reading /etc/resolv.conf could fail. - // If capture all DNS option is enabled, we don't need to read from the dns resolve conf. All - // traffic to port 53 will be captured. - if c.RedirectDNS && !c.CaptureAllDNS { - dnsConfig, err := dns.ClientConfigFromFile("/etc/resolv.conf") - if err != nil { - log.Fatalf("failed to load /etc/resolv.conf: %v", err) - } - c.DNSServersV4, c.DNSServersV6 = netutil.IPsSplitV4V6(dnsConfig.Servers) - } -} diff --git a/tools/istio-iptables/pkg/builder/helper.go b/tools/istio-iptables/pkg/builder/helper.go new file mode 100644 index 000000000000..f19eeb760eab --- /dev/null +++ b/tools/istio-iptables/pkg/builder/helper.go @@ -0,0 +1,147 @@ +// Copyright Istio Authors +// +// Licensed 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 builder + +import ( + "strings" + + "istio.io/istio/pkg/log" +) + +// CheckRules generates a set of iptables rules that are used to verify the existence of the input rules. +// The function transforms -A/--append and -I/--insert flags into -C/--check flags while preserving the +// structure of other parameters. +// The transformation allows for checking whether the corresponding rules are already present in the iptables configuration. +func CheckRules(rules []Rule) []Rule { + output := make([]Rule, 0) + for _, r := range rules { + var modifiedParams []string + insertIndex := -1 + for i, element := range r.params { + // insert index of a previous -I flag must be skipped + if insertIndex >= 0 && i == insertIndex+2 { + continue + } + if element == "-A" || element == "--append" { + // -A/--append is transformed to -D + modifiedParams = append(modifiedParams, "-C") + } else if element == "-I" || element == "--insert" { + // -I/--insert is transformed to -D, insert index at i+2 must be skipped + insertIndex = i + modifiedParams = append(modifiedParams, "-C") + } else { + // Every other flag/value is kept as it is + modifiedParams = append(modifiedParams, element) + } + } + output = append(output, Rule{ + chain: r.chain, + table: r.table, + params: modifiedParams, + }) + } + log.Debugf("Generated check-rules: %+v", output) + return output +} + +// UndoRules generates the minimal set of rules that are necessary to undo the changes made by the input rules. +// The function transforms -A/--append and -I/--insert flags into -D/--delete flags while preserving the +// structure of other parameters. +// Non-jump rules in ISTIO_* chains are skipped as these chains will be flushed, but jump rules are retained to ensure proper reversal. +// Note: This function does not support converting rules with -D/--delete flags back to -A/-I flags. +func UndoRules(rules []Rule) []Rule { + output := make([]Rule, 0) + for _, r := range rules { + var modifiedParams []string + skip := false + insertIndex := -1 + for i, element := range r.params { + // insert index of a previous -I flag must be skipped + if insertIndex >= 0 && i == insertIndex+2 { + continue + } + if element == "-A" || element == "--append" { + // -A/--append is transformed to -D + modifiedParams = append(modifiedParams, "-D") + } else if element == "-I" || element == "--insert" { + // -I/--insert is transformed to -D, insert index at i+2 must be skipped + insertIndex = i + modifiedParams = append(modifiedParams, "-D") + } else { + // Every other flag/value is kept as it is + modifiedParams = append(modifiedParams, element) + } + + if ((element == "-A" || element == "--append") || (element == "-I" || element == "--insert")) && + i < len(r.params)-1 && strings.HasPrefix(r.params[i+1], "ISTIO_") { + // Ignore every non-jump rule in ISTIO_* chains as we will flush the chain anyway + skip = true + } else if (element == "-j" || element == "--jump") && i < len(r.params)-1 && strings.HasPrefix(r.params[i+1], "ISTIO_") { + // Override previous skip if this is a jump-rule + skip = false + } + } + if skip { + continue + } + + output = append(output, Rule{ + chain: r.chain, + table: r.table, + params: modifiedParams, + }) + } + log.Debugf("Generated undo-rules: %+v", output) + return output +} + +// BuildCustomCleanup generates a set of iptables commands to clean up unexpected leftover rules and chains. +// The function takes the current state of iptables, represented by a map of table names to their associated chains and rules. +// It first transforms the provided rules into corresponding undo rules. +// It then appends flush and delete commands for each ISTIO_* chain. +// This function is used to clean up any leftover state that does not match the iptables configuration. +func BuildCleanupFromState(tableState map[string]struct{ Chains, Rules []string }) [][]string { + output := make([][]string, 0) + var rules []Rule + for table, content := range tableState { + for _, rule := range content.Rules { + params := strings.Fields(rule) + chain := "" + for i, item := range params { + if (item == "--append" || item == "-A" || item == "--insert" || item == "-I") && i+1 < len(params) { + chain = params[i+1] + break + } + } + rules = append(rules, Rule{ + chain: chain, + table: table, + params: params, + }) + } + } + for _, r := range UndoRules(rules) { + output = append(output, append([]string{"-t", r.table}, r.params...)) + } + + for table, content := range tableState { + for _, chain := range content.Chains { + if strings.HasPrefix(chain, "ISTIO_") { + output = append(output, []string{"-t", table, "-F", chain}, []string{"-t", table, "-X", chain}) + } + } + } + return output +} diff --git a/tools/istio-iptables/pkg/builder/iptables_builder_impl.go b/tools/istio-iptables/pkg/builder/iptables_builder_impl.go index 1051df1a29b3..48af68e7b61a 100644 --- a/tools/istio-iptables/pkg/builder/iptables_builder_impl.go +++ b/tools/istio-iptables/pkg/builder/iptables_builder_impl.go @@ -179,96 +179,9 @@ func (rb *IptablesRuleBuilder) buildRules(rules []Rule) [][]string { return output } -// undoRules generates the minimal set of rules that are necessary to undo the changes made by the input rules. -// The function transforms -A/--append and -I/--insert flags into -D/--delete flags while preserving the -// structure of other parameters. -// Non-jump rules in ISTIO_* chains are skipped as these chains will be flushed, but jump rules are retained to ensure proper reversal. -// Note: This function does not support converting rules with -D/--delete flags back to -A/-I flags. -func undoRules(rules []Rule) []Rule { - output := make([]Rule, 0) - for _, r := range rules { - var modifiedParams []string - skip := false - insertIndex := -1 - for i, element := range r.params { - // insert index of a previous -I flag must be skipped - if insertIndex >= 0 && i == insertIndex+2 { - continue - } - if element == "-A" || element == "--append" { - // -A/--append is transformed to -D - modifiedParams = append(modifiedParams, "-D") - } else if element == "-I" || element == "--insert" { - // -I/--insert is transformed to -D, insert index at i+2 must be skipped - insertIndex = i - modifiedParams = append(modifiedParams, "-D") - } else { - // Every other flag/value is kept as it is - modifiedParams = append(modifiedParams, element) - } - - if ((element == "-A" || element == "--append") || (element == "-I" || element == "--insert")) && - i < len(r.params)-1 && strings.HasPrefix(r.params[i+1], "ISTIO_") { - // Ignore every non-jump rule in ISTIO_* chains as we will flush the chain anyway - skip = true - } else if (element == "-j" || element == "--jump") && i < len(r.params)-1 && strings.HasPrefix(r.params[i+1], "ISTIO_") { - // Override previous skip if this is a jump-rule - skip = false - } - } - if skip { - continue - } - - output = append(output, Rule{ - chain: r.chain, - table: r.table, - params: modifiedParams, - }) - } - log.Debugf("Generated undo-rules: %+v", output) - return output -} - -// checkRules generates a set of iptables rules that are used to verify the existence of the input rules. -// The function transforms -A/--append and -I/--insert flags into -C/--check flags while preserving the -// structure of other parameters. -// The transformation allows for checking whether the corresponding rules are already present in the iptables configuration. -func checkRules(rules []Rule) []Rule { - output := make([]Rule, 0) - for _, r := range rules { - var modifiedParams []string - insertIndex := -1 - for i, element := range r.params { - // insert index of a previous -I flag must be skipped - if insertIndex >= 0 && i == insertIndex+2 { - continue - } - if element == "-A" || element == "--append" { - // -A/--append is transformed to -D - modifiedParams = append(modifiedParams, "-C") - } else if element == "-I" || element == "--insert" { - // -I/--insert is transformed to -D, insert index at i+2 must be skipped - insertIndex = i - modifiedParams = append(modifiedParams, "-C") - } else { - // Every other flag/value is kept as it is - modifiedParams = append(modifiedParams, element) - } - } - output = append(output, Rule{ - chain: r.chain, - table: r.table, - params: modifiedParams, - }) - } - log.Debugf("Generated check-rules: %+v", output) - return output -} - func (rb *IptablesRuleBuilder) buildCheckRules(rules []Rule) [][]string { output := make([][]string, 0) - checkRules := checkRules(rules) + checkRules := CheckRules(rules) for _, r := range checkRules { cmd := append([]string{"-t", r.table}, r.params...) output = append(output, cmd) @@ -283,7 +196,7 @@ func (rb *IptablesRuleBuilder) buildCleanupRules(rules []Rule) [][]string { } output := make([][]string, 0) - reversedRules := undoRules(newRules) + reversedRules := UndoRules(newRules) for _, r := range reversedRules { cmd := append([]string{"-t", r.table}, r.params...) output = append(output, cmd) @@ -352,7 +265,7 @@ func (rb *IptablesRuleBuilder) BuildGuardrails() [][]string { } func (rb *IptablesRuleBuilder) BuildCleanupGuardrails() [][]string { - rules := undoRules(rb.buildGuardrails()) + rules := UndoRules(rb.buildGuardrails()) output := make([][]string, 0) for _, r := range rules { cmd := append([]string{"-t", r.table}, r.params...) @@ -462,9 +375,16 @@ func (rb *IptablesRuleBuilder) GetStateFromSave(data string) map[string]map[stri rule := strings.Split(line, " ") ruleChain := "" + toAdd := false for i, item := range rule { if (item == "--append" || item == "-A" || item == "--insert" || item == "-I") && i+1 < len(rule) { - ruleChain = rule[i+1] + toAdd = true + ruleChain = strings.Trim(rule[i+1], "'\"") + } else if (item == "--new" || item == "-N") && i+1 < len(rule) { + target := strings.Trim(rule[i+1], "'\"") + if strings.HasPrefix(target, "ISTIO") { + ruleChain = target + } } } if ruleChain == "" { @@ -474,7 +394,9 @@ func (rb *IptablesRuleBuilder) GetStateFromSave(data string) map[string]map[stri if !ok { result[table][ruleChain] = []string{} } - result[table][ruleChain] = append(result[table][ruleChain], line) + if toAdd { + result[table][ruleChain] = append(result[table][ruleChain], line) + } } return result } diff --git a/tools/istio-iptables/pkg/capture/helper.go b/tools/istio-iptables/pkg/capture/helper.go new file mode 100644 index 000000000000..6854afc11c2e --- /dev/null +++ b/tools/istio-iptables/pkg/capture/helper.go @@ -0,0 +1,185 @@ +// Copyright Istio Authors +// +// Licensed 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 capture + +import ( + "strings" + + istiolog "istio.io/istio/pkg/log" + "istio.io/istio/tools/istio-iptables/pkg/builder" + "istio.io/istio/tools/istio-iptables/pkg/constants" + dep "istio.io/istio/tools/istio-iptables/pkg/dependencies" +) + +func CombineMatchers(values []string, matcher func(value string) []string) []string { + matchers := make([][]string, 0, len(values)) + for _, value := range values { + matchers = append(matchers, matcher(value)) + } + return Flatten(matchers...) +} + +func Flatten(lists ...[]string) []string { + var result []string + for _, list := range lists { + result = append(result, list...) + } + return result +} + +// VerifyIptablesState function verifies the current iptables state against the expected state. +// The current state is considered equal to the expected state if the following three conditions are met: +// - Every ISTIO_* chain in the expected state must also exist in the current state. +// - Every ISTIO_* chain must have the same number of elements in both the current and expected state. +// - Every rule in the expected state (whether it is in an ISTIO or non-ISTIO chain) must also exist in the current state. +// The verification is performed by using "iptables -C" on the rule produced by our iptables builder. No comparison of the parsed rules is done. +// +// Note: The order of the rules is not checked and is not used to determine the equivalence of the two states. +// The function returns two boolean values, the first one indicates whether residues exist, +// and the second one indicates whether differences were found between the current and expected state. +func VerifyIptablesState(log *istiolog.Scope, ext dep.Dependencies, ruleBuilder *builder.IptablesRuleBuilder, + iptVer, ipt6Ver *dep.IptablesVersion, +) (bool, bool) { + // These variables track the status of iptables installation + residueExists := false // Flag to indicate if iptables residues from previous executions are found + deltaExists := false // Flag to indicate if a difference is found between expected and current state + +check_loop: + for _, ipCfg := range []struct { + ver *dep.IptablesVersion + expected string + checkRules [][]string + }{ + {iptVer, ruleBuilder.BuildV4Restore(), ruleBuilder.BuildCheckV4()}, + {ipt6Ver, ruleBuilder.BuildV6Restore(), ruleBuilder.BuildCheckV6()}, + } { + if ipCfg.ver == nil { + continue + } + output, err := ext.RunWithOutput(log, constants.IPTablesSave, ipCfg.ver, nil) + if err == nil { + currentState := ruleBuilder.GetStateFromSave(output.String()) + log.Debugf("Current iptables state: %#v", currentState) + for _, value := range currentState { + if residueExists { + break + } + residueExists = len(value) != 0 + } + if !residueExists { + continue + } + expectedState := ruleBuilder.GetStateFromSave(ipCfg.expected) + log.Debugf("Expected iptables state: %#v", expectedState) + for table, chains := range expectedState { + _, ok := currentState[table] + if !ok { + deltaExists = true + log.Debugf("Can't find expected table %s in current state", table) + break check_loop + } + for chain, rules := range chains { + currentRules, ok := currentState[table][chain] + if !ok || (strings.HasPrefix(chain, "ISTIO_") && len(rules) != len(currentRules)) { + deltaExists = true + log.Debugf("Mismatching number of rules in chain %s (table: %s) between current and expected state", chain, table) + break check_loop + } + } + } + for table, chains := range currentState { + for chain := range chains { + if strings.HasPrefix(chain, "ISTIO_") { + _, ok := expectedState[table][chain] + if !ok { + deltaExists = true + log.Debugf("Found chain %s (table: %s) in current state which is missing in expected state", chain, table) + break check_loop + } + } + } + } + for _, cmd := range ipCfg.checkRules { + if err := ext.Run(log, constants.IPTables, ipCfg.ver, nil, cmd...); err != nil { + deltaExists = true + log.Debugf("iptables check rules failed") + break + } + } + } + + } + + if !residueExists { + log.Info("Clean-state detected, new iptables are needed") + return false, true + } + + if deltaExists { + log.Info("Found residues of old iptables rules/chains, reconciliation is recommended") + } else { + log.Info("Found compatible residues of old iptables rules/chains, reconciliation not needed") + } + + return residueExists, deltaExists +} + +// HasIstioLeftovers checks the given iptables state for any chains or rules related to Istio. +// It scans the provided map of tables, chains, and rules to identify any chains that start with the "ISTIO_" prefix, +// as well as any rules that involve Istio-specific jumps. +// The function returns a map where the keys are the tables, and the values are structs containing the leftover +// "ISTIO_" chains and jump rules for each table. Only tables with Istio-related leftovers are included in the result. +func HasIstioLeftovers(state map[string]map[string][]string) map[string]struct{ Chains, Rules []string } { + output := make(map[string]struct{ Chains, Rules []string }) + for table, chains := range state { + istioChains := []string{} + istioJumps := []string{} + for chain, rules := range chains { + if strings.HasPrefix(chain, "ISTIO_") { + istioChains = append(istioChains, chain) + } + for _, rule := range rules { + if isIstioJump(rule) { + istioJumps = append(istioJumps, rule) + } + } + } + if len(istioChains) != 0 || len(istioJumps) != 0 { + output[table] = struct{ Chains, Rules []string }{ + Chains: istioChains, + Rules: istioJumps, + } + } + } + return output +} + +// isIstioJump checks if the given rule is a jump to an Istio chain +func isIstioJump(rule string) bool { + // Split the rule into fields + fields := strings.Fields(rule) + for i, field := range fields { + // Check for --jump or -j + if field == "--jump" || field == "-j" { + // Check if there's a next field (the target) + if i+1 < len(fields) { + target := strings.Trim(fields[i+1], "'\"") + // Check if the target starts with ISTIO_ + return strings.HasPrefix(target, "ISTIO_") + } + } + } + return false +} diff --git a/tools/istio-iptables/pkg/capture/run.go b/tools/istio-iptables/pkg/capture/run.go index 66126fedfb20..af38ddcf8d11 100644 --- a/tools/istio-iptables/pkg/capture/run.go +++ b/tools/istio-iptables/pkg/capture/run.go @@ -200,14 +200,14 @@ func (cfg *IptablesConfigurator) handleOutboundIncludeRules( if rangeInclude.IsWildcard { // Wildcard specified. Redirect all remaining outbound traffic to Envoy. appendRule(iptableslog.UndefinedCommand, constants.ISTIOOUTPUT, constants.NAT, "-j", constants.ISTIOREDIRECT) - for _, internalInterface := range split(cfg.cfg.KubeVirtInterfaces) { + for _, internalInterface := range split(cfg.cfg.RerouteVirtualInterfaces) { insert(iptableslog.KubevirtCommand, constants.PREROUTING, constants.NAT, 1, "-i", internalInterface, "-j", constants.ISTIOREDIRECT) } } else if len(rangeInclude.CIDRs) > 0 { // User has specified a non-empty list of cidrs to be redirected to Envoy. for _, cidr := range rangeInclude.CIDRs { - for _, internalInterface := range split(cfg.cfg.KubeVirtInterfaces) { + for _, internalInterface := range split(cfg.cfg.RerouteVirtualInterfaces) { insert(iptableslog.KubevirtCommand, constants.PREROUTING, constants.NAT, 1, "-i", internalInterface, "-d", cidr.String(), "-j", constants.ISTIOREDIRECT) } @@ -218,7 +218,7 @@ func (cfg *IptablesConfigurator) handleOutboundIncludeRules( } func (cfg *IptablesConfigurator) shortCircuitKubeInternalInterface() { - for _, internalInterface := range split(cfg.cfg.KubeVirtInterfaces) { + for _, internalInterface := range split(cfg.cfg.RerouteVirtualInterfaces) { cfg.ruleBuilder.InsertRule(iptableslog.KubevirtCommand, constants.PREROUTING, constants.NAT, 1, "-i", internalInterface, "-j", constants.RETURN) } } @@ -289,9 +289,9 @@ func (cfg *IptablesConfigurator) Run() error { defer func() { // Best effort since we don't know if the commands exist - _ = cfg.ext.Run(constants.IPTablesSave, &iptVer, nil) + _ = cfg.ext.Run(log.WithLabels(), constants.IPTablesSave, &iptVer, nil) if cfg.cfg.EnableIPv6 { - _ = cfg.ext.Run(constants.IPTablesSave, &ipt6Ver, nil) + _ = cfg.ext.Run(log.WithLabels(), constants.IPTablesSave, &ipt6Ver, nil) } }() @@ -575,7 +575,7 @@ func (f UDPRuleApplier) RunV4(args ...string) { case DeleteOps: deleteArgs := []string{"-t", f.table, opsToString[f.ops], f.chain} deleteArgs = append(deleteArgs, args...) - f.ext.RunQuietlyAndIgnore(constants.IPTables, f.iptV, nil, deleteArgs...) + f.ext.RunQuietlyAndIgnore(log.WithLabels(), constants.IPTables, f.iptV, nil, deleteArgs...) } } @@ -586,7 +586,7 @@ func (f UDPRuleApplier) RunV6(args ...string) { case DeleteOps: deleteArgs := []string{"-t", f.table, opsToString[f.ops], f.chain} deleteArgs = append(deleteArgs, args...) - f.ext.RunQuietlyAndIgnore(constants.IPTables, f.ipt6V, nil, deleteArgs...) + f.ext.RunQuietlyAndIgnore(log.WithLabels(), constants.IPTables, f.ipt6V, nil, deleteArgs...) } } @@ -746,7 +746,7 @@ func (cfg *IptablesConfigurator) handleCaptureByOwnerGroup(filter config.Interce func (cfg *IptablesConfigurator) executeIptablesCommands(iptVer *dep.IptablesVersion, commands [][]string) error { for _, cmd := range commands { - if err := cfg.ext.Run(constants.IPTables, iptVer, nil, cmd...); err != nil { + if err := cfg.ext.Run(log.WithLabels(), constants.IPTables, iptVer, nil, cmd...); err != nil { return err } } @@ -755,93 +755,14 @@ func (cfg *IptablesConfigurator) executeIptablesCommands(iptVer *dep.IptablesVer func (cfg *IptablesConfigurator) tryExecuteIptablesCommands(iptVer *dep.IptablesVersion, commands [][]string) { for _, cmd := range commands { - cfg.ext.RunQuietlyAndIgnore(constants.IPTables, iptVer, nil, cmd...) + cfg.ext.RunQuietlyAndIgnore(log.WithLabels(), constants.IPTables, iptVer, nil, cmd...) } } func (cfg *IptablesConfigurator) executeIptablesRestoreCommand(iptVer *dep.IptablesVersion, data string) error { log.Infof("Running iptables restore with: %s and the following input:\n%v", iptVer.CmdToString(constants.IPTablesRestore), strings.TrimSpace(data)) // --noflush to prevent flushing/deleting previous contents from table - return cfg.ext.Run(constants.IPTablesRestore, iptVer, strings.NewReader(data), "--noflush") -} - -// VerifyIptablesState function verifies the current iptables state against the expected state. -// The current state is considered equal to the expected state if the following three conditions are met: -// - Every ISTIO_* chain in the expected state must also exist in the current state. -// - Every ISTIO_* chain must have the same number of elements in both the current and expected state. -// - Every rule in the expected state (whether it is in an ISTIO or non-ISTIO chain) must also exist in the current state. -// The verification is performed by using "iptables -C" on the rule produced by our iptables builder. No comparison of the parsed rules is done. -// -// Note: The order of the rules is not checked and is not used to determine the equivalence of the two states. -// The function returns two boolean values, the first one indicates whether residues exist, -// and the second one indicates whether differences were found between the current and expected state. -func (cfg *IptablesConfigurator) VerifyIptablesState(iptVer, ipt6Ver *dep.IptablesVersion) (bool, bool) { - // These variables track the status of iptables installation - residueExists := false // Flag to indicate if iptables residues from previous executions are found - deltaExists := false // Flag to indicate if a difference is found between expected and current state - -check_loop: - for _, ipCfg := range []struct { - ver *dep.IptablesVersion - expected string - checkRules [][]string - }{ - {iptVer, cfg.ruleBuilder.BuildV4Restore(), cfg.ruleBuilder.BuildCheckV4()}, - {ipt6Ver, cfg.ruleBuilder.BuildV6Restore(), cfg.ruleBuilder.BuildCheckV6()}, - } { - output, err := cfg.ext.RunWithOutput(constants.IPTablesSave, ipCfg.ver, nil) - if err == nil { - currentState := cfg.ruleBuilder.GetStateFromSave(output.String()) - log.Debugf("Current iptables state: %#v", currentState) - for _, value := range currentState { - if residueExists { - break - } - residueExists = len(value) != 0 - } - if !residueExists { - continue - } - expectedState := cfg.ruleBuilder.GetStateFromSave(ipCfg.expected) - log.Debugf("Expected iptables state: %#v", expectedState) - for table, chains := range expectedState { - _, ok := currentState[table] - if !ok { - deltaExists = true - log.Debugf("Can't find expected table %s in current state", table) - break check_loop - } - for chain, rules := range chains { - currentRules, ok := currentState[table][chain] - if !ok || (strings.HasPrefix(chain, "ISTIO_") && len(rules) != len(currentRules)) { - deltaExists = true - log.Debugf("Mismatching number of rules in chain %s between current and expected state", chain) - break check_loop - } - } - } - err = cfg.executeIptablesCommands(ipCfg.ver, ipCfg.checkRules) - if err != nil { - deltaExists = true - log.Debugf("iptables check rules failed") - break - } - } - - } - - if !residueExists { - log.Info("Clean-state detected, new iptables are needed") - return false, true - } - - if deltaExists { - log.Warn("Found residues of old iptables rules/chains, reconciliation is needed") - } else { - log.Warn("Found compatible residues of old iptables rules/chains, reconciliation not needed") - } - - return residueExists, deltaExists + return cfg.ext.Run(log.WithLabels(), constants.IPTablesRestore, iptVer, strings.NewReader(data), "--noflush") } func (cfg *IptablesConfigurator) executeCommands(iptVer, ipt6Ver *dep.IptablesVersion) error { @@ -855,9 +776,9 @@ func (cfg *IptablesConfigurator) executeCommands(iptVer, ipt6Ver *dep.IptablesVe } }() - residueExists, deltaExists := cfg.VerifyIptablesState(iptVer, ipt6Ver) + residueExists, deltaExists := VerifyIptablesState(log.WithLabels(), cfg.ext, cfg.ruleBuilder, iptVer, ipt6Ver) if residueExists && deltaExists && !cfg.cfg.Reconcile { - log.Warn("reconcile is needed but no-reconcile flag is set. Unexpected behavior may occur due to preexisting iptables rules") + log.Info("reconcile is recommended but no-reconcile flag is set. Unexpected behavior may occur due to preexisting iptables rules") } // Cleanup Step if (residueExists && deltaExists && cfg.cfg.Reconcile) || cfg.cfg.CleanupOnly { diff --git a/tools/istio-iptables/pkg/capture/run_test.go b/tools/istio-iptables/pkg/capture/run_test.go index cd3d65cecc07..e36e1022e585 100644 --- a/tools/istio-iptables/pkg/capture/run_test.go +++ b/tools/istio-iptables/pkg/capture/run_test.go @@ -33,6 +33,7 @@ import ( "github.com/howardjohn/unshare-go/userns" testutil "istio.io/istio/pilot/test/util" + "istio.io/istio/pkg/log" "istio.io/istio/pkg/test/util/assert" "istio.io/istio/tools/istio-iptables/pkg/config" "istio.io/istio/tools/istio-iptables/pkg/constants" @@ -108,7 +109,7 @@ func getCommonTestCases() []struct { "ipv6-virt-interfaces", func(cfg *config.Config) { cfg.InboundPortsInclude = "4000,5000" - cfg.KubeVirtInterfaces = "eth0,eth1" + cfg.RerouteVirtualInterfaces = "eth0,eth1" cfg.EnableIPv6 = true }, }, @@ -117,7 +118,7 @@ func getCommonTestCases() []struct { func(cfg *config.Config) { cfg.InboundPortsInclude = "4000,5000" cfg.InboundPortsExclude = "6000,7000," - cfg.KubeVirtInterfaces = "eth0,eth1" + cfg.RerouteVirtualInterfaces = "eth0,eth1" cfg.OutboundIPRangesExclude = "2001:db8::/32" cfg.OutboundIPRangesInclude = "2001:db8::/32" cfg.EnableIPv6 = true @@ -128,7 +129,7 @@ func getCommonTestCases() []struct { func(cfg *config.Config) { cfg.InboundPortsInclude = "4000,5000" cfg.InboundPortsExclude = "6000,7000" - cfg.KubeVirtInterfaces = "eth0,eth1" + cfg.RerouteVirtualInterfaces = "eth0,eth1" cfg.ProxyGID = "1,2" cfg.ProxyUID = "3,4" cfg.EnableIPv6 = true @@ -151,7 +152,7 @@ func getCommonTestCases() []struct { { "kube-virt-interfaces", func(cfg *config.Config) { - cfg.KubeVirtInterfaces = "eth1,eth2" + cfg.RerouteVirtualInterfaces = "eth1,eth2" cfg.OutboundIPRangesInclude = "*" }, }, @@ -164,7 +165,7 @@ func getCommonTestCases() []struct { { "ipnets-with-kube-virt-interfaces", func(cfg *config.Config) { - cfg.KubeVirtInterfaces = "eth1,eth2" + cfg.RerouteVirtualInterfaces = "eth1,eth2" cfg.OutboundIPRangesInclude = "10.0.0.0/8" }, }, @@ -358,8 +359,8 @@ func TestIdempotentEquivalentRerun(t *testing.T) { setup(t) commonCases := getCommonTestCases() ext := &dep.RealDependencies{ - HostFilesystemPodNetwork: false, - NetworkNamespace: "", + UsePodScopedXtablesLock: false, + NetworkNamespace: "", } iptVer, err := ext.DetectIptablesVersion(false) if err != nil { @@ -370,7 +371,7 @@ func TestIdempotentEquivalentRerun(t *testing.T) { if err != nil { t.Fatalf("Can't detect ip6tables version") } - + scope := log.FindScope(log.DefaultScopeName) for _, tt := range commonCases { t.Run(tt.name, func(t *testing.T) { cfg := constructTestConfig() @@ -391,7 +392,7 @@ func TestIdempotentEquivalentRerun(t *testing.T) { cfg.Reconcile = false iptConfigurator := NewIptablesConfigurator(cfg, ext) assert.NoError(t, iptConfigurator.Run()) - residueExists, deltaExists := iptConfigurator.VerifyIptablesState(&iptVer, &ipt6Ver) + residueExists, deltaExists := VerifyIptablesState(scope, iptConfigurator.ext, iptConfigurator.ruleBuilder, &iptVer, &ipt6Ver) assert.Equal(t, residueExists, false) assert.Equal(t, deltaExists, true) }() @@ -400,7 +401,7 @@ func TestIdempotentEquivalentRerun(t *testing.T) { cfg.Reconcile = false iptConfigurator := NewIptablesConfigurator(cfg, ext) assert.NoError(t, iptConfigurator.Run()) - residueExists, deltaExists := iptConfigurator.VerifyIptablesState(&iptVer, &ipt6Ver) + residueExists, deltaExists := VerifyIptablesState(scope, iptConfigurator.ext, iptConfigurator.ruleBuilder, &iptVer, &ipt6Ver) assert.Equal(t, residueExists, true) assert.Equal(t, deltaExists, false) @@ -437,8 +438,8 @@ func TestIdempotentUnequaledRerun(t *testing.T) { setup(t) commonCases := getCommonTestCases() ext := &dep.RealDependencies{ - HostFilesystemPodNetwork: false, - NetworkNamespace: "", + UsePodScopedXtablesLock: false, + NetworkNamespace: "", } iptVer, err := ext.DetectIptablesVersion(false) if err != nil { @@ -449,7 +450,7 @@ func TestIdempotentUnequaledRerun(t *testing.T) { if err != nil { t.Fatalf("Can't detect ip6tables version") } - + scope := log.FindScope(log.DefaultScopeName) for _, tt := range commonCases { t.Run(tt.name, func(t *testing.T) { cfg := constructTestConfig() @@ -471,7 +472,7 @@ func TestIdempotentUnequaledRerun(t *testing.T) { cfg.Reconcile = false iptConfigurator := NewIptablesConfigurator(cfg, ext) assert.NoError(t, iptConfigurator.Run()) - residueExists, deltaExists := iptConfigurator.VerifyIptablesState(&iptVer, &ipt6Ver) + residueExists, deltaExists := VerifyIptablesState(scope, iptConfigurator.ext, iptConfigurator.ruleBuilder, &iptVer, &ipt6Ver) assert.Equal(t, residueExists, true) // residue found due to extra OUTPUT rule assert.Equal(t, deltaExists, true) // Remove additional rule @@ -481,7 +482,7 @@ func TestIdempotentUnequaledRerun(t *testing.T) { if err := cmd.Run(); err != nil { t.Errorf("iptables cmd (%s %s) failed: %s", cmd.Path, cmd.Args, stderr.String()) } - residueExists, deltaExists = iptConfigurator.VerifyIptablesState(&iptVer, &ipt6Ver) + residueExists, deltaExists = VerifyIptablesState(scope, iptConfigurator.ext, iptConfigurator.ruleBuilder, &iptVer, &ipt6Ver) assert.Equal(t, residueExists, false) assert.Equal(t, deltaExists, true) }() @@ -489,7 +490,7 @@ func TestIdempotentUnequaledRerun(t *testing.T) { // First Pass iptConfigurator := NewIptablesConfigurator(cfg, ext) assert.NoError(t, iptConfigurator.Run()) - residueExists, deltaExists := iptConfigurator.VerifyIptablesState(&iptVer, &ipt6Ver) + residueExists, deltaExists := VerifyIptablesState(scope, iptConfigurator.ext, iptConfigurator.ruleBuilder, &iptVer, &ipt6Ver) assert.Equal(t, residueExists, true) assert.Equal(t, deltaExists, false) @@ -502,7 +503,7 @@ func TestIdempotentUnequaledRerun(t *testing.T) { } // Apply not required after tainting non-ISTIO chains with extra rules - residueExists, deltaExists = iptConfigurator.VerifyIptablesState(&iptVer, &ipt6Ver) + residueExists, deltaExists = VerifyIptablesState(scope, iptConfigurator.ext, iptConfigurator.ruleBuilder, &iptVer, &ipt6Ver) assert.Equal(t, residueExists, true) assert.Equal(t, deltaExists, false) @@ -514,7 +515,7 @@ func TestIdempotentUnequaledRerun(t *testing.T) { } // Apply required after tainting ISTIO chains - residueExists, deltaExists = iptConfigurator.VerifyIptablesState(&iptVer, &ipt6Ver) + residueExists, deltaExists = VerifyIptablesState(scope, iptConfigurator.ext, iptConfigurator.ruleBuilder, &iptVer, &ipt6Ver) assert.Equal(t, residueExists, true) assert.Equal(t, deltaExists, true) diff --git a/tools/istio-iptables/pkg/cmd/root.go b/tools/istio-iptables/pkg/cmd/root.go index 5e6a6e61cc1c..25a4dad215c3 100644 --- a/tools/istio-iptables/pkg/cmd/root.go +++ b/tools/istio-iptables/pkg/cmd/root.go @@ -92,9 +92,9 @@ func bindCmdlineFlags(cfg *config.Config, cmd *cobra.Command) { "Comma separated list of outbound ports to be excluded from redirection to Envoy.", &cfg.OutboundPortsExclude) - flag.BindEnv(fs, constants.KubeVirtInterfaces, "k", + flag.BindEnv(fs, constants.RerouteVirtualInterfaces, "k", "Comma separated list of virtual interfaces whose inbound traffic (from VM) will be treated as outbound.", - &cfg.KubeVirtInterfaces) + &cfg.RerouteVirtualInterfaces) flag.BindEnv(fs, constants.InboundTProxyMark, "t", "", &cfg.InboundTProxyMark) @@ -202,8 +202,8 @@ func ProgramIptables(cfg *config.Config) error { ext = &dep.DependenciesStub{} } else { ext = &dep.RealDependencies{ - HostFilesystemPodNetwork: cfg.HostFilesystemPodNetwork, - NetworkNamespace: cfg.NetworkNamespace, + UsePodScopedXtablesLock: cfg.HostFilesystemPodNetwork, + NetworkNamespace: cfg.NetworkNamespace, } } diff --git a/tools/istio-iptables/pkg/config/config.go b/tools/istio-iptables/pkg/config/config.go index af9ff16f2578..ee6994482d44 100644 --- a/tools/istio-iptables/pkg/config/config.go +++ b/tools/istio-iptables/pkg/config/config.go @@ -50,36 +50,36 @@ func DefaultConfig() *Config { // Command line options // nolint: maligned type Config struct { - ProxyPort string `json:"PROXY_PORT"` - InboundCapturePort string `json:"INBOUND_CAPTURE_PORT"` - InboundTunnelPort string `json:"INBOUND_TUNNEL_PORT"` - ProxyUID string `json:"PROXY_UID"` - ProxyGID string `json:"PROXY_GID"` - InboundInterceptionMode string `json:"INBOUND_INTERCEPTION_MODE"` - InboundTProxyMark string `json:"INBOUND_TPROXY_MARK"` - InboundTProxyRouteTable string `json:"INBOUND_TPROXY_ROUTE_TABLE"` - InboundPortsInclude string `json:"INBOUND_PORTS_INCLUDE"` - InboundPortsExclude string `json:"INBOUND_PORTS_EXCLUDE"` - OwnerGroupsInclude string `json:"OUTBOUND_OWNER_GROUPS_INCLUDE"` - OwnerGroupsExclude string `json:"OUTBOUND_OWNER_GROUPS_EXCLUDE"` - OutboundPortsInclude string `json:"OUTBOUND_PORTS_INCLUDE"` - OutboundPortsExclude string `json:"OUTBOUND_PORTS_EXCLUDE"` - OutboundIPRangesInclude string `json:"OUTBOUND_IPRANGES_INCLUDE"` - OutboundIPRangesExclude string `json:"OUTBOUND_IPRANGES_EXCLUDE"` - KubeVirtInterfaces string `json:"KUBE_VIRT_INTERFACES"` - ExcludeInterfaces string `json:"EXCLUDE_INTERFACES"` - IptablesProbePort uint16 `json:"IPTABLES_PROBE_PORT"` - ProbeTimeout time.Duration `json:"PROBE_TIMEOUT"` - DryRun bool `json:"DRY_RUN"` - SkipRuleApply bool `json:"SKIP_RULE_APPLY"` - RunValidation bool `json:"RUN_VALIDATION"` - RedirectDNS bool `json:"REDIRECT_DNS"` - DropInvalid bool `json:"DROP_INVALID"` - CaptureAllDNS bool `json:"CAPTURE_ALL_DNS"` - EnableIPv6 bool `json:"ENABLE_INBOUND_IPV6"` - DNSServersV4 []string `json:"DNS_SERVERS_V4"` - DNSServersV6 []string `json:"DNS_SERVERS_V6"` - NetworkNamespace string `json:"NETWORK_NAMESPACE"` + ProxyPort string `json:"PROXY_PORT"` + InboundCapturePort string `json:"INBOUND_CAPTURE_PORT"` + InboundTunnelPort string `json:"INBOUND_TUNNEL_PORT"` + ProxyUID string `json:"PROXY_UID"` + ProxyGID string `json:"PROXY_GID"` + InboundInterceptionMode string `json:"INBOUND_INTERCEPTION_MODE"` + InboundTProxyMark string `json:"INBOUND_TPROXY_MARK"` + InboundTProxyRouteTable string `json:"INBOUND_TPROXY_ROUTE_TABLE"` + InboundPortsInclude string `json:"INBOUND_PORTS_INCLUDE"` + InboundPortsExclude string `json:"INBOUND_PORTS_EXCLUDE"` + OwnerGroupsInclude string `json:"OUTBOUND_OWNER_GROUPS_INCLUDE"` + OwnerGroupsExclude string `json:"OUTBOUND_OWNER_GROUPS_EXCLUDE"` + OutboundPortsInclude string `json:"OUTBOUND_PORTS_INCLUDE"` + OutboundPortsExclude string `json:"OUTBOUND_PORTS_EXCLUDE"` + OutboundIPRangesInclude string `json:"OUTBOUND_IPRANGES_INCLUDE"` + OutboundIPRangesExclude string `json:"OUTBOUND_IPRANGES_EXCLUDE"` + RerouteVirtualInterfaces string `json:"KUBE_VIRT_INTERFACES"` + ExcludeInterfaces string `json:"EXCLUDE_INTERFACES"` + IptablesProbePort uint16 `json:"IPTABLES_PROBE_PORT"` + ProbeTimeout time.Duration `json:"PROBE_TIMEOUT"` + DryRun bool `json:"DRY_RUN"` + SkipRuleApply bool `json:"SKIP_RULE_APPLY"` + RunValidation bool `json:"RUN_VALIDATION"` + RedirectDNS bool `json:"REDIRECT_DNS"` + DropInvalid bool `json:"DROP_INVALID"` + CaptureAllDNS bool `json:"CAPTURE_ALL_DNS"` + EnableIPv6 bool `json:"ENABLE_INBOUND_IPV6"` + DNSServersV4 []string `json:"DNS_SERVERS_V4"` + DNSServersV6 []string `json:"DNS_SERVERS_V6"` + NetworkNamespace string `json:"NETWORK_NAMESPACE"` // When running in host filesystem, we have different semantics around the environment. // For instance, we would have a node-shared IPTables lock, despite not needing it. // HostFilesystemPodNetwork indicates we are in this mode, typically from the CNI. @@ -119,7 +119,7 @@ func (c *Config) Print() { b.WriteString(fmt.Sprintf("OUTBOUND_IP_RANGES_EXCLUDE=%s\n", c.OutboundIPRangesExclude)) b.WriteString(fmt.Sprintf("OUTBOUND_PORTS_INCLUDE=%s\n", c.OutboundPortsInclude)) b.WriteString(fmt.Sprintf("OUTBOUND_PORTS_EXCLUDE=%s\n", c.OutboundPortsExclude)) - b.WriteString(fmt.Sprintf("KUBE_VIRT_INTERFACES=%s\n", c.KubeVirtInterfaces)) + b.WriteString(fmt.Sprintf("KUBE_VIRT_INTERFACES=%s\n", c.RerouteVirtualInterfaces)) // TODO consider renaming this env var to ENABLE_IPV6 - nothing about it is specific to "INBOUND" b.WriteString(fmt.Sprintf("ENABLE_INBOUND_IPV6=%t\n", c.EnableIPv6)) // TODO remove this flag - "dual stack" should just mean diff --git a/tools/istio-iptables/pkg/constants/constants.go b/tools/istio-iptables/pkg/constants/constants.go index fde57cd0e928..fbb024bdd959 100644 --- a/tools/istio-iptables/pkg/constants/constants.go +++ b/tools/istio-iptables/pkg/constants/constants.go @@ -97,7 +97,7 @@ const ( InboundTunnelPort = "inbound-tunnel-port" ProxyUID = "proxy-uid" ProxyGID = "proxy-gid" - KubeVirtInterfaces = "kube-virt-interfaces" + RerouteVirtualInterfaces = "kube-virt-interfaces" DryRun = "dry-run" TraceLogging = "iptables-trace-logging" SkipRuleApply = "skip-rule-apply" diff --git a/tools/istio-iptables/pkg/dependencies/implementation.go b/tools/istio-iptables/pkg/dependencies/implementation.go index bfdeb5c8ecd1..ebf7a857acb7 100644 --- a/tools/istio-iptables/pkg/dependencies/implementation.go +++ b/tools/istio-iptables/pkg/dependencies/implementation.go @@ -54,8 +54,11 @@ var exittypeToString = map[XTablesExittype]string{ // RealDependencies implementation of interface Dependencies, which is used in production type RealDependencies struct { - NetworkNamespace string - HostFilesystemPodNetwork bool + NetworkNamespace string + // Should generally be set to true anytime we are "jumping" from a shared iptables + // context (the node, an agent container) into a pod to do iptables stuff, + // as it's faster and reduces contention for legacy iptables versions that use file-based locking. + UsePodScopedXtablesLock bool } const iptablesVersionPattern = `v([0-9]+(\.[0-9]+)+)` @@ -217,16 +220,34 @@ func transformToXTablesErrorMessage(stderr string, err error) string { } // Run runs a command -func (r *RealDependencies) Run(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) error { - return r.executeXTables(cmd, iptVer, false, stdin, args...) +func (r *RealDependencies) Run( + logger *log.Scope, + cmd constants.IptablesCmd, + iptVer *IptablesVersion, + stdin io.ReadSeeker, + args ...string, +) error { + return r.executeXTables(logger, cmd, iptVer, false, stdin, args...) } // Run runs a command and returns stdout -func (r *RealDependencies) RunWithOutput(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) (*bytes.Buffer, error) { - return r.executeXTablesWithOutput(cmd, iptVer, false, stdin, args...) +func (r *RealDependencies) RunWithOutput( + logger *log.Scope, + cmd constants.IptablesCmd, + iptVer *IptablesVersion, + stdin io.ReadSeeker, + args ...string, +) (*bytes.Buffer, error) { + return r.executeXTablesWithOutput(logger, cmd, iptVer, false, true, stdin, args...) } // RunQuietlyAndIgnore runs a command quietly and ignores errors -func (r *RealDependencies) RunQuietlyAndIgnore(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) { - _ = r.executeXTables(cmd, iptVer, true, stdin, args...) +func (r *RealDependencies) RunQuietlyAndIgnore( + logger *log.Scope, + cmd constants.IptablesCmd, + iptVer *IptablesVersion, + stdin io.ReadSeeker, + args ...string, +) { + _ = r.executeXTables(logger, cmd, iptVer, true, stdin, args...) } diff --git a/tools/istio-iptables/pkg/dependencies/implementation_linux.go b/tools/istio-iptables/pkg/dependencies/implementation_linux.go index 288f53df9fe9..ce8b8cafa8f7 100644 --- a/tools/istio-iptables/pkg/dependencies/implementation_linux.go +++ b/tools/istio-iptables/pkg/dependencies/implementation_linux.go @@ -203,8 +203,8 @@ func mount(src, dst string) error { return syscall.Mount(src, dst, "", syscall.MS_BIND|syscall.MS_RDONLY, "") } -func (r *RealDependencies) executeXTablesWithOutput(cmd constants.IptablesCmd, iptVer *IptablesVersion, - ignoreErrors bool, stdin io.ReadSeeker, args ...string, +func (r *RealDependencies) executeXTablesWithOutput(log *log.Scope, cmd constants.IptablesCmd, iptVer *IptablesVersion, + ignoreErrors bool, silenceOutput bool, stdin io.ReadSeeker, args ...string, ) (*bytes.Buffer, error) { mode := "without lock" stdout := &bytes.Buffer{} @@ -219,7 +219,16 @@ func (r *RealDependencies) executeXTablesWithOutput(cmd constants.IptablesCmd, i run := func(c *exec.Cmd) error { return c.Run() } - if r.HostFilesystemPodNetwork { + if needLock { + // For _any_ mode where we need a lock (sandboxed or not) + // use the wait flag. In sandbox mode we use the container's netns itself + // as the lockfile, if one is needed, to avoid lock contention 99% of the time. + // But a container netns is just a file, and like any Linux file, + // we can't guarantee no other process has it locked. + args = append(args, "--wait=30") + } + + if r.UsePodScopedXtablesLock { c = exec.Command(cmdBin, args...) // In CNI, we are running the pod network namespace, but the host filesystem, so we need to do some tricks // Call our binary again, but with "unshare (subcommand to trigger mounts)" --lock-file= @@ -227,14 +236,14 @@ func (r *RealDependencies) executeXTablesWithOutput(cmd constants.IptablesCmd, i var lockFile string if needLock { if iptVer.Version.LessThan(IptablesLockfileEnv) { - mode = "without lock by mount and nss" + mode = "sandboxed local lock by mount and nss" lockFile = r.NetworkNamespace } else { - mode = "without lock by env and nss" + mode = "sandboxed local lock by env and nss" c.Env = append(c.Env, "XTABLES_LOCKFILE="+r.NetworkNamespace) } } else { - mode = "without nss" + mode = "sandboxed without lock" } run = func(c *exec.Cmd) error { @@ -244,11 +253,9 @@ func (r *RealDependencies) executeXTablesWithOutput(cmd constants.IptablesCmd, i } } else { if needLock { - // We want the lock. Wait up to 30s for it. - args = append(args, "--wait=30") c = exec.Command(cmdBin, args...) log.Debugf("running with lock") - mode = "with wait lock" + mode = "with global lock" } else { // No locking supported/needed, just run as is. Nothing special c = exec.Command(cmdBin, args...) @@ -261,7 +268,11 @@ func (r *RealDependencies) executeXTablesWithOutput(cmd constants.IptablesCmd, i c.Stdin = stdin err := run(c) if len(stdout.String()) != 0 { - log.Infof("Command output: \n%v", stdout.String()) + if !silenceOutput { + log.Infof("Command output: \n%v", stdout.String()) + } else { + log.Debugf("Command output: \n%v", stdout.String()) + } } // TODO Check naming and redirection logic @@ -274,12 +285,22 @@ func (r *RealDependencies) executeXTablesWithOutput(cmd constants.IptablesCmd, i } log.Errorf("Command error output: %v", stderrStr) + } else if err != nil && ignoreErrors { + // Log ignored errors for debugging purposes + log.Debugf("Ignoring iptables command error: %v", err) } return stdout, err } -func (r *RealDependencies) executeXTables(cmd constants.IptablesCmd, iptVer *IptablesVersion, ignoreErrors bool, stdin io.ReadSeeker, args ...string) error { - _, err := r.executeXTablesWithOutput(cmd, iptVer, ignoreErrors, stdin, args...) +func (r *RealDependencies) executeXTables( + logger *log.Scope, + cmd constants.IptablesCmd, + iptVer *IptablesVersion, + ignoreErrors bool, + stdin io.ReadSeeker, + args ...string, +) error { + _, err := r.executeXTablesWithOutput(logger, cmd, iptVer, ignoreErrors, false, stdin, args...) return err } diff --git a/tools/istio-iptables/pkg/dependencies/implementation_unspecified.go b/tools/istio-iptables/pkg/dependencies/implementation_unspecified.go index 52b4e03dfa37..27a59f6e1afe 100644 --- a/tools/istio-iptables/pkg/dependencies/implementation_unspecified.go +++ b/tools/istio-iptables/pkg/dependencies/implementation_unspecified.go @@ -22,23 +22,20 @@ import ( "errors" "io" + "istio.io/istio/pkg/log" "istio.io/istio/tools/istio-iptables/pkg/constants" ) // ErrNotImplemented is returned when a requested feature is not implemented. var ErrNotImplemented = errors.New("not implemented") -func (r *RealDependencies) execute(cmd string, ignoreErrors bool, stdin io.Reader, args ...string) error { - return ErrNotImplemented -} - -func (r *RealDependencies) executeXTables(cmd constants.IptablesCmd, iptVer *IptablesVersion, ignoreErrors bool, stdin io.ReadSeeker, args ...string) error { - _, err := r.executeXTablesWithOutput(cmd, iptVer, ignoreErrors, stdin, args...) +func (r *RealDependencies) executeXTables(log *log.Scope, cmd constants.IptablesCmd, iptVer *IptablesVersion, ignoreErrors bool, stdin io.ReadSeeker, args ...string) error { + _, err := r.executeXTablesWithOutput(log, cmd, iptVer, ignoreErrors, false, stdin, args...) return err } -func (r *RealDependencies) executeXTablesWithOutput(cmd constants.IptablesCmd, iptVer *IptablesVersion, - ignoreErrors bool, stdin io.ReadSeeker, args ...string, +func (r *RealDependencies) executeXTablesWithOutput(log *log.Scope, cmd constants.IptablesCmd, iptVer *IptablesVersion, + ignoreErrors bool, silenceOutput bool, stdin io.ReadSeeker, args ...string, ) (*bytes.Buffer, error) { return nil, ErrNotImplemented } diff --git a/tools/istio-iptables/pkg/dependencies/interface.go b/tools/istio-iptables/pkg/dependencies/interface.go index 5ee48a07cad5..9adb46128f08 100644 --- a/tools/istio-iptables/pkg/dependencies/interface.go +++ b/tools/istio-iptables/pkg/dependencies/interface.go @@ -18,19 +18,20 @@ import ( "bytes" "io" + istiolog "istio.io/istio/pkg/log" "istio.io/istio/tools/istio-iptables/pkg/constants" ) // Dependencies is used as abstraction for the commands used from the operating system type Dependencies interface { // Run runs a command - Run(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) error + Run(log *istiolog.Scope, cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) error // Run runs a command and get the output - RunWithOutput(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) (*bytes.Buffer, error) + RunWithOutput(log *istiolog.Scope, cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) (*bytes.Buffer, error) // RunQuietlyAndIgnore runs a command quietly and ignores errors - RunQuietlyAndIgnore(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) + RunQuietlyAndIgnore(log *istiolog.Scope, cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) // DetectIptablesVersion consults the available binaries and in-use tables to determine // which iptables variant (legacy, nft, v6, v4) we should use in the current context. diff --git a/tools/istio-iptables/pkg/dependencies/stub.go b/tools/istio-iptables/pkg/dependencies/stub.go index 12b12ff31e86..c1f3315c969d 100644 --- a/tools/istio-iptables/pkg/dependencies/stub.go +++ b/tools/istio-iptables/pkg/dependencies/stub.go @@ -23,6 +23,7 @@ import ( "strings" "istio.io/istio/pkg/env" + "istio.io/istio/pkg/log" "istio.io/istio/tools/istio-iptables/pkg/constants" ) @@ -36,19 +37,31 @@ type DependenciesStub struct { ExecutedAll []string } -func (s *DependenciesStub) Run(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) error { +func (s *DependenciesStub) Run(logger *log.Scope, cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) error { s.execute(false /*quietly*/, cmd, iptVer, stdin, args...) _ = s.writeAllToDryRunPath() return nil } -func (s *DependenciesStub) RunWithOutput(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) (*bytes.Buffer, error) { +func (s *DependenciesStub) RunWithOutput( + ogger *log.Scope, + cmd constants.IptablesCmd, + iptVer *IptablesVersion, + stdin io.ReadSeeker, + args ...string, +) (*bytes.Buffer, error) { s.execute(false /*quietly*/, cmd, iptVer, stdin, args...) _ = s.writeAllToDryRunPath() return &bytes.Buffer{}, nil } -func (s *DependenciesStub) RunQuietlyAndIgnore(cmd constants.IptablesCmd, iptVer *IptablesVersion, stdin io.ReadSeeker, args ...string) { +func (s *DependenciesStub) RunQuietlyAndIgnore( + logger *log.Scope, + cmd constants.IptablesCmd, + iptVer *IptablesVersion, + stdin io.ReadSeeker, + args ...string, +) { s.execute(true /*quietly*/, cmd, iptVer, stdin, args...) _ = s.writeAllToDryRunPath() } diff --git a/tools/istio-iptables/pkg/e2e/e2e_test.go b/tools/istio-iptables/pkg/e2e/e2e_test.go deleted file mode 100644 index 9758b1752c00..000000000000 --- a/tools/istio-iptables/pkg/e2e/e2e_test.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright Istio Authors -// -// Licensed 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 e2e - -import ( - "os" - "os/exec" - "path/filepath" - "strings" - "sync" - "testing" - - // Create a new mount namespace. - "github.com/howardjohn/unshare-go/mountns" - // Create a new network namespace. This will have the 'lo' interface ready but nothing else. - _ "github.com/howardjohn/unshare-go/netns" - "github.com/howardjohn/unshare-go/userns" - - "istio.io/istio/pkg/log" - "istio.io/istio/pkg/slices" - "istio.io/istio/pkg/test/util/assert" - cleancmd "istio.io/istio/tools/istio-clean-iptables/pkg/cmd" - iptablescmd "istio.io/istio/tools/istio-iptables/pkg/cmd" -) - -func TestIptablesCleanRoundTrip(t *testing.T) { - setup(t) - roundtrip := func(t *testing.T, args ...string) { - // We only have UID 0 in our namespace, so always set it to that - args = append([]string{"--proxy-uid=0"}, args...) - // Apply, cleanup with the old approach - assert.NoError(t, runIptables(args...)) - assert.NoError(t, runIptablesOldClean(args...)) - validateIptablesClean(t) - // App, cleanup with the new approach - assert.NoError(t, runIptables(args...)) - assert.NoError(t, runIptablesClean(args...)) - validateIptablesClean(t) - } - t.Run("basic", func(t *testing.T) { - roundtrip(t) - }) - t.Run("dns", func(t *testing.T) { - roundtrip(t, "--redirect-dns") - }) -} - -func validateIptablesClean(t *testing.T) { - cur := iptablesSave(t) - if strings.Contains(cur, "ISTIO") { - t.Fatalf("Istio rules leftover: %v", cur) - } - if strings.Contains(cur, "-A") { - t.Fatalf("Rules: %v", cur) - } -} - -var initialized = &sync.Once{} - -func setup(t *testing.T) { - initialized.Do(func() { - // Setup group namespace so iptables --gid-owner will work - assert.NoError(t, userns.WriteGroupMap(map[uint32]uint32{userns.OriginalGID(): 0})) - // Istio iptables expects to find a non-localhost IP in some interface - assert.NoError(t, exec.Command("ip", "addr", "add", "240.240.240.240/32", "dev", "lo").Run()) - // Put a new file we have permission to access over xtables.lock - xtables := filepath.Join(t.TempDir(), "xtables.lock") - _, err := os.Create(xtables) - assert.NoError(t, err) - _ = os.Mkdir("/run", 0o777) - _ = mountns.BindMount(xtables, "/run/xtables.lock") - }) -} - -func runIptables(args ...string) error { - c := iptablescmd.GetCommand(log.DefaultOptions()) - c.SetArgs(args) - return c.Execute() -} - -func runIptablesClean(args ...string) error { - c := iptablescmd.GetCommand(log.DefaultOptions()) - args = append(slices.Clone(args), "--cleanup-only") - c.SetArgs(args) - return c.Execute() -} - -func runIptablesOldClean(args ...string) error { - c := cleancmd.GetCommand(log.DefaultOptions()) - c.SetArgs(args) - return c.Execute() -} - -func iptablesSave(t *testing.T) string { - res, err := exec.Command("iptables-save").CombinedOutput() - assert.NoError(t, err) - return string(res) -} diff --git a/tools/proto/buf.golang-json.yaml b/tools/proto/buf.golang-json.yaml new file mode 100644 index 000000000000..74f8c1783a08 --- /dev/null +++ b/tools/proto/buf.golang-json.yaml @@ -0,0 +1,13 @@ +version: v1beta1 +plugins: +- name: go + out: . + opt: + - paths=source_relative +- name: go-grpc + out: . + opt: + - paths=source_relative +- name: golang-jsonshim + out: . + opt: paths=source_relative diff --git a/tools/proto/proto.mk b/tools/proto/proto.mk index a1a157d0fd07..09a93eaa6338 100644 --- a/tools/proto/proto.mk +++ b/tools/proto/proto.mk @@ -28,7 +28,7 @@ echo-proto: buf generate --config $(BUF_CONFIG_DIR)/buf.yaml --path pkg/test/echo --output pkg --template $(BUF_CONFIG_DIR)/buf.golang.yaml workload-proto: - buf generate --config $(BUF_CONFIG_DIR)/buf.yaml --path pkg/workloadapi --output pkg --template $(BUF_CONFIG_DIR)/buf.golang.yaml + buf generate --config $(BUF_CONFIG_DIR)/buf.yaml --path pkg/workloadapi --output pkg --template $(BUF_CONFIG_DIR)/buf.golang-json.yaml zds-proto: buf generate --config $(BUF_CONFIG_DIR)/buf.yaml --path pkg/zdsapi --output pkg --template $(BUF_CONFIG_DIR)/buf.golang.yaml