From e964640bb52a8e987b8ba7fc20e8139790cb9896 Mon Sep 17 00:00:00 2001 From: Swetha Repakula Date: Wed, 24 Jun 2020 10:37:56 -0700 Subject: [PATCH 1/2] Add feature flag for custom neg names - when enabled, NEG CRD is ensured in k8s cluster --- cmd/glbc/main.go | 8 ++++++++ pkg/flags/flags.go | 2 ++ pkg/svcneg/svcneg.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 pkg/svcneg/svcneg.go diff --git a/cmd/glbc/main.go b/cmd/glbc/main.go index aff1a0eb51..8d02bc4322 100644 --- a/cmd/glbc/main.go +++ b/cmd/glbc/main.go @@ -26,6 +26,7 @@ import ( flag "github.com/spf13/pflag" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/ingress-gce/pkg/frontendconfig" + "k8s.io/ingress-gce/pkg/svcneg" "k8s.io/klog" crdclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" @@ -125,6 +126,13 @@ func main() { } } + if flags.F.EnableNegCrd { + negCRDMeta := svcneg.CRDMeta() + if _, err := crdHandler.EnsureCRD(negCRDMeta); err != nil { + klog.Fatalf("Failed to ensure ServiceNetworkEndpointGroup CRD: %v", err) + } + } + namer, err := app.NewNamer(kubeClient, flags.F.ClusterName, firewalls.DefaultFirewallName) if err != nil { klog.Fatalf("app.NewNamer(ctx.KubeClient, %q, %q) = %v", flags.F.ClusterName, firewalls.DefaultFirewallName, err) diff --git a/pkg/flags/flags.go b/pkg/flags/flags.go index fd0bea464b..f4c5e110ef 100644 --- a/pkg/flags/flags.go +++ b/pkg/flags/flags.go @@ -96,6 +96,7 @@ var ( EnableV2FrontendNamer bool FinalizerAdd bool // Should have been named Enablexxx. FinalizerRemove bool // Should have been named Enablexxx. + EnableNegCrd bool }{} ) @@ -217,6 +218,7 @@ L7 load balancing. CSV values accepted. Example: -node-port-ranges=80,8080,400-5 flag.BoolVar(&F.RunIngressController, "run-ingress-controller", true, `Optional, whether or not to run IngressController as part of glbc. If set to false, ingress resources will not be processed. Only the L4 Service controller will be run, if that flag is set to true.`) flag.BoolVar(&F.RunL4Controller, "run-l4-controller", false, `Optional, whether or not to run L4 Service Controller as part of glbc. If set to true, services of Type:LoadBalancer with Internal annotation will be processed by this controller.`) flag.BoolVar(&F.EnableBackendConfigHealthCheck, "enable-backendconfig-healthcheck", false, "Enable configuration of HealthChecks from the BackendConfig") + flag.BoolVar(&F.EnableNegCrd, "enable-neg-crd", false, "Enable NEG CRD") } type RateLimitSpecs struct { diff --git a/pkg/svcneg/svcneg.go b/pkg/svcneg/svcneg.go new file mode 100644 index 0000000000..9ff3e6c348 --- /dev/null +++ b/pkg/svcneg/svcneg.go @@ -0,0 +1,35 @@ +/* +Copyright 2020 The Kubernetes 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 svcneg + +import ( + negv1beta1 "k8s.io/ingress-gce/pkg/apis/frontendconfig/v1beta1" + apisneg "k8s.io/ingress-gce/pkg/apis/svcneg" + "k8s.io/ingress-gce/pkg/crd" +) + +func CRDMeta() *crd.CRDMeta { + meta := crd.NewCRDMeta( + apisneg.GroupName, + "v1beta1", + "ServiceNetworkEndpointGroup", + "ServiceNetworkingEndpointGroupList", + "servicenetworkendpointgroup", + "servicenetworkendpointgroups", + ) + meta.AddValidationInfo("k8s.io/ingress-gce/pkg/apis/svcneg/v1beta1.ServiceNetworkEndpointGroup", negv1beta1.GetOpenAPIDefinitions) + return meta +} From 991b0460c0544fc092d2a60ab19418e5b409ba22 Mon Sep 17 00:00:00 2001 From: Swetha Repakula Date: Thu, 18 Jun 2020 13:59:50 -0700 Subject: [PATCH 2/2] newServicePorts return desired custom neg names - names specified in service annotations are passed along into the port info map --- pkg/neg/controller.go | 10 +-- pkg/neg/controller_test.go | 30 ++++--- pkg/neg/manager_test.go | 54 +++++------ pkg/neg/types/types.go | 8 +- pkg/neg/types/types_test.go | 173 +++++++++++++++++++++++++----------- pkg/neg/utils.go | 10 ++- pkg/neg/utils_test.go | 60 +++++++++++-- 7 files changed, 238 insertions(+), 107 deletions(-) diff --git a/pkg/neg/controller.go b/pkg/neg/controller.go index a3bb74db22..f2a8f01da9 100644 --- a/pkg/neg/controller.go +++ b/pkg/neg/controller.go @@ -451,7 +451,7 @@ func (c *Controller) mergeIngressPortInfo(service *apiv1.Service, name types.Nam // Only service ports referenced by ingress are synced for NEG ings := getIngressServicesFromStore(c.ingressLister, service) ingressSvcPortTuples := gatherPortMappingUsedByIngress(ings, service) - ingressPortInfoMap := negtypes.NewPortInfoMap(name.Namespace, name.Name, ingressSvcPortTuples, c.namer, true) + ingressPortInfoMap := negtypes.NewPortInfoMap(name.Namespace, name.Name, ingressSvcPortTuples, c.namer, true, nil) if err := portInfoMap.Merge(ingressPortInfoMap); err != nil { return fmt.Errorf("failed to merge service ports referenced by ingress (%v): %v", ingressPortInfoMap, err) } @@ -481,12 +481,12 @@ func (c *Controller) mergeStandaloneNEGsPortInfo(service *apiv1.Service, name ty ) } - exposedNegSvcPort, err := negServicePorts(negAnnotation, knowSvcPortSet) + exposedNegSvcPort, _, err := negServicePorts(negAnnotation, knowSvcPortSet) if err != nil { return err } - if err := portInfoMap.Merge(negtypes.NewPortInfoMap(name.Namespace, name.Name, exposedNegSvcPort, c.namer /*readinessGate*/, true)); err != nil { + if err := portInfoMap.Merge(negtypes.NewPortInfoMap(name.Namespace, name.Name, exposedNegSvcPort, c.namer /*readinessGate*/, true, nil)); err != nil { return fmt.Errorf("failed to merge service ports exposed as standalone NEGs (%v) into ingress referenced service ports (%v): %v", exposedNegSvcPort, portInfoMap, err) } } @@ -533,7 +533,7 @@ func (c *Controller) mergeDefaultBackendServicePortInfoMap(key string, portInfoM Port: c.defaultBackendService.Port, TargetPort: c.defaultBackendService.TargetPort, }) - defaultServicePortInfoMap := negtypes.NewPortInfoMap(c.defaultBackendService.ID.Service.Namespace, c.defaultBackendService.ID.Service.Name, svcPortTupleSet, c.namer, false) + defaultServicePortInfoMap := negtypes.NewPortInfoMap(c.defaultBackendService.ID.Service.Namespace, c.defaultBackendService.ID.Service.Name, svcPortTupleSet, c.namer, false, nil) return portInfoMap.Merge(defaultServicePortInfoMap) } } @@ -570,7 +570,7 @@ func (c *Controller) getCSMPortInfoMap(namespace, name string, service *apiv1.Se } else if contains(c.asmServiceNEGSkipNamespaces, namespace) { klog.Infof("Skip NEG creation for services in namespace: %s", namespace) } else { - servicePortInfoMap = negtypes.NewPortInfoMap(namespace, name, servicePorts, c.namer, false) + servicePortInfoMap = negtypes.NewPortInfoMap(namespace, name, servicePorts, c.namer, false, nil) } return servicePortInfoMap, destinationRulesPortInfoMap, nil } diff --git a/pkg/neg/controller_test.go b/pkg/neg/controller_test.go index 15237c41d4..dd6664fd37 100644 --- a/pkg/neg/controller_test.go +++ b/pkg/neg/controller_test.go @@ -524,39 +524,39 @@ func TestSyncNegAnnotation(t *testing.T) { }{ { desc: "apply new annotation with no previous annotation", - portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 443, TargetPort: "other_port"}), namer, false), + portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 443, TargetPort: "other_port"}), namer, false, nil), }, { desc: "same annotation applied twice", - previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false), - portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false), + previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false, nil), + portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false, nil), }, { desc: "apply new annotation and override previous annotation", - previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false), - portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "6000"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "8000"}), namer, false), + previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false, nil), + portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "6000"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "8000"}), namer, false, nil), }, { desc: "remove previous annotation", - previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false), + previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false, nil), }, { desc: "remove annotation with no previous annotation", }, { desc: "readiness gate makes no difference 1", - previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false), - portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "6000"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "8000"}), namer, true), + previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false, nil), + portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "6000"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "8000"}), namer, true, nil), }, { desc: "readiness gate makes no difference 2", - previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, true), - portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false), + previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, true, nil), + portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, false, nil), }, { desc: "no difference with port name", - previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, true), - portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, Name: "foo", TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, Name: "bar", TargetPort: "other_port"}), namer, false), + previousPortMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, TargetPort: "other_port"}), namer, true, nil), + portMap: negtypes.NewPortInfoMap(namespace, name, negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 80, Name: "foo", TargetPort: "named_port"}, negtypes.SvcPortTuple{Port: 4040, Name: "bar", TargetPort: "other_port"}), namer, false, nil), }, } @@ -633,6 +633,7 @@ func TestDefaultBackendServicePortInfoMap(t *testing.T) { negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: "http", Port: 80, TargetPort: defaultBackend.TargetPort}), controller.namer, false, + nil, ), }, { @@ -656,6 +657,7 @@ func TestDefaultBackendServicePortInfoMap(t *testing.T) { negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: "80", Port: 80, TargetPort: "8888"}), controller.namer, false, + nil, ), }, } @@ -716,6 +718,7 @@ func TestNewDestinationRule(t *testing.T) { negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: "port80", Port: 80, TargetPort: "80"}, negtypes.SvcPortTuple{Name: "port90", Port: 90, TargetPort: "90"}), controllerHelper.namer, false, + nil, ), wantDRPortMap: helperNewPortInfoMapWithDestinationRule( "namespace1", @@ -737,6 +740,7 @@ func TestNewDestinationRule(t *testing.T) { negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: "port80", Port: 80, TargetPort: "80"}, negtypes.SvcPortTuple{Name: "port90", Port: 90, TargetPort: "90"}), controllerHelper.namer, false, + nil, ), wantDRPortMap: negtypes.PortInfoMap{}, }, @@ -820,6 +824,7 @@ func TestMergeCSMPortInfoMap(t *testing.T) { negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: "port80", Port: 80, TargetPort: "80"}, negtypes.SvcPortTuple{Name: "port90", Port: 90, TargetPort: "90"}), controller.namer, false, + nil, ), wantDRPortMap: helperNewPortInfoMapWithDestinationRule( "namespace1", @@ -841,6 +846,7 @@ func TestMergeCSMPortInfoMap(t *testing.T) { negtypes.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: "port90", Port: 90, TargetPort: "90"}), controller.namer, false, + nil, ), wantDRPortMap: negtypes.PortInfoMap{}, }, diff --git a/pkg/neg/manager_test.go b/pkg/neg/manager_test.go index 8440b6b730..f1de54e21d 100644 --- a/pkg/neg/manager_test.go +++ b/pkg/neg/manager_test.go @@ -117,7 +117,7 @@ func TestEnsureAndStopSyncer(t *testing.T) { desc: "add 2 new ports", namespace: svcNamespace1, name: svcName, - portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 1000, TargetPort: "80"}, negtypes.SvcPortTuple{Port: 2000, TargetPort: "443"}), namer, false), + portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 1000, TargetPort: "80"}, negtypes.SvcPortTuple{Port: 2000, TargetPort: "443"}), namer, false, nil), stop: false, expectInternals: map[negtypes.NegSyncerKey]bool{ getSyncerKey(svcNamespace1, svcName, negtypes.PortInfoMapKey{ServicePort: 1000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Port: 1000, TargetPort: "80"}}): false, @@ -128,7 +128,7 @@ func TestEnsureAndStopSyncer(t *testing.T) { desc: "modify 1 port to enable readinessGate", namespace: svcNamespace1, name: svcName, - portInfoMap: portInfoUnion(negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 1000, TargetPort: "80"}), namer, false), negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 2000, TargetPort: "443"}), namer, true)), + portInfoMap: portInfoUnion(negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 1000, TargetPort: "80"}), namer, false, nil), negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 2000, TargetPort: "443"}), namer, true, nil)), stop: false, expectInternals: map[negtypes.NegSyncerKey]bool{ getSyncerKey(svcNamespace1, svcName, negtypes.PortInfoMapKey{ServicePort: 1000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Port: 1000, TargetPort: "80"}}): false, @@ -140,7 +140,7 @@ func TestEnsureAndStopSyncer(t *testing.T) { desc: "add 2 new ports, remove 2 existing ports", namespace: svcNamespace1, name: svcName, - portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "namedport"}), namer, false), + portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "namedport"}), namer, false, nil), stop: false, expectInternals: map[negtypes.NegSyncerKey]bool{ getSyncerKey(svcNamespace1, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}}): false, @@ -151,7 +151,7 @@ func TestEnsureAndStopSyncer(t *testing.T) { desc: "modify 2 existing ports to enable readinessGate", namespace: svcNamespace1, name: svcName, - portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "namedport"}), namer, true), + portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "namedport"}), namer, true, nil), stop: false, expectInternals: map[negtypes.NegSyncerKey]bool{ getSyncerKey(svcNamespace1, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}}): true, @@ -162,7 +162,7 @@ func TestEnsureAndStopSyncer(t *testing.T) { desc: "add 1 new port for a different service", namespace: svcNamespace2, name: svcName, - portInfoMap: negtypes.NewPortInfoMap(svcNamespace2, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}), namer, false), + portInfoMap: negtypes.NewPortInfoMap(svcNamespace2, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}), namer, false, nil), stop: false, expectInternals: map[negtypes.NegSyncerKey]bool{ getSyncerKey(svcNamespace1, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}}): true, @@ -174,7 +174,7 @@ func TestEnsureAndStopSyncer(t *testing.T) { desc: "change target port of 1 existing port", namespace: svcNamespace1, name: svcName, - portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "443"}), namer, true), + portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Port: 4000, TargetPort: "443"}), namer, true, nil), stop: false, expectInternals: map[negtypes.NegSyncerKey]bool{ getSyncerKey(svcNamespace1, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}}): true, @@ -197,7 +197,7 @@ func TestEnsureAndStopSyncer(t *testing.T) { namespace: svcNamespace1, name: svcName, stop: false, - portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName1, Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Name: portName2, Port: 4000, TargetPort: "bar"}), namer, true), + portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName1, Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Name: portName2, Port: 4000, TargetPort: "bar"}), namer, true, nil), expectInternals: map[negtypes.NegSyncerKey]bool{ getSyncerKey(svcNamespace2, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}}): false, getSyncerKey(svcNamespace1, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Name: portName1, Port: 3000, TargetPort: "80"}}): true, @@ -210,7 +210,7 @@ func TestEnsureAndStopSyncer(t *testing.T) { namespace: svcNamespace1, name: svcName, stop: false, - portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName2, Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Name: portName0, Port: 4000, TargetPort: "bar"}), namer, true), + portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName2, Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Name: portName0, Port: 4000, TargetPort: "bar"}), namer, true, nil), expectInternals: map[negtypes.NegSyncerKey]bool{ getSyncerKey(svcNamespace2, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}}): false, getSyncerKey(svcNamespace1, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Name: portName2, Port: 3000, TargetPort: "80"}}): true, @@ -223,7 +223,7 @@ func TestEnsureAndStopSyncer(t *testing.T) { namespace: svcNamespace1, name: svcName, stop: false, - portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName2, Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Name: portName0, Port: 4000, TargetPort: "bar"}, negtypes.SvcPortTuple{Name: string(negtypes.VmIpEndpointType), Port: 0}), namer, true), + portInfoMap: negtypes.NewPortInfoMap(svcNamespace1, svcName, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName2, Port: 3000, TargetPort: "80"}, negtypes.SvcPortTuple{Name: portName0, Port: 4000, TargetPort: "bar"}, negtypes.SvcPortTuple{Name: string(negtypes.VmIpEndpointType), Port: 0}), namer, true, nil), expectInternals: map[negtypes.NegSyncerKey]bool{ getSyncerKey(svcNamespace2, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Port: 3000, TargetPort: "80"}}): false, getSyncerKey(svcNamespace1, svcName, negtypes.PortInfoMapKey{ServicePort: 3000, Subset: ""}, negtypes.PortInfo{PortTuple: negtypes.SvcPortTuple{Name: portName2, Port: 3000, TargetPort: "80"}}): true, @@ -636,31 +636,31 @@ func TestFilterCommonPorts(t *testing.T) { }, { desc: "empty input 2", - p1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false), + p1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false, nil), p2: negtypes.PortInfoMap{}, - expectP1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false), + expectP1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false, nil), expectP2: negtypes.PortInfoMap{}, }, { desc: "empty input 3", p1: negtypes.PortInfoMap{}, - p2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, true), + p2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, true, nil), expectP1: negtypes.PortInfoMap{}, - expectP2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, true), + expectP2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, true, nil), }, { desc: "difference in readiness gate", - p1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false), - p2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, true), + p1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false, nil), + p2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, true, nil), expectP1: negtypes.PortInfoMap{}, expectP2: negtypes.PortInfoMap{}, }, { desc: "difference in port name and readiness gate", - p1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName1, Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false), - p2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, true), - expectP1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName1, Port: port1, TargetPort: targetPort1}), namer, false), - expectP2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}), namer, true), + p1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName1, Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false, nil), + p2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, true, nil), + expectP1: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Name: portName1, Port: port1, TargetPort: targetPort1}), namer, false, nil), + expectP2: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}), namer, true, nil), }, } { t.Run(tc.desc, func(t *testing.T) { @@ -691,35 +691,35 @@ func populateSyncerManager(manager *syncerManager, kubeClient kubernetes.Interfa { namespace: namespace1, name: name1, - portInfoMap: portInfoUnion(negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false), - negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port3, TargetPort: targetPort3}, negtypes.SvcPortTuple{Port: port4, TargetPort: targetPort4}), namer, true)), + portInfoMap: portInfoUnion(negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false, nil), + negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port3, TargetPort: targetPort3}, negtypes.SvcPortTuple{Port: port4, TargetPort: targetPort4}), namer, true, nil)), selector: map[string]string{labelKey1: labelValue1}, }, { // nil selector namespace: namespace1, name: name2, - portInfoMap: portInfoUnion(negtypes.NewPortInfoMap(namespace1, name2, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false), - negtypes.NewPortInfoMap(namespace1, name2, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port3, TargetPort: targetPort3}, negtypes.SvcPortTuple{Port: port4, TargetPort: targetPort4}), namer, true)), + portInfoMap: portInfoUnion(negtypes.NewPortInfoMap(namespace1, name2, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false, nil), + negtypes.NewPortInfoMap(namespace1, name2, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port3, TargetPort: targetPort3}, negtypes.SvcPortTuple{Port: port4, TargetPort: targetPort4}), namer, true, nil)), selector: nil, }, { namespace: namespace2, name: name1, - portInfoMap: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false), + portInfoMap: negtypes.NewPortInfoMap(namespace1, name1, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}), namer, false, nil), selector: map[string]string{labelKey1: labelValue1}, }, { namespace: namespace2, name: name2, - portInfoMap: negtypes.NewPortInfoMap(namespace2, name2, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}, negtypes.SvcPortTuple{Port: port3, TargetPort: targetPort3}), namer, true), + portInfoMap: negtypes.NewPortInfoMap(namespace2, name2, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}, negtypes.SvcPortTuple{Port: port3, TargetPort: targetPort3}), namer, true, nil), selector: map[string]string{labelKey2: labelValue2}, }, { namespace: namespace2, name: name3, - portInfoMap: portInfoUnion(negtypes.NewPortInfoMap(namespace2, name3, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}, negtypes.SvcPortTuple{Port: port3, TargetPort: targetPort3}), namer, false), - negtypes.NewPortInfoMap(namespace2, name3, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port4, TargetPort: targetPort4}), namer, true)), + portInfoMap: portInfoUnion(negtypes.NewPortInfoMap(namespace2, name3, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port1, TargetPort: targetPort1}, negtypes.SvcPortTuple{Port: port2, TargetPort: targetPort2}, negtypes.SvcPortTuple{Port: port3, TargetPort: targetPort3}), namer, false, nil), + negtypes.NewPortInfoMap(namespace2, name3, types.NewSvcPortTupleSet(negtypes.SvcPortTuple{Port: port4, TargetPort: targetPort4}), namer, true, nil)), selector: map[string]string{labelKey1: labelValue2}, }, } diff --git a/pkg/neg/types/types.go b/pkg/neg/types/types.go index f655070c8f..c71c7ffb7a 100644 --- a/pkg/neg/types/types.go +++ b/pkg/neg/types/types.go @@ -126,12 +126,16 @@ type PortInfoMapKey struct { // PortInfoMap is a map of PortInfoMapKey:PortInfo type PortInfoMap map[PortInfoMapKey]PortInfo -func NewPortInfoMap(namespace, name string, svcPortTupleSet SvcPortTupleSet, namer NetworkEndpointGroupNamer, readinessGate bool) PortInfoMap { +func NewPortInfoMap(namespace, name string, svcPortTupleSet SvcPortTupleSet, namer NetworkEndpointGroupNamer, readinessGate bool, customNegNames map[SvcPortTuple]string) PortInfoMap { ret := PortInfoMap{} for svcPortTuple := range svcPortTupleSet { + negName, ok := customNegNames[svcPortTuple] + if !ok { + negName = namer.NEG(namespace, name, svcPortTuple.Port) + } ret[PortInfoMapKey{svcPortTuple.Port, ""}] = PortInfo{ PortTuple: svcPortTuple, - NegName: namer.NEG(namespace, name, svcPortTuple.Port), + NegName: negName, ReadinessGate: readinessGate, } } diff --git a/pkg/neg/types/types_test.go b/pkg/neg/types/types_test.go index 788974e458..d7b5162b41 100644 --- a/pkg/neg/types/types_test.go +++ b/pkg/neg/types/types_test.go @@ -75,42 +75,42 @@ func TestPortInfoMapMerge(t *testing.T) { { "empty map union a non-empty map is the non-empty map", PortInfoMap{}, - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false, nil), false, }, { "empty map union a non-empty map is the non-empty map 2", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, true), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, true, nil), PortInfoMap{}, - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, true), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, true, nil), false, }, { "union of two non-empty maps, none has readiness gate enabled", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), false, }, { "union of two non-empty maps, all have readiness gate enabled ", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, true), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, true, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true, nil), false, }, { "union of two non-empty maps with one overlapping service port", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), false, }, { "union of two non-empty maps with overlapping service port and difference in readiness gate configurations ", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, true), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, true, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), PortInfoMap{ PortInfoMapKey{80, ""}: PortInfo{ PortTuple: SvcPortTuple{ @@ -141,8 +141,8 @@ func TestPortInfoMapMerge(t *testing.T) { }, { "union of two non-empty maps with overlapping service port and difference in readiness gate configurations with named port", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "foo", TargetPort: "3000"}, SvcPortTuple{Port: 5000, Name: "bar", TargetPort: "6000"}), namer, true), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "foo", TargetPort: "3000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "foo", TargetPort: "3000"}, SvcPortTuple{Port: 5000, Name: "bar", TargetPort: "6000"}), namer, true, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "foo", TargetPort: "3000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), PortInfoMap{ PortInfoMapKey{80, ""}: PortInfo{ PortTuple: SvcPortTuple{ @@ -221,15 +221,22 @@ func TestPortInfoMapMerge(t *testing.T) { }, { "error on inconsistent value", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8000, TargetPort: "9000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "3000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8000, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), true, }, { "error on inconsistent port name", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "foo", TargetPort: "3000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "bar", TargetPort: "3000"}, SvcPortTuple{Port: 8000, TargetPort: "9000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "foo", TargetPort: "3000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "bar", TargetPort: "3000"}, SvcPortTuple{Port: 8000, TargetPort: "9000"}), namer, false, nil), + PortInfoMap{}, + true, + }, + { + "error on inconsistent neg name", + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "foo", TargetPort: "3000"}), namer, false, map[SvcPortTuple]string{SvcPortTuple{Port: 80, Name: "foo", TargetPort: "3000"}: "neg-1"}), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, Name: "bar", TargetPort: "3000"}, SvcPortTuple{Port: 8000, TargetPort: "9000"}), namer, false, nil), PortInfoMap{}, true, }, @@ -280,62 +287,68 @@ func TestPortInfoMapDifference(t *testing.T) { { "empty map difference a non-empty map is empty map", PortInfoMap{}, - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false, nil), PortInfoMap{}, }, { "non-empty map difference a non-empty map is the non-empty map", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false, nil), PortInfoMap{}, - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false, nil), }, { "non-empty map difference a non-empty map is the non-empty map 2", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, true), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, true, nil), PortInfoMap{}, - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, true), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, true, nil), }, { "difference of two non-empty maps with the same elements", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false, nil), PortInfoMap{}, }, { "difference of two non-empty maps with no elements in common returns p1", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false, nil), }, { "difference of two non-empty maps with elements in common", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}), namer, false, nil), }, { "difference of two non-empty maps with a key in common but different in value", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}), namer, false, nil), }, { "difference of two non-empty maps with 2 keys in common but different in values", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "8443"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}, SvcPortTuple{Port: 443, TargetPort: "9443"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "8443"}), namer, false), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "8443"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}, SvcPortTuple{Port: 443, TargetPort: "9443"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "8443"}), namer, false, nil), }, { "difference of two non-empty maps with a key in common but different in readiness gate fields", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}), namer, true), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}), namer, true), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}), namer, true, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}), namer, true, nil), }, { "difference of two non-empty maps with 2 keys in common and 2 more items with different readinessGate", - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false), - NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true, nil), + }, + { + "difference of two non-empty maps with a key in common but different neg names", + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}), namer, true, map[SvcPortTuple]string{SvcPortTuple{Port: 80, TargetPort: "8080"}: "neg-1"}), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil), + NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "8080"}), namer, true, map[SvcPortTuple]string{SvcPortTuple{Port: 80, TargetPort: "8080"}: "neg-1"}), }, } @@ -404,22 +417,22 @@ func TestNegsWithReadinessGate(t *testing.T) { { desc: "PortInfoMap with no readiness gate enabled", getPortInfoMap: func() PortInfoMap { - return NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false) + return NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, false, nil) }, expectNegs: sets.NewString(), }, { desc: "PortInfoMap with all readiness gates enabled", getPortInfoMap: func() PortInfoMap { - return NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true) + return NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}, SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true, nil) }, expectNegs: sets.NewString(namer.NEG(namespace, name, 80), namer.NEG(namespace, name, 443), namer.NEG(namespace, name, 5000), namer.NEG(namespace, name, 8080)), }, { desc: "PortInfoMap with part of readiness gates enabled", getPortInfoMap: func() PortInfoMap { - p := NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true) - p.Merge(NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false)) + p := NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 5000, TargetPort: "6000"}, SvcPortTuple{Port: 8080, TargetPort: "9000"}), namer, true, nil) + p.Merge(NewPortInfoMap(namespace, name, NewSvcPortTupleSet(SvcPortTuple{Port: 80, TargetPort: "namedport"}, SvcPortTuple{Port: 443, TargetPort: "3000"}), namer, false, nil)) return p }, expectNegs: sets.NewString(namer.NEG(namespace, name, 5000), namer.NEG(namespace, name, 8080)), @@ -431,3 +444,61 @@ func TestNegsWithReadinessGate(t *testing.T) { } } } + +func TestCustomNamedNegs(t *testing.T) { + var ( + svcNamespace = "namespace" + svcName = "svc-name" + negName1 = "neg1" + negName2 = "neg2" + port1 = int32(80) + port2 = int32(432) + targetPort1 = "3000" + targetPort2 = "3001" + namer = &negNamer{} + svcPortTuple1 = SvcPortTuple{Port: port1, TargetPort: targetPort1} + svcPortTuple2 = SvcPortTuple{Port: port2, TargetPort: targetPort2} + ) + testcases := []struct { + desc string + svcPortTuples SvcPortTupleSet + customNamedNegs map[SvcPortTuple]string + expectedPortInfoMap PortInfoMap + }{ + { + desc: "no custom named negs", + svcPortTuples: NewSvcPortTupleSet(svcPortTuple1, svcPortTuple2), + expectedPortInfoMap: PortInfoMap{ + PortInfoMapKey{port1, ""}: PortInfo{PortTuple: svcPortTuple1, NegName: namer.NEG(svcNamespace, svcName, port1), ReadinessGate: false}, + PortInfoMapKey{port2, ""}: PortInfo{PortTuple: svcPortTuple2, NegName: namer.NEG(svcNamespace, svcName, port2), ReadinessGate: false}, + }, + }, + { + desc: "all custom named negs", + svcPortTuples: NewSvcPortTupleSet(svcPortTuple1, svcPortTuple2), + customNamedNegs: map[SvcPortTuple]string{svcPortTuple1: negName1, svcPortTuple2: negName2}, + expectedPortInfoMap: PortInfoMap{ + PortInfoMapKey{port1, ""}: PortInfo{PortTuple: svcPortTuple1, NegName: negName1, ReadinessGate: false}, + PortInfoMapKey{port2, ""}: PortInfo{PortTuple: svcPortTuple2, NegName: negName2, ReadinessGate: false}, + }, + }, + { + desc: "1 custom named negs, 1 autogenerated named neg", + svcPortTuples: NewSvcPortTupleSet(svcPortTuple1, svcPortTuple2), + customNamedNegs: map[SvcPortTuple]string{svcPortTuple1: negName1}, + expectedPortInfoMap: PortInfoMap{ + PortInfoMapKey{port1, ""}: PortInfo{PortTuple: svcPortTuple1, NegName: negName1, ReadinessGate: false}, + PortInfoMapKey{port2, ""}: PortInfo{PortTuple: svcPortTuple2, NegName: namer.NEG(svcNamespace, svcName, port2), ReadinessGate: false}, + }, + }, + } + + for _, tc := range testcases { + t.Run(tc.desc, func(t *testing.T) { + result := NewPortInfoMap(svcNamespace, svcName, tc.svcPortTuples, namer, false, tc.customNamedNegs) + if !reflect.DeepEqual(tc.expectedPortInfoMap, result) { + t.Errorf("Expected portInfoMap to equal: %v; got: %v", tc.expectedPortInfoMap, result) + } + }) + } +} diff --git a/pkg/neg/utils.go b/pkg/neg/utils.go index 2b56b2d3ae..b1b0c30d07 100644 --- a/pkg/neg/utils.go +++ b/pkg/neg/utils.go @@ -34,20 +34,24 @@ type NegSyncerType string // negServicePorts returns the SvcPortTupleSet that matches the exposed service port in the NEG annotation. // knownSvcTupleSet represents the known service port tuples that already exist on the service. // This function returns an error if any of the service port from the annotation is not in knownSvcTupleSet. -func negServicePorts(ann *annotations.NegAnnotation, knownSvcTupleSet types.SvcPortTupleSet) (types.SvcPortTupleSet, error) { +func negServicePorts(ann *annotations.NegAnnotation, knownSvcTupleSet types.SvcPortTupleSet) (types.SvcPortTupleSet, map[types.SvcPortTuple]string, error) { svcPortTupleSet := make(types.SvcPortTupleSet) + customNameMap := make(map[types.SvcPortTuple]string) var errList []error - for port := range ann.ExposedPorts { + for port, attr := range ann.ExposedPorts { // TODO: also validate ServicePorts in the exposed NEG annotation via webhook tuple, ok := knownSvcTupleSet.Get(port) if !ok { errList = append(errList, fmt.Errorf("port %v specified in %q doesn't exist in the service", port, annotations.NEGAnnotationKey)) } else { + if attr.Name != "" { + customNameMap[tuple] = attr.Name + } svcPortTupleSet.Insert(tuple) } } - return svcPortTupleSet, utilerrors.NewAggregate(errList) + return svcPortTupleSet, customNameMap, utilerrors.NewAggregate(errList) } // castToDestinationRule cast Unstructured obj to istioV1alpha3.DestinationRule diff --git a/pkg/neg/utils_test.go b/pkg/neg/utils_test.go index c812ad2a4c..d739b4aa46 100644 --- a/pkg/neg/utils_test.go +++ b/pkg/neg/utils_test.go @@ -21,7 +21,7 @@ import ( "reflect" "testing" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/ingress-gce/pkg/annotations" @@ -34,11 +34,12 @@ func TestNEGServicePorts(t *testing.T) { portName2 := "name2" testcases := []struct { - desc string - annotation string - knownPortMap []types.SvcPortTuple - expectedPortMap []types.SvcPortTuple - expectedErr error + desc string + annotation string + knownPortMap []types.SvcPortTuple + expectedPortMap []types.SvcPortTuple + expectedCustomNameMap map[types.SvcPortTuple]string + expectedErr error }{ { desc: "NEG annotation references port that Service does not have", @@ -148,6 +149,37 @@ func TestNEGServicePorts(t *testing.T) { }, }, }, + { + desc: "NEG annotation has custom names for negs", + annotation: `{"exposed_ports":{"80":{"name":"neg-name"},"443":{}}}`, + knownPortMap: []types.SvcPortTuple{ + { + Name: portName0, + Port: 80, + TargetPort: "namedport", + }, + { + Name: portName0, + Port: 443, + TargetPort: "3000", + }, + }, + expectedPortMap: []types.SvcPortTuple{ + { + Name: portName0, + Port: 80, + TargetPort: "namedport", + }, + { + Name: portName0, + Port: 443, + TargetPort: "3000", + }, + }, + expectedCustomNameMap: map[types.SvcPortTuple]string{ + types.SvcPortTuple{Name: portName0, Port: 80, TargetPort: "namedport"}: "neg-name", + }, + }, } for _, tc := range testcases { @@ -168,7 +200,7 @@ func TestNEGServicePorts(t *testing.T) { inputSet := types.NewSvcPortTupleSet(tc.knownPortMap...) expectSet := types.NewSvcPortTupleSet(tc.expectedPortMap...) - outputSet, err := negServicePorts(exposeNegStruct, inputSet) + outputSet, customNameMap, err := negServicePorts(exposeNegStruct, inputSet) if tc.expectedErr == nil && err != nil { t.Errorf("ExpectedNEGServicePorts to not return an error, got: %v", err) } @@ -182,6 +214,20 @@ func TestNEGServicePorts(t *testing.T) { t.Errorf("Expected negServicePorts to return a %v error, got: %v", tc.expectedErr, err) } } + + if len(tc.expectedCustomNameMap) == 0 && len(customNameMap) != 0 { + t.Errorf("Expected no custom names, but found %+v", customNameMap) + } + + for expectedTuple, expectedNegName := range tc.expectedCustomNameMap { + if negName, ok := customNameMap[expectedTuple]; ok { + if negName != expectedNegName { + t.Errorf("Expected neg name for tuple %+v to be %s, but was %s", expectedTuple, expectedNegName, negName) + } + } else { + t.Errorf("Expected tuple %+v to be a key in customNameMap", expectedTuple) + } + } }) } }