// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: MIT package k8sclient import ( "log" "testing" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awsutil" "gotest.tools/v3/assert" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var endpointsArray = []interface{}{ &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "guestbook", GenerateName: "", Namespace: "default", SelfLink: "/api/v1/namespaces/default/endpoints/guestbook", UID: "a885b78c-5573-11e9-b47e-066a7a20bac8", ResourceVersion: "1550348", Generation: 0, CreationTimestamp: metav1.Time{ Time: time.Now(), }, Labels: map[string]string{ "app": "guestbook", }, }, Subsets: []v1.EndpointSubset{ { Addresses: []v1.EndpointAddress{ { IP: "192.168.122.125", Hostname: "", NodeName: aws.String("ip-192-168-76-61.eu-west-1.compute.internal"), TargetRef: &v1.ObjectReference{ Kind: "Pod", Namespace: "default", Name: "guestbook-qjqnz", UID: "9ca74e86-5573-11e9-b47e-066a7a20bac8", APIVersion: "", ResourceVersion: "1550311", FieldPath: "", }, }, { IP: "192.168.176.235", Hostname: "", NodeName: aws.String("ip-192-168-153-1.eu-west-1.compute.internal"), TargetRef: &v1.ObjectReference{ Kind: "Pod", Namespace: "default", Name: "guestbook-92wmq", UID: "9ca662bb-5573-11e9-b47e-066a7a20bac8", APIVersion: "", ResourceVersion: "1550313", FieldPath: "", }, }, { IP: "192.168.251.65", Hostname: "", NodeName: aws.String("ip-192-168-200-63.eu-west-1.compute.internal"), TargetRef: &v1.ObjectReference{ Kind: "Pod", Namespace: "default", Name: "guestbook-qbdv8", UID: "9ca76fd6-5573-11e9-b47e-066a7a20bac8", APIVersion: "", ResourceVersion: "1550319", FieldPath: "", }, }, }, Ports: []v1.EndpointPort{ { Name: "", Port: 3000, Protocol: "TCP", }, }, }, }, }, &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "kubernetes", GenerateName: "", Namespace: "default", SelfLink: "/api/v1/namespaces/default/endpoints/kubernetes", UID: "4daf1688-4c0a-11e9-b47e-066a7a20bac8", ResourceVersion: "5807557", Generation: 0, CreationTimestamp: metav1.Time{ Time: time.Now(), }, }, Subsets: []v1.EndpointSubset{ { Addresses: []v1.EndpointAddress{ { IP: "192.168.174.242", Hostname: "", }, { IP: "192.168.82.3", Hostname: "", }, }, Ports: []v1.EndpointPort{ { Name: "https", Port: 443, Protocol: "TCP", }, }, }, }, }, &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "redis-master", GenerateName: "", Namespace: "default", SelfLink: "/api/v1/namespaces/default/endpoints/redis-master", UID: "74ac431b-5573-11e9-b47e-066a7a20bac8", ResourceVersion: "1550146", Generation: 0, CreationTimestamp: metav1.Time{ Time: time.Now(), }, Labels: map[string]string{ "app": "redis", "role": "master", }, }, Subsets: []v1.EndpointSubset{ { Addresses: []v1.EndpointAddress{ { IP: "192.168.108.68", Hostname: "", NodeName: aws.String("ip-192-168-76-61.eu-west-1.compute.internal"), TargetRef: &v1.ObjectReference{ Kind: "Pod", Namespace: "default", Name: "redis-master-rh2bd", UID: "5d7825f3-5573-11e9-b47e-066a7a20bac8", APIVersion: "", ResourceVersion: "1550097", FieldPath: "", }, }, }, Ports: []v1.EndpointPort{ { Name: "", Port: 6379, Protocol: "TCP", }, }, }, }, }, &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "redis-slave", GenerateName: "", Namespace: "default", SelfLink: "/api/v1/namespaces/default/endpoints/redis-slave", UID: "8dee375e-5573-11e9-b47e-066a7a20bac8", ResourceVersion: "1550242", Generation: 0, CreationTimestamp: metav1.Time{ Time: time.Now(), }, Labels: map[string]string{ "app": "redis", "role": "slave", }, }, Subsets: []v1.EndpointSubset{ { Addresses: []v1.EndpointAddress{ { IP: "192.168.186.217", Hostname: "", NodeName: aws.String("ip-192-168-153-1.eu-west-1.compute.internal"), TargetRef: &v1.ObjectReference{ Kind: "Pod", Namespace: "default", Name: "redis-slave-mdjsj", UID: "8137c74b-5573-11e9-b47e-066a7a20bac8", APIVersion: "", ResourceVersion: "1550223", FieldPath: "", }, }, { IP: "192.168.68.108", Hostname: "", NodeName: aws.String("ip-192-168-76-61.eu-west-1.compute.internal"), TargetRef: &v1.ObjectReference{ Kind: "Pod", Namespace: "default", Name: "redis-slave-gtd5x", UID: "813878c3-5573-11e9-b47e-066a7a20bac8", APIVersion: "", ResourceVersion: "1550226", FieldPath: "", }, }, }, Ports: []v1.EndpointPort{ { Name: "", Port: 6379, Protocol: "TCP", }, }, }, }, }, &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "kube-controller-manager", GenerateName: "", Namespace: "kube-system", SelfLink: "/api/v1/namespaces/kube-system/endpoints/kube-controller-manager", UID: "4f77dc4b-4c0a-11e9-b47e-066a7a20bac8", ResourceVersion: "6461574", Generation: 0, CreationTimestamp: metav1.Time{ Time: time.Now(), }, Annotations: map[string]string{ "control-plane.alpha.kubernetes.io/leader": "{\"holderIdentity\":\"ip-10-0-189-120.eu-west-1.compute.internal_89407f85-57e1-11e9-b6ea-02eb484bead6\",\"leaseDurationSeconds\":15,\"acquireTime\":\"2019-04-05T20:34:54Z\",\"renewTime\":\"2019-05-06T20:04:02Z\",\"leaderTransitions\":1}", }, }, }, &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "kube-dns", GenerateName: "", Namespace: "kube-system", SelfLink: "/api/v1/namespaces/kube-system/endpoints/kube-dns", UID: "5049bf97-4c0a-11e9-b47e-066a7a20bac8", ResourceVersion: "5847", Generation: 0, CreationTimestamp: metav1.Time{ Time: time.Now(), }, Labels: map[string]string{ "eks.amazonaws.com/component": "kube-dns", "k8s-app": "kube-dns", "kubernetes.io/cluster-service": "true", "kubernetes.io/name": "CoreDNS", }, }, Subsets: []v1.EndpointSubset{ { Addresses: []v1.EndpointAddress{ { IP: "192.168.212.227", Hostname: "", NodeName: aws.String("ip-192-168-200-63.eu-west-1.compute.internal"), TargetRef: &v1.ObjectReference{ Kind: "Pod", Namespace: "kube-system", Name: "coredns-7554568866-26jdf", UID: "503e1eae-4c0a-11e9-b47e-066a7a20bac8", APIVersion: "", ResourceVersion: "5842", FieldPath: "", }, }, { IP: "192.168.222.250", Hostname: "", NodeName: aws.String("ip-192-168-200-63.eu-west-1.compute.internal"), TargetRef: &v1.ObjectReference{ Kind: "Pod", Namespace: "kube-system", Name: "coredns-7554568866-shwn6", UID: "503f9b07-4c0a-11e9-b47e-066a7a20bac8", APIVersion: "", ResourceVersion: "5839", FieldPath: "", }, }, }, Ports: []v1.EndpointPort{ { Name: "dns", Port: 53, Protocol: "UDP", }, { Name: "dns-tcp", Port: 53, Protocol: "TCP", }, }, }, }, }, &v1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "kube-scheduler", GenerateName: "", Namespace: "kube-system", SelfLink: "/api/v1/namespaces/kube-system/endpoints/kube-scheduler", UID: "4e8782bc-4c0a-11e9-b47e-066a7a20bac8", ResourceVersion: "6461575", Generation: 0, CreationTimestamp: metav1.Time{ Time: time.Now(), }, Annotations: map[string]string{ "control-plane.alpha.kubernetes.io/leader": "{\"holderIdentity\":\"ip-10-0-189-120.eu-west-1.compute.internal_949a4400-57e1-11e9-a7bb-02eb484bead6\",\"leaseDurationSeconds\":15,\"acquireTime\":\"2019-04-05T20:34:57Z\",\"renewTime\":\"2019-05-06T20:04:02Z\",\"leaderTransitions\":1}", }, }, }, } func setUpEndpointClient() (*epClient, chan struct{}) { stopChan := make(chan struct{}) client := &epClient{ stopChan: stopChan, store: NewObjStore(transformFuncEndpoint), inited: true, //make it true to avoid further initialization invocation. } return client, stopChan } func TestEpClient_PodKeyToServiceNames(t *testing.T) { client, stopChan := setUpEndpointClient() defer close(stopChan) client.store.Replace(endpointsArray, "") expectedMap := map[string][]string{ "namespace:default,podName:redis-master-rh2bd": {"redis-master"}, "namespace:default,podName:redis-slave-mdjsj": {"redis-slave"}, "namespace:default,podName:redis-slave-gtd5x": {"redis-slave"}, "namespace:kube-system,podName:coredns-7554568866-26jdf": {"kube-dns"}, "namespace:kube-system,podName:coredns-7554568866-shwn6": {"kube-dns"}, "namespace:default,podName:guestbook-qjqnz": {"guestbook"}, "namespace:default,podName:guestbook-92wmq": {"guestbook"}, "namespace:default,podName:guestbook-qbdv8": {"guestbook"}, } resultMap := client.PodKeyToServiceNames() log.Printf("PodKeyToServiceNames (len=%v): %v", len(resultMap), awsutil.Prettify(resultMap)) assert.DeepEqual(t, resultMap, expectedMap) } func TestEpClient_ServiceNameToPodNum(t *testing.T) { client, stopChan := setUpEndpointClient() defer close(stopChan) client.store.Replace(endpointsArray, "") expectedMap := map[Service]int{ NewService("redis-slave", "default"): 2, NewService("kube-dns", "kube-system"): 2, NewService("redis-master", "default"): 1, NewService("guestbook", "default"): 3, } resultMap := client.ServiceToPodNum() log.Printf("ServiceNameToPodNum (len=%v): %v", len(resultMap), awsutil.Prettify(resultMap)) assert.DeepEqual(t, resultMap, expectedMap) }