diff --git a/admiral/cmd/admiral/cmd/root.go b/admiral/cmd/admiral/cmd/root.go index 4e100077..91556e03 100644 --- a/admiral/cmd/admiral/cmd/root.go +++ b/admiral/cmd/admiral/cmd/root.go @@ -4,17 +4,17 @@ import ( "context" "flag" "fmt" - "github.com/istio-ecosystem/admiral/admiral/pkg/apis/admiral/routes" - "github.com/istio-ecosystem/admiral/admiral/pkg/apis/admiral/server" - "github.com/istio-ecosystem/admiral/admiral/pkg/clusters" - "github.com/istio-ecosystem/admiral/admiral/pkg/controller/common" - log "github.com/sirupsen/logrus" "os" "os/signal" "sync" "syscall" "time" + "github.com/istio-ecosystem/admiral/admiral/pkg/apis/admiral/routes" + "github.com/istio-ecosystem/admiral/admiral/pkg/apis/admiral/server" + "github.com/istio-ecosystem/admiral/admiral/pkg/clusters" + "github.com/istio-ecosystem/admiral/admiral/pkg/controller/common" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -142,6 +142,8 @@ func GetRootCmd(args []string) *cobra.Command { "The value of envoy filter is to add additional config to the filter config section") rootCmd.PersistentFlags().BoolVar(¶ms.EnableRoutingPolicy, "enable_routing_policy", false, "If Routing Policy feature needs to be enabled") + rootCmd.PersistentFlags().StringArrayVar(¶ms.ExcludedIdentityList, "excluded_identity_list", []string{}, + "List of identities which should be excluded from getting processed") return rootCmd } diff --git a/admiral/pkg/clusters/handler.go b/admiral/pkg/clusters/handler.go index 2b5d9c8d..a2bf4e70 100644 --- a/admiral/pkg/clusters/handler.go +++ b/admiral/pkg/clusters/handler.go @@ -8,16 +8,15 @@ import ( "strings" "time" + argo "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" + "github.com/golang/protobuf/ptypes/duration" + "github.com/golang/protobuf/ptypes/wrappers" + "github.com/google/go-cmp/cmp" "github.com/istio-ecosystem/admiral/admiral/pkg/apis/admiral/model" v1 "github.com/istio-ecosystem/admiral/admiral/pkg/apis/admiral/v1" "github.com/istio-ecosystem/admiral/admiral/pkg/controller/admiral" "github.com/istio-ecosystem/admiral/admiral/pkg/controller/common" "github.com/istio-ecosystem/admiral/admiral/pkg/controller/util" - - argo "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" - "github.com/golang/protobuf/ptypes/duration" - "github.com/golang/protobuf/ptypes/wrappers" - "github.com/google/go-cmp/cmp" log "github.com/sirupsen/logrus" "google.golang.org/protobuf/testing/protocmp" v1alpha32 "istio.io/api/networking/v1alpha3" diff --git a/admiral/pkg/clusters/registry_test.go b/admiral/pkg/clusters/registry_test.go index fa7c662b..92f50d53 100644 --- a/admiral/pkg/clusters/registry_test.go +++ b/admiral/pkg/clusters/registry_test.go @@ -3,6 +3,7 @@ package clusters import ( "context" "strings" + "sync" "testing" "time" @@ -23,10 +24,17 @@ import ( "k8s.io/client-go/tools/clientcmd" ) -func init() { - p := common.AdmiralParams{ +var registryTestSingleton sync.Once + +func admiralParamsForRegistryTests() common.AdmiralParams { + return common.AdmiralParams{ + LabelSet: &common.LabelSet{ + WorkloadIdentityKey: "identity", + GlobalTrafficDeploymentLabel: "identity", + PriorityKey: "priority", + EnvKey: "admiral.io/env", + }, KubeconfigPath: "testdata/fake.config", - LabelSet: &common.LabelSet{}, EnableSAN: true, SANPrefix: "prefix", HostnameSuffix: "mesh", @@ -40,34 +48,30 @@ func init() { EnableRoutingPolicy: true, EnvoyFilterVersion: "1.13", } +} - p.LabelSet.WorkloadIdentityKey = "identity" - p.LabelSet.GlobalTrafficDeploymentLabel = "identity" - p.LabelSet.PriorityKey = "priority" - p.LabelSet.EnvKey = "admiral.io/env" - - common.InitializeConfig(p) +func setupForRegistryTests() { + registryTestSingleton.Do(func() { + common.ResetSync() + common.InitializeConfig(admiralParamsForRegistryTests()) + }) } func TestDeleteCacheControllerThatDoesntExist(t *testing.T) { - + setupForRegistryTests() w := NewRemoteRegistry(nil, common.AdmiralParams{}) - err := w.deleteCacheController("I don't exit") - if err != nil { t.Fail() } } func TestDeleteCacheController(t *testing.T) { - + setupForRegistryTests() w := NewRemoteRegistry(nil, common.AdmiralParams{}) - r := rest.Config{ Host: "test.com", } - cluster := "test.cluster" w.createCacheController(&r, cluster, time.Second*time.Duration(300)) rc := w.GetRemoteController(cluster) @@ -89,7 +93,7 @@ func TestDeleteCacheController(t *testing.T) { } func TestCopyServiceEntry(t *testing.T) { - + setupForRegistryTests() se := networking.ServiceEntry{ Hosts: []string{"test.com"}, } @@ -102,7 +106,7 @@ func TestCopyServiceEntry(t *testing.T) { } func TestCopyEndpoint(t *testing.T) { - + setupForRegistryTests() se := networking.WorkloadEntry{ Address: "127.0.0.1", } @@ -116,6 +120,7 @@ func TestCopyEndpoint(t *testing.T) { } func TestCopySidecar(t *testing.T) { + setupForRegistryTests() spec := networking.Sidecar{ WorkloadSelector: &networking.WorkloadSelector{ Labels: map[string]string{"TestLabel": "TestValue"}, @@ -202,9 +207,8 @@ func createMockRemoteController(f func(interface{})) (*RemoteController, error) } func TestCreateSecretController(t *testing.T) { - + setupForRegistryTests() err := createSecretController(context.Background(), NewRemoteRegistry(nil, common.AdmiralParams{})) - if err != nil { t.Fail() } @@ -221,14 +225,12 @@ func TestCreateSecretController(t *testing.T) { } func TestInitAdmiral(t *testing.T) { - + setupForRegistryTests() p := common.AdmiralParams{ KubeconfigPath: "testdata/fake.config", LabelSet: &common.LabelSet{}, } - p.LabelSet.WorkloadIdentityKey = "overridden-key" - rr, err := InitAdmiral(context.Background(), p) if err != nil { @@ -244,6 +246,7 @@ func TestInitAdmiral(t *testing.T) { } func TestAdded(t *testing.T) { + setupForRegistryTests() ctx := context.Background() p := common.AdmiralParams{ KubeconfigPath: "testdata/fake.config", @@ -279,6 +282,7 @@ func TestAdded(t *testing.T) { } func TestGetServiceForDeployment(t *testing.T) { + setupForRegistryTests() baseRc, _ := createMockRemoteController(func(i interface{}) { //res := i.(istio.Config) //se, ok := res.Spec.(*v1alpha3.ServiceEntry) @@ -364,6 +368,7 @@ func TestGetServiceForDeployment(t *testing.T) { } func TestUpdateCacheController(t *testing.T) { + setupForRegistryTests() p := common.AdmiralParams{ KubeconfigPath: "testdata/fake.config", } diff --git a/admiral/pkg/clusters/serviceentry.go b/admiral/pkg/clusters/serviceentry.go index c6cf2a82..31cdaf7b 100644 --- a/admiral/pkg/clusters/serviceentry.go +++ b/admiral/pkg/clusters/serviceentry.go @@ -99,7 +99,15 @@ func modifyServiceEntryForNewServiceOrPod( if rc.RolloutController != nil { rollout = rc.RolloutController.Cache.Get(sourceIdentity, env) } + if deployment == nil && rollout == nil { + log.Infof("Neither deployment nor rollouts found for identity=%s in env=%s namespace=%s", sourceIdentity, env, namespace) + continue + } if deployment != nil { + if len(remoteRegistry.ExcludedIdentityMap) > 0 && remoteRegistry.ExcludedIdentityMap[common.GetDeploymentGlobalIdentifier(deployment)] { + log.Infof(LogFormat, event, env, sourceIdentity, clusterId, "Processing skipped as identity is in the exclude list") + return nil + } remoteRegistry.AdmiralCache.IdentityClusterCache.Put(sourceIdentity, rc.ClusterID, rc.ClusterID) serviceInstance = getServiceForDeployment(rc, deployment) if serviceInstance == nil { @@ -112,6 +120,10 @@ func modifyServiceEntryForNewServiceOrPod( sourceDeployments[rc.ClusterID] = deployment createServiceEntryForDeployment(ctx, event, rc, remoteRegistry.AdmiralCache, localMeshPorts, deployment, serviceEntries) } else if rollout != nil { + if len(remoteRegistry.ExcludedIdentityMap) > 0 && remoteRegistry.ExcludedIdentityMap[common.GetRolloutGlobalIdentifier(rollout)] { + log.Infof(LogFormat, event, env, sourceIdentity, clusterId, "Processing skipped as identity is in the exclude list") + return nil + } remoteRegistry.AdmiralCache.IdentityClusterCache.Put(sourceIdentity, rc.ClusterID, rc.ClusterID) weightedServices = getServiceForRollout(ctx, rc, rollout) if len(weightedServices) == 0 { @@ -367,8 +379,10 @@ func modifySidecarForLocalClusterCommunication(ctx context.Context, sidecarNames return } - sidecar, _ := sidecarConfig.IstioClient.NetworkingV1alpha3().Sidecars(sidecarNamespace).Get(ctx, common.GetWorkloadSidecarName(), v12.GetOptions{}) - + sidecar, err := sidecarConfig.IstioClient.NetworkingV1alpha3().Sidecars(sidecarNamespace).Get(ctx, common.GetWorkloadSidecarName(), v12.GetOptions{}) + if err != nil { + return + } if sidecar == nil || (sidecar.Spec.Egress == nil) { return } diff --git a/admiral/pkg/clusters/serviceentry_test.go b/admiral/pkg/clusters/serviceentry_test.go index 4a8add8b..946af6c4 100644 --- a/admiral/pkg/clusters/serviceentry_test.go +++ b/admiral/pkg/clusters/serviceentry_test.go @@ -19,38 +19,383 @@ import ( "github.com/istio-ecosystem/admiral/admiral/pkg/controller/common" "github.com/istio-ecosystem/admiral/admiral/pkg/controller/istio" "github.com/istio-ecosystem/admiral/admiral/pkg/test" + log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "google.golang.org/protobuf/testing/protocmp" "gopkg.in/yaml.v2" - istionetworkingv1alpha3 "istio.io/api/networking/v1alpha3" + istioNetworkingV1Alpha3 "istio.io/api/networking/v1alpha3" "istio.io/client-go/pkg/apis/networking/v1alpha3" istiofake "istio.io/client-go/pkg/clientset/versioned/fake" + k8sAppsV1 "k8s.io/api/apps/v1" v14 "k8s.io/api/apps/v1" coreV1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" v12 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/rest" ) -func init() { - p := common.AdmiralParams{ - KubeconfigPath: "testdata/fake.config", - LabelSet: &common.LabelSet{}, +func admiralParamsForServiceEntryTests() common.AdmiralParams { + return common.AdmiralParams{ + KubeconfigPath: "testdata/fake.config", + LabelSet: &common.LabelSet{ + GatewayApp: "gatewayapp", + WorkloadIdentityKey: "identity", + PriorityKey: "priority", + EnvKey: "env", + GlobalTrafficDeploymentLabel: "identity", + }, EnableSAN: true, SANPrefix: "prefix", HostnameSuffix: "mesh", SyncNamespace: "ns", - CacheRefreshDuration: time.Minute, + CacheRefreshDuration: 0, ClusterRegistriesNamespace: "default", DependenciesNamespace: "default", + WorkloadSidecarName: "default", SecretResolver: "", } +} + +var serviceEntryTestSingleton sync.Once + +func setupForServiceEntryTests() { + var initHappened bool + serviceEntryTestSingleton.Do(func() { + common.ResetSync() + initHappened = true + common.InitializeConfig(admiralParamsForServiceEntryTests()) + }) + if !initHappened { + log.Warn("InitializeConfig was NOT called from setupForServiceEntryTests") + } else { + log.Info("InitializeConfig was called setupForServiceEntryTests") + } +} + +func makeTestDeployment(name, namespace, identityLabelValue string) *k8sAppsV1.Deployment { + return &k8sAppsV1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Annotations: map[string]string{ + "env": "test", + "traffic.sidecar.istio.io/includeInboundPorts": "8090", + }, + }, + Spec: k8sAppsV1.DeploymentSpec{ + Template: coreV1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "env": "test", + "traffic.sidecar.istio.io/includeInboundPorts": "8090", + }, + Labels: map[string]string{ + "identity": identityLabelValue, + }, + }, + Spec: coreV1.PodSpec{}, + }, + Selector: &v12.LabelSelector{ + MatchLabels: map[string]string{ + "identity": identityLabelValue, + "app": identityLabelValue, + }, + }, + }, + } +} + +func makeTestRollout(name, namespace, identityLabelValue string) argo.Rollout { + return argo.Rollout{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Annotations: map[string]string{ + "env": "test", + }, + }, + Spec: argo.RolloutSpec{ + Template: coreV1.PodTemplateSpec{ + ObjectMeta: v12.ObjectMeta{ + Labels: map[string]string{"identity": identityLabelValue}, + Annotations: map[string]string{ + "env": "test", + "traffic.sidecar.istio.io/includeInboundPorts": "8090", + }, + }, + }, + Strategy: argo.RolloutStrategy{ + Canary: &argo.CanaryStrategy{ + TrafficRouting: &argo.RolloutTrafficRouting{ + Istio: &argo.IstioTrafficRouting{ + VirtualService: &argo.IstioVirtualService{ + Name: name + "-canary", + }, + }, + }, + CanaryService: name + "-canary", + StableService: name + "-stable", + }, + }, + Selector: &v12.LabelSelector{ + MatchLabels: map[string]string{ + "identity": identityLabelValue, + "app": identityLabelValue, + }, + }, + }, + } +} + +func makeGTP(name, namespace, identity, env, dnsPrefix string, creationTimestamp v12.Time) *v13.GlobalTrafficPolicy { + return &v13.GlobalTrafficPolicy{ + ObjectMeta: v12.ObjectMeta{ + Name: name, + Namespace: namespace, + CreationTimestamp: creationTimestamp, + Labels: map[string]string{"identity": identity, "env": env}, + }, + Spec: model.GlobalTrafficPolicy{ + Policy: []*model.TrafficPolicy{{DnsPrefix: dnsPrefix}}, + }, + } +} + +func TestModifyServiceEntryForNewServiceOrPodForExcludedIdentity(t *testing.T) { + setupForServiceEntryTests() + var ( + env = "test" + stop = make(chan struct{}) + foobarMetadataName = "foobar" + foobarMetadataNamespace = "foobar-ns" + rollout1Identity = "rollout1" + deployment1Identity = "deployment1" + testRollout1 = makeTestRollout(foobarMetadataName, foobarMetadataNamespace, rollout1Identity) + testDeployment1 = makeTestDeployment(foobarMetadataName, foobarMetadataNamespace, deployment1Identity) + clusterID = "test-dev-k8s" + fakeIstioClient = istiofake.NewSimpleClientset() + config = rest.Config{Host: "localhost"} + expectedServiceEntriesForDeployment = map[string]*istioNetworkingV1Alpha3.ServiceEntry{ + "test." + deployment1Identity + ".mesh": &istioNetworkingV1Alpha3.ServiceEntry{ + Hosts: []string{"test." + deployment1Identity + ".mesh"}, + Addresses: []string{"127.0.0.1"}, + Ports: []*istioNetworkingV1Alpha3.Port{ + &istioNetworkingV1Alpha3.Port{ + Number: 80, + Protocol: "http", + Name: "http", + }, + }, + Location: istioNetworkingV1Alpha3.ServiceEntry_MESH_INTERNAL, + Resolution: istioNetworkingV1Alpha3.ServiceEntry_DNS, + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ + &istioNetworkingV1Alpha3.WorkloadEntry{ + Address: "dummy.admiral.global", + Ports: map[string]uint32{ + "http": 0, + }, + Locality: "us-west-2", + }, + }, + SubjectAltNames: []string{"spiffe://prefix/" + deployment1Identity}, + }, + } + /* + expectedServiceEntriesForRollout = map[string]*istioNetworkingV1Alpha3.ServiceEntry{ + "test." + deployment1Identity + ".mesh": &istioNetworkingV1Alpha3.ServiceEntry{ + Hosts: []string{"test." + rollout1Identity + ".mesh"}, + Addresses: []string{"127.0.0.1"}, + Ports: []*istioNetworkingV1Alpha3.Port{ + &istioNetworkingV1Alpha3.Port{ + Number: 80, + Protocol: "http", + Name: "http", + }, + }, + Location: istioNetworkingV1Alpha3.ServiceEntry_MESH_INTERNAL, + Resolution: istioNetworkingV1Alpha3.ServiceEntry_DNS, + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ + &istioNetworkingV1Alpha3.WorkloadEntry{ + Address: "dummy.admiral.global", + Ports: map[string]uint32{ + "http": 0, + }, + Locality: "us-west-2", + }, + }, + SubjectAltNames: []string{"spiffe://prefix/" + rollout1Identity}, + }, + } + */ + serviceEntryAddressStore = &ServiceEntryAddressStore{ + EntryAddresses: map[string]string{ + "test." + deployment1Identity + ".mesh-se": "127.0.0.1", + "test." + rollout1Identity + ".mesh-se": "127.0.0.1", + }, + Addresses: []string{}, + } + serviceForRollout = &coreV1.Service{ + ObjectMeta: v12.ObjectMeta{ + Name: foobarMetadataName + "-stable", + Namespace: foobarMetadataNamespace, + }, + Spec: coreV1.ServiceSpec{ + Selector: map[string]string{"app": rollout1Identity}, + Ports: []coreV1.ServicePort{ + { + Name: "http", + Port: 8090, + }, + }, + }, + } + serviceForDeployment = &coreV1.Service{ + ObjectMeta: v12.ObjectMeta{ + Name: foobarMetadataName, + Namespace: foobarMetadataNamespace, + }, + Spec: coreV1.ServiceSpec{ + Selector: map[string]string{"app": deployment1Identity}, + Ports: []coreV1.ServicePort{ + { + Name: "http", + Port: 8090, + }, + }, + }, + } + rr1, _ = InitAdmiral(context.Background(), admiralParamsForServiceEntryTests()) + rr2, _ = InitAdmiral(context.Background(), admiralParamsForServiceEntryTests()) + ) + deploymentController, err := admiral.NewDeploymentController(clusterID, make(chan struct{}), &test.MockDeploymentHandler{}, &config, time.Second*time.Duration(300)) + if err != nil { + t.Fail() + } + deploymentController.Cache.UpdateDeploymentToClusterCache(deployment1Identity, testDeployment1) + rolloutController, err := admiral.NewRolloutsController(clusterID, make(chan struct{}), &test.MockRolloutHandler{}, &config, time.Second*time.Duration(300)) + if err != nil { + t.Fail() + } + rolloutController.Cache.UpdateRolloutToClusterCache(rollout1Identity, &testRollout1) + serviceController, err := admiral.NewServiceController(clusterID, stop, &test.MockServiceHandler{}, &config, time.Second*time.Duration(300)) + if err != nil { + t.Fatalf("%v", err) + } + virtualServiceController, err := istio.NewVirtualServiceController(clusterID, make(chan struct{}), &test.MockVirtualServiceHandler{}, &config, time.Second*time.Duration(300)) + if err != nil { + t.Fatalf("%v", err) + } + gtpc, err := admiral.NewGlobalTrafficController("", make(chan struct{}), &test.MockGlobalTrafficHandler{}, &config, time.Second*time.Duration(300)) + if err != nil { + t.Fatalf("%v", err) + t.FailNow() + } + t.Logf("expectedServiceEntriesForDeployment: %v\n", expectedServiceEntriesForDeployment) + serviceController.Cache.Put(serviceForRollout) + serviceController.Cache.Put(serviceForDeployment) + rc := &RemoteController{ + ClusterID: clusterID, + DeploymentController: deploymentController, + RolloutController: rolloutController, + ServiceController: serviceController, + VirtualServiceController: virtualServiceController, + NodeController: &admiral.NodeController{ + Locality: &admiral.Locality{ + Region: "us-west-2", + }, + }, + ServiceEntryController: &istio.ServiceEntryController{ + IstioClient: fakeIstioClient, + }, + DestinationRuleController: &istio.DestinationRuleController{ + IstioClient: fakeIstioClient, + }, + GlobalTraffic: gtpc, + } + rr1.PutRemoteController(clusterID, rc) + rr1.ExcludedIdentityMap = map[string]bool{ + "asset1": true, + } + rr1.StartTime = time.Now() + rr1.AdmiralCache.ServiceEntryAddressStore = serviceEntryAddressStore - p.LabelSet.WorkloadIdentityKey = "identity" - p.LabelSet.GlobalTrafficDeploymentLabel = "identity" - p.LabelSet.PriorityKey = "priority" + rr2.PutRemoteController(clusterID, rc) + rr2.StartTime = time.Now() + rr2.AdmiralCache.ServiceEntryAddressStore = serviceEntryAddressStore - common.InitializeConfig(p) + testCases := []struct { + name string + assetIdentity string + remoteRegistry *RemoteRegistry + expectedServiceEntries map[string]*istioNetworkingV1Alpha3.ServiceEntry + }{ + { + name: "Given asset is using a deployment," + + "And asset is in the exclude list, " + + "When modifyServiceEntryForNewServiceOrPod is called, " + + "Then, it should skip creating service entries, and return an empty map of service entries", + assetIdentity: "asset1", + remoteRegistry: rr1, + expectedServiceEntries: nil, + }, + { + name: "Given asset is using a rollout," + + "And asset is in the exclude list, " + + "When modifyServiceEntryForNewServiceOrPod is called, " + + "Then, it should skip creating service entries, and return an empty map of service entries", + assetIdentity: "asset1", + remoteRegistry: rr1, + expectedServiceEntries: nil, + }, + { + name: "Given asset is using a deployment, " + + "And asset is NOT in the exclude list" + + "When modifyServiceEntryForNewServiceOrPod is called, " + + "Then, corresponding service entry should be created, " + + "And the function should return a map containing the created service entry", + assetIdentity: deployment1Identity, + remoteRegistry: rr2, + expectedServiceEntries: expectedServiceEntriesForDeployment, + }, + /* + { + name: "Given asset is using a rollout, " + + "And asset is NOT in the exclude list" + + "When modifyServiceEntryForNewServiceOrPod is called, " + + "Then, corresponding service entry should be created, " + + "And the function should return a map containing the created service entry", + assetIdentity: rollout1Identity, + remoteRegistry: rr2, + expectedServiceEntries: expectedServiceEntriesForRollout, + }, + */ + } + for _, c := range testCases { + t.Run(c.name, func(t *testing.T) { + serviceEntries := modifyServiceEntryForNewServiceOrPod( + context.Background(), + admiral.Add, + env, + c.assetIdentity, + c.remoteRegistry, + ) + if len(serviceEntries) != len(c.expectedServiceEntries) { + t.Fatalf("expected service entries to be of length: %d, but got: %d", len(c.expectedServiceEntries), len(serviceEntries)) + } + if len(c.expectedServiceEntries) > 0 { + for k := range c.expectedServiceEntries { + if serviceEntries[k] == nil { + t.Fatalf( + "expected service entries to contain service entry for: %s, "+ + "but did not find it. Got map: %v", + k, serviceEntries, + ) + } + } + } + }) + } } func TestAddServiceEntriesWithDr(t *testing.T) { @@ -67,21 +412,21 @@ func TestAddServiceEntriesWithDr(t *testing.T) { gtpCache.mutex = &sync.Mutex{} admiralCache.GlobalTrafficCache = gtpCache - se := istionetworkingv1alpha3.ServiceEntry{ + se := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"dev.bar.global"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: "127.0.0.1", Ports: map[string]uint32{"https": 80}, Labels: map[string]string{}, Network: "mesh1", Locality: "us-west", Weight: 100}, }, } - emptyEndpointSe := istionetworkingv1alpha3.ServiceEntry{ + emptyEndpointSe := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"dev.bar.global"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{}, + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{}, } - dummyEndpointSe := istionetworkingv1alpha3.ServiceEntry{ + dummyEndpointSe := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"dev.dummy.global"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: "dummy.admiral.global", Ports: map[string]uint32{"https": 80}, Labels: map[string]string{}, Network: "mesh1", Locality: "us-west", Weight: 100}, }, } @@ -122,9 +467,9 @@ func TestAddServiceEntriesWithDr(t *testing.T) { rr := NewRemoteRegistry(nil, common.AdmiralParams{}) rr.PutRemoteController("cl1", rc) rr.AdmiralCache = &admiralCache - AddServiceEntriesWithDr(ctx, rr, map[string]string{"cl1": "cl1"}, map[string]*istionetworkingv1alpha3.ServiceEntry{"se1": &se}) - AddServiceEntriesWithDr(ctx, rr, map[string]string{"cl1": "cl1"}, map[string]*istionetworkingv1alpha3.ServiceEntry{"se1": &emptyEndpointSe}) - AddServiceEntriesWithDr(ctx, rr, map[string]string{"cl1": "cl1"}, map[string]*istionetworkingv1alpha3.ServiceEntry{"dummySe": &dummyEndpointSe}) + AddServiceEntriesWithDr(ctx, rr, map[string]string{"cl1": "cl1"}, map[string]*istioNetworkingV1Alpha3.ServiceEntry{"se1": &se}) + AddServiceEntriesWithDr(ctx, rr, map[string]string{"cl1": "cl1"}, map[string]*istioNetworkingV1Alpha3.ServiceEntry{"se1": &emptyEndpointSe}) + AddServiceEntriesWithDr(ctx, rr, map[string]string{"cl1": "cl1"}, map[string]*istioNetworkingV1Alpha3.ServiceEntry{"dummySe": &dummyEndpointSe}) } @@ -155,10 +500,10 @@ func TestCreateSeAndDrSetFromGtp(t *testing.T) { admiralCache.ConfigMapController = cacheController - se := &istionetworkingv1alpha3.ServiceEntry{ + se := &istioNetworkingV1Alpha3.ServiceEntry{ Addresses: []string{"240.10.1.0"}, Hosts: []string{host}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: "127.0.0.1", Ports: map[string]uint32{"https": 80}, Labels: map[string]string{}, Locality: "us-west-2"}, {Address: "240.20.0.1", Ports: map[string]uint32{"https": 80}, Labels: map[string]string{}, Locality: "us-east-2"}, }, @@ -222,7 +567,7 @@ func TestCreateSeAndDrSetFromGtp(t *testing.T) { name string env string locality string - se *istionetworkingv1alpha3.ServiceEntry + se *istioNetworkingV1Alpha3.ServiceEntry gtp *v13.GlobalTrafficPolicy seDrSet map[string]*SeDrTuple }{ @@ -530,12 +875,12 @@ func TestModifyExistingSidecarForLocalClusterCommunication(t *testing.T) { existingSidecarObj.ObjectMeta.Namespace = "test-sidecar-namespace" existingSidecarObj.ObjectMeta.Name = "default" - istioEgress := istionetworkingv1alpha3.IstioEgressListener{ + istioEgress := istioNetworkingV1Alpha3.IstioEgressListener{ Hosts: []string{"test-host"}, } - existingSidecarObj.Spec = istionetworkingv1alpha3.Sidecar{ - Egress: []*istionetworkingv1alpha3.IstioEgressListener{&istioEgress}, + existingSidecarObj.Spec = istioNetworkingV1Alpha3.Sidecar{ + Egress: []*istioNetworkingV1Alpha3.IstioEgressListener{&istioEgress}, } ctx := context.Background() @@ -567,7 +912,7 @@ func TestModifyExistingSidecarForLocalClusterCommunication(t *testing.T) { if !cmp.Equal(updatedSidecar, createdSidecar, protocmp.Transform()) { t.Fatalf("Modify existing sidecar failed as configuration is not same. Details - %v", cmp.Diff(updatedSidecar, createdSidecar)) } - var matched *istionetworkingv1alpha3.IstioEgressListener + var matched *istioNetworkingV1Alpha3.IstioEgressListener for _, listener := range createdSidecarEgress { matched = nil @@ -658,93 +1003,93 @@ func TestCreateServiceEntry(t *testing.T) { secondDeployment := v14.Deployment{} secondDeployment.Spec.Template.Labels = map[string]string{"env": "e2e", "identity": "my-first-service"} - se := istionetworkingv1alpha3.ServiceEntry{ + se := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"e2e.my-first-service.mesh"}, Addresses: []string{localAddress}, - Ports: []*istionetworkingv1alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), + Ports: []*istioNetworkingV1Alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), Name: "http", Protocol: "http"}}, - Location: istionetworkingv1alpha3.ServiceEntry_MESH_INTERNAL, - Resolution: istionetworkingv1alpha3.ServiceEntry_DNS, + Location: istioNetworkingV1Alpha3.ServiceEntry_MESH_INTERNAL, + Resolution: istioNetworkingV1Alpha3.ServiceEntry_DNS, SubjectAltNames: []string{"spiffe://prefix/my-first-service"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: "dummy.admiral.global", Ports: map[string]uint32{"http": 0}, Locality: "us-west-2"}, }, } - oneEndpointSe := istionetworkingv1alpha3.ServiceEntry{ + oneEndpointSe := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"e2e.my-first-service.mesh"}, Addresses: []string{localAddress}, - Ports: []*istionetworkingv1alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), + Ports: []*istioNetworkingV1Alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), Name: "http", Protocol: "http"}}, - Location: istionetworkingv1alpha3.ServiceEntry_MESH_INTERNAL, - Resolution: istionetworkingv1alpha3.ServiceEntry_DNS, + Location: istioNetworkingV1Alpha3.ServiceEntry_MESH_INTERNAL, + Resolution: istioNetworkingV1Alpha3.ServiceEntry_DNS, SubjectAltNames: []string{"spiffe://prefix/my-first-service"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: "dummy.admiral.global", Ports: map[string]uint32{"http": 0}, Locality: "us-west-2"}, }, } - twoEndpointSe := istionetworkingv1alpha3.ServiceEntry{ + twoEndpointSe := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"e2e.my-first-service.mesh"}, Addresses: []string{localAddress}, - Ports: []*istionetworkingv1alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), + Ports: []*istioNetworkingV1Alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), Name: "http", Protocol: "http"}}, - Location: istionetworkingv1alpha3.ServiceEntry_MESH_INTERNAL, - Resolution: istionetworkingv1alpha3.ServiceEntry_DNS, + Location: istioNetworkingV1Alpha3.ServiceEntry_MESH_INTERNAL, + Resolution: istioNetworkingV1Alpha3.ServiceEntry_DNS, SubjectAltNames: []string{"spiffe://prefix/my-first-service"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: "dummy.admiral.global", Ports: map[string]uint32{"http": 0}, Locality: "us-west-2"}, {Address: "dummy.admiral.global", Ports: map[string]uint32{"http": 0}, Locality: "us-east-2"}, }, } - threeEndpointSe := istionetworkingv1alpha3.ServiceEntry{ + threeEndpointSe := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"e2e.my-first-service.mesh"}, Addresses: []string{localAddress}, - Ports: []*istionetworkingv1alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), + Ports: []*istioNetworkingV1Alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), Name: "http", Protocol: "http"}}, - Location: istionetworkingv1alpha3.ServiceEntry_MESH_INTERNAL, - Resolution: istionetworkingv1alpha3.ServiceEntry_DNS, + Location: istioNetworkingV1Alpha3.ServiceEntry_MESH_INTERNAL, + Resolution: istioNetworkingV1Alpha3.ServiceEntry_DNS, SubjectAltNames: []string{"spiffe://prefix/my-first-service"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: "dummy.admiral.global", Ports: map[string]uint32{"http": 0}, Locality: "us-west-2"}, {Address: "dummy.admiral.global", Ports: map[string]uint32{"http": 0}, Locality: "us-west-2"}, {Address: "dummy.admiral.global", Ports: map[string]uint32{"http": 0}, Locality: "us-east-2"}, }, } - eastEndpointSe := istionetworkingv1alpha3.ServiceEntry{ + eastEndpointSe := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"e2e.my-first-service.mesh"}, Addresses: []string{localAddress}, - Ports: []*istionetworkingv1alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), + Ports: []*istioNetworkingV1Alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), Name: "http", Protocol: "http"}}, - Location: istionetworkingv1alpha3.ServiceEntry_MESH_INTERNAL, - Resolution: istionetworkingv1alpha3.ServiceEntry_DNS, + Location: istioNetworkingV1Alpha3.ServiceEntry_MESH_INTERNAL, + Resolution: istioNetworkingV1Alpha3.ServiceEntry_DNS, SubjectAltNames: []string{"spiffe://prefix/my-first-service"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: "dummy.admiral.global", Ports: map[string]uint32{"http": 0}, Locality: "us-east-2"}, }, } - emptyEndpointSe := istionetworkingv1alpha3.ServiceEntry{ + emptyEndpointSe := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"e2e.my-first-service.mesh"}, Addresses: []string{localAddress}, - Ports: []*istionetworkingv1alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), + Ports: []*istioNetworkingV1Alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), Name: "http", Protocol: "http"}}, - Location: istionetworkingv1alpha3.ServiceEntry_MESH_INTERNAL, - Resolution: istionetworkingv1alpha3.ServiceEntry_DNS, + Location: istioNetworkingV1Alpha3.ServiceEntry_MESH_INTERNAL, + Resolution: istioNetworkingV1Alpha3.ServiceEntry_DNS, SubjectAltNames: []string{"spiffe://prefix/my-first-service"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{}, + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{}, } - grpcSe := istionetworkingv1alpha3.ServiceEntry{ + grpcSe := istioNetworkingV1Alpha3.ServiceEntry{ Hosts: []string{"e2e.my-first-service.mesh"}, Addresses: []string{localAddress}, - Ports: []*istionetworkingv1alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), + Ports: []*istioNetworkingV1Alpha3.Port{{Number: uint32(common.DefaultServiceEntryPort), Name: "grpc", Protocol: "grpc"}}, - Location: istionetworkingv1alpha3.ServiceEntry_MESH_INTERNAL, - Resolution: istionetworkingv1alpha3.ServiceEntry_DNS, + Location: istioNetworkingV1Alpha3.ServiceEntry_MESH_INTERNAL, + Resolution: istioNetworkingV1Alpha3.ServiceEntry_DNS, SubjectAltNames: []string{"spiffe://prefix/my-first-service"}, - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: "dummy.admiral.global", Ports: map[string]uint32{"grpc": 0}, Locality: "us-west-2"}, }, } @@ -756,8 +1101,8 @@ func TestCreateServiceEntry(t *testing.T) { admiralCache AdmiralCache meshPorts map[string]uint32 deployment v14.Deployment - serviceEntries map[string]*istionetworkingv1alpha3.ServiceEntry - expectedResult *istionetworkingv1alpha3.ServiceEntry + serviceEntries map[string]*istioNetworkingV1Alpha3.ServiceEntry + expectedResult *istioNetworkingV1Alpha3.ServiceEntry }{ { name: "Should return a created service entry with grpc protocol", @@ -766,7 +1111,7 @@ func TestCreateServiceEntry(t *testing.T) { admiralCache: admiralCache, meshPorts: map[string]uint32{"grpc": uint32(80)}, deployment: deployment, - serviceEntries: map[string]*istionetworkingv1alpha3.ServiceEntry{}, + serviceEntries: map[string]*istioNetworkingV1Alpha3.ServiceEntry{}, expectedResult: &grpcSe, }, { @@ -776,7 +1121,7 @@ func TestCreateServiceEntry(t *testing.T) { admiralCache: admiralCache, meshPorts: map[string]uint32{"http": uint32(80)}, deployment: deployment, - serviceEntries: map[string]*istionetworkingv1alpha3.ServiceEntry{}, + serviceEntries: map[string]*istioNetworkingV1Alpha3.ServiceEntry{}, expectedResult: &se, }, { @@ -786,7 +1131,7 @@ func TestCreateServiceEntry(t *testing.T) { admiralCache: admiralCache, meshPorts: map[string]uint32{"http": uint32(80)}, deployment: deployment, - serviceEntries: map[string]*istionetworkingv1alpha3.ServiceEntry{ + serviceEntries: map[string]*istioNetworkingV1Alpha3.ServiceEntry{ "e2e.my-first-service.mesh": &oneEndpointSe, }, expectedResult: &emptyEndpointSe, @@ -798,7 +1143,7 @@ func TestCreateServiceEntry(t *testing.T) { admiralCache: admiralCache, meshPorts: map[string]uint32{"http": uint32(80)}, deployment: deployment, - serviceEntries: map[string]*istionetworkingv1alpha3.ServiceEntry{ + serviceEntries: map[string]*istioNetworkingV1Alpha3.ServiceEntry{ "e2e.my-first-service.mesh": &twoEndpointSe, }, expectedResult: &eastEndpointSe, @@ -810,7 +1155,7 @@ func TestCreateServiceEntry(t *testing.T) { admiralCache: admiralCache, meshPorts: map[string]uint32{"http": uint32(80)}, deployment: deployment, - serviceEntries: map[string]*istionetworkingv1alpha3.ServiceEntry{ + serviceEntries: map[string]*istioNetworkingV1Alpha3.ServiceEntry{ "e2e.my-first-service.mesh": &threeEndpointSe, }, expectedResult: &eastEndpointSe, @@ -839,7 +1184,7 @@ func TestCreateServiceEntry(t *testing.T) { admiralCache AdmiralCache meshPorts map[string]uint32 rollout argo.Rollout - expectedResult *istionetworkingv1alpha3.ServiceEntry + expectedResult *istioNetworkingV1Alpha3.ServiceEntry }{ { name: "Should return a created service entry with grpc protocol", @@ -862,7 +1207,7 @@ func TestCreateServiceEntry(t *testing.T) { //Run the test for every provided case for _, c := range rolloutSeCreationTestCases { t.Run(c.name, func(t *testing.T) { - createdSE := createServiceEntryForRollout(ctx, admiral.Add, c.rc, &c.admiralCache, c.meshPorts, &c.rollout, map[string]*istionetworkingv1alpha3.ServiceEntry{}) + createdSE := createServiceEntryForRollout(ctx, admiral.Add, c.rc, &c.admiralCache, c.meshPorts, &c.rollout, map[string]*istioNetworkingV1Alpha3.ServiceEntry{}) if !reflect.DeepEqual(createdSE, c.expectedResult) { t.Errorf("Test %s failed, expected: %v got %v", c.name, c.expectedResult, createdSE) } @@ -891,17 +1236,25 @@ func TestCreateServiceEntryForNewServiceOrPodRolloutsUsecase(t *testing.T) { } d, e := admiral.NewDeploymentController("", make(chan struct{}), &test.MockDeploymentHandler{}, &config, time.Second*time.Duration(300)) - + if e != nil { + t.Fail() + } r, e := admiral.NewRolloutsController("test", make(chan struct{}), &test.MockRolloutHandler{}, &config, time.Second*time.Duration(300)) + if e != nil { + t.Fail() + } v, e := istio.NewVirtualServiceController("", make(chan struct{}), &test.MockVirtualServiceHandler{}, &config, time.Second*time.Duration(300)) - if e != nil { t.Fail() } s, e := admiral.NewServiceController("test", make(chan struct{}), &test.MockServiceHandler{}, &config, time.Second*time.Duration(300)) - + if e != nil { + t.Fail() + } gtpc, e := admiral.NewGlobalTrafficController("", make(chan struct{}), &test.MockGlobalTrafficHandler{}, &config, time.Second*time.Duration(300)) - + if e != nil { + t.Fail() + } cacheWithEntry := ServiceEntryAddressStore{ EntryAddresses: map[string]string{"test.test.mesh-se": common.LocalAddressPrefix + ".10.1"}, Addresses: []string{common.LocalAddressPrefix + ".10.1"}, @@ -1199,7 +1552,7 @@ func TestUpdateEndpointsForBlueGreen(t *testing.T) { rollout.Spec.Template.Annotations = map[string]string{} rollout.Spec.Template.Annotations[common.SidecarEnabledPorts] = "8080" - endpoint := &istionetworkingv1alpha3.WorkloadEntry{ + endpoint := &istioNetworkingV1Alpha3.WorkloadEntry{ Labels: map[string]string{}, Address: CLUSTER_INGRESS_1, Ports: map[string]uint32{"http": 15443}, } @@ -1210,23 +1563,23 @@ func TestUpdateEndpointsForBlueGreen(t *testing.T) { PREVIEW_SERVICE: {Service: &v1.Service{ObjectMeta: v12.ObjectMeta{Name: PREVIEW_SERVICE, Namespace: NAMESPACE}}}, } - activeWantedEndpoints := &istionetworkingv1alpha3.WorkloadEntry{ + activeWantedEndpoints := &istioNetworkingV1Alpha3.WorkloadEntry{ Address: ACTIVE_SERVICE + common.Sep + NAMESPACE + common.DotLocalDomainSuffix, Ports: meshPorts, } - previewWantedEndpoints := &istionetworkingv1alpha3.WorkloadEntry{ + previewWantedEndpoints := &istioNetworkingV1Alpha3.WorkloadEntry{ Address: PREVIEW_SERVICE + common.Sep + NAMESPACE + common.DotLocalDomainSuffix, Ports: meshPorts, } testCases := []struct { name string rollout *argo.Rollout - inputEndpoint *istionetworkingv1alpha3.WorkloadEntry + inputEndpoint *istioNetworkingV1Alpha3.WorkloadEntry weightedServices map[string]*WeightedService clusterIngress string meshPorts map[string]uint32 meshHost string - wantedEndpoints *istionetworkingv1alpha3.WorkloadEntry + wantedEndpoints *istioNetworkingV1Alpha3.WorkloadEntry }{ { name: "should return endpoint with active service address", @@ -1267,8 +1620,8 @@ func TestUpdateEndpointsForWeightedServices(t *testing.T) { const STABLE_SERVICE = "stableService" const NAMESPACE = "namespace" - se := &istionetworkingv1alpha3.ServiceEntry{ - Endpoints: []*istionetworkingv1alpha3.WorkloadEntry{ + se := &istioNetworkingV1Alpha3.ServiceEntry{ + Endpoints: []*istioNetworkingV1Alpha3.WorkloadEntry{ {Labels: map[string]string{}, Address: CLUSTER_INGRESS_1, Weight: 10, Ports: map[string]uint32{"http": 15443}}, {Labels: map[string]string{}, Address: CLUSTER_INGRESS_2, Weight: 10, Ports: map[string]uint32{"http": 15443}}, }, @@ -1285,24 +1638,24 @@ func TestUpdateEndpointsForWeightedServices(t *testing.T) { STABLE_SERVICE: {Weight: 100, Service: &v1.Service{ObjectMeta: v12.ObjectMeta{Name: STABLE_SERVICE, Namespace: NAMESPACE}}}, } - wantedEndpoints := []*istionetworkingv1alpha3.WorkloadEntry{ + wantedEndpoints := []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: CLUSTER_INGRESS_2, Weight: 10, Ports: map[string]uint32{"http": 15443}}, {Address: STABLE_SERVICE + common.Sep + NAMESPACE + common.DotLocalDomainSuffix, Weight: 90, Ports: meshPorts}, {Address: CANARY_SERVICE + common.Sep + NAMESPACE + common.DotLocalDomainSuffix, Weight: 10, Ports: meshPorts}, } - wantedEndpointsZeroWeights := []*istionetworkingv1alpha3.WorkloadEntry{ + wantedEndpointsZeroWeights := []*istioNetworkingV1Alpha3.WorkloadEntry{ {Address: CLUSTER_INGRESS_2, Weight: 10, Ports: map[string]uint32{"http": 15443}}, {Address: STABLE_SERVICE + common.Sep + NAMESPACE + common.DotLocalDomainSuffix, Weight: 100, Ports: meshPorts}, } testCases := []struct { name string - inputServiceEntry *istionetworkingv1alpha3.ServiceEntry + inputServiceEntry *istioNetworkingV1Alpha3.ServiceEntry weightedServices map[string]*WeightedService clusterIngress string meshPorts map[string]uint32 - wantedEndpoints []*istionetworkingv1alpha3.WorkloadEntry + wantedEndpoints []*istioNetworkingV1Alpha3.WorkloadEntry }{ { name: "should return endpoints with assigned weights", @@ -1352,39 +1705,37 @@ func TestUpdateEndpointsForWeightedServices(t *testing.T) { } func TestUpdateGlobalGtpCache(t *testing.T) { - + setupForServiceEntryTests() var ( admiralCache = &AdmiralCache{GlobalTrafficCache: &globalTrafficCache{identityCache: make(map[string]*v13.GlobalTrafficPolicy), mutex: &sync.Mutex{}}} + identity1 = "identity1" + envStage = "stage" - identity1 = "identity1" - - env_stage = "stage" - - gtp = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-30))), Labels: map[string]string{"identity": identity1, "env": env_stage}}, Spec: model.GlobalTrafficPolicy{ + gtp = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-30))), Labels: map[string]string{"identity": identity1, "env": envStage}}, Spec: model.GlobalTrafficPolicy{ Policy: []*model.TrafficPolicy{{DnsPrefix: "hello"}}, }} - gtp2 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp2", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-15))), Labels: map[string]string{"identity": identity1, "env": env_stage}}, Spec: model.GlobalTrafficPolicy{ + gtp2 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp2", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-15))), Labels: map[string]string{"identity": identity1, "env": envStage}}, Spec: model.GlobalTrafficPolicy{ Policy: []*model.TrafficPolicy{{DnsPrefix: "hellogtp2"}}, }} - gtp7 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp7", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-45))), Labels: map[string]string{"identity": identity1, "env": env_stage, "priority": "2"}}, Spec: model.GlobalTrafficPolicy{ + gtp7 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp7", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-45))), Labels: map[string]string{"identity": identity1, "env": envStage, "priority": "2"}}, Spec: model.GlobalTrafficPolicy{ Policy: []*model.TrafficPolicy{{DnsPrefix: "hellogtp7"}}, }} - gtp3 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp3", Namespace: "namespace2", CreationTimestamp: v12.NewTime(time.Now()), Labels: map[string]string{"identity": identity1, "env": env_stage}}, Spec: model.GlobalTrafficPolicy{ + gtp3 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp3", Namespace: "namespace2", CreationTimestamp: v12.NewTime(time.Now()), Labels: map[string]string{"identity": identity1, "env": envStage}}, Spec: model.GlobalTrafficPolicy{ Policy: []*model.TrafficPolicy{{DnsPrefix: "hellogtp3"}}, }} - gtp4 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp4", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-30))), Labels: map[string]string{"identity": identity1, "env": env_stage, "priority": "10"}}, Spec: model.GlobalTrafficPolicy{ + gtp4 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp4", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-30))), Labels: map[string]string{"identity": identity1, "env": envStage, "priority": "10"}}, Spec: model.GlobalTrafficPolicy{ Policy: []*model.TrafficPolicy{{DnsPrefix: "hellogtp4"}}, }} - gtp5 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp5", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-15))), Labels: map[string]string{"identity": identity1, "env": env_stage, "priority": "2"}}, Spec: model.GlobalTrafficPolicy{ + gtp5 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp5", Namespace: "namespace1", CreationTimestamp: v12.NewTime(time.Now().Add(time.Duration(-15))), Labels: map[string]string{"identity": identity1, "env": envStage, "priority": "2"}}, Spec: model.GlobalTrafficPolicy{ Policy: []*model.TrafficPolicy{{DnsPrefix: "hellogtp5"}}, }} - gtp6 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp6", Namespace: "namespace3", CreationTimestamp: v12.NewTime(time.Now()), Labels: map[string]string{"identity": identity1, "env": env_stage, "priority": "1000"}}, Spec: model.GlobalTrafficPolicy{ + gtp6 = &v13.GlobalTrafficPolicy{ObjectMeta: v12.ObjectMeta{Name: "gtp6", Namespace: "namespace3", CreationTimestamp: v12.NewTime(time.Now()), Labels: map[string]string{"identity": identity1, "env": envStage, "priority": "1000"}}, Spec: model.GlobalTrafficPolicy{ Policy: []*model.TrafficPolicy{{DnsPrefix: "hellogtp6"}}, }} ) @@ -1400,49 +1751,49 @@ func TestUpdateGlobalGtpCache(t *testing.T) { name: "Should return nil when no GTP present", gtps: map[string][]*v13.GlobalTrafficPolicy{}, identity: identity1, - env: env_stage, + env: envStage, expectedGtp: nil, }, { name: "Should return the only existing gtp", gtps: map[string][]*v13.GlobalTrafficPolicy{"c1": {gtp}}, identity: identity1, - env: env_stage, + env: envStage, expectedGtp: gtp, }, { name: "Should return the gtp recently created within the cluster", gtps: map[string][]*v13.GlobalTrafficPolicy{"c1": {gtp, gtp2}}, identity: identity1, - env: env_stage, + env: envStage, expectedGtp: gtp2, }, { name: "Should return the gtp recently created from another cluster", gtps: map[string][]*v13.GlobalTrafficPolicy{"c1": {gtp, gtp2}, "c2": {gtp3}}, identity: identity1, - env: env_stage, + env: envStage, expectedGtp: gtp3, }, { name: "Should return the existing priority gtp within the cluster", gtps: map[string][]*v13.GlobalTrafficPolicy{"c1": {gtp, gtp2, gtp7}}, identity: identity1, - env: env_stage, + env: envStage, expectedGtp: gtp7, }, { name: "Should return the recently created priority gtp within the cluster", gtps: map[string][]*v13.GlobalTrafficPolicy{"c1": {gtp5, gtp4, gtp, gtp2}}, identity: identity1, - env: env_stage, + env: envStage, expectedGtp: gtp4, }, { name: "Should return the recently created priority gtp from another cluster", gtps: map[string][]*v13.GlobalTrafficPolicy{"c1": {gtp, gtp2, gtp4, gtp5, gtp7}, "c2": {gtp6}, "c3": {gtp3}}, identity: identity1, - env: env_stage, + env: envStage, expectedGtp: gtp6, }, } diff --git a/admiral/pkg/clusters/types.go b/admiral/pkg/clusters/types.go index e59b1a73..c03ceb23 100644 --- a/admiral/pkg/clusters/types.go +++ b/admiral/pkg/clusters/types.go @@ -60,12 +60,13 @@ type AdmiralCache struct { type RemoteRegistry struct { sync.Mutex - remoteControllers map[string]*RemoteController - SecretController *secret.Controller - secretClient k8s.Interface - ctx context.Context - AdmiralCache *AdmiralCache - StartTime time.Time + remoteControllers map[string]*RemoteController + SecretController *secret.Controller + secretClient k8s.Interface + ctx context.Context + AdmiralCache *AdmiralCache + StartTime time.Time + ExcludedIdentityMap map[string]bool } func NewRemoteRegistry(ctx context.Context, params common.AdmiralParams) *RemoteRegistry { @@ -96,10 +97,11 @@ func NewRemoteRegistry(ctx context.Context, params common.AdmiralParams) *Remote argoRolloutsEnabled: params.ArgoRolloutsEnabled, } return &RemoteRegistry{ - ctx: ctx, - StartTime: time.Now(), - remoteControllers: make(map[string]*RemoteController), - AdmiralCache: admiralCache, + ctx: ctx, + StartTime: time.Now(), + remoteControllers: make(map[string]*RemoteController), + AdmiralCache: admiralCache, + ExcludedIdentityMap: mapSliceToBool(params.ExcludedIdentityList, true), } } @@ -196,7 +198,6 @@ func (g *globalTrafficCache) Put(gtp *v1.GlobalTrafficPolicy) error { identity := gtp.Labels[common.GetGlobalTrafficDeploymentLabel()] key := common.ConstructGtpKey(gtpEnv, identity) g.identityCache[key] = gtp - return nil } @@ -459,9 +460,9 @@ func HandleEventForService(ctx context.Context, svc *k8sV1.Service, remoteRegist deploymentController := rc.DeploymentController rolloutController := rc.RolloutController if deploymentController != nil { - matchingDeployements := deploymentController.GetDeploymentBySelectorInNamespace(ctx, svc.Spec.Selector, svc.Namespace) - if len(matchingDeployements) > 0 { - for _, deployment := range matchingDeployements { + matchingDeployments := deploymentController.GetDeploymentBySelectorInNamespace(ctx, svc.Spec.Selector, svc.Namespace) + if len(matchingDeployments) > 0 { + for _, deployment := range matchingDeployments { HandleEventForDeployment(ctx, admiral.Update, &deployment, remoteRegistry, clusterName) } } diff --git a/admiral/pkg/clusters/types_test.go b/admiral/pkg/clusters/types_test.go index faa3cc58..840bebee 100644 --- a/admiral/pkg/clusters/types_test.go +++ b/admiral/pkg/clusters/types_test.go @@ -27,10 +27,17 @@ import ( var ignoreUnexported = cmpopts.IgnoreUnexported(v1.GlobalTrafficPolicy{}.Status) -func init() { - p := common.AdmiralParams{ - KubeconfigPath: "testdata/fake.config", - LabelSet: &common.LabelSet{}, +var typeTestSingleton sync.Once + +func admiralParamsForTypesTests() common.AdmiralParams { + return common.AdmiralParams{ + KubeconfigPath: "testdata/fake.config", + LabelSet: &common.LabelSet{ + WorkloadIdentityKey: "identity", + EnvKey: "admiral.io/env", + GlobalTrafficDeploymentLabel: "identity", + PriorityKey: "priority", + }, EnableSAN: true, SANPrefix: "prefix", HostnameSuffix: "mesh", @@ -42,17 +49,17 @@ func init() { EnableRoutingPolicy: true, EnvoyFilterVersion: "1.13", } +} - p.LabelSet.WorkloadIdentityKey = "identity" - p.LabelSet.EnvKey = "admiral.io/env" - p.LabelSet.GlobalTrafficDeploymentLabel = "identity" - p.LabelSet.PriorityKey = "priority" - - common.InitializeConfig(p) +func setupForTypeTests() { + typeTestSingleton.Do(func() { + common.ResetSync() + common.InitializeConfig(admiralParamsForTypesTests()) + }) } func TestDeploymentHandler(t *testing.T) { - + setupForTypeTests() ctx := context.Background() p := common.AdmiralParams{ @@ -134,7 +141,7 @@ func TestDeploymentHandler(t *testing.T) { } func TestRolloutHandler(t *testing.T) { - + setupForTypeTests() ctx := context.Background() p := common.AdmiralParams{ @@ -221,6 +228,7 @@ func TestRolloutHandler(t *testing.T) { } func TestHandleEventForGlobalTrafficPolicy(t *testing.T) { + setupForTypeTests() ctx := context.Background() event := admiral.EventType("Add") p := common.AdmiralParams{ @@ -276,6 +284,7 @@ func TestHandleEventForGlobalTrafficPolicy(t *testing.T) { } func TestRoutingPolicyHandler(t *testing.T) { + common.ResetSync() p := common.AdmiralParams{ KubeconfigPath: "testdata/fake.config", LabelSet: &common.LabelSet{}, @@ -454,7 +463,6 @@ func TestRoutingPolicyHandler(t *testing.T) { handler.Updated(ctx, routingPolicyFoo) assert.Nil(t, registry.AdmiralCache.RoutingPolicyFilterCache.Get("bar4stage")) assert.Nil(t, registry.AdmiralCache.RoutingPolicyFilterCache.Get("bar3stage")) - } func TestRoutingPolicyReadOnly(t *testing.T) { diff --git a/admiral/pkg/clusters/util.go b/admiral/pkg/clusters/util.go index 0db890de..666280b0 100644 --- a/admiral/pkg/clusters/util.go +++ b/admiral/pkg/clusters/util.go @@ -2,15 +2,16 @@ package clusters import ( "errors" + "strconv" + "strings" + "time" + argo "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" "github.com/istio-ecosystem/admiral/admiral/pkg/controller/common" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" k8sAppsV1 "k8s.io/api/apps/v1" k8sV1 "k8s.io/api/core/v1" - "strconv" - "strings" - "time" ) func GetMeshPorts(clusterName string, destService *k8sV1.Service, @@ -30,13 +31,13 @@ func GetMeshPortsForRollout(clusterName string, destService *k8sV1.Service, // Get the service selector to add as workload selector for envoyFilter func GetServiceSelector(clusterName string, destService *k8sV1.Service) *common.Map { var selectors = destService.Spec.Selector - if len(selectors) == 0{ + if len(selectors) == 0 { log.Infof(LogFormat, "GetServiceLabels", "no selectors present", destService.Name, clusterName, selectors) return nil } var tempMap = common.NewMap() for key, value := range selectors { - tempMap.Put(key,value) + tempMap.Put(key, value) } log.Infof(LogFormat, "GetServiceLabels", "selectors present", destService.Name, clusterName, selectors) return tempMap @@ -93,7 +94,7 @@ func getMeshPortsHelper(meshPorts string, destService *k8sV1.Service, clusterNam } if _, ok := meshPortMap[targetPort]; ok { var protocol = GetPortProtocol(servicePort.Name) - log.Debugf(LogFormat, "GetMeshPorts", servicePort.Port, destService.Name, clusterName, "Adding mesh port for protocol: " + protocol) + log.Debugf(LogFormat, "GetMeshPorts", servicePort.Port, destService.Name, clusterName, "Adding mesh port for protocol: "+protocol) ports[protocol] = uint32(servicePort.Port) break } @@ -147,3 +148,11 @@ func ValidateConfigmapBeforePutting(cm *k8sV1.ConfigMap) error { func IsCacheWarmupTime(remoteRegistry *RemoteRegistry) bool { return time.Since(remoteRegistry.StartTime) < common.GetAdmiralParams().CacheRefreshDuration } + +func mapSliceToBool(list []string, value bool) map[string]bool { + m := make(map[string]bool, len(list)) + for _, item := range list { + m[item] = value + } + return m +} diff --git a/admiral/pkg/clusters/util_test.go b/admiral/pkg/clusters/util_test.go index d418177f..e5d8dd01 100644 --- a/admiral/pkg/clusters/util_test.go +++ b/admiral/pkg/clusters/util_test.go @@ -2,56 +2,49 @@ package clusters import ( "errors" + "reflect" + "strconv" + "testing" + argo "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" "github.com/istio-ecosystem/admiral/admiral/pkg/controller/common" k8sAppsV1 "k8s.io/api/apps/v1" coreV1 "k8s.io/api/core/v1" k8sV1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "reflect" - "strconv" - "testing" ) func TestGetMeshPorts(t *testing.T) { - - annotatedPort := 8090 - annotatedSecondPort := 8091 - defaultServicePort := uint32(8080) - - defaultK8sSvcPortNoName := k8sV1.ServicePort{Port: int32(defaultServicePort)} - defaultK8sSvcPort := k8sV1.ServicePort{Name: "default", Port: int32(defaultServicePort)} - meshK8sSvcPort := k8sV1.ServicePort{Name: "mesh", Port: int32(annotatedPort)} - - serviceMeshPorts := []k8sV1.ServicePort{defaultK8sSvcPort, meshK8sSvcPort} - - serviceMeshPortsOnlyDefault := []k8sV1.ServicePort{defaultK8sSvcPortNoName} - - service := k8sV1.Service{ - ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, - Spec: k8sV1.ServiceSpec{Ports: serviceMeshPorts}, - } - deployment := k8sAppsV1.Deployment{ - Spec: k8sAppsV1.DeploymentSpec{Template: coreV1.PodTemplateSpec{ - ObjectMeta: v1.ObjectMeta{Annotations: map[string]string{common.SidecarEnabledPorts: strconv.Itoa(annotatedPort)}}, - }}} - - deploymentWithMultipleMeshPorts := k8sAppsV1.Deployment{ - Spec: k8sAppsV1.DeploymentSpec{Template: coreV1.PodTemplateSpec{ - ObjectMeta: v1.ObjectMeta{Annotations: map[string]string{common.SidecarEnabledPorts: strconv.Itoa(annotatedPort) + "," + strconv.Itoa(annotatedSecondPort)}}, - }}} - - ports := map[string]uint32{"http": uint32(annotatedPort)} - portsDiffTargetPort := map[string]uint32{"http": uint32(80)} - - grpcPorts := map[string]uint32{"grpc": uint32(annotatedPort)} - grpcWebPorts := map[string]uint32{"grpc-web": uint32(annotatedPort)} - http2Ports := map[string]uint32{"http2": uint32(annotatedPort)} - - portsFromDefaultSvcPort := map[string]uint32{"http": defaultServicePort} - - emptyPorts := map[string]uint32{} + var ( + annotatedPort = 8090 + annotatedSecondPort = 8091 + defaultServicePort = uint32(8080) + ports = map[string]uint32{"http": uint32(annotatedPort)} + portsDiffTargetPort = map[string]uint32{"http": uint32(80)} + grpcPorts = map[string]uint32{"grpc": uint32(annotatedPort)} + grpcWebPorts = map[string]uint32{"grpc-web": uint32(annotatedPort)} + http2Ports = map[string]uint32{"http2": uint32(annotatedPort)} + portsFromDefaultSvcPort = map[string]uint32{"http": defaultServicePort} + emptyPorts = map[string]uint32{} + defaultK8sSvcPortNoName = k8sV1.ServicePort{Port: int32(defaultServicePort)} + defaultK8sSvcPort = k8sV1.ServicePort{Name: "default", Port: int32(defaultServicePort)} + meshK8sSvcPort = k8sV1.ServicePort{Name: "mesh", Port: int32(annotatedPort)} + serviceMeshPorts = []k8sV1.ServicePort{defaultK8sSvcPort, meshK8sSvcPort} + serviceMeshPortsOnlyDefault = []k8sV1.ServicePort{defaultK8sSvcPortNoName} + service = k8sV1.Service{ + ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, + Spec: k8sV1.ServiceSpec{Ports: serviceMeshPorts}, + } + deployment = k8sAppsV1.Deployment{ + Spec: k8sAppsV1.DeploymentSpec{Template: coreV1.PodTemplateSpec{ + ObjectMeta: v1.ObjectMeta{Annotations: map[string]string{common.SidecarEnabledPorts: strconv.Itoa(annotatedPort)}}, + }}} + deploymentWithMultipleMeshPorts = k8sAppsV1.Deployment{ + Spec: k8sAppsV1.DeploymentSpec{Template: coreV1.PodTemplateSpec{ + ObjectMeta: v1.ObjectMeta{Annotations: map[string]string{common.SidecarEnabledPorts: strconv.Itoa(annotatedPort) + "," + strconv.Itoa(annotatedSecondPort)}}, + }}} + ) testCases := []struct { name string @@ -67,17 +60,17 @@ func TestGetMeshPorts(t *testing.T) { expected: ports, }, { - name: "should return a http port if no port name is specified", - service: k8sV1.Service{ + name: "should return a http port if no port name is specified", + service: k8sV1.Service{ ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, - Spec: k8sV1.ServiceSpec{Ports: []k8sV1.ServicePort{{Port: int32(80), TargetPort: intstr.FromInt(annotatedPort),}}}, + Spec: k8sV1.ServiceSpec{Ports: []k8sV1.ServicePort{{Port: int32(80), TargetPort: intstr.FromInt(annotatedPort)}}}, }, deployment: deployment, expected: portsDiffTargetPort, }, { - name: "should return a http port if the port name doesn't start with a protocol name", - service: k8sV1.Service{ + name: "should return a http port if the port name doesn't start with a protocol name", + service: k8sV1.Service{ ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, Spec: k8sV1.ServiceSpec{Ports: []k8sV1.ServicePort{{Name: "hello-grpc", Port: int32(annotatedPort)}}}, }, @@ -85,8 +78,8 @@ func TestGetMeshPorts(t *testing.T) { expected: ports, }, { - name: "should return a grpc port based on annotation", - service: k8sV1.Service{ + name: "should return a grpc port based on annotation", + service: k8sV1.Service{ ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, Spec: k8sV1.ServiceSpec{Ports: []k8sV1.ServicePort{{Name: "grpc-service", Port: int32(annotatedPort)}}}, }, @@ -94,8 +87,8 @@ func TestGetMeshPorts(t *testing.T) { expected: grpcPorts, }, { - name: "should return a grpc-web port based on annotation", - service: k8sV1.Service{ + name: "should return a grpc-web port based on annotation", + service: k8sV1.Service{ ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, Spec: k8sV1.ServiceSpec{Ports: []k8sV1.ServicePort{{Name: "grpc-web", Port: int32(annotatedPort)}}}, }, @@ -103,8 +96,8 @@ func TestGetMeshPorts(t *testing.T) { expected: grpcWebPorts, }, { - name: "should return a http2 port based on annotation", - service: k8sV1.Service{ + name: "should return a http2 port based on annotation", + service: k8sV1.Service{ ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, Spec: k8sV1.ServiceSpec{Ports: []k8sV1.ServicePort{{Name: "http2", Port: int32(annotatedPort)}}}, }, @@ -136,10 +129,10 @@ func TestGetMeshPorts(t *testing.T) { expected: emptyPorts, }, { - name: "should return a http port if the port name doesn't start with a protocol name", - service: k8sV1.Service{ + name: "should return a http port if the port name doesn't start with a protocol name", + service: k8sV1.Service{ ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, - Spec: k8sV1.ServiceSpec{Ports: []k8sV1.ServicePort{{Name: "http", Port: int32(annotatedPort)}, + Spec: k8sV1.ServiceSpec{Ports: []k8sV1.ServicePort{{Name: "http", Port: int32(annotatedPort)}, {Name: "grpc", Port: int32(annotatedSecondPort)}}}, }, deployment: deploymentWithMultipleMeshPorts, @@ -216,51 +209,51 @@ func TestValidateConfigmapBeforePutting(t *testing.T) { func TestGetServiceSelector(t *testing.T) { - selector := map[string]string {"app":"test1"} + selector := map[string]string{"app": "test1"} testCases := []struct { name string clusterName string service k8sV1.Service expected map[string]string - }{ + }{ { name: "should return a selectors based on service", clusterName: "test-cluster", - service: k8sV1.Service{ + service: k8sV1.Service{ ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, - Spec: k8sV1.ServiceSpec{Selector: selector}, + Spec: k8sV1.ServiceSpec{Selector: selector}, }, - expected: selector, + expected: selector, }, { name: "should return empty selectors", clusterName: "test-cluster", - service: k8sV1.Service{ + service: k8sV1.Service{ ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, Spec: k8sV1.ServiceSpec{Selector: map[string]string{}}, }, - expected: nil, + expected: nil, }, { name: "should return nil", clusterName: "test-cluster", - service: k8sV1.Service{ + service: k8sV1.Service{ ObjectMeta: v1.ObjectMeta{Name: "server", Labels: map[string]string{"asset": "Intuit.platform.mesh.server"}}, Spec: k8sV1.ServiceSpec{Selector: nil}, }, - expected: nil, + expected: nil, }, } for _, c := range testCases { t.Run(c.name, func(t *testing.T) { - selectors := GetServiceSelector(c.clusterName,&c.service) + selectors := GetServiceSelector(c.clusterName, &c.service) if selectors == nil { if c.expected != nil { t.Errorf("Wanted selectors: %v, got: %v", c.expected, selectors) } - }else if !reflect.DeepEqual(selectors.Copy(), c.expected) { + } else if !reflect.DeepEqual(selectors.Copy(), c.expected) { t.Errorf("Wanted selectors: %v, got: %v", c.expected, selectors) } }) diff --git a/admiral/pkg/controller/common/config.go b/admiral/pkg/controller/common/config.go index d4afaaa3..554bc993 100644 --- a/admiral/pkg/controller/common/config.go +++ b/admiral/pkg/controller/common/config.go @@ -1,16 +1,21 @@ package common import ( - log "github.com/sirupsen/logrus" - "sync" "time" + + "github.com/matryer/resync" + log "github.com/sirupsen/logrus" ) var admiralParams = AdmiralParams{ LabelSet: &LabelSet{}, } -var once sync.Once +var once resync.Once + +func ResetSync() { + once.Reset() +} func InitializeConfig(params AdmiralParams) { var initHappened = false @@ -19,7 +24,9 @@ func InitializeConfig(params AdmiralParams) { initHappened = true InitializeMetrics() }) - if !initHappened { + if initHappened { + log.Info("InitializeConfig was called.") + } else { log.Warn("InitializeConfig was called but didn't take effect. It can only be called once, and thus has already been initialized. Please ensure you aren't re-initializing the config.") } } diff --git a/admiral/pkg/controller/common/types.go b/admiral/pkg/controller/common/types.go index f1e0e9e0..171fab30 100644 --- a/admiral/pkg/controller/common/types.go +++ b/admiral/pkg/controller/common/types.go @@ -48,9 +48,10 @@ type AdmiralParams struct { AdmiralStateCheckerName string DRStateStoreConfigPath string ServiceEntryIPPrefix string - EnvoyFilterVersion string - EnvoyFilterAdditionalConfig string + EnvoyFilterVersion string + EnvoyFilterAdditionalConfig string EnableRoutingPolicy bool + ExcludedIdentityList []string } func (b AdmiralParams) String() string { diff --git a/go.mod b/go.mod index 0543e668..2d2984ca 100644 --- a/go.mod +++ b/go.mod @@ -53,6 +53,7 @@ require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/matryer/resync v0.0.0-20161211202428-d39c09a11215 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect diff --git a/go.sum b/go.sum index 581873f2..44b63ae6 100644 --- a/go.sum +++ b/go.sum @@ -235,6 +235,8 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/resync v0.0.0-20161211202428-d39c09a11215 h1:hDa3vAq/Zo5gjfJ46XMsGFbH+hTizpR4fUzQCk2nxgk= +github.com/matryer/resync v0.0.0-20161211202428-d39c09a11215/go.mod h1:LH+NgPY9AJpDfqAFtzyer01N9MYNsAKUf3DC9DV1xIY= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=