From 9c9a726e722ab3ad7d544fc4cda47d01e8e18de9 Mon Sep 17 00:00:00 2001 From: Nathan Mittler Date: Fri, 2 Aug 2019 14:14:43 -0700 Subject: [PATCH] Moving config hostname to subpackage (#16026) This is part of the cleanup of pkg/config. Planning on moving everything here to subpackages. --- istioctl/cmd/proxyconfig.go | 4 +- .../pkg/writer/envoy/configdump/cluster.go | 10 +- mixer/test/client/gateway/gateway_test.go | 8 +- .../client/pilotplugin/pilotplugin_test.go | 8 +- .../pilotplugin_mtls/pilotplugin_mtls_test.go | 8 +- .../pilotplugin_tcp/pilotplugin_tcp_test.go | 8 +- pilot/pkg/bootstrap/server.go | 38 ++-- pilot/pkg/model/config.go | 21 +- pilot/pkg/model/config_test.go | 42 ++-- pilot/pkg/model/destination_rule.go | 9 +- pilot/pkg/model/push_context.go | 56 ++--- pilot/pkg/model/service.go | 24 +-- pilot/pkg/model/service_test.go | 4 +- pilot/pkg/model/sidecar.go | 41 ++-- pilot/pkg/model/sidecar_test.go | 26 +-- .../networking/core/v1alpha3/cluster_test.go | 10 +- .../v1alpha3/envoyfilter/cluster_patch.go | 7 +- .../v1alpha3/fakes/fake_service_discovery.go | 12 +- pilot/pkg/networking/core/v1alpha3/gateway.go | 39 ++-- .../pkg/networking/core/v1alpha3/httproute.go | 10 +- .../core/v1alpha3/httproute_test.go | 4 +- .../pkg/networking/core/v1alpha3/listener.go | 14 +- .../networking/core/v1alpha3/listener_test.go | 6 +- .../networking/core/v1alpha3/networkfilter.go | 7 +- .../networking/core/v1alpha3/route/route.go | 32 +-- .../core/v1alpha3/route/route_test.go | 4 +- pilot/pkg/networking/core/v1alpha3/tls.go | 6 +- pilot/pkg/networking/plugin/mixer/mixer.go | 30 +-- pilot/pkg/proxy/envoy/v2/debug.go | 5 +- pilot/pkg/proxy/envoy/v2/eds.go | 8 +- pilot/pkg/proxy/envoy/v2/eds_sh_test.go | 8 +- pilot/pkg/proxy/envoy/v2/eds_test.go | 5 +- pilot/pkg/proxy/envoy/v2/ep_filters.go | 5 +- pilot/pkg/proxy/envoy/v2/ep_filters_test.go | 7 +- pilot/pkg/proxy/envoy/v2/mem.go | 22 +- pilot/pkg/proxy/envoy/v2/xds_test.go | 4 +- .../security/authz/builder/builder_test.go | 5 +- pilot/pkg/security/authz/model/model_test.go | 6 +- pilot/pkg/security/authz/policy/helper.go | 5 +- .../serviceregistry/aggregate/controller.go | 6 +- .../aggregate/controller_test.go | 16 +- .../pkg/serviceregistry/consul/controller.go | 4 +- .../pkg/serviceregistry/consul/conversion.go | 8 +- .../serviceregistry/external/conversion.go | 16 +- .../external/conversion_test.go | 4 +- .../external/servicediscovery.go | 10 +- .../external/servicediscovery_test.go | 16 +- .../kube/controller/controller.go | 12 +- pilot/pkg/serviceregistry/kube/conversion.go | 6 +- pilot/pkg/serviceregistry/memory/discovery.go | 16 +- .../serviceregistry/memory/discovery_mock.go | 4 +- pkg/config/{hostname.go => host/name.go} | 66 +++--- .../{hostname_test.go => host/name_test.go} | 16 +- pkg/config/{hostnames.go => host/names.go} | 58 ++--- pkg/config/host/names_test.go | 199 ++++++++++++++++++ pkg/config/hostnames_test.go | 197 ----------------- pkg/config/security.go | 6 +- pkg/config/validation.go | 83 ++++---- 58 files changed, 668 insertions(+), 643 deletions(-) rename pkg/config/{hostname.go => host/name.go} (60%) rename pkg/config/{hostname_test.go => host/name_test.go} (95%) rename pkg/config/{hostnames.go => host/names.go} (56%) create mode 100644 pkg/config/host/names_test.go delete mode 100644 pkg/config/hostnames_test.go diff --git a/istioctl/cmd/proxyconfig.go b/istioctl/cmd/proxyconfig.go index 6115c6d8e076..ee3fb24b6342 100644 --- a/istioctl/cmd/proxyconfig.go +++ b/istioctl/cmd/proxyconfig.go @@ -24,7 +24,7 @@ import ( "istio.io/istio/istioctl/pkg/writer/envoy/clusters" "istio.io/istio/istioctl/pkg/writer/envoy/configdump" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" ) const ( @@ -115,7 +115,7 @@ func proxyConfig() *cobra.Command { return err } filter := configdump.ClusterFilter{ - FQDN: config.Hostname(fqdn), + FQDN: host.Name(fqdn), Port: port, Subset: subset, Direction: model.TrafficDirection(direction), diff --git a/istioctl/pkg/writer/envoy/configdump/cluster.go b/istioctl/pkg/writer/envoy/configdump/cluster.go index 0ea1e6043b78..3327c70637a0 100644 --- a/istioctl/pkg/writer/envoy/configdump/cluster.go +++ b/istioctl/pkg/writer/envoy/configdump/cluster.go @@ -25,12 +25,12 @@ import ( protio "istio.io/istio/istioctl/pkg/util/proto" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" ) // ClusterFilter is used to pass filter information into cluster based config writer print functions type ClusterFilter struct { - FQDN config.Hostname + FQDN host.Name Port int Subset string Direction model.TrafficDirection @@ -151,10 +151,10 @@ func (c *ConfigWriter) retrieveSortedClusterSlice() ([]*xdsapi.Cluster, error) { return clusters, nil } -func safelyParseSubsetKey(key string) (model.TrafficDirection, string, config.Hostname, int) { +func safelyParseSubsetKey(key string) (model.TrafficDirection, string, host.Name, int) { if len(strings.Split(key, "|")) > 3 { return model.ParseSubsetKey(key) } - name := config.Hostname(key) - return model.TrafficDirection(""), "", name, 0 + name := host.Name(key) + return "", "", name, 0 } diff --git a/mixer/test/client/gateway/gateway_test.go b/mixer/test/client/gateway/gateway_test.go index 728f1cac78f3..15292d0c7b6b 100644 --- a/mixer/test/client/gateway/gateway_test.go +++ b/mixer/test/client/gateway/gateway_test.go @@ -40,7 +40,7 @@ import ( "istio.io/istio/pilot/pkg/networking/plugin" "istio.io/istio/pilot/pkg/networking/plugin/mixer" pilotutil "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -238,7 +238,7 @@ func (mock) GetProxyServiceInstances(_ *model.Proxy) ([]*model.ServiceInstance, func (mock) GetProxyWorkloadLabels(proxy *model.Proxy) (labels.Collection, error) { return nil, nil } -func (mock) GetService(_ config.Hostname) (*model.Service, error) { return nil, nil } +func (mock) GetService(_ host.Name) (*model.Service, error) { return nil, nil } func (mock) InstancesByPort(_ *model.Service, _ int, _ labels.Collection) ([]*model.ServiceInstance, error) { return nil, nil } @@ -268,8 +268,8 @@ var ( ServiceDiscovery: mock{}, } pushContext = model.PushContext{ - ServiceByHostnameAndNamespace: map[config.Hostname]map[string]*model.Service{ - config.Hostname("svc.ns3"): { + ServiceByHostnameAndNamespace: map[host.Name]map[string]*model.Service{ + host.Name("svc.ns3"): { "ns3": &svc, }, }, diff --git a/mixer/test/client/pilotplugin/pilotplugin_test.go b/mixer/test/client/pilotplugin/pilotplugin_test.go index be6d4414f85c..da4639d09c30 100644 --- a/mixer/test/client/pilotplugin/pilotplugin_test.go +++ b/mixer/test/client/pilotplugin/pilotplugin_test.go @@ -38,7 +38,7 @@ import ( "istio.io/istio/pilot/pkg/networking/plugin" "istio.io/istio/pilot/pkg/networking/plugin/mixer" pilotutil "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -304,7 +304,7 @@ func (mock) GetProxyServiceInstances(_ *model.Proxy) ([]*model.ServiceInstance, func (mock) GetProxyWorkloadLabels(proxy *model.Proxy) (labels.Collection, error) { return nil, nil } -func (mock) GetService(_ config.Hostname) (*model.Service, error) { return nil, nil } +func (mock) GetService(_ host.Name) (*model.Service, error) { return nil, nil } func (mock) InstancesByPort(_ *model.Service, _ int, _ labels.Collection) ([]*model.ServiceInstance, error) { return nil, nil } @@ -335,8 +335,8 @@ var ( ServiceDiscovery: mock{}, } pushContext = model.PushContext{ - ServiceByHostnameAndNamespace: map[config.Hostname]map[string]*model.Service{ - config.Hostname("svc.ns3"): { + ServiceByHostnameAndNamespace: map[host.Name]map[string]*model.Service{ + host.Name("svc.ns3"): { "ns3": &svc, }, }, diff --git a/mixer/test/client/pilotplugin_mtls/pilotplugin_mtls_test.go b/mixer/test/client/pilotplugin_mtls/pilotplugin_mtls_test.go index 1fcbb912a715..d23883cacfb3 100644 --- a/mixer/test/client/pilotplugin_mtls/pilotplugin_mtls_test.go +++ b/mixer/test/client/pilotplugin_mtls/pilotplugin_mtls_test.go @@ -39,7 +39,7 @@ import ( "istio.io/istio/pilot/pkg/networking/plugin" "istio.io/istio/pilot/pkg/networking/plugin/mixer" pilotutil "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/proto" ) @@ -319,7 +319,7 @@ func (mock) GetProxyServiceInstances(_ *model.Proxy) ([]*model.ServiceInstance, func (mock) GetProxyWorkloadLabels(proxy *model.Proxy) (labels.Collection, error) { return nil, nil } -func (mock) GetService(_ config.Hostname) (*model.Service, error) { return nil, nil } +func (mock) GetService(_ host.Name) (*model.Service, error) { return nil, nil } func (mock) InstancesByPort(_ *model.Service, _ int, _ labels.Collection) ([]*model.ServiceInstance, error) { return nil, nil } @@ -350,8 +350,8 @@ var ( ServiceDiscovery: mock{}, } pushContext = model.PushContext{ - ServiceByHostnameAndNamespace: map[config.Hostname]map[string]*model.Service{ - config.Hostname("svc.ns3"): { + ServiceByHostnameAndNamespace: map[host.Name]map[string]*model.Service{ + host.Name("svc.ns3"): { "ns3": &svc, }, }, diff --git a/mixer/test/client/pilotplugin_tcp/pilotplugin_tcp_test.go b/mixer/test/client/pilotplugin_tcp/pilotplugin_tcp_test.go index 9179dcd93d37..369c52e4841f 100644 --- a/mixer/test/client/pilotplugin_tcp/pilotplugin_tcp_test.go +++ b/mixer/test/client/pilotplugin_tcp/pilotplugin_tcp_test.go @@ -37,7 +37,7 @@ import ( "istio.io/istio/pilot/pkg/networking/plugin" "istio.io/istio/pilot/pkg/networking/plugin/mixer" pilotutil "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -187,7 +187,7 @@ func (mock) GetProxyServiceInstances(_ *model.Proxy) ([]*model.ServiceInstance, func (mock) GetProxyWorkloadLabels(proxy *model.Proxy) (labels.Collection, error) { return nil, nil } -func (mock) GetService(_ config.Hostname) (*model.Service, error) { return nil, nil } +func (mock) GetService(_ host.Name) (*model.Service, error) { return nil, nil } func (mock) InstancesByPort(_ *model.Service, _ int, _ labels.Collection) ([]*model.ServiceInstance, error) { return nil, nil } @@ -217,8 +217,8 @@ var ( ServiceDiscovery: mock{}, } pushContext = model.PushContext{ - ServiceByHostnameAndNamespace: map[config.Hostname]map[string]*model.Service{ - config.Hostname("svc.ns3"): { + ServiceByHostnameAndNamespace: map[host.Name]map[string]*model.Service{ + host.Name("svc.ns3"): { "ns3": &svc, }, }, diff --git a/pilot/pkg/bootstrap/server.go b/pilot/pkg/bootstrap/server.go index b939c29190dc..541981876f0c 100644 --- a/pilot/pkg/bootstrap/server.go +++ b/pilot/pkg/bootstrap/server.go @@ -72,8 +72,8 @@ import ( "istio.io/istio/pilot/pkg/serviceregistry/external" controller2 "istio.io/istio/pilot/pkg/serviceregistry/kube/controller" srmemory "istio.io/istio/pilot/pkg/serviceregistry/memory" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/mesh" istiokeepalive "istio.io/istio/pkg/keepalive" kubelib "istio.io/istio/pkg/kube" @@ -365,11 +365,11 @@ func GetMeshConfig(kube kubernetes.Interface, namespace, name string) (*v1.Confi return nil, nil, fmt.Errorf("missing configuration map key %q", ConfigMapKey) } - mesh, err := mesh.ApplyMeshConfigDefaults(cfgYaml) + meshConfig, err := mesh.ApplyMeshConfigDefaults(cfgYaml) if err != nil { return nil, nil, err } - return cfg, mesh, nil + return cfg, meshConfig, nil } // initMesh creates the mesh in the pilotConfig from the input arguments. @@ -379,11 +379,11 @@ func (s *Server) initMesh(args *PilotArgs) error { s.mesh = args.MeshConfig return nil } - var mesh *meshconfig.MeshConfig + var meshConfig *meshconfig.MeshConfig var err error if args.Mesh.ConfigFile != "" { - mesh, err = cmd.ReadMeshConfig(args.Mesh.ConfigFile) + meshConfig, err = cmd.ReadMeshConfig(args.Mesh.ConfigFile) if err != nil { log.Warnf("failed to read mesh configuration, using default: %v", err) } @@ -391,29 +391,29 @@ func (s *Server) initMesh(args *PilotArgs) error { // Watch the config file for changes and reload if it got modified s.addFileWatcher(args.Mesh.ConfigFile, func() { // Reload the config file - mesh, err = cmd.ReadMeshConfig(args.Mesh.ConfigFile) + meshConfig, err = cmd.ReadMeshConfig(args.Mesh.ConfigFile) if err != nil { log.Warnf("failed to read mesh configuration, using default: %v", err) return } - if !reflect.DeepEqual(mesh, s.mesh) { - log.Infof("mesh configuration updated to: %s", spew.Sdump(mesh)) - if !reflect.DeepEqual(mesh.ConfigSources, s.mesh.ConfigSources) { + if !reflect.DeepEqual(meshConfig, s.mesh) { + log.Infof("mesh configuration updated to: %s", spew.Sdump(meshConfig)) + if !reflect.DeepEqual(meshConfig.ConfigSources, s.mesh.ConfigSources) { log.Infof("mesh configuration sources have changed") //TODO Need to re-create or reload initConfigController() } - s.mesh = mesh + s.mesh = meshConfig if s.EnvoyXdsServer != nil { - s.EnvoyXdsServer.Env.Mesh = mesh + s.EnvoyXdsServer.Env.Mesh = meshConfig s.EnvoyXdsServer.ConfigUpdate(true) } } }) } - if mesh == nil { + if meshConfig == nil { // Config file either wasn't specified or failed to load - use a default mesh. - if _, mesh, err = GetMeshConfig(s.kubeClient, controller2.IstioNamespace, controller2.IstioConfigMap); err != nil { + if _, meshConfig, err = GetMeshConfig(s.kubeClient, controller2.IstioNamespace, controller2.IstioConfigMap); err != nil { log.Warnf("failed to read the default mesh configuration: %v, from the %s config map in the %s namespace", err, controller2.IstioConfigMap, controller2.IstioNamespace) return err @@ -421,16 +421,16 @@ func (s *Server) initMesh(args *PilotArgs) error { // Allow some overrides for testing purposes. if args.Mesh.MixerAddress != "" { - mesh.MixerCheckServer = args.Mesh.MixerAddress - mesh.MixerReportServer = args.Mesh.MixerAddress + meshConfig.MixerCheckServer = args.Mesh.MixerAddress + meshConfig.MixerReportServer = args.Mesh.MixerAddress } } - log.Infof("mesh configuration %s", spew.Sdump(mesh)) + log.Infof("mesh configuration %s", spew.Sdump(meshConfig)) log.Infof("version %s", version.Info.String()) log.Infof("flags %s", spew.Sdump(args)) - s.mesh = mesh + s.mesh = meshConfig return nil } @@ -865,11 +865,11 @@ func (s *Server) initServiceControllers(args *PilotArgs) error { func (s *Server) initMemoryRegistry(serviceControllers *aggregate.Controller) { // MemServiceDiscovery implementation discovery1 := srmemory.NewDiscovery( - map[config.Hostname]*model.Service{ // srmemory.HelloService.Hostname: srmemory.HelloService, + map[host.Name]*model.Service{ // srmemory.HelloService.Hostname: srmemory.HelloService, }, 2) discovery2 := srmemory.NewDiscovery( - map[config.Hostname]*model.Service{ // srmemory.WorldService.Hostname: srmemory.WorldService, + map[host.Name]*model.Service{ // srmemory.WorldService.Hostname: srmemory.WorldService, }, 2) registry1 := aggregate.Registry{ diff --git a/pilot/pkg/model/config.go b/pilot/pkg/model/config.go index 430b28be550c..223a49596c35 100644 --- a/pilot/pkg/model/config.go +++ b/pilot/pkg/model/config.go @@ -33,6 +33,7 @@ import ( "istio.io/istio/pilot/pkg/model/test" "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -550,7 +551,7 @@ var ( // ResolveHostname produces a FQDN based on either the service or // a concat of the namespace + domain // Deprecated. Do not use -func ResolveHostname(meta ConfigMeta, svc *mccpb.IstioService) config.Hostname { +func ResolveHostname(meta ConfigMeta, svc *mccpb.IstioService) host.Name { out := svc.Name // if FQDN is specified, do not append domain or namespace to hostname // Service field has precedence over Name @@ -570,20 +571,20 @@ func ResolveHostname(meta ConfigMeta, svc *mccpb.IstioService) config.Hostname { } } - return config.Hostname(out) + return host.Name(out) } // ResolveShortnameToFQDN uses metadata information to resolve a reference // to shortname of the service to FQDN -func ResolveShortnameToFQDN(host string, meta ConfigMeta) config.Hostname { - out := host - // Treat the wildcard host as fully qualified. Any other variant of a wildcard hostname will contain a `.` too, +func ResolveShortnameToFQDN(hostname string, meta ConfigMeta) host.Name { + out := hostname + // Treat the wildcard hostname as fully qualified. Any other variant of a wildcard hostname will contain a `.` too, // and skip the next if, so we only need to check for the literal wildcard itself. - if host == "*" { - return config.Hostname(out) + if hostname == "*" { + return host.Name(out) } // if FQDN is specified, do not append domain or namespace to hostname - if !strings.Contains(host, ".") { + if !strings.Contains(hostname, ".") { if meta.Namespace != "" { out = out + "." + meta.Namespace } @@ -596,7 +597,7 @@ func ResolveShortnameToFQDN(host string, meta ConfigMeta) config.Hostname { } } - return config.Hostname(out) + return host.Name(out) } // resolveGatewayName uses metadata information to resolve a reference @@ -627,7 +628,7 @@ func resolveGatewayName(gwname string, meta ConfigMeta) string { // MostSpecificHostMatch compares the elements of the stack to the needle, and returns the longest stack element // matching the needle, or false if no element in the stack matches the needle. -func MostSpecificHostMatch(needle config.Hostname, stack []config.Hostname) (config.Hostname, bool) { +func MostSpecificHostMatch(needle host.Name, stack []host.Name) (host.Name, bool) { for _, h := range stack { if needle.Matches(h) { return h, true diff --git a/pilot/pkg/model/config_test.go b/pilot/pkg/model/config_test.go index 072935d5ac63..31fbb07aa407 100644 --- a/pilot/pkg/model/config_test.go +++ b/pilot/pkg/model/config_test.go @@ -33,8 +33,8 @@ import ( "istio.io/istio/pilot/pkg/config/memory" "istio.io/istio/pilot/pkg/model" mock_config "istio.io/istio/pilot/test/mock" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" ) @@ -196,9 +196,9 @@ func TestServiceKey(t *testing.T) { } func TestSubsetKey(t *testing.T) { - hostname := config.Hostname("hostname") + hostname := host.Name("hostname") cases := []struct { - hostname config.Hostname + hostname host.Name subset string port int want string @@ -269,7 +269,7 @@ func TestResolveHostname(t *testing.T) { cases := []struct { meta model.ConfigMeta svc *mccpb.IstioService - want config.Hostname + want host.Name }{ { meta: model.ConfigMeta{Namespace: "default", Domain: "cluster.local"}, @@ -385,7 +385,7 @@ func TestAuthenticationPolicyConfig(t *testing.T) { } cases := []struct { - hostname config.Hostname + hostname host.Name namespace string port int expected string @@ -508,7 +508,7 @@ func TestAuthenticationPolicyConfigWithGlobal(t *testing.T) { } cases := []struct { - hostname config.Hostname + hostname host.Name namespace string port int expected *authn.Policy @@ -573,7 +573,7 @@ func TestResolveShortnameToFQDN(t *testing.T) { tests := []struct { name string meta model.ConfigMeta - out config.Hostname + out host.Name }{ { "*", model.ConfigMeta{}, "*", @@ -606,24 +606,24 @@ func TestResolveShortnameToFQDN(t *testing.T) { func TestMostSpecificHostMatch(t *testing.T) { tests := []struct { - in []config.Hostname - needle config.Hostname - want config.Hostname + in []host.Name + needle host.Name + want host.Name }{ // this has to be a sorted list - {[]config.Hostname{}, "*", ""}, - {[]config.Hostname{"*.foo.com", "*.com"}, "bar.foo.com", "*.foo.com"}, - {[]config.Hostname{"*.foo.com", "*.com"}, "foo.com", "*.com"}, - {[]config.Hostname{"foo.com", "*.com"}, "*.foo.com", "*.com"}, + {[]host.Name{}, "*", ""}, + {[]host.Name{"*.foo.com", "*.com"}, "bar.foo.com", "*.foo.com"}, + {[]host.Name{"*.foo.com", "*.com"}, "foo.com", "*.com"}, + {[]host.Name{"foo.com", "*.com"}, "*.foo.com", "*.com"}, - {[]config.Hostname{"*.foo.com", "foo.com"}, "foo.com", "foo.com"}, - {[]config.Hostname{"*.foo.com", "foo.com"}, "*.foo.com", "*.foo.com"}, + {[]host.Name{"*.foo.com", "foo.com"}, "foo.com", "foo.com"}, + {[]host.Name{"*.foo.com", "foo.com"}, "*.foo.com", "*.foo.com"}, // this passes because we sort alphabetically - {[]config.Hostname{"bar.com", "foo.com"}, "*.com", "bar.com"}, + {[]host.Name{"bar.com", "foo.com"}, "*.com", "bar.com"}, - {[]config.Hostname{"bar.com", "*.foo.com"}, "*foo.com", "*.foo.com"}, - {[]config.Hostname{"foo.com", "*.foo.com"}, "*foo.com", "foo.com"}, + {[]host.Name{"bar.com", "*.foo.com"}, "*foo.com", "*.foo.com"}, + {[]host.Name{"foo.com", "*.foo.com"}, "*foo.com", "foo.com"}, } for idx, tt := range tests { @@ -836,7 +836,7 @@ func TestIstioConfigStore_QuotaSpecByDestination(t *testing.T) { ii := model.MakeIstioStore(l) cfgs := ii.QuotaSpecByDestination(&model.ServiceInstance{ Service: &model.Service{ - Hostname: config.Hostname("a." + ns + ".svc.cluster.local"), + Hostname: host.Name("a." + ns + ".svc.cluster.local"), }, }) @@ -1104,7 +1104,7 @@ func TestIstioConfigStore_HTTPAPISpecByDestination(t *testing.T) { ii := model.MakeIstioStore(l) cfgs := ii.HTTPAPISpecByDestination(&model.ServiceInstance{ Service: &model.Service{ - Hostname: config.Hostname("foo." + ns + ".svc.cluster.local"), + Hostname: host.Name("foo." + ns + ".svc.cluster.local"), }, }) diff --git a/pilot/pkg/model/destination_rule.go b/pilot/pkg/model/destination_rule.go index e192eba11e29..4cf2936e2e49 100644 --- a/pilot/pkg/model/destination_rule.go +++ b/pilot/pkg/model/destination_rule.go @@ -18,7 +18,8 @@ import ( "fmt" networking "istio.io/api/networking/v1alpha3" - "istio.io/istio/pkg/config" + + "istio.io/istio/pkg/config/host" ) // This function merges one or more destination rules for a given host string @@ -26,9 +27,9 @@ import ( // IOW, given three dest rules (*.foo.com, *.foo.com, *.com), calling this function for // each config will result in a final dest rule set (*.foo.com, and *.com). func (ps *PushContext) combineSingleDestinationRule( - combinedDestRuleHosts []config.Hostname, - combinedDestRuleMap map[config.Hostname]*combinedDestinationRule, - destRuleConfig Config) []config.Hostname { + combinedDestRuleHosts []host.Name, + combinedDestRuleMap map[host.Name]*combinedDestinationRule, + destRuleConfig Config) []host.Name { rule := destRuleConfig.Spec.(*networking.DestinationRule) resolvedHost := ResolveShortnameToFQDN(rule.Host, destRuleConfig.ConfigMeta) diff --git a/pilot/pkg/model/push_context.go b/pilot/pkg/model/push_context.go index d8529fa6456e..26d67167ef61 100644 --- a/pilot/pkg/model/push_context.go +++ b/pilot/pkg/model/push_context.go @@ -22,8 +22,8 @@ import ( networking "istio.io/api/networking/v1alpha3" "istio.io/istio/pilot/pkg/monitoring" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/config/visibility" @@ -78,7 +78,7 @@ type PushContext struct { // Namespace specific views do not apply here. // ServiceByHostnameAndNamespace has all services, indexed by hostname then namesace. - ServiceByHostnameAndNamespace map[config.Hostname]map[string]*Service `json:"-"` + ServiceByHostnameAndNamespace map[host.Name]map[string]*Service `json:"-"` // AuthzPolicies stores the existing authorization policies in the cluster. Could be nil if there // are no authorization policies in the cluster. @@ -88,16 +88,16 @@ type PushContext struct { Env *Environment `json:"-"` // ServiceAccounts contains a map of hostname and port to service accounts. - ServiceAccounts map[config.Hostname]map[int][]string `json:"-"` + ServiceAccounts map[host.Name]map[int][]string `json:"-"` initDone bool } type processedDestRules struct { // List of dest rule hosts. We match with the most specific host first - hosts []config.Hostname + hosts []host.Name // Map of dest rule host and the merged destination rules for that host - destRule map[config.Hostname]*combinedDestinationRule + destRule map[host.Name]*combinedDestinationRule } // XDSUpdater is used for direct updates of the xDS model and incremental push. @@ -301,15 +301,15 @@ func NewPushContext() *PushContext { namespaceLocalDestRules: map[string]*processedDestRules{}, namespaceExportedDestRules: map[string]*processedDestRules{}, allExportedDestRules: &processedDestRules{ - hosts: make([]config.Hostname, 0), - destRule: map[config.Hostname]*combinedDestinationRule{}, + hosts: make([]host.Name, 0), + destRule: map[host.Name]*combinedDestinationRule{}, }, sidecarsByNamespace: map[string][]*SidecarScope{}, envoyFiltersByNamespace: map[string][]*EnvoyFilterWrapper{}, - ServiceByHostnameAndNamespace: map[config.Hostname]map[string]*Service{}, + ServiceByHostnameAndNamespace: map[host.Name]map[string]*Service{}, ProxyStatus: map[string]map[string]ProxyPushStatus{}, - ServiceAccounts: map[config.Hostname]map[int][]string{}, + ServiceAccounts: map[host.Name]map[int][]string{}, } } @@ -396,7 +396,7 @@ func (ps *PushContext) VirtualServices(proxy *Proxy, gateways map[string]bool) [ } } else { for _, g := range rule.Gateways { - // note: Gateway names do _not_ use wildcard matching, so we do not use Hostname.Matches here + // note: Gateway names do _not_ use wildcard matching, so we do not use Name.Matches here if gateways[resolveGatewayName(g, cfg.ConfigMeta)] { out = append(out, cfg) break @@ -475,8 +475,8 @@ func (ps *PushContext) GetAllSidecarScopes() map[string][]*SidecarScope { func (ps *PushContext) DestinationRule(proxy *Proxy, service *Service) *Config { // FIXME: this code should be removed once the EDS issue is fixed if proxy == nil { - if host, ok := MostSpecificHostMatch(service.Hostname, ps.allExportedDestRules.hosts); ok { - return ps.allExportedDestRules.destRule[host].config + if hostname, ok := MostSpecificHostMatch(service.Hostname, ps.allExportedDestRules.hosts); ok { + return ps.allExportedDestRules.destRule[hostname].config } return nil } @@ -500,9 +500,9 @@ func (ps *PushContext) DestinationRule(proxy *Proxy, service *Service) *Config { if proxy.ConfigNamespace != ps.Env.Mesh.RootNamespace { // search through the DestinationRules in proxy's namespace first if ps.namespaceLocalDestRules[proxy.ConfigNamespace] != nil { - if host, ok := MostSpecificHostMatch(service.Hostname, + if hostname, ok := MostSpecificHostMatch(service.Hostname, ps.namespaceLocalDestRules[proxy.ConfigNamespace].hosts); ok { - return ps.namespaceLocalDestRules[proxy.ConfigNamespace].destRule[host].config + return ps.namespaceLocalDestRules[proxy.ConfigNamespace].destRule[hostname].config } } } @@ -510,9 +510,9 @@ func (ps *PushContext) DestinationRule(proxy *Proxy, service *Service) *Config { // if no private/public rule matched in the calling proxy's namespace, // check the target service's namespace for public rules if service.Attributes.Namespace != "" && ps.namespaceExportedDestRules[service.Attributes.Namespace] != nil { - if host, ok := MostSpecificHostMatch(service.Hostname, + if hostname, ok := MostSpecificHostMatch(service.Hostname, ps.namespaceExportedDestRules[service.Attributes.Namespace].hosts); ok { - return ps.namespaceExportedDestRules[service.Attributes.Namespace].destRule[host].config + return ps.namespaceExportedDestRules[service.Attributes.Namespace].destRule[hostname].config } } @@ -520,9 +520,9 @@ func (ps *PushContext) DestinationRule(proxy *Proxy, service *Service) *Config { // target service's namespace matched, search for any public destination rule in the config root namespace // NOTE: This does mean that we are effectively ignoring private dest rules in the config root namespace if ps.namespaceExportedDestRules[ps.Env.Mesh.RootNamespace] != nil { - if host, ok := MostSpecificHostMatch(service.Hostname, + if hostname, ok := MostSpecificHostMatch(service.Hostname, ps.namespaceExportedDestRules[ps.Env.Mesh.RootNamespace].hosts); ok { - return ps.namespaceExportedDestRules[ps.Env.Mesh.RootNamespace].destRule[host].config + return ps.namespaceExportedDestRules[ps.Env.Mesh.RootNamespace].destRule[hostname].config } } @@ -530,7 +530,7 @@ func (ps *PushContext) DestinationRule(proxy *Proxy, service *Service) *Config { } // SubsetToLabels returns the labels associated with a subset of a given service. -func (ps *PushContext) SubsetToLabels(proxy *Proxy, subsetName string, hostname config.Hostname) labels.Collection { +func (ps *PushContext) SubsetToLabels(proxy *Proxy, subsetName string, hostname host.Name) labels.Collection { // empty subset if subsetName == "" { return nil @@ -886,8 +886,8 @@ func (ps *PushContext) SetDestinationRules(configs []Config) { namespaceLocalDestRules := make(map[string]*processedDestRules) namespaceExportedDestRules := make(map[string]*processedDestRules) allExportedDestRules := &processedDestRules{ - hosts: make([]config.Hostname, 0), - destRule: map[config.Hostname]*combinedDestinationRule{}, + hosts: make([]host.Name, 0), + destRule: map[host.Name]*combinedDestinationRule{}, } for i := range configs { @@ -900,8 +900,8 @@ func (ps *PushContext) SetDestinationRules(configs []Config) { // The global exportTo doesn't matter here (its either . or * - both of which are applicable here) if _, exist := namespaceLocalDestRules[configs[i].Namespace]; !exist { namespaceLocalDestRules[configs[i].Namespace] = &processedDestRules{ - hosts: make([]config.Hostname, 0), - destRule: map[config.Hostname]*combinedDestinationRule{}, + hosts: make([]host.Name, 0), + destRule: map[host.Name]*combinedDestinationRule{}, } } // Merge this destination rule with any public/private dest rules for same host in the same namespace @@ -931,8 +931,8 @@ func (ps *PushContext) SetDestinationRules(configs []Config) { if isPubliclyExported { if _, exist := namespaceExportedDestRules[configs[i].Namespace]; !exist { namespaceExportedDestRules[configs[i].Namespace] = &processedDestRules{ - hosts: make([]config.Hostname, 0), - destRule: map[config.Hostname]*combinedDestinationRule{}, + hosts: make([]host.Name, 0), + destRule: map[host.Name]*combinedDestinationRule{}, } } // Merge this destination rule with any public dest rule for the same host in the same namespace @@ -952,12 +952,12 @@ func (ps *PushContext) SetDestinationRules(configs []Config) { // presort it so that we don't sort it for each DestinationRule call. // sort.Sort for Hostnames will automatically sort from the most specific to least specific for ns := range namespaceLocalDestRules { - sort.Sort(config.Hostnames(namespaceLocalDestRules[ns].hosts)) + sort.Sort(host.Names(namespaceLocalDestRules[ns].hosts)) } for ns := range namespaceExportedDestRules { - sort.Sort(config.Hostnames(namespaceExportedDestRules[ns].hosts)) + sort.Sort(host.Names(namespaceExportedDestRules[ns].hosts)) } - sort.Sort(config.Hostnames(allExportedDestRules.hosts)) + sort.Sort(host.Names(allExportedDestRules.hosts)) ps.namespaceLocalDestRules = namespaceLocalDestRules ps.namespaceExportedDestRules = namespaceExportedDestRules diff --git a/pilot/pkg/model/service.go b/pilot/pkg/model/service.go index cd16cf6d76d4..3690e5381935 100644 --- a/pilot/pkg/model/service.go +++ b/pilot/pkg/model/service.go @@ -35,7 +35,7 @@ import ( authn "istio.io/api/authentication/v1alpha1" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/config/visibility" @@ -52,8 +52,8 @@ import ( // foo.default.svc.cluster.local hostname, has a virtual IP of 10.0.1.1 and // listens on ports 80, 8080 type Service struct { - // Hostname of the service, e.g. "catalog.mystore.com" - Hostname config.Hostname `json:"hostname"` + // Name of the service, e.g. "catalog.mystore.com" + Hostname host.Name `json:"hostname"` // Address specifies the service IPv4 address of the load balancer Address string `json:"address,omitempty"` @@ -372,7 +372,7 @@ type ServiceDiscovery interface { // GetService retrieves a service by host name if it exists // Deprecated - do not use for anything other than tests - GetService(hostname config.Hostname) (*Service, error) + GetService(hostname host.Name) (*Service, error) // InstancesByPort retrieves instances for a service on the given ports with labels that match // any of the supplied labels. All instances match an empty tag list. @@ -500,9 +500,9 @@ func (s *Service) Key(port *Port, l labels.Instance) string { // ServiceKey generates a service key for a collection of ports and labels // Deprecated // -// Interface wants to turn `Hostname` into `fmt.Stringer`, completely defeating the purpose of the type alias. +// Interface wants to turn `Name` into `fmt.Stringer`, completely defeating the purpose of the type alias. // nolint: interfacer -func ServiceKey(hostname config.Hostname, servicePorts PortList, labelsList labels.Collection) string { +func ServiceKey(hostname host.Name, servicePorts PortList, labelsList labels.Collection) string { // example: name.namespace|http|env=prod;env=test,version=my-v1 var buffer bytes.Buffer buffer.WriteString(string(hostname)) @@ -554,9 +554,9 @@ func ServiceKey(hostname config.Hostname, servicePorts PortList, labelsList labe // ParseServiceKey is the inverse of the Service.String() method // Deprecated -func ParseServiceKey(s string) (hostname config.Hostname, ports PortList, lc labels.Collection) { +func ParseServiceKey(s string) (hostname host.Name, ports PortList, lc labels.Collection) { parts := strings.Split(s, "|") - hostname = config.Hostname(parts[0]) + hostname = host.Name(parts[0]) var names []string if len(parts) > 1 { @@ -579,7 +579,7 @@ func ParseServiceKey(s string) (hostname config.Hostname, ports PortList, lc lab // BuildSubsetKey generates a unique string referencing service instances for a given service name, a subset and a port. // The proxy queries Pilot with this key to obtain the list of instances in a subset. -func BuildSubsetKey(direction TrafficDirection, subsetName string, hostname config.Hostname, port int) string { +func BuildSubsetKey(direction TrafficDirection, subsetName string, hostname host.Name, port int) string { return fmt.Sprintf("%s|%d|%s|%s", direction, port, subsetName, hostname) } @@ -587,7 +587,7 @@ func BuildSubsetKey(direction TrafficDirection, subsetName string, hostname conf // The proxy queries Pilot with this key to obtain the list of instances in a subset. // This is used only for the SNI-DNAT router. Do not use for other purposes. // The DNS Srv format of the cluster is also used as the default SNI string for Istio mTLS connections -func BuildDNSSrvSubsetKey(direction TrafficDirection, subsetName string, hostname config.Hostname, port int) string { +func BuildDNSSrvSubsetKey(direction TrafficDirection, subsetName string, hostname host.Name, port int) string { return fmt.Sprintf("%s_.%d_.%s_.%s", direction, port, subsetName, hostname) } @@ -597,7 +597,7 @@ func IsValidSubsetKey(s string) bool { } // ParseSubsetKey is the inverse of the BuildSubsetKey method -func ParseSubsetKey(s string) (direction TrafficDirection, subsetName string, hostname config.Hostname, port int) { +func ParseSubsetKey(s string) (direction TrafficDirection, subsetName string, hostname host.Name, port int) { var parts []string dnsSrvMode := false // This could be the DNS srv form of the cluster that uses outbound_.port_.subset_.hostname @@ -623,7 +623,7 @@ func ParseSubsetKey(s string) (direction TrafficDirection, subsetName string, ho subsetName = strings.TrimSuffix(parts[2], "_") } - hostname = config.Hostname(parts[3]) + hostname = host.Name(parts[3]) return } diff --git a/pilot/pkg/model/service_test.go b/pilot/pkg/model/service_test.go index b1c573311adc..66266438b845 100644 --- a/pilot/pkg/model/service_test.go +++ b/pilot/pkg/model/service_test.go @@ -17,7 +17,7 @@ package model import ( "testing" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -138,7 +138,7 @@ func TestParseSubsetKey(t *testing.T) { input string direction TrafficDirection subsetName string - hostname config.Hostname + hostname host.Name port int }{ {"outbound|80|v1|example.com", TrafficDirectionOutbound, "v1", "example.com", 80}, diff --git a/pilot/pkg/model/sidecar.go b/pilot/pkg/model/sidecar.go index a4293cf751cb..0b6e78dcd7e1 100644 --- a/pilot/pkg/model/sidecar.go +++ b/pilot/pkg/model/sidecar.go @@ -20,14 +20,15 @@ import ( xdsapi "github.com/envoyproxy/go-control-plane/envoy/api/v2" networking "istio.io/api/networking/v1alpha3" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" ) const ( wildcardNamespace = "*" currentNamespace = "." - wildcardService = config.Hostname("*") + wildcardService = host.Name("*") ) // SidecarScope is a wrapper over the Sidecar resource with some @@ -77,11 +78,11 @@ type SidecarScope struct { // corresponds to a service in the services array above. When computing // CDS, we simply have to find the matching service and return the // destination rule. - destinationRules map[config.Hostname]*Config + destinationRules map[host.Name]*Config // A given hostname should only be considered in a single namespace. This mapping determines which // namespace a hostname exists in - NamespaceForHostname map[config.Hostname]string + NamespaceForHostname map[host.Name]string // CDSOutboundClusters is the CDS output for sidecars that map to this // sidecarScope object. Contains the outbound clusters only, indexed @@ -107,10 +108,10 @@ type IstioEgressListenerWrapper struct { // The hosts field has entries of the form namespace/dnsName. For // example ns1/*, */*, */foo.tcp.com, etc. This map preprocesses all // these string fields into a map of namespace and services. - // We cannot use a map of Hostnames because Hostname match allows + // We cannot use a map of Hostnames because Name match allows // wildcard matching semantics (i.e. foo.bar.com will match import like *.com). // Go's map/hash data structure doesn't do such semantic matches - listenerHosts map[string][]config.Hostname + listenerHosts map[string][]host.Name // List of services imported by this egress listener extracted from the // listenerHosts above. This will be used by LDS and RDS code when @@ -135,8 +136,8 @@ type IstioEgressListenerWrapper struct { virtualServices []Config } -func createNamespaceForHostname(egress []*IstioEgressListenerWrapper) map[config.Hostname]string { - var namespaceForHostname = make(map[config.Hostname]string) +func createNamespaceForHostname(egress []*IstioEgressListenerWrapper) map[host.Name]string { + var namespaceForHostname = make(map[host.Name]string) for _, egress := range egress { for _, svc := range egress.Services() { if _, f := namespaceForHostname[svc.Hostname]; !f { @@ -156,7 +157,7 @@ func DefaultSidecarScopeForNamespace(ps *PushContext, configNamespace string) *S } defaultEgressListener := &IstioEgressListenerWrapper{ - listenerHosts: map[string][]config.Hostname{wildcardNamespace: {wildcardService}}, + listenerHosts: map[string][]host.Name{wildcardNamespace: {wildcardService}}, } defaultEgressListener.services = ps.Services(&dummyNode) @@ -166,7 +167,7 @@ func DefaultSidecarScopeForNamespace(ps *PushContext, configNamespace string) *S out := &SidecarScope{ EgressListeners: []*IstioEgressListenerWrapper{defaultEgressListener}, services: defaultEgressListener.services, - destinationRules: make(map[config.Hostname]*Config), + destinationRules: make(map[host.Name]*Config), } out.NamespaceForHostname = createNamespaceForHostname(out.EgressListeners) @@ -223,7 +224,7 @@ func ConvertToSidecarScope(ps *PushContext, sidecarConfig *Config, configNamespa // Now that we have all the services that sidecars using this scope (in // this config namespace) will see, identify all the destinationRules // that these services need - out.destinationRules = make(map[config.Hostname]*Config) + out.destinationRules = make(map[host.Name]*Config) for _, s := range out.services { out.destinationRules[s.Hostname] = ps.DestinationRule(&dummyNode, s) } @@ -251,7 +252,7 @@ func convertIstioListenerToWrapper(ps *PushContext, configNamespace string, out := &IstioEgressListenerWrapper{ IstioListener: istioListener, - listenerHosts: make(map[string][]config.Hostname), + listenerHosts: make(map[string][]host.Name), } if istioListener.Hosts != nil { @@ -261,10 +262,10 @@ func convertIstioListenerToWrapper(ps *PushContext, configNamespace string, parts[0] = configNamespace } if _, exists := out.listenerHosts[parts[0]]; !exists { - out.listenerHosts[parts[0]] = make([]config.Hostname, 0) + out.listenerHosts[parts[0]] = make([]host.Name, 0) } - out.listenerHosts[parts[0]] = append(out.listenerHosts[parts[0]], config.Hostname(parts[1])) + out.listenerHosts[parts[0]] = append(out.listenerHosts[parts[0]], host.Name(parts[1])) } } @@ -280,7 +281,7 @@ func convertIstioListenerToWrapper(ps *PushContext, configNamespace string, } // ServiceForHostname returns the service associated with a given hostname following SidecarScope -func (sc *SidecarScope) ServiceForHostname(hostname config.Hostname, serviceByHostname map[config.Hostname]map[string]*Service) *Service { +func (sc *SidecarScope) ServiceForHostname(hostname host.Name, serviceByHostname map[host.Name]map[string]*Service) *Service { // SidecarScope shouldn't be null here. If it is, we can't disambiguate the hostname to use for a namespace, // so the selection must be undefined. if sc == nil { @@ -311,7 +312,7 @@ func (sc *SidecarScope) Services() []*Service { // DestinationRule returns the destination rule applicable for a given hostname // used by CDS code -func (sc *SidecarScope) DestinationRule(hostname config.Hostname) *Config { +func (sc *SidecarScope) DestinationRule(hostname host.Name) *Config { if sc == nil { return nil } @@ -403,7 +404,7 @@ func (ilw *IstioEgressListenerWrapper) selectVirtualServices(virtualServices []C // TODO: This is a bug. VirtualServices can have many hosts // while the user might be importing only a single host // We need to generate a new VirtualService with just the matched host - if importedHost.Matches(config.Hostname(h)) { + if importedHost.Matches(host.Name(h)) { importedVirtualServices = append(importedVirtualServices, c) hostFound = true break @@ -425,7 +426,7 @@ func (ilw *IstioEgressListenerWrapper) selectVirtualServices(virtualServices []C // TODO: This is a bug. VirtualServices can have many hosts // while the user might be importing only a single host // We need to generate a new VirtualService with just the matched host - if importedHost.Matches(config.Hostname(h)) { + if importedHost.Matches(host.Name(h)) { importedVirtualServices = append(importedVirtualServices, c) hostFound = true break @@ -483,7 +484,7 @@ func (ilw *IstioEgressListenerWrapper) selectServices(services []*Service, confi } } - var validServices = make(map[config.Hostname]string) + var validServices = make(map[host.Name]string) for _, svc := range importedServices { _, f := validServices[svc.Hostname] // Select a single namespace for a given hostname. @@ -494,7 +495,7 @@ func (ilw *IstioEgressListenerWrapper) selectServices(services []*Service, confi } } - filteredServices := []*Service{} + filteredServices := make([]*Service, 0) // Filter down to just instances in scope for the service for _, i := range importedServices { if validServices[i.Hostname] == i.Attributes.Namespace { diff --git a/pilot/pkg/model/sidecar_test.go b/pilot/pkg/model/sidecar_test.go index e83255217bb1..221fe808dc5f 100644 --- a/pilot/pkg/model/sidecar_test.go +++ b/pilot/pkg/model/sidecar_test.go @@ -24,7 +24,7 @@ import ( "istio.io/api/mesh/v1alpha1" networking "istio.io/api/networking/v1alpha3" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/mesh" ) @@ -219,13 +219,13 @@ func TestCreateSidecarScope(t *testing.T) { if sidecarConfig != nil { a := sidecarConfig.Spec.(*networking.Sidecar) for _, egress := range a.Egress { - for _, host := range egress.Hosts { - parts := strings.SplitN(host, "/", 2) + for _, egressHost := range egress.Hosts { + parts := strings.SplitN(egressHost, "/", 2) found = false for _, listeners := range sidecarScope.EgressListeners { if sidecarScopeHosts, ok := listeners.listenerHosts[parts[0]]; ok { for _, sidecarScopeHost := range sidecarScopeHosts { - if sidecarScopeHost == config.Hostname(parts[1]) && + if sidecarScopeHost == host.Name(parts[1]) && listeners.IstioListener.Port == egress.Port { found = true break @@ -237,7 +237,7 @@ func TestCreateSidecarScope(t *testing.T) { } } if !found { - t.Errorf("Did not find %v entry in any listener", host) + t.Errorf("Did not find %v entry in any listener", egressHost) } } } @@ -309,56 +309,56 @@ func TestIstioEgressListenerWrapper(t *testing.T) { tests := []struct { name string - listenerHosts map[string][]config.Hostname + listenerHosts map[string][]host.Name services []*Service expected []*Service namespace string }{ { name: "*/* imports only those in a", - listenerHosts: map[string][]config.Hostname{wildcardNamespace: {wildcardService}}, + listenerHosts: map[string][]host.Name{wildcardNamespace: {wildcardService}}, services: allServices, expected: []*Service{serviceA8000, serviceA9000, serviceAalt}, namespace: "a", }, { name: "*/* will bias towards configNamespace", - listenerHosts: map[string][]config.Hostname{wildcardNamespace: {wildcardService}}, + listenerHosts: map[string][]host.Name{wildcardNamespace: {wildcardService}}, services: []*Service{serviceB8000, serviceB9000, serviceBalt, serviceA8000, serviceA9000, serviceAalt}, expected: []*Service{serviceA8000, serviceA9000, serviceAalt}, namespace: "a", }, { name: "a/* imports only those in a", - listenerHosts: map[string][]config.Hostname{"a": {wildcardService}}, + listenerHosts: map[string][]host.Name{"a": {wildcardService}}, services: allServices, expected: []*Service{serviceA8000, serviceA9000, serviceAalt}, namespace: "a", }, { name: "b/*, b/* imports only those in b", - listenerHosts: map[string][]config.Hostname{"b": {wildcardService, wildcardService}}, + listenerHosts: map[string][]host.Name{"b": {wildcardService, wildcardService}}, services: allServices, expected: []*Service{serviceB8000, serviceB9000, serviceBalt}, namespace: "a", }, { name: "*/alt imports alt in namespace a", - listenerHosts: map[string][]config.Hostname{wildcardNamespace: {"alt"}}, + listenerHosts: map[string][]host.Name{wildcardNamespace: {"alt"}}, services: allServices, expected: []*Service{serviceAalt}, namespace: "a", }, { name: "b/alt imports alt in a namespaces", - listenerHosts: map[string][]config.Hostname{"b": {"alt"}}, + listenerHosts: map[string][]host.Name{"b": {"alt"}}, services: allServices, expected: []*Service{serviceBalt}, namespace: "a", }, { name: "b/* imports doesn't import in namespace a with proxy in a", - listenerHosts: map[string][]config.Hostname{"b": {wildcardService}}, + listenerHosts: map[string][]host.Name{"b": {wildcardService}}, services: []*Service{serviceA8000}, expected: []*Service{}, namespace: "a", diff --git a/pilot/pkg/networking/core/v1alpha3/cluster_test.go b/pilot/pkg/networking/core/v1alpha3/cluster_test.go index 607d9d866e74..66b5b5e96e2c 100644 --- a/pilot/pkg/networking/core/v1alpha3/cluster_test.go +++ b/pilot/pkg/networking/core/v1alpha3/cluster_test.go @@ -35,8 +35,8 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/networking/core/v1alpha3/fakes" "istio.io/istio/pilot/pkg/networking/plugin" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/protocol" ) @@ -193,7 +193,7 @@ func buildTestClustersWithProxyMetadata(serviceHostname string, serviceResolutio Protocol: protocol.HTTP, } service := &model.Service{ - Hostname: config.Hostname(serviceHostname), + Hostname: host.Name(serviceHostname), Address: "1.1.1.1", ClusterVIPs: make(map[string]string), Ports: model.PortList{servicePort}, @@ -817,7 +817,7 @@ func TestBuildLocalityLbEndpoints(t *testing.T) { Protocol: protocol.HTTP, } service := &model.Service{ - Hostname: config.Hostname("*.example.org"), + Hostname: host.Name("*.example.org"), Address: "1.1.1.1", ClusterVIPs: make(map[string]string), Ports: model.PortList{servicePort}, @@ -958,7 +958,7 @@ func TestRedisProtocolWithPassThroughResolution(t *testing.T) { Protocol: protocol.Redis, } service := &model.Service{ - Hostname: config.Hostname("redis.com"), + Hostname: host.Name("redis.com"), Address: "1.1.1.1", ClusterVIPs: make(map[string]string), Ports: model.PortList{servicePort}, @@ -996,7 +996,7 @@ func TestRedisProtocolCluster(t *testing.T) { Protocol: protocol.Redis, } service := &model.Service{ - Hostname: config.Hostname("redis.com"), + Hostname: host.Name("redis.com"), Address: "1.1.1.1", ClusterVIPs: make(map[string]string), Ports: model.PortList{servicePort}, diff --git a/pilot/pkg/networking/core/v1alpha3/envoyfilter/cluster_patch.go b/pilot/pkg/networking/core/v1alpha3/envoyfilter/cluster_patch.go index 9e66f276c633..c24b1119d80f 100644 --- a/pilot/pkg/networking/core/v1alpha3/envoyfilter/cluster_patch.go +++ b/pilot/pkg/networking/core/v1alpha3/envoyfilter/cluster_patch.go @@ -19,8 +19,9 @@ import ( "github.com/gogo/protobuf/proto" networking "istio.io/api/networking/v1alpha3" + "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" ) // ApplyClusterPatches applies patches to CDS clusters @@ -85,13 +86,13 @@ func clusterMatch(cluster *xdsapi.Cluster, cp *model.EnvoyFilterConfigPatchWrapp return cMatch.Name == cluster.Name } - _, subset, host, port := model.ParseSubsetKey(cluster.Name) + _, subset, hostname, port := model.ParseSubsetKey(cluster.Name) if cMatch.Subset != "" && cMatch.Subset != subset { return false } - if cMatch.Service != "" && config.Hostname(cMatch.Service) != host { + if cMatch.Service != "" && host.Name(cMatch.Service) != hostname { return false } diff --git a/pilot/pkg/networking/core/v1alpha3/fakes/fake_service_discovery.go b/pilot/pkg/networking/core/v1alpha3/fakes/fake_service_discovery.go index aedc300db638..989c4cc6b353 100644 --- a/pilot/pkg/networking/core/v1alpha3/fakes/fake_service_discovery.go +++ b/pilot/pkg/networking/core/v1alpha3/fakes/fake_service_discovery.go @@ -5,7 +5,7 @@ import ( "sync" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -21,10 +21,10 @@ type ServiceDiscovery struct { result1 []*model.Service result2 error } - GetServiceStub func(hostname config.Hostname) (*model.Service, error) + GetServiceStub func(hostname host.Name) (*model.Service, error) getServiceMutex sync.RWMutex getServiceArgsForCall []struct { - hostname config.Hostname + hostname host.Name } getServiceReturns struct { result1 *model.Service @@ -156,11 +156,11 @@ func (fake *ServiceDiscovery) ServicesReturnsOnCall(i int, result1 []*model.Serv }{result1, result2} } -func (fake *ServiceDiscovery) GetService(hostname config.Hostname) (*model.Service, error) { +func (fake *ServiceDiscovery) GetService(hostname host.Name) (*model.Service, error) { fake.getServiceMutex.Lock() ret, specificReturn := fake.getServiceReturnsOnCall[len(fake.getServiceArgsForCall)] fake.getServiceArgsForCall = append(fake.getServiceArgsForCall, struct { - hostname config.Hostname + hostname host.Name }{hostname}) fake.recordInvocation("GetService", []interface{}{hostname}) fake.getServiceMutex.Unlock() @@ -179,7 +179,7 @@ func (fake *ServiceDiscovery) GetServiceCallCount() int { return len(fake.getServiceArgsForCall) } -func (fake *ServiceDiscovery) GetServiceArgsForCall(i int) config.Hostname { +func (fake *ServiceDiscovery) GetServiceArgsForCall(i int) host.Name { fake.getServiceMutex.RLock() defer fake.getServiceMutex.RUnlock() return fake.getServiceArgsForCall[i].hostname diff --git a/pilot/pkg/networking/core/v1alpha3/gateway.go b/pilot/pkg/networking/core/v1alpha3/gateway.go index 148976c55746..2a5bf2ab83c6 100644 --- a/pilot/pkg/networking/core/v1alpha3/gateway.go +++ b/pilot/pkg/networking/core/v1alpha3/gateway.go @@ -37,6 +37,7 @@ import ( "istio.io/istio/pilot/pkg/networking/util" authn_model "istio.io/istio/pilot/pkg/security/model" "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/proto" @@ -232,18 +233,18 @@ func (configgen *ConfigGeneratorImpl) buildGatewayHTTPRouteConfig(env *model.Env servers := merged.ServersByRouteName[routeName] port := int(servers[0].Port.Number) // all these servers are for the same routeName, and therefore same port - nameToServiceMap := make(map[config.Hostname]*model.Service, len(services)) + nameToServiceMap := make(map[host.Name]*model.Service, len(services)) for _, svc := range services { nameToServiceMap[svc.Hostname] = svc } - vHostDedupMap := make(map[config.Hostname]*route.VirtualHost) + vHostDedupMap := make(map[host.Name]*route.VirtualHost) for _, server := range servers { gatewayName := merged.GatewayNameForServer[server] virtualServices := push.VirtualServices(node, map[string]bool{gatewayName: true}) for _, virtualService := range virtualServices { - virtualServiceHosts := config.StringsToHostnames(virtualService.Spec.(*networking.VirtualService).Hosts) - serverHosts := config.HostnamesForNamespace(server.Hosts, virtualService.Namespace) + virtualServiceHosts := host.NewNames(virtualService.Spec.(*networking.VirtualService).Hosts) + serverHosts := host.NamesForNamespace(server.Hosts, virtualService.Namespace) // We have two cases here: // 1. virtualService hosts are 1.foo.com, 2.foo.com, 3.foo.com and server hosts are ns/*.foo.com @@ -259,19 +260,19 @@ func (configgen *ConfigGeneratorImpl) buildGatewayHTTPRouteConfig(env *model.Env continue } - for _, host := range intersectingHosts { - if vHost, exists := vHostDedupMap[host]; exists { + for _, hostname := range intersectingHosts { + if vHost, exists := vHostDedupMap[hostname]; exists { vHost.Routes = istio_route.CombineVHostRoutes(vHost.Routes, routes) } else { newVHost := &route.VirtualHost{ - Name: fmt.Sprintf("%s:%d", host, port), - Domains: []string{string(host), fmt.Sprintf("%s:%d", host, port)}, + Name: fmt.Sprintf("%s:%d", hostname, port), + Domains: []string{string(hostname), fmt.Sprintf("%s:%d", hostname, port)}, Routes: routes, } if server.Tls != nil && server.Tls.HttpsRedirect { newVHost.RequireTls = route.VirtualHost_ALL } - vHostDedupMap[host] = newVHost + vHostDedupMap[hostname] = newVHost } } } @@ -565,9 +566,9 @@ func buildGatewayNetworkFiltersFromTCPRoutes(node *model.Proxy, env *model.Envir Protocol: protocol.Parse(server.Port.Protocol), } - gatewayServerHosts := make(map[config.Hostname]bool, len(server.Hosts)) - for _, host := range server.Hosts { - gatewayServerHosts[config.Hostname(host)] = true + gatewayServerHosts := make(map[host.Name]bool, len(server.Hosts)) + for _, hostname := range server.Hosts { + gatewayServerHosts[host.Name(hostname)] = true } virtualServices := push.VirtualServices(node, gatewaysForWorkload) @@ -607,9 +608,9 @@ func buildGatewayNetworkFiltersFromTLSRoutes(node *model.Proxy, env *model.Envir Protocol: protocol.Parse(server.Port.Protocol), } - gatewayServerHosts := make(map[config.Hostname]bool, len(server.Hosts)) - for _, host := range server.Hosts { - gatewayServerHosts[config.Hostname(host)] = true + gatewayServerHosts := make(map[host.Name]bool, len(server.Hosts)) + for _, hostname := range server.Hosts { + gatewayServerHosts[host.Name(hostname)] = true } filterChains := make([]*filterChainOpts, 0) @@ -660,8 +661,8 @@ func buildGatewayNetworkFiltersFromTLSRoutes(node *model.Proxy, env *model.Envir // Select the virtualService's hosts that match the ones specified in the gateway server's hosts // based on the wildcard hostname match and the namespace match -func pickMatchingGatewayHosts(gatewayServerHosts map[config.Hostname]bool, virtualService model.Config) map[string]config.Hostname { - matchingHosts := make(map[string]config.Hostname) +func pickMatchingGatewayHosts(gatewayServerHosts map[host.Name]bool, virtualService model.Config) map[string]host.Name { + matchingHosts := make(map[string]host.Name) virtualServiceHosts := virtualService.Spec.(*networking.VirtualService).Hosts for _, vsvcHost := range virtualServiceHosts { for gatewayHost := range gatewayServerHosts { @@ -675,9 +676,9 @@ func pickMatchingGatewayHosts(gatewayServerHosts map[config.Hostname]bool, virtu continue } //strip the namespace - gwHostnameForMatching = config.Hostname(parts[1]) + gwHostnameForMatching = host.Name(parts[1]) } - if gwHostnameForMatching.Matches(config.Hostname(vsvcHost)) { + if gwHostnameForMatching.Matches(host.Name(vsvcHost)) { // assign the actual gateway host because calling code uses it as a key // to locate TLS redirect servers matchingHosts[vsvcHost] = gatewayHost diff --git a/pilot/pkg/networking/core/v1alpha3/httproute.go b/pilot/pkg/networking/core/v1alpha3/httproute.go index 1e05d8f68445..1f091daaf70d 100644 --- a/pilot/pkg/networking/core/v1alpha3/httproute.go +++ b/pilot/pkg/networking/core/v1alpha3/httproute.go @@ -31,8 +31,8 @@ import ( istio_route "istio.io/istio/pilot/pkg/networking/core/v1alpha3/route" "istio.io/istio/pilot/pkg/networking/plugin" "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/proto" @@ -150,7 +150,7 @@ func (configgen *ConfigGeneratorImpl) buildSidecarOutboundHTTPRouteConfig(env *m listenerPort = 0 } - nameToServiceMap := make(map[config.Hostname]*model.Service) + nameToServiceMap := make(map[host.Name]*model.Service) for _, svc := range services { if listenerPort == 0 { // Take all ports when listen port is 0 (http_proxy or uds) @@ -182,13 +182,13 @@ func (configgen *ConfigGeneratorImpl) buildSidecarOutboundHTTPRouteConfig(env *m continue } virtualHosts := make([]*route.VirtualHost, 0, len(virtualHostWrapper.VirtualServiceHosts)+len(virtualHostWrapper.Services)) - for _, host := range virtualHostWrapper.VirtualServiceHosts { - name := fmt.Sprintf("%s:%d", host, virtualHostWrapper.Port) + for _, hostname := range virtualHostWrapper.VirtualServiceHosts { + name := fmt.Sprintf("%s:%d", hostname, virtualHostWrapper.Port) if _, found := uniques[name]; !found { uniques[name] = struct{}{} virtualHosts = append(virtualHosts, &route.VirtualHost{ Name: name, - Domains: []string{host, fmt.Sprintf("%s:%d", host, virtualHostWrapper.Port)}, + Domains: []string{hostname, fmt.Sprintf("%s:%d", hostname, virtualHostWrapper.Port)}, Routes: virtualHostWrapper.Routes, }) } else { diff --git a/pilot/pkg/networking/core/v1alpha3/httproute_test.go b/pilot/pkg/networking/core/v1alpha3/httproute_test.go index 08c3a15a766e..cb01ed6677e6 100644 --- a/pilot/pkg/networking/core/v1alpha3/httproute_test.go +++ b/pilot/pkg/networking/core/v1alpha3/httproute_test.go @@ -27,7 +27,7 @@ import ( "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/networking/plugin" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/config/visibility" ) @@ -604,7 +604,7 @@ func testSidecarRDSVHosts(t *testing.T, services []*model.Service, func buildHTTPService(hostname string, v visibility.Instance, ip, namespace string, ports ...int) *model.Service { service := &model.Service{ CreationTime: tnow, - Hostname: config.Hostname(hostname), + Hostname: host.Name(hostname), Address: ip, ClusterVIPs: make(map[string]string), Resolution: model.Passthrough, diff --git a/pilot/pkg/networking/core/v1alpha3/listener.go b/pilot/pkg/networking/core/v1alpha3/listener.go index 5e57990f3cc8..40818fdaf34a 100644 --- a/pilot/pkg/networking/core/v1alpha3/listener.go +++ b/pilot/pkg/networking/core/v1alpha3/listener.go @@ -46,8 +46,8 @@ import ( "istio.io/istio/pilot/pkg/networking/plugin" "istio.io/istio/pilot/pkg/networking/util" authn_model "istio.io/istio/pilot/pkg/security/model" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/proto" @@ -502,7 +502,7 @@ func (configgen *ConfigGeneratorImpl) buildSidecarInboundListenerForPortOrUDS(no type inboundListenerEntry struct { bind string - instanceHostname config.Hostname // could be empty if generated via Sidecar CRD + instanceHostname host.Name // could be empty if generated via Sidecar CRD } type outboundListenerEntry struct { @@ -530,7 +530,7 @@ type outboundListenerConflict struct { listenerName string currentProtocol protocol.Instance currentServices []*model.Service - newHostname config.Hostname + newHostname host.Name newProtocol protocol.Instance } @@ -1001,7 +1001,7 @@ func (configgen *ConfigGeneratorImpl) buildSidecarOutboundTCPListenerOptsForPort // for user defined Egress listeners with ports. And these should occur in the API before // the wildcard egress listener. the check for the "locked" bit will eliminate the collision. // User is also not allowed to add duplicate ports in the egress listener - var newHostname config.Hostname + var newHostname host.Name if pluginParams.Service != nil { newHostname = pluginParams.Service.Hostname } else { @@ -1141,7 +1141,7 @@ func (configgen *ConfigGeneratorImpl) buildSidecarOutboundListenerForPortOrUDS(l // for user defined Egress listeners with ports. And these should occur in the API before // the wildcard egress listener. the check for the "locked" bit will eliminate the collision. // User is also not allowed to add duplicate ports in the egress listener - var newHostname config.Hostname + var newHostname host.Name if pluginParams.Service != nil { newHostname = pluginParams.Service.Hostname } else { @@ -1170,7 +1170,7 @@ func (configgen *ConfigGeneratorImpl) buildSidecarOutboundListenerForPortOrUDS(l // We have two non-catch all filter chains. Check for duplicates if reflect.DeepEqual(*existingFilterChain.FilterChainMatch, *incomingFilterChain.FilterChainMatch) { - var newHostname config.Hostname + var newHostname host.Name if pluginParams.Service != nil { newHostname = pluginParams.Service.Hostname } else { @@ -1266,7 +1266,7 @@ func (configgen *ConfigGeneratorImpl) onVirtualOutboundListener(env *model.Envir push *model.PushContext, ipTablesListener *xdsapi.Listener) *xdsapi.Listener { - hostname := config.Hostname(util.BlackHoleCluster) + hostname := host.Name(util.BlackHoleCluster) mesh := env.Mesh redirectPort := &model.Port{ Port: int(mesh.ProxyListenPort), diff --git a/pilot/pkg/networking/core/v1alpha3/listener_test.go b/pilot/pkg/networking/core/v1alpha3/listener_test.go index 002699031f5a..1de1872f102b 100644 --- a/pilot/pkg/networking/core/v1alpha3/listener_test.go +++ b/pilot/pkg/networking/core/v1alpha3/listener_test.go @@ -35,7 +35,7 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/networking/core/v1alpha3/fakes" "istio.io/istio/pilot/pkg/networking/plugin" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/mesh" "istio.io/istio/pkg/config/protocol" @@ -611,7 +611,7 @@ func TestOutboundListenerAccessLogs(t *testing.T) { } } -func verifyOutboundTCPListenerHostname(t *testing.T, l *xdsapi.Listener, hostname config.Hostname) { +func verifyOutboundTCPListenerHostname(t *testing.T, l *xdsapi.Listener, hostname host.Name) { t.Helper() if len(l.FilterChains) != 1 { t.Fatalf("expected %d filter chains, found %d", 1, len(l.FilterChains)) @@ -904,7 +904,7 @@ func findListenerByPort(listeners []*xdsapi.Listener, port uint32) *xdsapi.Liste func buildService(hostname string, ip string, protocol protocol.Instance, creationTime time.Time) *model.Service { return &model.Service{ CreationTime: creationTime, - Hostname: config.Hostname(hostname), + Hostname: host.Name(hostname), Address: ip, ClusterVIPs: make(map[string]string), Ports: model.PortList{ diff --git a/pilot/pkg/networking/core/v1alpha3/networkfilter.go b/pilot/pkg/networking/core/v1alpha3/networkfilter.go index 3a880031d029..ae5c7edd3868 100644 --- a/pilot/pkg/networking/core/v1alpha3/networkfilter.go +++ b/pilot/pkg/networking/core/v1alpha3/networkfilter.go @@ -29,11 +29,12 @@ import ( xdsutil "github.com/envoyproxy/go-control-plane/pkg/util" networking "istio.io/api/networking/v1alpha3" + "istio.io/istio/pilot/pkg/features" "istio.io/istio/pilot/pkg/model" istio_route "istio.io/istio/pilot/pkg/networking/core/v1alpha3/route" "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/protocol" ) @@ -162,7 +163,7 @@ func buildOutboundNetworkFiltersWithWeightedClusters(env *model.Environment, nod } for _, route := range routes { - service := node.SidecarScope.ServiceForHostname(config.Hostname(route.Destination.Host), push.ServiceByHostnameAndNamespace) + service := node.SidecarScope.ServiceForHostname(host.Name(route.Destination.Host), push.ServiceByHostnameAndNamespace) if route.Weight > 0 { clusterName := istio_route.GetDestinationCluster(route.Destination, service, port.Port) clusterSpecifier.WeightedClusters.Clusters = append(clusterSpecifier.WeightedClusters.Clusters, &tcp_proxy.TcpProxy_WeightedCluster_ClusterWeight{ @@ -212,7 +213,7 @@ func buildOutboundNetworkFilters(env *model.Environment, node *model.Proxy, port *model.Port, configMeta model.ConfigMeta) []*listener.Filter { if len(routes) == 1 { - service := node.SidecarScope.ServiceForHostname(config.Hostname(routes[0].Destination.Host), push.ServiceByHostnameAndNamespace) + service := node.SidecarScope.ServiceForHostname(host.Name(routes[0].Destination.Host), push.ServiceByHostnameAndNamespace) clusterName := istio_route.GetDestinationCluster(routes[0].Destination, service, port.Port) return buildOutboundNetworkFiltersWithSingleDestination(env, node, clusterName, port) } diff --git a/pilot/pkg/networking/core/v1alpha3/route/route.go b/pilot/pkg/networking/core/v1alpha3/route/route.go index 92d1fb98a5d1..79aae9fd2060 100644 --- a/pilot/pkg/networking/core/v1alpha3/route/route.go +++ b/pilot/pkg/networking/core/v1alpha3/route/route.go @@ -35,8 +35,8 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/networking/core/v1alpha3/route/retry" "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -76,7 +76,7 @@ type VirtualHostWrapper struct { func BuildSidecarVirtualHostsFromConfigAndRegistry( node *model.Proxy, push *model.PushContext, - serviceRegistry map[config.Hostname]*model.Service, + serviceRegistry map[host.Name]*model.Service, proxyLabels labels.Collection, virtualServices []model.Config, listenPort int) []VirtualHostWrapper { @@ -93,12 +93,12 @@ func BuildSidecarVirtualHostsFromConfigAndRegistry( } // compute services missing virtual service configs - missing := make(map[config.Hostname]bool) + missing := make(map[host.Name]bool) for fqdn := range serviceRegistry { missing[fqdn] = true } - for _, host := range out { - for _, service := range host.Services { + for _, hostname := range out { + for _, service := range hostname.Services { delete(missing, service.Hostname) } } @@ -125,13 +125,13 @@ func BuildSidecarVirtualHostsFromConfigAndRegistry( // separateVSHostsAndServices splits the virtual service hosts into services (if they are found in the registry) and // plain non-registry hostnames func separateVSHostsAndServices(virtualService model.Config, - serviceRegistry map[config.Hostname]*model.Service) ([]string, []*model.Service) { + serviceRegistry map[host.Name]*model.Service) ([]string, []*model.Service) { rule := virtualService.Spec.(*networking.VirtualService) hosts := make([]string, 0) servicesInVirtualService := make([]*model.Service, 0) - for _, host := range rule.Hosts { + for _, hostname := range rule.Hosts { // Say host is *.global - vsHostname := config.Hostname(host) + vsHostname := host.Name(hostname) foundSvcMatch := false // TODO: Optimize me. This is O(n2) or worse. Need to prune at top level in config // Say we have services *.foo.global, *.bar.global @@ -143,7 +143,7 @@ func separateVSHostsAndServices(virtualService model.Config, } } if !foundSvcMatch { - hosts = append(hosts, host) + hosts = append(hosts, hostname) } } return hosts, servicesInVirtualService @@ -156,7 +156,7 @@ func buildSidecarVirtualHostsForVirtualService( node *model.Proxy, push *model.PushContext, virtualService model.Config, - serviceRegistry map[config.Hostname]*model.Service, + serviceRegistry map[host.Name]*model.Service, proxyLabels labels.Collection, listenPort int) []VirtualHostWrapper { hosts, servicesInVirtualService := separateVSHostsAndServices(virtualService, serviceRegistry) @@ -225,7 +225,7 @@ func GetDestinationCluster(destination *networking.Destination, service *model.S // If blackhole cluster is needed, do the check on the caller side. See gateway and tls.go for examples. } - return model.BuildSubsetKey(model.TrafficDirectionOutbound, destination.Subset, config.Hostname(destination.Host), port) + return model.BuildSubsetKey(model.TrafficDirectionOutbound, destination.Subset, host.Name(destination.Host), port) } // BuildHTTPRoutesForVirtualService creates data plane HTTP routes from the virtual service spec. @@ -240,7 +240,7 @@ func BuildHTTPRoutesForVirtualService( node *model.Proxy, push *model.PushContext, virtualService model.Config, - serviceRegistry map[config.Hostname]*model.Service, + serviceRegistry map[host.Name]*model.Service, listenPort int, proxyLabels labels.Collection, gatewayNames map[string]bool) ([]*route.Route, error) { @@ -303,7 +303,7 @@ func sourceMatchHTTP(match *networking.HTTPMatchRequest, proxyLabels labels.Coll func translateRoute(push *model.PushContext, node *model.Proxy, in *networking.HTTPRoute, match *networking.HTTPMatchRequest, port int, virtualService model.Config, - serviceRegistry map[config.Hostname]*model.Service, + serviceRegistry map[host.Name]*model.Service, proxyLabels labels.Collection, gatewayNames map[string]bool) *route.Route { @@ -404,7 +404,7 @@ func translateRoute(push *model.PushContext, node *model.Proxy, in *networking.H out.ResponseHeadersToRemove = responseHeadersToRemove if in.Mirror != nil { - n := GetDestinationCluster(in.Mirror, serviceRegistry[config.Hostname(in.Mirror.Host)], port) + n := GetDestinationCluster(in.Mirror, serviceRegistry[host.Name(in.Mirror.Host)], port) action.RequestMirrorPolicy = &route.RouteAction_RequestMirrorPolicy{Cluster: n} } @@ -435,7 +435,7 @@ func translateRoute(push *model.PushContext, node *model.Proxy, in *networking.H responseHeadersToRemove = append(responseHeadersToRemove, dst.Headers.GetResponse().GetRemove()...) responseHeadersToRemove = append(responseHeadersToRemove, dst.RemoveResponseHeaders...) - hostname := config.Hostname(dst.GetDestination().GetHost()) + hostname := host.Name(dst.GetDestination().GetHost()) n := GetDestinationCluster(dst.Destination, serviceRegistry[hostname], port) clusterWeight := &route.WeightedCluster_ClusterWeight{ @@ -803,7 +803,7 @@ func getHashPolicy(push *model.PushContext, node *model.Proxy, dst *networking.H destination := dst.GetDestination() destinationRule := push.DestinationRule(node, &model.Service{ - Hostname: config.Hostname(destination.Host), + Hostname: host.Name(destination.Host), Attributes: model.ServiceAttributes{Namespace: configNamespace}, }) if destinationRule == nil { diff --git a/pilot/pkg/networking/core/v1alpha3/route/route_test.go b/pilot/pkg/networking/core/v1alpha3/route/route_test.go index f878cf5a10fd..0ca9ba78296f 100644 --- a/pilot/pkg/networking/core/v1alpha3/route/route_test.go +++ b/pilot/pkg/networking/core/v1alpha3/route/route_test.go @@ -26,14 +26,14 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/networking/core/v1alpha3/route" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/mesh" "istio.io/istio/pkg/config/protocol" ) func TestBuildHTTPRoutes(t *testing.T) { - serviceRegistry := map[config.Hostname]*model.Service{ + serviceRegistry := map[host.Name]*model.Service{ "*.example.org": { Hostname: "*.example.org", Address: "1.1.1.1", diff --git a/pilot/pkg/networking/core/v1alpha3/tls.go b/pilot/pkg/networking/core/v1alpha3/tls.go index 3637938a37a4..dca9bde90b0c 100644 --- a/pilot/pkg/networking/core/v1alpha3/tls.go +++ b/pilot/pkg/networking/core/v1alpha3/tls.go @@ -23,7 +23,7 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/pkg/log" @@ -70,12 +70,12 @@ func matchTCP(match *v1alpha3.L4MatchAttributes, proxyLabels labels.Collection, } // Select the config pertaining to the service being processed. -func getConfigsForHost(host config.Hostname, configs []model.Config) []model.Config { +func getConfigsForHost(hostname host.Name, configs []model.Config) []model.Config { svcConfigs := make([]model.Config, 0) for index := range configs { virtualService := configs[index].Spec.(*v1alpha3.VirtualService) for _, vsHost := range virtualService.Hosts { - if config.Hostname(vsHost).Matches(host) { + if host.Name(vsHost).Matches(hostname) { svcConfigs = append(svcConfigs, configs[index]) break } diff --git a/pilot/pkg/networking/plugin/mixer/mixer.go b/pilot/pkg/networking/plugin/mixer/mixer.go index 3440d01f3cc7..cce5fb38520b 100644 --- a/pilot/pkg/networking/plugin/mixer/mixer.go +++ b/pilot/pkg/networking/plugin/mixer/mixer.go @@ -33,10 +33,12 @@ import ( meshconfig "istio.io/api/mesh/v1alpha1" mpb "istio.io/api/mixer/v1" mccpb "istio.io/api/mixer/v1/config/client" + "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/networking/plugin" "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" + "istio.io/pkg/log" ) @@ -234,11 +236,11 @@ func (mixerplugin) OnOutboundRouteConfiguration(in *plugin.InputParams, routeCon return } for i := 0; i < len(routeConfiguration.VirtualHosts); i++ { - host := routeConfiguration.VirtualHosts[i] - for j := 0; j < len(host.Routes); j++ { - host.Routes[j] = modifyOutboundRouteConfig(in.Push, in, host.Name, host.Routes[j]) + virtualHost := routeConfiguration.VirtualHosts[i] + for j := 0; j < len(virtualHost.Routes); j++ { + virtualHost.Routes[j] = modifyOutboundRouteConfig(in.Push, in, virtualHost.Name, virtualHost.Routes[j]) } - routeConfiguration.VirtualHosts[i] = host + routeConfiguration.VirtualHosts[i] = virtualHost } } @@ -252,17 +254,17 @@ func (mixerplugin) OnInboundRouteConfiguration(in *plugin.InputParams, routeConf case plugin.ListenerProtocolHTTP: // copy structs in place for i := 0; i < len(routeConfiguration.VirtualHosts); i++ { - host := routeConfiguration.VirtualHosts[i] - for j := 0; j < len(host.Routes); j++ { - r := host.Routes[j] + virtualHost := routeConfiguration.VirtualHosts[i] + for j := 0; j < len(virtualHost.Routes); j++ { + r := virtualHost.Routes[j] if isXDSMarshalingToAnyEnabled { r.TypedPerFilterConfig = addTypedServiceConfig(r.TypedPerFilterConfig, buildInboundRouteConfig(in, in.ServiceInstance)) } else { r.PerFilterConfig = addServiceConfig(r.PerFilterConfig, buildInboundRouteConfig(in, in.ServiceInstance)) } - host.Routes[j] = r + virtualHost.Routes[j] = r } - routeConfiguration.VirtualHosts[i] = host + routeConfiguration.VirtualHosts[i] = virtualHost } case plugin.ListenerProtocolTCP: @@ -282,9 +284,9 @@ func buildUpstreamName(address string) string { return "" } - host, port, _ := net.SplitHostPort(address) + hostname, port, _ := net.SplitHostPort(address) v, _ := strconv.Atoi(port) - return model.BuildSubsetKey(model.TrafficDirectionOutbound, "", config.Hostname(host), v) + return model.BuildSubsetKey(model.TrafficDirectionOutbound, "", host.Name(hostname), v) } func buildTransport(mesh *meshconfig.MeshConfig, node *model.Proxy) *mccpb.TransportConfig { @@ -469,7 +471,7 @@ func modifyOutboundRouteConfig(push *model.PushContext, in *plugin.InputParams, // hence adding the attributes for the mixer filter case *route.Route_DirectResponse: if virtualHostname == util.BlackHoleRouteName { - hostname := config.Hostname(util.BlackHoleCluster) + hostname := host.Name(util.BlackHoleCluster) attrs := addVirtualDestinationServiceAttributes(make(attributes), hostname) addFilterConfigToRoute(in, httpRoute, attrs, isXDSMarshalingToAnyEnabled) } @@ -566,7 +568,7 @@ func addTypedServiceConfig(filterConfigs map[string]*types.Any, config *mccpb.Se return filterConfigs } -func addVirtualDestinationServiceAttributes(attrs attributes, destinationHostname config.Hostname) attributes { +func addVirtualDestinationServiceAttributes(attrs attributes, destinationHostname host.Name) attributes { if destinationHostname == "" { return attrs } diff --git a/pilot/pkg/proxy/envoy/v2/debug.go b/pilot/pkg/proxy/envoy/v2/debug.go index bba4dacedf9e..126c085b5238 100644 --- a/pilot/pkg/proxy/envoy/v2/debug.go +++ b/pilot/pkg/proxy/envoy/v2/debug.go @@ -24,19 +24,20 @@ import ( authn "istio.io/api/authentication/v1alpha1" networking "istio.io/api/networking/v1alpha3" + "istio.io/istio/pilot/pkg/model" networking_core "istio.io/istio/pilot/pkg/networking/core/v1alpha3" authn_alpha1 "istio.io/istio/pilot/pkg/security/authn/v1alpha1" "istio.io/istio/pilot/pkg/serviceregistry" "istio.io/istio/pilot/pkg/serviceregistry/aggregate" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" ) // InitDebug initializes the debug handlers and adds a debug in-memory registry. func (s *DiscoveryServer) InitDebug(mux *http.ServeMux, sctl *aggregate.Controller) { // For debugging and load testing v2 we add an memory registry. s.MemRegistry = NewMemServiceDiscovery( - map[config.Hostname]*model.Service{ // mock.HelloService.Hostname: mock.HelloService, + map[host.Name]*model.Service{ // mock.HelloService.Hostname: mock.HelloService, }, 2) s.MemRegistry.EDSUpdater = s s.MemRegistry.ClusterID = "v2-debug" diff --git a/pilot/pkg/proxy/envoy/v2/eds.go b/pilot/pkg/proxy/envoy/v2/eds.go index 8d97170f8db9..4b8955d7163f 100644 --- a/pilot/pkg/proxy/envoy/v2/eds.go +++ b/pilot/pkg/proxy/envoy/v2/eds.go @@ -34,7 +34,7 @@ import ( "istio.io/istio/pilot/pkg/networking/util" "istio.io/istio/pilot/pkg/serviceregistry" "istio.io/istio/pilot/pkg/serviceregistry/aggregate" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" ) @@ -193,7 +193,7 @@ func endpointMetadata(uid string, network string) *core.Metadata { // Determine Service associated with a hostname when there is no Sidecar scope. Which namespace the service comes from // is undefined, as we do not have enough information to make a smart decision -func legacyServiceForHostname(hostname config.Hostname, serviceByHostname map[config.Hostname]map[string]*model.Service) *model.Service { +func legacyServiceForHostname(hostname host.Name, serviceByHostname map[host.Name]map[string]*model.Service) *model.Service { for _, service := range serviceByHostname[hostname] { return service } @@ -208,7 +208,7 @@ func legacyServiceForHostname(hostname config.Hostname, serviceByHostname map[co func (s *DiscoveryServer) updateClusterInc(push *model.PushContext, clusterName string, edsCluster *EdsCluster) error { - var hostname config.Hostname + var hostname host.Name var clusterPort int var subsetName string _, subsetName, hostname, clusterPort = model.ParseSubsetKey(clusterName) @@ -771,7 +771,7 @@ func (s *DiscoveryServer) pushEds(push *model.PushContext, con *XdsConnection, v // getDestinationRule gets the DestinationRule for a given hostname. As an optimization, this also gets the service port, // which is needed to access the traffic policy from the destination rule. -func getDestinationRule(push *model.PushContext, proxy *model.Proxy, hostname config.Hostname, clusterPort int) (*networkingapi.DestinationRule, *model.Port) { +func getDestinationRule(push *model.PushContext, proxy *model.Proxy, hostname host.Name, clusterPort int) (*networkingapi.DestinationRule, *model.Port) { for _, service := range push.Services(proxy) { if service.Hostname == hostname { cfg := push.DestinationRule(proxy, service) diff --git a/pilot/pkg/proxy/envoy/v2/eds_sh_test.go b/pilot/pkg/proxy/envoy/v2/eds_sh_test.go index 7eaaf279b057..6c1dc9f82ba6 100644 --- a/pilot/pkg/proxy/envoy/v2/eds_sh_test.go +++ b/pilot/pkg/proxy/envoy/v2/eds_sh_test.go @@ -25,13 +25,13 @@ import ( proto "github.com/gogo/protobuf/types" meshconfig "istio.io/api/mesh/v1alpha1" + testenv "istio.io/istio/mixer/test/client/env" "istio.io/istio/pilot/pkg/bootstrap" "istio.io/istio/pilot/pkg/model" v2 "istio.io/istio/pilot/pkg/proxy/envoy/v2" - "istio.io/istio/pilot/pkg/serviceregistry" "istio.io/istio/pilot/pkg/serviceregistry/aggregate" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/test/env" "istio.io/istio/tests/util" @@ -228,10 +228,10 @@ func initSplitHorizonTestEnv(t *testing.T) (*bootstrap.Server, util.TearDownFunc func initRegistry(server *bootstrap.Server, clusterNum int, gatewaysIP []string, numOfEndpoints int) { id := fmt.Sprintf("network%d", clusterNum) memRegistry := v2.NewMemServiceDiscovery( - map[config.Hostname]*model.Service{}, 2) + map[host.Name]*model.Service{}, 2) server.ServiceController.AddRegistry(aggregate.Registry{ ClusterID: id, - Name: serviceregistry.ServiceRegistry("memAdapter"), + Name: "memAdapter", ServiceDiscovery: memRegistry, Controller: &v2.MemServiceController{}, }) diff --git a/pilot/pkg/proxy/envoy/v2/eds_test.go b/pilot/pkg/proxy/envoy/v2/eds_test.go index 1867e96fdcc4..4f5359a7b5f9 100644 --- a/pilot/pkg/proxy/envoy/v2/eds_test.go +++ b/pilot/pkg/proxy/envoy/v2/eds_test.go @@ -32,11 +32,12 @@ import ( "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint" "istio.io/api/mesh/v1alpha1" + "istio.io/istio/pilot/pkg/bootstrap" "istio.io/istio/pilot/pkg/model" v2 "istio.io/istio/pilot/pkg/proxy/envoy/v2" "istio.io/istio/pkg/adsc" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/test/env" "istio.io/istio/tests/util" @@ -587,7 +588,7 @@ func addUdsEndpoint(server *bootstrap.Server) { server.EnvoyXdsServer.Push(true, nil) } -func addLocalityEndpoints(server *bootstrap.Server, hostname config.Hostname) { +func addLocalityEndpoints(server *bootstrap.Server, hostname host.Name) { server.EnvoyXdsServer.MemRegistry.AddService(hostname, &model.Service{ Hostname: hostname, Ports: model.PortList{ diff --git a/pilot/pkg/proxy/envoy/v2/ep_filters.go b/pilot/pkg/proxy/envoy/v2/ep_filters.go index 3a4aa94cd916..90983a1e98d5 100644 --- a/pilot/pkg/proxy/envoy/v2/ep_filters.go +++ b/pilot/pkg/proxy/envoy/v2/ep_filters.go @@ -21,9 +21,10 @@ import ( "github.com/gogo/protobuf/types" "istio.io/api/mesh/v1alpha1" + "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/networking/util" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" ) // EndpointsFilterFunc is a function that filters data from the ClusterLoadAssignment and returns updated one @@ -205,7 +206,7 @@ func getGatewayAddresses(gw *v1alpha1.Network_IstioNetworkGateway, registryName // Second, try to find the gateway addresses by the provided service name if gwSvcName := gw.GetRegistryServiceName(); len(gwSvcName) > 0 && len(registryName) > 0 { - svc, _ := env.GetService(config.Hostname(gwSvcName)) + svc, _ := env.GetService(host.Name(gwSvcName)) if svc != nil { return svc.Attributes.ClusterExternalAddresses[registryName] } diff --git a/pilot/pkg/proxy/envoy/v2/ep_filters_test.go b/pilot/pkg/proxy/envoy/v2/ep_filters_test.go index 79a18d365afe..4ace75d82399 100644 --- a/pilot/pkg/proxy/envoy/v2/ep_filters_test.go +++ b/pilot/pkg/proxy/envoy/v2/ep_filters_test.go @@ -23,8 +23,9 @@ import ( "github.com/gogo/protobuf/types" meshconfig "istio.io/api/mesh/v1alpha1" + "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" ) type LbEpInfo struct { @@ -205,8 +206,8 @@ func TestEndpointsByNetworkFilter_RegistryServiceName(t *testing.T) { }, } - gwSvcName := config.Hostname("istio-ingressgateway.istio-system.svc.cluster.local") - serviceDiscovery := NewMemServiceDiscovery(map[config.Hostname]*model.Service{ + gwSvcName := host.Name("istio-ingressgateway.istio-system.svc.cluster.local") + serviceDiscovery := NewMemServiceDiscovery(map[host.Name]*model.Service{ gwSvcName: { Hostname: gwSvcName, Attributes: model.ServiceAttributes{ diff --git a/pilot/pkg/proxy/envoy/v2/mem.go b/pilot/pkg/proxy/envoy/v2/mem.go index dff6fa48035d..98dde8c7760e 100644 --- a/pilot/pkg/proxy/envoy/v2/mem.go +++ b/pilot/pkg/proxy/envoy/v2/mem.go @@ -20,7 +20,7 @@ import ( "sync" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/spiffe" @@ -58,7 +58,7 @@ func (c *MemServiceController) Run(<-chan struct{}) {} // MemServiceDiscovery is a mock discovery interface type MemServiceDiscovery struct { - services map[config.Hostname]*model.Service + services map[host.Name]*model.Service // EndpointShards table. Key is the fqdn of the service, ':', port instancesByPortNum map[string][]*model.ServiceInstance instancesByPortName map[string][]*model.ServiceInstance @@ -86,7 +86,7 @@ type MemServiceDiscovery struct { } // NewMemServiceDiscovery builds an in-memory MemServiceDiscovery -func NewMemServiceDiscovery(services map[config.Hostname]*model.Service, versions int) *MemServiceDiscovery { +func NewMemServiceDiscovery(services map[host.Name]*model.Service, versions int) *MemServiceDiscovery { return &MemServiceDiscovery{ services: services, versions: versions, @@ -113,8 +113,8 @@ func (sd *MemServiceDiscovery) AddWorkload(ip string, labels labels.Instance) { // AddHTTPService is a helper to add a service of type http, named 'http-main', with the // specified vip and port. func (sd *MemServiceDiscovery) AddHTTPService(name, vip string, port int) { - sd.AddService(config.Hostname(name), &model.Service{ - Hostname: config.Hostname(name), + sd.AddService(host.Name(name), &model.Service{ + Hostname: host.Name(name), Ports: model.PortList{ { Name: "http-main", @@ -126,7 +126,7 @@ func (sd *MemServiceDiscovery) AddHTTPService(name, vip string, port int) { } // AddService adds an in-memory service. -func (sd *MemServiceDiscovery) AddService(name config.Hostname, svc *model.Service) { +func (sd *MemServiceDiscovery) AddService(name host.Name, svc *model.Service) { sd.mutex.Lock() sd.services[name] = svc sd.mutex.Unlock() @@ -134,7 +134,7 @@ func (sd *MemServiceDiscovery) AddService(name config.Hostname, svc *model.Servi } // AddInstance adds an in-memory instance. -func (sd *MemServiceDiscovery) AddInstance(service config.Hostname, instance *model.ServiceInstance) { +func (sd *MemServiceDiscovery) AddInstance(service host.Name, instance *model.ServiceInstance) { // WIP: add enough code to allow tests and load tests to work sd.mutex.Lock() defer sd.mutex.Unlock() @@ -155,7 +155,7 @@ func (sd *MemServiceDiscovery) AddInstance(service config.Hostname, instance *mo } // AddEndpoint adds an endpoint to a service. -func (sd *MemServiceDiscovery) AddEndpoint(service config.Hostname, servicePortName string, servicePort int, address string, port int) *model.ServiceInstance { +func (sd *MemServiceDiscovery) AddEndpoint(service host.Name, servicePortName string, servicePort int, address string, port int) *model.ServiceInstance { instance := &model.ServiceInstance{ Endpoint: model.NetworkEndpoint{ Address: address, @@ -174,7 +174,7 @@ func (sd *MemServiceDiscovery) AddEndpoint(service config.Hostname, servicePortN // SetEndpoints update the list of endpoints for a service, similar with K8S controller. func (sd *MemServiceDiscovery) SetEndpoints(service string, namespace string, endpoints []*model.IstioEndpoint) { - sh := config.Hostname(service) + sh := host.Name(service) sd.mutex.Lock() defer sd.mutex.Unlock() @@ -252,7 +252,7 @@ func (sd *MemServiceDiscovery) Services() ([]*model.Service, error) { // GetService implements discovery interface // Each call to GetService() should return a new *model.Service -func (sd *MemServiceDiscovery) GetService(hostname config.Hostname) (*model.Service, error) { +func (sd *MemServiceDiscovery) GetService(hostname host.Name) (*model.Service, error) { sd.mutex.Lock() defer sd.mutex.Unlock() if sd.GetServiceError != nil { @@ -267,7 +267,7 @@ func (sd *MemServiceDiscovery) GetService(hostname config.Hostname) (*model.Serv // Instances filters the service instances by labels. This assumes single port, as is // used by EDS/ADS. -func (sd *MemServiceDiscovery) Instances(hostname config.Hostname, ports []string, +func (sd *MemServiceDiscovery) Instances(hostname host.Name, ports []string, labels labels.Collection) ([]*model.ServiceInstance, error) { sd.mutex.Lock() defer sd.mutex.Unlock() diff --git a/pilot/pkg/proxy/envoy/v2/xds_test.go b/pilot/pkg/proxy/envoy/v2/xds_test.go index 3109ab06d774..b4af82bd7c71 100644 --- a/pilot/pkg/proxy/envoy/v2/xds_test.go +++ b/pilot/pkg/proxy/envoy/v2/xds_test.go @@ -30,8 +30,8 @@ import ( testenv "istio.io/istio/mixer/test/client/env" "istio.io/istio/pilot/pkg/bootstrap" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/test/env" @@ -150,7 +150,7 @@ func initLocalPilotTestEnv(t *testing.T) (*bootstrap.Server, util.TearDownFunc) localIP = getLocalIP() // Service and endpoints for hello.default - used in v1 pilot tests - hostname := config.Hostname("hello.default.svc.cluster.local") + hostname := host.Name("hello.default.svc.cluster.local") server.EnvoyXdsServer.MemRegistry.AddService(hostname, &model.Service{ Hostname: hostname, Address: "10.10.0.3", diff --git a/pilot/pkg/security/authz/builder/builder_test.go b/pilot/pkg/security/authz/builder/builder_test.go index a81ea03fcbfc..188e695e368a 100644 --- a/pilot/pkg/security/authz/builder/builder_test.go +++ b/pilot/pkg/security/authz/builder/builder_test.go @@ -23,10 +23,11 @@ import ( "github.com/envoyproxy/go-control-plane/pkg/util" istio_rbac "istio.io/api/rbac/v1alpha1" + "istio.io/istio/pilot/pkg/model" authz_model "istio.io/istio/pilot/pkg/security/authz/model" "istio.io/istio/pilot/pkg/security/authz/policy" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" ) func newAuthzPolicyWithRbacConfig(mode istio_rbac.RbacConfig_Mode, include *istio_rbac.RbacConfig_Target, @@ -54,7 +55,7 @@ func newService(hostname string, labels map[string]string, t *testing.T) *model. Name: name, Namespace: namespace, }, - Hostname: config.Hostname(hostname), + Hostname: host.Name(hostname), }, Labels: labels, } diff --git a/pilot/pkg/security/authz/model/model_test.go b/pilot/pkg/security/authz/model/model_test.go index 97d8d944a17c..9364c8903cfd 100644 --- a/pilot/pkg/security/authz/model/model_test.go +++ b/pilot/pkg/security/authz/model/model_test.go @@ -24,7 +24,7 @@ import ( istio_rbac "istio.io/api/rbac/v1alpha1" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -46,7 +46,7 @@ func TestNewServiceMetadata(t *testing.T) { namespace: "test-ns", serviceInstance: &model.ServiceInstance{ Service: &model.Service{ - Hostname: config.Hostname("svc-name.test-ns"), + Hostname: host.Name("svc-name.test-ns"), }, Labels: labels.Instance{"version": "v1"}, ServiceAccount: "spiffe://xyz.com/sa/service-account/ns/test-ns", @@ -126,7 +126,7 @@ func TestModel_Generate(t *testing.T) { serviceFoo := "foo.default.svc.cluster.local" serviceInstance := &model.ServiceInstance{ Service: &model.Service{ - Hostname: config.Hostname(serviceFoo), + Hostname: host.Name(serviceFoo), }, } serviceMetadata, _ := NewServiceMetadata("foo", "default", serviceInstance) diff --git a/pilot/pkg/security/authz/policy/helper.go b/pilot/pkg/security/authz/policy/helper.go index f8c522290179..1429d19b7c69 100644 --- a/pilot/pkg/security/authz/policy/helper.go +++ b/pilot/pkg/security/authz/policy/helper.go @@ -23,10 +23,11 @@ import ( "github.com/hashicorp/go-multierror" istio_rbac "istio.io/api/rbac/v1alpha1" + "istio.io/istio/pilot/pkg/config/memory" "istio.io/istio/pilot/pkg/model" authz_model "istio.io/istio/pilot/pkg/security/authz/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" ) // We cannot import `testing` here, as it will bring extra test flags into the binary. Instead, just include the interface here @@ -50,7 +51,7 @@ func NewServiceMetadata(hostname string, labels map[string]string, t mockTest) * Name: name, Namespace: namespace, }, - Hostname: config.Hostname(hostname), + Hostname: host.Name(hostname), }, Labels: labels, } diff --git a/pilot/pkg/serviceregistry/aggregate/controller.go b/pilot/pkg/serviceregistry/aggregate/controller.go index b332a4c5467c..848a002f0d5b 100644 --- a/pilot/pkg/serviceregistry/aggregate/controller.go +++ b/pilot/pkg/serviceregistry/aggregate/controller.go @@ -23,7 +23,7 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/serviceregistry" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -110,7 +110,7 @@ func (c *Controller) GetRegistryIndex(clusterID string) (int, bool) { func (c *Controller) Services() ([]*model.Service, error) { // smap is a map of hostname (string) to service, used to identify services that // are installed in multiple clusters. - smap := make(map[config.Hostname]*model.Service) + smap := make(map[host.Name]*model.Service) services := make([]*model.Service, 0) var errs error @@ -167,7 +167,7 @@ func (c *Controller) Services() ([]*model.Service, error) { } // GetService retrieves a service by hostname if exists -func (c *Controller) GetService(hostname config.Hostname) (*model.Service, error) { +func (c *Controller) GetService(hostname host.Name) (*model.Service, error) { var errs error for _, r := range c.GetRegistries() { service, err := r.GetService(hostname) diff --git a/pilot/pkg/serviceregistry/aggregate/controller_test.go b/pilot/pkg/serviceregistry/aggregate/controller_test.go index d50a9ba90f89..a3c7db794761 100644 --- a/pilot/pkg/serviceregistry/aggregate/controller_test.go +++ b/pilot/pkg/serviceregistry/aggregate/controller_test.go @@ -23,7 +23,7 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/serviceregistry" "istio.io/istio/pilot/pkg/serviceregistry/memory" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" ) @@ -46,13 +46,13 @@ var discovery2 *memory.ServiceDiscovery func buildMockController() *Controller { discovery1 = memory.NewDiscovery( - map[config.Hostname]*model.Service{ + map[host.Name]*model.Service{ memory.HelloService.Hostname: memory.HelloService, memory.ExtHTTPService.Hostname: memory.ExtHTTPService, }, 2) discovery2 = memory.NewDiscovery( - map[config.Hostname]*model.Service{ + map[host.Name]*model.Service{ memory.WorldService.Hostname: memory.WorldService, memory.ExtHTTPSService.Hostname: memory.ExtHTTPSService, }, 2) @@ -78,12 +78,12 @@ func buildMockController() *Controller { func buildMockControllerForMultiCluster() *Controller { discovery1 = memory.NewDiscovery( - map[config.Hostname]*model.Service{ + map[host.Name]*model.Service{ memory.HelloService.Hostname: memory.MakeService("hello.default.svc.cluster.local", "10.1.1.0"), }, 2) discovery2 = memory.NewDiscovery( - map[config.Hostname]*model.Service{ + map[host.Name]*model.Service{ memory.HelloService.Hostname: memory.MakeService("hello.default.svc.cluster.local", "10.1.2.0"), memory.WorldService.Hostname: memory.WorldService, }, 2) @@ -129,7 +129,7 @@ func TestServicesForMultiCluster(t *testing.T) { } // Set up ground truth hostname values - serviceMap := map[config.Hostname]bool{ + serviceMap := map[host.Name]bool{ memory.HelloService.Hostname: false, memory.WorldService.Hostname: false, } @@ -148,7 +148,7 @@ func TestServicesForMultiCluster(t *testing.T) { } //Now verify ClusterVIPs for each service - ClusterVIPs := map[config.Hostname]map[string]string{ + ClusterVIPs := map[host.Name]map[string]string{ memory.HelloService.Hostname: { "cluster-1": "10.1.1.0", "cluster-2": "10.1.2.0", @@ -171,7 +171,7 @@ func TestServices(t *testing.T) { services, err := aggregateCtl.Services() // Set up ground truth hostname values - serviceMap := map[config.Hostname]bool{ + serviceMap := map[host.Name]bool{ memory.HelloService.Hostname: false, memory.ExtHTTPService.Hostname: false, memory.WorldService.Hostname: false, diff --git a/pilot/pkg/serviceregistry/consul/controller.go b/pilot/pkg/serviceregistry/consul/controller.go index f759241ad401..d22fae4e8c3c 100644 --- a/pilot/pkg/serviceregistry/consul/controller.go +++ b/pilot/pkg/serviceregistry/consul/controller.go @@ -24,7 +24,7 @@ import ( "istio.io/pkg/log" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/spiffe" ) @@ -72,7 +72,7 @@ func (c *Controller) Services() ([]*model.Service, error) { } // GetService retrieves a service by host name if it exists -func (c *Controller) GetService(hostname config.Hostname) (*model.Service, error) { +func (c *Controller) GetService(hostname host.Name) (*model.Service, error) { c.cacheMutex.Lock() defer c.cacheMutex.Unlock() diff --git a/pilot/pkg/serviceregistry/consul/conversion.go b/pilot/pkg/serviceregistry/consul/conversion.go index ef0d02a2a47f..9652a30c21c6 100644 --- a/pilot/pkg/serviceregistry/consul/conversion.go +++ b/pilot/pkg/serviceregistry/consul/conversion.go @@ -23,7 +23,7 @@ import ( "istio.io/pkg/log" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" ) @@ -148,14 +148,14 @@ func convertInstance(instance *api.CatalogService) *model.ServiceInstance { } // serviceHostname produces FQDN for a consul service -func serviceHostname(name string) config.Hostname { +func serviceHostname(name string) host.Name { // TODO include datacenter in Hostname? // consul DNS uses "redis.service.us-east-1.consul" -> "[]..service.[].consul" - return config.Hostname(fmt.Sprintf("%s.service.consul", name)) + return host.Name(fmt.Sprintf("%s.service.consul", name)) } // parseHostname extracts service name from the service hostname -func parseHostname(hostname config.Hostname) (name string, err error) { +func parseHostname(hostname host.Name) (name string, err error) { parts := strings.Split(string(hostname), ".") if len(parts) < 1 || parts[0] == "" { err = fmt.Errorf("missing service name from the service hostname %q", hostname) diff --git a/pilot/pkg/serviceregistry/external/conversion.go b/pilot/pkg/serviceregistry/external/conversion.go index b8e2ed400c5f..3d365eeea1ba 100644 --- a/pilot/pkg/serviceregistry/external/conversion.go +++ b/pilot/pkg/serviceregistry/external/conversion.go @@ -21,8 +21,8 @@ import ( networking "istio.io/api/networking/v1alpha3" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/config/visibility" ) @@ -64,7 +64,7 @@ func convertServices(cfg model.Config) []*model.Service { } } - for _, host := range serviceEntry.Hosts { + for _, hostname := range serviceEntry.Hosts { if len(serviceEntry.Addresses) > 0 { for _, address := range serviceEntry.Addresses { if ip, network, cidrErr := net.ParseCIDR(address); cidrErr == nil { @@ -77,12 +77,12 @@ func convertServices(cfg model.Config) []*model.Service { out = append(out, &model.Service{ CreationTime: creationTime, MeshExternal: serviceEntry.Location == networking.ServiceEntry_MESH_EXTERNAL, - Hostname: config.Hostname(host), + Hostname: host.Name(hostname), Address: newAddress, Ports: svcPorts, Resolution: resolution, Attributes: model.ServiceAttributes{ - Name: host, + Name: hostname, Namespace: cfg.Namespace, ExportTo: exportTo, }, @@ -91,12 +91,12 @@ func convertServices(cfg model.Config) []*model.Service { out = append(out, &model.Service{ CreationTime: creationTime, MeshExternal: serviceEntry.Location == networking.ServiceEntry_MESH_EXTERNAL, - Hostname: config.Hostname(host), + Hostname: host.Name(hostname), Address: address, Ports: svcPorts, Resolution: resolution, Attributes: model.ServiceAttributes{ - Name: host, + Name: hostname, Namespace: cfg.Namespace, ExportTo: exportTo, }, @@ -107,12 +107,12 @@ func convertServices(cfg model.Config) []*model.Service { out = append(out, &model.Service{ CreationTime: creationTime, MeshExternal: serviceEntry.Location == networking.ServiceEntry_MESH_EXTERNAL, - Hostname: config.Hostname(host), + Hostname: host.Name(hostname), Address: constants.UnspecifiedIP, Ports: svcPorts, Resolution: resolution, Attributes: model.ServiceAttributes{ - Name: host, + Name: hostname, Namespace: cfg.Namespace, ExportTo: exportTo, }, diff --git a/pilot/pkg/serviceregistry/external/conversion_test.go b/pilot/pkg/serviceregistry/external/conversion_test.go index 2767519397cb..75cc15521345 100644 --- a/pilot/pkg/serviceregistry/external/conversion_test.go +++ b/pilot/pkg/serviceregistry/external/conversion_test.go @@ -24,8 +24,8 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/test/util" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/protocol" ) @@ -284,7 +284,7 @@ func convertPortNameToProtocol(name string) protocol.Instance { return protocol.Parse(prefix) } -func makeService(hostname config.Hostname, configNamespace, address string, ports map[string]int, external bool, resolution model.Resolution) *model.Service { +func makeService(hostname host.Name, configNamespace, address string, ports map[string]int, external bool, resolution model.Resolution) *model.Service { svc := &model.Service{ CreationTime: GlobalTime, diff --git a/pilot/pkg/serviceregistry/external/servicediscovery.go b/pilot/pkg/serviceregistry/external/servicediscovery.go index a735fdb94702..bb60fcf34a5d 100644 --- a/pilot/pkg/serviceregistry/external/servicediscovery.go +++ b/pilot/pkg/serviceregistry/external/servicediscovery.go @@ -19,7 +19,7 @@ import ( "time" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -40,7 +40,7 @@ type ServiceEntryStore struct { ip2instance map[string][]*model.ServiceInstance // Endpoints table. Key is the fqdn hostname and namespace - instances map[config.Hostname]map[string][]*model.ServiceInstance + instances map[host.Name]map[string][]*model.ServiceInstance changeMutex sync.RWMutex lastChange time.Time @@ -54,7 +54,7 @@ func NewServiceDiscovery(callbacks model.ConfigStoreCache, store model.IstioConf instanceHandlers: make([]instanceHandler, 0), store: store, ip2instance: map[string][]*model.ServiceInstance{}, - instances: map[config.Hostname]map[string][]*model.ServiceInstance{}, + instances: map[host.Name]map[string][]*model.ServiceInstance{}, updateNeeded: true, } if callbacks != nil { @@ -116,7 +116,7 @@ func (d *ServiceEntryStore) Services() ([]*model.Service, error) { // GetService retrieves a service by host name if it exists // THIS IS A LINEAR SEARCH WHICH CAUSES ALL SERVICE ENTRIES TO BE RECONVERTED - // DO NOT USE -func (d *ServiceEntryStore) GetService(hostname config.Hostname) (*model.Service, error) { +func (d *ServiceEntryStore) GetService(hostname host.Name) (*model.Service, error) { for _, service := range d.getServices() { if service.Hostname == hostname { return service, nil @@ -182,7 +182,7 @@ func (d *ServiceEntryStore) update() { } d.changeMutex.RUnlock() - di := map[config.Hostname]map[string][]*model.ServiceInstance{} + di := map[host.Name]map[string][]*model.ServiceInstance{} dip := map[string][]*model.ServiceInstance{} for _, cfg := range d.store.ServiceEntries() { diff --git a/pilot/pkg/serviceregistry/external/servicediscovery_test.go b/pilot/pkg/serviceregistry/external/servicediscovery_test.go index e079ef6731fa..55400c595d57 100644 --- a/pilot/pkg/serviceregistry/external/servicediscovery_test.go +++ b/pilot/pkg/serviceregistry/external/servicediscovery_test.go @@ -23,8 +23,8 @@ import ( "istio.io/istio/pilot/pkg/config/memory" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" ) @@ -78,7 +78,7 @@ func TestServiceDiscoveryServices(t *testing.T) { } func TestServiceDiscoveryGetService(t *testing.T) { - host := "*.google.com" + hostname := "*.google.com" hostDNE := "does.not.exist.local" store, sd, stopFn := initServiceDiscovery() @@ -86,7 +86,7 @@ func TestServiceDiscoveryGetService(t *testing.T) { createServiceEntries([]*model.Config{httpDNS, tcpStatic}, store, t) - service, err := sd.GetService(config.Hostname(hostDNE)) + service, err := sd.GetService(host.Name(hostDNE)) if err != nil { t.Errorf("GetService() encountered unexpected error: %v", err) } @@ -94,15 +94,15 @@ func TestServiceDiscoveryGetService(t *testing.T) { t.Errorf("GetService(%q) => should not exist, got %s", hostDNE, service.Hostname) } - service, err = sd.GetService(config.Hostname(host)) + service, err = sd.GetService(host.Name(hostname)) if err != nil { - t.Errorf("GetService(%q) encountered unexpected error: %v", host, err) + t.Errorf("GetService(%q) encountered unexpected error: %v", hostname, err) } if service == nil { - t.Errorf("GetService(%q) => should exist", host) + t.Errorf("GetService(%q) => should exist", hostname) } - if service.Hostname != config.Hostname(host) { - t.Errorf("GetService(%q) => %q, want %q", host, service.Hostname, host) + if service.Hostname != host.Name(hostname) { + t.Errorf("GetService(%q) => %q, want %q", hostname, service.Hostname, hostname) } } diff --git a/pilot/pkg/serviceregistry/kube/controller/controller.go b/pilot/pkg/serviceregistry/kube/controller/controller.go index 94870eee7a59..88b97ca1b0bb 100644 --- a/pilot/pkg/serviceregistry/kube/controller/controller.go +++ b/pilot/pkg/serviceregistry/kube/controller/controller.go @@ -37,7 +37,7 @@ import ( "istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/monitoring" "istio.io/istio/pilot/pkg/serviceregistry/kube" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" configKube "istio.io/istio/pkg/config/kube" "istio.io/istio/pkg/config/labels" @@ -129,9 +129,9 @@ type Controller struct { sync.RWMutex // servicesMap stores hostname ==> service, it is used to reduce convertService calls. - servicesMap map[config.Hostname]*model.Service + servicesMap map[host.Name]*model.Service // externalNameSvcInstanceMap stores hostname ==> instance, is used to store instances for ExternalName k8s services - externalNameSvcInstanceMap map[config.Hostname][]*model.ServiceInstance + externalNameSvcInstanceMap map[host.Name][]*model.ServiceInstance // CIDR ranger based on path-compressed prefix trie ranger cidranger.Ranger @@ -158,8 +158,8 @@ func NewController(client kubernetes.Interface, options Options) *Controller { queue: kube.NewQueue(1 * time.Second), ClusterID: options.ClusterID, XDSUpdater: options.XDSUpdater, - servicesMap: make(map[config.Hostname]*model.Service), - externalNameSvcInstanceMap: make(map[config.Hostname][]*model.ServiceInstance), + servicesMap: make(map[host.Name]*model.Service), + externalNameSvcInstanceMap: make(map[host.Name][]*model.ServiceInstance), } sharedInformers := informers.NewSharedInformerFactoryWithOptions(client, options.ResyncPeriod, informers.WithNamespace(options.WatchedNamespace)) @@ -309,7 +309,7 @@ func (c *Controller) Services() ([]*model.Service, error) { } // GetService implements a service catalog operation by hostname specified. -func (c *Controller) GetService(hostname config.Hostname) (*model.Service, error) { +func (c *Controller) GetService(hostname host.Name) (*model.Service, error) { c.RLock() defer c.RUnlock() return c.servicesMap[hostname], nil diff --git a/pilot/pkg/serviceregistry/kube/conversion.go b/pilot/pkg/serviceregistry/kube/conversion.go index a9d784129fa6..9dd8c9416d98 100644 --- a/pilot/pkg/serviceregistry/kube/conversion.go +++ b/pilot/pkg/serviceregistry/kube/conversion.go @@ -29,8 +29,8 @@ import ( "istio.io/api/annotation" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/kube" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/config/visibility" @@ -153,8 +153,8 @@ func ExternalNameServiceInstances(k8sSvc coreV1.Service, svc *model.Service) []* } // ServiceHostname produces FQDN for a k8s service -func ServiceHostname(name, namespace, domainSuffix string) config.Hostname { - return config.Hostname(fmt.Sprintf("%s.%s.svc.%s", name, namespace, domainSuffix)) +func ServiceHostname(name, namespace, domainSuffix string) host.Name { + return host.Name(fmt.Sprintf("%s.%s.svc.%s", name, namespace, domainSuffix)) } // kubeToIstioServiceAccount converts a K8s service account to an Istio service account diff --git a/pilot/pkg/serviceregistry/memory/discovery.go b/pilot/pkg/serviceregistry/memory/discovery.go index bd043cd109bd..513bf5bb6d19 100644 --- a/pilot/pkg/serviceregistry/memory/discovery.go +++ b/pilot/pkg/serviceregistry/memory/discovery.go @@ -20,7 +20,7 @@ import ( "time" "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/spiffe" @@ -32,7 +32,7 @@ var ( ) // NewDiscovery builds a memory ServiceDiscovery -func NewDiscovery(services map[config.Hostname]*model.Service, versions int) *ServiceDiscovery { +func NewDiscovery(services map[host.Name]*model.Service, versions int) *ServiceDiscovery { return &ServiceDiscovery{ services: services, versions: versions, @@ -40,7 +40,7 @@ func NewDiscovery(services map[config.Hostname]*model.Service, versions int) *Se } // MakeService creates a memory service -func MakeService(hostname config.Hostname, address string) *model.Service { +func MakeService(hostname host.Name, address string) *model.Service { return &model.Service{ CreationTime: time.Now(), Hostname: hostname, @@ -76,7 +76,7 @@ func MakeService(hostname config.Hostname, address string) *model.Service { } // MakeExternalHTTPService creates memory external service -func MakeExternalHTTPService(hostname config.Hostname, isMeshExternal bool, address string) *model.Service { +func MakeExternalHTTPService(hostname host.Name, isMeshExternal bool, address string) *model.Service { return &model.Service{ CreationTime: time.Now(), Hostname: hostname, @@ -91,7 +91,7 @@ func MakeExternalHTTPService(hostname config.Hostname, isMeshExternal bool, addr } // MakeExternalHTTPSService creates memory external service -func MakeExternalHTTPSService(hostname config.Hostname, isMeshExternal bool, address string) *model.Service { +func MakeExternalHTTPSService(hostname host.Name, isMeshExternal bool, address string) *model.Service { return &model.Service{ CreationTime: time.Now(), Hostname: hostname, @@ -143,7 +143,7 @@ func MakeIP(service *model.Service, version int) string { // ServiceDiscovery is a memory discovery interface type ServiceDiscovery struct { - services map[config.Hostname]*model.Service + services map[host.Name]*model.Service versions int WantGetProxyServiceInstances []*model.ServiceInstance ServicesError error @@ -161,7 +161,7 @@ func (sd *ServiceDiscovery) ClearErrors() { } // AddService will add to the registry the provided service -func (sd *ServiceDiscovery) AddService(name config.Hostname, svc *model.Service) { +func (sd *ServiceDiscovery) AddService(name host.Name, svc *model.Service) { sd.services[name] = svc } @@ -178,7 +178,7 @@ func (sd *ServiceDiscovery) Services() ([]*model.Service, error) { } // GetService implements discovery interface -func (sd *ServiceDiscovery) GetService(hostname config.Hostname) (*model.Service, error) { +func (sd *ServiceDiscovery) GetService(hostname host.Name) (*model.Service, error) { if sd.GetServiceError != nil { return nil, sd.GetServiceError } diff --git a/pilot/pkg/serviceregistry/memory/discovery_mock.go b/pilot/pkg/serviceregistry/memory/discovery_mock.go index b7fa36e10150..5d5eb6d733e5 100644 --- a/pilot/pkg/serviceregistry/memory/discovery_mock.go +++ b/pilot/pkg/serviceregistry/memory/discovery_mock.go @@ -16,7 +16,7 @@ package memory import ( "istio.io/istio/pilot/pkg/model" - "istio.io/istio/pkg/config" + "istio.io/istio/pkg/config/host" ) var ( @@ -50,7 +50,7 @@ var ( // MockDiscovery is an in-memory ServiceDiscover with mock services MockDiscovery = &ServiceDiscovery{ - services: map[config.Hostname]*model.Service{ + services: map[host.Name]*model.Service{ HelloService.Hostname: HelloService, WorldService.Hostname: WorldService, ExtHTTPService.Hostname: ExtHTTPService, diff --git a/pkg/config/hostname.go b/pkg/config/host/name.go similarity index 60% rename from pkg/config/hostname.go rename to pkg/config/host/name.go index b2362b0d657c..1f854438f4c8 100644 --- a/pkg/config/hostname.go +++ b/pkg/config/host/name.go @@ -20,75 +20,79 @@ // generate the configuration files for the Layer 7 proxy sidecar. The proxy // code is specific to individual proxy implementations -package config +package host import ( "strings" ) -// Hostname describes a (possibly wildcarded) hostname -type Hostname string +// Name describes a (possibly wildcarded) hostname +type Name string -// Matches returns true if this hostname overlaps with the other hostname. Hostnames overlap if: +// Matches returns true if this hostname overlaps with the other hostname. Names overlap if: // - they're fully resolved (i.e. not wildcarded) and match exactly (i.e. an exact string match) // - one or both are wildcarded (e.g. "*.foo.com"), in which case we use wildcard resolution rules // to determine if h is covered by o or o is covered by h. // e.g.: -// Hostname("foo.com").Matches("foo.com") = true -// Hostname("foo.com").Matches("bar.com") = false -// Hostname("*.com").Matches("foo.com") = true -// Hostname("bar.com").Matches("*.com") = true -// Hostname("*.foo.com").Matches("foo.com") = false -// Hostname("*").Matches("foo.com") = true -// Hostname("*").Matches("*.com") = true -func (h Hostname) Matches(o Hostname) bool { - hWildcard := len(h) > 0 && string(h[0]) == "*" - oWildcard := len(o) > 0 && string(o[0]) == "*" +// Name("foo.com").Matches("foo.com") = true +// Name("foo.com").Matches("bar.com") = false +// Name("*.com").Matches("foo.com") = true +// Name("bar.com").Matches("*.com") = true +// Name("*.foo.com").Matches("foo.com") = false +// Name("*").Matches("foo.com") = true +// Name("*").Matches("*.com") = true +func (n Name) Matches(o Name) bool { + hWildcard := n.isWildCarded() + oWildcard := o.isWildCarded() if hWildcard { if oWildcard { - // both h and o are wildcards - if len(h) < len(o) { - return strings.HasSuffix(string(o[1:]), string(h[1:])) + // both n and o are wildcards + if len(n) < len(o) { + return strings.HasSuffix(string(o[1:]), string(n[1:])) } - return strings.HasSuffix(string(h[1:]), string(o[1:])) + return strings.HasSuffix(string(n[1:]), string(o[1:])) } - // only h is wildcard - return strings.HasSuffix(string(o), string(h[1:])) + // only n is wildcard + return strings.HasSuffix(string(o), string(n[1:])) } if oWildcard { // only o is wildcard - return strings.HasSuffix(string(h), string(o[1:])) + return strings.HasSuffix(string(n), string(o[1:])) } // both are non-wildcards, so do normal string comparison - return h == o + return n == o } // SubsetOf returns true if this hostname is a valid subset of the other hostname. The semantics are // the same as "Matches", but only in one direction (i.e., h is covered by o). -func (h Hostname) SubsetOf(o Hostname) bool { - hWildcard := len(h) > 0 && string(h[0]) == "*" - oWildcard := len(o) > 0 && string(o[0]) == "*" +func (n Name) SubsetOf(o Name) bool { + hWildcard := n.isWildCarded() + oWildcard := o.isWildCarded() if hWildcard { if oWildcard { - // both h and o are wildcards - if len(h) < len(o) { + // both n and o are wildcards + if len(n) < len(o) { return false } - return strings.HasSuffix(string(h[1:]), string(o[1:])) + return strings.HasSuffix(string(n[1:]), string(o[1:])) } - // only h is wildcard + // only n is wildcard return false } if oWildcard { // only o is wildcard - return strings.HasSuffix(string(h), string(o[1:])) + return strings.HasSuffix(string(n), string(o[1:])) } // both are non-wildcards, so do normal string comparison - return h == o + return n == o +} + +func (n Name) isWildCarded() bool { + return len(n) > 0 && string(n[0]) == "*" } diff --git a/pkg/config/hostname_test.go b/pkg/config/host/name_test.go similarity index 95% rename from pkg/config/hostname_test.go rename to pkg/config/host/name_test.go index 9ddb1b2a2287..5255b5eb1fe0 100644 --- a/pkg/config/hostname_test.go +++ b/pkg/config/host/name_test.go @@ -12,17 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package config +package host_test import ( "fmt" "testing" + + "istio.io/istio/pkg/config/host" ) -func TestHostnameMatches(t *testing.T) { +func TestNameMatches(t *testing.T) { tests := []struct { name string - a, b Hostname + a, b host.Name out bool }{ {"empty", "", "", true}, @@ -73,10 +75,10 @@ func TestHostnameMatches(t *testing.T) { } } -func TestHostnameSubsetOf(t *testing.T) { +func TestNameSubsetOf(t *testing.T) { tests := []struct { name string - a, b Hostname + a, b host.Name out bool }{ {"empty", "", "", true}, @@ -124,9 +126,9 @@ func TestHostnameSubsetOf(t *testing.T) { } } -func BenchmarkMatch(b *testing.B) { +func BenchmarkNameMatch(b *testing.B) { tests := []struct { - a, z Hostname + a, z host.Name matches bool }{ {"foo.com", "foo.com", true}, diff --git a/pkg/config/hostnames.go b/pkg/config/host/names.go similarity index 56% rename from pkg/config/hostnames.go rename to pkg/config/host/names.go index 17ed6d216685..8a3436ad837c 100644 --- a/pkg/config/hostnames.go +++ b/pkg/config/host/names.go @@ -12,26 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -package config +package host import ( "sort" "strings" ) -// Hostnames is a collection of Hostname; it exists so it's easy to sort hostnames consistently across Pilot. +// Names is a collection of Name; it exists so it's easy to sort hostnames consistently across Istio. // In a few locations we care about the order hostnames appear in Envoy config: primarily HTTP routes, but also in // gateways, and for SNI. In those locations, we sort hostnames longest to shortest with wildcards last. -type Hostnames []Hostname +type Names []Name // prove we implement the interface at compile time -var _ sort.Interface = Hostnames{} +var _ sort.Interface = Names{} -func (h Hostnames) Len() int { +func (h Names) Len() int { return len(h) } -func (h Hostnames) Less(i, j int) bool { +func (h Names) Less(i, j int) bool { a, b := h[i], h[j] if len(a) == 0 && len(b) == 0 { return true // doesn't matter, they're both the empty string @@ -55,11 +55,11 @@ func (h Hostnames) Less(i, j int) bool { return len(a) > len(b) } -func (h Hostnames) Swap(i, j int) { +func (h Names) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -func (h Hostnames) Contains(host Hostname) bool { +func (h Names) Contains(host Name) bool { for _, hHost := range h { if hHost == host { return true @@ -70,13 +70,13 @@ func (h Hostnames) Contains(host Hostname) bool { // Intersection returns the subset of host names that are covered by both h and other. // e.g.: -// Hostnames(["foo.com","bar.com"]).Intersection(Hostnames(["*.com"])) = Hostnames(["foo.com","bar.com"]) -// Hostnames(["foo.com","*.net"]).Intersection(Hostnames(["*.com","bar.net"])) = Hostnames(["foo.com","bar.net"]) -// Hostnames(["foo.com","*.net"]).Intersection(Hostnames(["*.bar.net"])) = Hostnames(["*.bar.net"]) -// Hostnames(["foo.com"]).Intersection(Hostnames(["bar.com"])) = Hostnames([]) -// Hostnames([]).Intersection(Hostnames(["bar.com"]) = Hostnames([]) -func (h Hostnames) Intersection(other Hostnames) Hostnames { - result := make(Hostnames, 0, len(h)) +// Names(["foo.com","bar.com"]).Intersection(Names(["*.com"])) = Names(["foo.com","bar.com"]) +// Names(["foo.com","*.net"]).Intersection(Names(["*.com","bar.net"])) = Names(["foo.com","bar.net"]) +// Names(["foo.com","*.net"]).Intersection(Names(["*.bar.net"])) = Names(["*.bar.net"]) +// Names(["foo.com"]).Intersection(Names(["bar.com"])) = Names([]) +// Names([]).Intersection(Names(["bar.com"]) = Names([]) +func (h Names) Intersection(other Names) Names { + result := make(Names, 0, len(h)) for _, hHost := range h { for _, oHost := range other { if hHost.SubsetOf(oHost) { @@ -93,27 +93,27 @@ func (h Hostnames) Intersection(other Hostnames) Hostnames { return result } -// StringsToHostnames converts a slice of host name strings to type Hostnames. -func StringsToHostnames(hosts []string) Hostnames { - result := make(Hostnames, 0, len(hosts)) +// NewNames converts a slice of host name strings to type Names. +func NewNames(hosts []string) Names { + result := make(Names, 0, len(hosts)) for _, host := range hosts { - result = append(result, Hostname(host)) + result = append(result, Name(host)) } return result } -// HostnamesForNamespace returns the subset of hosts that are in the specified namespace. +// NamesForNamespace returns the subset of hosts that are in the specified namespace. // The list of hosts contains host names optionally qualified with namespace/ or */. // If not qualified or qualified with *, the host name is considered to be in every namespace. // e.g.: -// HostnamesForNamespace(["ns1/foo.com","ns2/bar.com"], "ns1") = Hostnames(["foo.com"]) -// HostnamesForNamespace(["ns1/foo.com","ns2/bar.com"], "ns3") = Hostnames([]) -// HostnamesForNamespace(["ns1/foo.com","*/bar.com"], "ns1") = Hostnames(["foo.com","bar.com"]) -// HostnamesForNamespace(["ns1/foo.com","*/bar.com"], "ns3") = Hostnames(["bar.com"]) -// HostnamesForNamespace(["foo.com","ns2/bar.com"], "ns2") = Hostnames(["foo.com","bar.com"]) -// HostnamesForNamespace(["foo.com","ns2/bar.com"], "ns3") = Hostnames(["foo.com"]) -func HostnamesForNamespace(hosts []string, namespace string) Hostnames { - result := make(Hostnames, 0, len(hosts)) +// NamesForNamespace(["ns1/foo.com","ns2/bar.com"], "ns1") = Names(["foo.com"]) +// NamesForNamespace(["ns1/foo.com","ns2/bar.com"], "ns3") = Names([]) +// NamesForNamespace(["ns1/foo.com","*/bar.com"], "ns1") = Names(["foo.com","bar.com"]) +// NamesForNamespace(["ns1/foo.com","*/bar.com"], "ns3") = Names(["bar.com"]) +// NamesForNamespace(["foo.com","ns2/bar.com"], "ns2") = Names(["foo.com","bar.com"]) +// NamesForNamespace(["foo.com","ns2/bar.com"], "ns3") = Names(["foo.com"]) +func NamesForNamespace(hosts []string, namespace string) Names { + result := make(Names, 0, len(hosts)) for _, host := range hosts { if strings.Contains(host, "/") { parts := strings.Split(host, "/") @@ -123,7 +123,7 @@ func HostnamesForNamespace(hosts []string, namespace string) Hostnames { //strip the namespace host = parts[1] } - result = append(result, Hostname(host)) + result = append(result, Name(host)) } return result } diff --git a/pkg/config/host/names_test.go b/pkg/config/host/names_test.go new file mode 100644 index 000000000000..58340a6c99b6 --- /dev/null +++ b/pkg/config/host/names_test.go @@ -0,0 +1,199 @@ +// Copyright 2017 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 host_test + +import ( + "fmt" + "reflect" + "sort" + "testing" + + "istio.io/istio/pkg/config/host" +) + +func TestNamesIntersection(t *testing.T) { + tests := []struct { + a, b, intersection host.Names + }{ + { + host.Names{"foo,com"}, + host.Names{"bar.com"}, + host.Names{}, + }, + { + host.Names{"foo.com", "bar.com"}, + host.Names{"bar.com"}, + host.Names{"bar.com"}, + }, + { + host.Names{"foo.com", "bar.com"}, + host.Names{"*.com"}, + host.Names{"foo.com", "bar.com"}, + }, + { + host.Names{"*.com"}, + host.Names{"foo.com", "bar.com"}, + host.Names{"foo.com", "bar.com"}, + }, + { + host.Names{"foo.com", "*.net"}, + host.Names{"*.com", "bar.net"}, + host.Names{"foo.com", "bar.net"}, + }, + { + host.Names{"foo.com", "*.net"}, + host.Names{"*.bar.net"}, + host.Names{"*.bar.net"}, + }, + { + host.Names{"foo.com", "bar.net"}, + host.Names{"*"}, + host.Names{"foo.com", "bar.net"}, + }, + { + host.Names{"foo.com"}, + host.Names{}, + host.Names{}, + }, + { + host.Names{}, + host.Names{"bar.com"}, + host.Names{}, + }, + { + host.Names{"*", "foo.com"}, + host.Names{"foo.com"}, + host.Names{"foo.com"}, + }, + } + + for idx, tt := range tests { + t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { + result := tt.a.Intersection(tt.b) + if !reflect.DeepEqual(result, tt.intersection) { + t.Fatalf("%v.Intersection(%v) = %v, want %v", tt.a, tt.b, result, tt.intersection) + } + }) + } +} + +func TestNamesForNamespace(t *testing.T) { + tests := []struct { + hosts []string + namespace string + want host.Names + }{ + { + []string{"ns1/foo.com", "ns2/bar.com"}, + "ns1", + host.Names{"foo.com"}, + }, + { + []string{"ns1/foo.com", "ns2/bar.com"}, + "ns3", + host.Names{}, + }, + { + []string{"ns1/foo.com", "*/bar.com"}, + "ns1", + host.Names{"foo.com", "bar.com"}, + }, + { + []string{"ns1/foo.com", "*/bar.com"}, + "ns3", + host.Names{"bar.com"}, + }, + { + []string{"foo.com", "ns2/bar.com"}, + "ns2", + host.Names{"foo.com", "bar.com"}, + }, + { + []string{"foo.com", "ns2/bar.com"}, + "ns3", + host.Names{"foo.com"}, + }, + } + + for idx, tt := range tests { + t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { + result := host.NamesForNamespace(tt.hosts, tt.namespace) + if !reflect.DeepEqual(result, tt.want) { + t.Fatalf("host.NamesForNamespace(%v, %v) = %v, want %v", tt.hosts, tt.namespace, result, tt.want) + } + }) + } +} + +func TestNamesSortOrder(t *testing.T) { + tests := []struct { + in, want host.Names + }{ + // Prove we sort alphabetically: + { + host.Names{"b", "a"}, + host.Names{"a", "b"}, + }, + { + host.Names{"bb", "cc", "aa"}, + host.Names{"aa", "bb", "cc"}, + }, + // Prove we sort longest first, alphabetically: + { + host.Names{"b", "a", "aa"}, + host.Names{"aa", "a", "b"}, + }, + { + host.Names{"foo.com", "bar.com", "foo.bar.com"}, + host.Names{"foo.bar.com", "bar.com", "foo.com"}, + }, + // We sort wildcards last, always + { + host.Names{"a", "*", "z"}, + host.Names{"a", "z", "*"}, + }, + { + host.Names{"foo.com", "bar.com", "*.com"}, + host.Names{"bar.com", "foo.com", "*.com"}, + }, + { + host.Names{"foo.com", "bar.com", "*.com", "*.foo.com", "*", "baz.bar.com"}, + host.Names{"baz.bar.com", "bar.com", "foo.com", "*.foo.com", "*.com", "*"}, + }, + } + + for idx, tt := range tests { + t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { + // Save a copy to report errors with + tmp := make(host.Names, len(tt.in)) + copy(tmp, tt.in) + + sort.Sort(tt.in) + if !reflect.DeepEqual(tt.in, tt.want) { + t.Fatalf("sort.Sort(%v) = %v, want %v", tmp, tt.in, tt.want) + } + }) + } +} + +func BenchmarkNamesSort(b *testing.B) { + unsorted := host.Names{"foo.com", "bar.com", "*.com", "*.foo.com", "*", "baz.bar.com"} + + for n := 0; n < b.N; n++ { + given := make(host.Names, len(unsorted)) + copy(given, unsorted) + sort.Sort(given) + } +} diff --git a/pkg/config/hostnames_test.go b/pkg/config/hostnames_test.go deleted file mode 100644 index 393951b17abb..000000000000 --- a/pkg/config/hostnames_test.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2017 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 ( - "fmt" - "reflect" - "sort" - "testing" -) - -func TestHostnamesIntersection(t *testing.T) { - tests := []struct { - a, b, intersection Hostnames - }{ - { - Hostnames{"foo,com"}, - Hostnames{"bar.com"}, - Hostnames{}, - }, - { - Hostnames{"foo.com", "bar.com"}, - Hostnames{"bar.com"}, - Hostnames{"bar.com"}, - }, - { - Hostnames{"foo.com", "bar.com"}, - Hostnames{"*.com"}, - Hostnames{"foo.com", "bar.com"}, - }, - { - Hostnames{"*.com"}, - Hostnames{"foo.com", "bar.com"}, - Hostnames{"foo.com", "bar.com"}, - }, - { - Hostnames{"foo.com", "*.net"}, - Hostnames{"*.com", "bar.net"}, - Hostnames{"foo.com", "bar.net"}, - }, - { - Hostnames{"foo.com", "*.net"}, - Hostnames{"*.bar.net"}, - Hostnames{"*.bar.net"}, - }, - { - Hostnames{"foo.com", "bar.net"}, - Hostnames{"*"}, - Hostnames{"foo.com", "bar.net"}, - }, - { - Hostnames{"foo.com"}, - Hostnames{}, - Hostnames{}, - }, - { - Hostnames{}, - Hostnames{"bar.com"}, - Hostnames{}, - }, - { - Hostnames{"*", "foo.com"}, - Hostnames{"foo.com"}, - Hostnames{"foo.com"}, - }, - } - - for idx, tt := range tests { - t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { - result := tt.a.Intersection(tt.b) - if !reflect.DeepEqual(result, tt.intersection) { - t.Fatalf("%v.Intersection(%v) = %v, want %v", tt.a, tt.b, result, tt.intersection) - } - }) - } -} - -func TestHostnamesForNamespace(t *testing.T) { - tests := []struct { - hosts []string - namespace string - want Hostnames - }{ - { - []string{"ns1/foo.com", "ns2/bar.com"}, - "ns1", - Hostnames{"foo.com"}, - }, - { - []string{"ns1/foo.com", "ns2/bar.com"}, - "ns3", - Hostnames{}, - }, - { - []string{"ns1/foo.com", "*/bar.com"}, - "ns1", - Hostnames{"foo.com", "bar.com"}, - }, - { - []string{"ns1/foo.com", "*/bar.com"}, - "ns3", - Hostnames{"bar.com"}, - }, - { - []string{"foo.com", "ns2/bar.com"}, - "ns2", - Hostnames{"foo.com", "bar.com"}, - }, - { - []string{"foo.com", "ns2/bar.com"}, - "ns3", - Hostnames{"foo.com"}, - }, - } - - for idx, tt := range tests { - t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { - result := HostnamesForNamespace(tt.hosts, tt.namespace) - if !reflect.DeepEqual(result, tt.want) { - t.Fatalf("HostnamesForNamespace(%v, %v) = %v, want %v", tt.hosts, tt.namespace, result, tt.want) - } - }) - } -} - -func TestHostnamesSortOrder(t *testing.T) { - tests := []struct { - in, want Hostnames - }{ - // Prove we sort alphabetically: - { - Hostnames{"b", "a"}, - Hostnames{"a", "b"}, - }, - { - Hostnames{"bb", "cc", "aa"}, - Hostnames{"aa", "bb", "cc"}, - }, - // Prove we sort longest first, alphabetically: - { - Hostnames{"b", "a", "aa"}, - Hostnames{"aa", "a", "b"}, - }, - { - Hostnames{"foo.com", "bar.com", "foo.bar.com"}, - Hostnames{"foo.bar.com", "bar.com", "foo.com"}, - }, - // We sort wildcards last, always - { - Hostnames{"a", "*", "z"}, - Hostnames{"a", "z", "*"}, - }, - { - Hostnames{"foo.com", "bar.com", "*.com"}, - Hostnames{"bar.com", "foo.com", "*.com"}, - }, - { - Hostnames{"foo.com", "bar.com", "*.com", "*.foo.com", "*", "baz.bar.com"}, - Hostnames{"baz.bar.com", "bar.com", "foo.com", "*.foo.com", "*.com", "*"}, - }, - } - - for idx, tt := range tests { - t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) { - // Save a copy to report errors with - tmp := make(Hostnames, len(tt.in)) - copy(tmp, tt.in) - - sort.Sort(tt.in) - if !reflect.DeepEqual(tt.in, tt.want) { - t.Fatalf("sort.Sort(%v) = %v, want %v", tmp, tt.in, tt.want) - } - }) - } -} - -func BenchmarkSort(b *testing.B) { - unsorted := Hostnames{"foo.com", "bar.com", "*.com", "*.foo.com", "*", "baz.bar.com"} - - for n := 0; n < b.N; n++ { - given := make(Hostnames, len(unsorted)) - copy(given, unsorted) - sort.Sort(given) - } -} diff --git a/pkg/config/security.go b/pkg/config/security.go index 9254ea7bf8b0..65863e3535ac 100644 --- a/pkg/config/security.go +++ b/pkg/config/security.go @@ -26,11 +26,13 @@ import ( "fmt" "net/url" "strconv" + + "istio.io/istio/pkg/config/host" ) // JwksInfo provides values resulting from parsing a jwks URI. type JwksInfo struct { - Hostname Hostname + Hostname host.Name Scheme string Port int UseSSL bool @@ -67,7 +69,7 @@ func ParseJwksURI(jwksURI string) (JwksInfo, error) { return JwksInfo{}, err } } - info.Hostname = Hostname(u.Hostname()) + info.Hostname = host.Name(u.Hostname()) info.Scheme = u.Scheme return info, nil diff --git a/pkg/config/validation.go b/pkg/config/validation.go index 2d08997bc6bd..1b776e5a5153 100644 --- a/pkg/config/validation.go +++ b/pkg/config/validation.go @@ -39,6 +39,7 @@ import ( "istio.io/pkg/log" "istio.io/istio/pkg/config/constants" + "istio.io/istio/pkg/config/host" "istio.io/istio/pkg/config/labels" "istio.io/istio/pkg/config/protocol" "istio.io/istio/pkg/config/visibility" @@ -344,8 +345,8 @@ func validateServer(server *networking.Server) (errs error) { if len(server.Hosts) == 0 { errs = appendErrors(errs, fmt.Errorf("server config must contain at least one host")) } else { - for _, host := range server.Hosts { - errs = appendErrors(errs, validateNamespaceSlashWildcardHostname(host, true)) + for _, hostname := range server.Hosts { + errs = appendErrors(errs, validateNamespaceSlashWildcardHostname(hostname, true)) } } portErr := validateServerPort(server.Port) @@ -584,19 +585,19 @@ func ValidateEnvoyFilter(_, _ string, msg proto.Message) (errs error) { // validates that hostname in ns/ is a valid hostname according to // API specs -func validateSidecarOrGatewayHostnamePart(host string, isGateway bool) (errs error) { +func validateSidecarOrGatewayHostnamePart(hostname string, isGateway bool) (errs error) { // short name hosts are not allowed - if host != "*" && !strings.Contains(host, ".") { + if hostname != "*" && !strings.Contains(hostname, ".") { errs = appendErrors(errs, fmt.Errorf("short names (non FQDN) are not allowed")) } - if err := ValidateWildcardDomain(host); err != nil { + if err := ValidateWildcardDomain(hostname); err != nil { if !isGateway { errs = appendErrors(errs, err) } // Gateway allows IP as the host string, as well - ipAddr := net.ParseIP(host) + ipAddr := net.ParseIP(hostname) if ipAddr == nil { errs = appendErrors(errs, err) } @@ -604,12 +605,12 @@ func validateSidecarOrGatewayHostnamePart(host string, isGateway bool) (errs err return } -func validateNamespaceSlashWildcardHostname(host string, isGateway bool) (errs error) { - parts := strings.SplitN(host, "/", 2) +func validateNamespaceSlashWildcardHostname(hostname string, isGateway bool) (errs error) { + parts := strings.SplitN(hostname, "/", 2) if len(parts) != 2 { if isGateway { // Old style host in the gateway - return validateSidecarOrGatewayHostnamePart(host, true) + return validateSidecarOrGatewayHostnamePart(hostname, true) } errs = appendErrors(errs, fmt.Errorf("host must be of form namespace/dnsName")) return @@ -744,8 +745,8 @@ func ValidateSidecar(_, _ string, msg proto.Message) (errs error) { if len(i.Hosts) == 0 { errs = appendErrors(errs, fmt.Errorf("sidecar: egress listener must contain at least one host")) } else { - for _, host := range i.Hosts { - errs = appendErrors(errs, validateNamespaceSlashWildcardHostname(host, false)) + for _, hostname := range i.Hosts { + errs = appendErrors(errs, validateNamespaceSlashWildcardHostname(hostname, false)) } } } @@ -926,7 +927,7 @@ func validatePortTrafficPolicies(pls []*networking.TrafficPolicy_PortTrafficPoli // ValidateProxyAddress checks that a network address is well-formed func ValidateProxyAddress(hostAddr string) error { - host, p, err := net.SplitHostPort(hostAddr) + hostname, p, err := net.SplitHostPort(hostAddr) if err != nil { return fmt.Errorf("unable to split %q: %v", hostAddr, err) } @@ -937,10 +938,10 @@ func ValidateProxyAddress(hostAddr string) error { if err = ValidatePort(port); err != nil { return err } - if err = ValidateFQDN(host); err != nil { - ip := net.ParseIP(host) + if err = ValidateFQDN(hostname); err != nil { + ip := net.ParseIP(hostname) if ip == nil { - return fmt.Errorf("%q is not a valid hostname or an IP address", host) + return fmt.Errorf("%q is not a valid hostname or an IP address", hostname) } } @@ -1754,14 +1755,14 @@ func ValidateVirtualService(_, _ string, msg proto.Message) (errs error) { } allHostsValid := true - for _, host := range virtualService.Hosts { - if err := ValidateWildcardDomain(host); err != nil { - ipAddr := net.ParseIP(host) // Could also be an IP + for _, virtualHost := range virtualService.Hosts { + if err := ValidateWildcardDomain(virtualHost); err != nil { + ipAddr := net.ParseIP(virtualHost) // Could also be an IP if ipAddr == nil { errs = appendErrors(errs, err) allHostsValid = false } - } else if appliesToMesh && host == "*" { + } else if appliesToMesh && virtualHost == "*" { errs = appendErrors(errs, fmt.Errorf("wildcard host * is not allowed for virtual services bound to the mesh gateway")) allHostsValid = false } @@ -1772,9 +1773,9 @@ func ValidateVirtualService(_, _ string, msg proto.Message) (errs error) { // E.g., *.foo.com, and *.com are duplicates in the same virtual service if allHostsValid { for i := 0; i < len(virtualService.Hosts); i++ { - hostI := Hostname(virtualService.Hosts[i]) + hostI := host.Name(virtualService.Hosts[i]) for j := i + 1; j < len(virtualService.Hosts); j++ { - hostJ := Hostname(virtualService.Hosts[j]) + hostJ := host.Name(virtualService.Hosts[j]) if hostI.Matches(hostJ) { errs = appendErrors(errs, fmt.Errorf("duplicate hosts in virtual service: %s & %s", hostI, hostJ)) } @@ -1847,9 +1848,9 @@ func validateSniHost(sniHost string, context *networking.VirtualService) error { return err } } - sniHostname := Hostname(sniHost) - for _, host := range context.Hosts { - if sniHostname.SubsetOf(Hostname(host)) { + sniHostname := host.Name(sniHost) + for _, hostname := range context.Hosts { + if sniHostname.SubsetOf(host.Name(hostname)) { return nil } } @@ -2075,11 +2076,11 @@ func validateCORSPolicy(policy *networking.CorsPolicy) (errs error) { return } - for _, host := range policy.AllowOrigin { - if host != "*" { - host = strings.TrimPrefix(host, "https://") - host = strings.TrimPrefix(host, "http://") - parts := strings.Split(host, ":") + for _, hostname := range policy.AllowOrigin { + if hostname != "*" { + hostname = strings.TrimPrefix(hostname, "https://") + hostname = strings.TrimPrefix(hostname, "http://") + parts := strings.Split(hostname, ":") if len(parts) > 2 { errs = appendErrors(errs, fmt.Errorf("CORS Allow Origin must be '*' or of [http[s]://]host[:port] format")) } else { @@ -2089,9 +2090,9 @@ func validateCORSPolicy(policy *networking.CorsPolicy) (errs error) { } else { errs = ValidatePort(port) } - host = parts[0] + hostname = parts[0] } - errs = appendErrors(errs, ValidateFQDN(host)) + errs = appendErrors(errs, ValidateFQDN(hostname)) } } } @@ -2191,11 +2192,11 @@ func validateDestination(destination *networking.Destination) (errs error) { return } - host := destination.Host - if host == "*" { - errs = appendErrors(errs, fmt.Errorf("invalid destination host %s", host)) + hostname := destination.Host + if hostname == "*" { + errs = appendErrors(errs, fmt.Errorf("invalid destination host %s", hostname)) } else { - errs = appendErrors(errs, ValidateWildcardDomain(host)) + errs = appendErrors(errs, ValidateWildcardDomain(hostname)) } if destination.Subset != "" { errs = appendErrors(errs, validateSubsetName(destination.Subset)) @@ -2312,12 +2313,12 @@ func ValidateServiceEntry(_, _ string, config proto.Message) (errs error) { if len(serviceEntry.Hosts) == 0 { errs = appendErrors(errs, fmt.Errorf("service entry must have at least one host")) } - for _, host := range serviceEntry.Hosts { + for _, hostname := range serviceEntry.Hosts { // Full wildcard is not allowed in the service entry. - if host == "*" { - errs = appendErrors(errs, fmt.Errorf("invalid host %s", host)) + if hostname == "*" { + errs = appendErrors(errs, fmt.Errorf("invalid host %s", hostname)) } else { - errs = appendErrors(errs, ValidateWildcardDomain(host)) + errs = appendErrors(errs, ValidateWildcardDomain(hostname)) } } @@ -2383,8 +2384,8 @@ func ValidateServiceEntry(_, _ string, config proto.Message) (errs error) { } case networking.ServiceEntry_DNS: if len(serviceEntry.Endpoints) == 0 { - for _, host := range serviceEntry.Hosts { - if err := ValidateFQDN(host); err != nil { + for _, hostname := range serviceEntry.Hosts { + if err := ValidateFQDN(hostname); err != nil { errs = appendErrors(errs, fmt.Errorf("hosts must be FQDN if no endpoints are provided for resolution mode DNS")) }