Add IP addresses filtering 87/103687/5
authorPawel Wieczorek <p.wieczorek2@samsung.com>
Thu, 12 Mar 2020 17:39:03 +0000 (18:39 +0100)
committerBartek Grzybowski <b.grzybowski@partner.samsung.com>
Wed, 25 Mar 2020 13:08:24 +0000 (13:08 +0000)
Each node might be described with 3 types of addresses [1]. Some
providers also use node annotations [2] for assigned addresses.

This patch filters out all IP addresses from nodes list. External IPs
take precedence over internal ones. The first address on the extracted
slice will be later used to run the scan on.

This behaviour could be later modified to e.g. loop over all extracted
IP addresses (if scan fails).

[1] https://kubernetes.io/docs/concepts/architecture/nodes/#addresses
[2] https://github.com/rancher/rke/blob/master/k8s/node.go#L18

Issue-ID: SECCOM-261
Change-Id: Ifd094447f778da378dfe1aee765f552b6ebd669f
Signed-off-by: Pawel Wieczorek <p.wieczorek2@samsung.com>
test/security/sslendpoints/main.go
test/security/sslendpoints/ports/ports.go
test/security/sslendpoints/ports/ports_test.go

index 44f2509..68d11b3 100644 (file)
@@ -34,6 +34,19 @@ func main() {
                log.Panicf("Unable to build client: %v", err)
        }
 
+       // get list of nodes to extract addresses for running scan
+       nodes, err := clientset.CoreV1().Nodes().List(metav1.ListOptions{})
+       if err != nil {
+               log.Panicf("Unable to get list of nodes: %v", err)
+       }
+
+       // filter out addresses for running scan
+       addresses, ok := ports.FilterIPAddresses(nodes)
+       if !ok {
+               log.Println("There are no IP addresses to run scan")
+               os.Exit(0)
+       }
+
        // get list of services to extract nodeport information
        services, err := clientset.CoreV1().Services("").List(metav1.ListOptions{})
        if err != nil {
index 823e075..a80fb78 100644 (file)
@@ -16,3 +16,20 @@ func FilterNodePorts(services *v1.ServiceList) (map[uint16]string, bool) {
        }
        return nodeports, len(nodeports) > 0
 }
+
+// FilterIPAddresses extracts IP addresses from NodeList.
+// External IP addresses take precedence over internal ones.
+func FilterIPAddresses(nodes *v1.NodeList) ([]string, bool) {
+       addresses := make([]string, 0)
+       for _, node := range nodes.Items {
+               for _, address := range node.Status.Addresses {
+                       switch address.Type {
+                       case "InternalIP":
+                               addresses = append(addresses, address.Address)
+                       case "ExternalIP":
+                               addresses = append([]string{address.Address}, addresses...)
+                       }
+               }
+       }
+       return addresses, len(addresses) > 0
+}
index 1078db1..0480b71 100644 (file)
@@ -20,6 +20,12 @@ var _ = Describe("Ports", func() {
                serviceR    = "serviceR"
                serviceL    = "serviceL"
                serviceZ    = "serviceZ"
+
+               externalIpControl = "1.2.3.4"
+               internalIpControl = "192.168.121.100"
+               internalIpWorker  = "192.168.121.200"
+               hostnameControl   = "onap-control-1"
+               hostnameWorker    = "onap-worker-1"
        )
 
        var (
@@ -30,6 +36,12 @@ var _ = Describe("Ports", func() {
                servicesManyWithNodePort            *v1.ServiceList
                servicesManyWithMultipleNodePorts   *v1.ServiceList
                servicesManyMixedNodePorts          *v1.ServiceList
+
+               nodesEmpty             *v1.NodeList
+               nodesSingleWithIP      *v1.NodeList
+               nodesSingleWithBothIPs *v1.NodeList
+               nodesManyWithHostnames *v1.NodeList
+               nodesManyWithMixedIPs  *v1.NodeList
        )
 
        BeforeEach(func() {
@@ -148,6 +160,72 @@ var _ = Describe("Ports", func() {
                                },
                        },
                }
+
+               nodesEmpty = &v1.NodeList{}
+               nodesSingleWithIP = &v1.NodeList{
+                       Items: []v1.Node{
+                               v1.Node{
+                                       Status: v1.NodeStatus{
+                                               Addresses: []v1.NodeAddress{
+                                                       v1.NodeAddress{Type: "InternalIP", Address: internalIpControl},
+                                                       v1.NodeAddress{Type: "Hostname", Address: hostnameControl},
+                                               },
+                                       },
+                               },
+                       },
+               }
+               nodesSingleWithBothIPs = &v1.NodeList{
+                       Items: []v1.Node{
+                               v1.Node{
+                                       Status: v1.NodeStatus{
+                                               Addresses: []v1.NodeAddress{
+                                                       v1.NodeAddress{Type: "ExternalIP", Address: externalIpControl},
+                                                       v1.NodeAddress{Type: "InternalIP", Address: internalIpControl},
+                                                       v1.NodeAddress{Type: "Hostname", Address: hostnameControl},
+                                               },
+                                       },
+                               },
+                       },
+               }
+               nodesManyWithHostnames = &v1.NodeList{
+                       Items: []v1.Node{
+                               v1.Node{
+                                       Status: v1.NodeStatus{
+                                               Addresses: []v1.NodeAddress{
+                                                       v1.NodeAddress{Type: "Hostname", Address: hostnameControl},
+                                               },
+                                       },
+                               },
+                               v1.Node{
+                                       Status: v1.NodeStatus{
+                                               Addresses: []v1.NodeAddress{
+                                                       v1.NodeAddress{Type: "Hostname", Address: hostnameWorker},
+                                               },
+                                       },
+                               },
+                       },
+               }
+               nodesManyWithMixedIPs = &v1.NodeList{
+                       Items: []v1.Node{
+                               v1.Node{
+                                       Status: v1.NodeStatus{
+                                               Addresses: []v1.NodeAddress{
+                                                       v1.NodeAddress{Type: "ExternalIP", Address: externalIpControl},
+                                                       v1.NodeAddress{Type: "InternalIP", Address: internalIpControl},
+                                                       v1.NodeAddress{Type: "Hostname", Address: hostnameControl},
+                                               },
+                                       },
+                               },
+                               v1.Node{
+                                       Status: v1.NodeStatus{
+                                               Addresses: []v1.NodeAddress{
+                                                       v1.NodeAddress{Type: "InternalIP", Address: internalIpWorker},
+                                                       v1.NodeAddress{Type: "Hostname", Address: hostnameWorker},
+                                               },
+                                       },
+                               },
+                       },
+               }
        })
 
        Describe("NodePorts extraction", func() {
@@ -211,4 +289,44 @@ var _ = Describe("Ports", func() {
                        })
                })
        })
+
+       Describe("IP addresses extraction", func() {
+               Context("With empty node list", func() {
+                       It("should report no IP addresses", func() {
+                               addresses, ok := FilterIPAddresses(nodesEmpty)
+                               Expect(ok).To(BeFalse())
+                               Expect(addresses).To(BeEmpty())
+                       })
+               })
+               Context("With nodes using only hostnames", func() {
+                       It("should report no IP addresses", func() {
+                               addresses, ok := FilterIPAddresses(nodesManyWithHostnames)
+                               Expect(ok).To(BeFalse())
+                               Expect(addresses).To(BeEmpty())
+                       })
+               })
+               Context("With node using only internal IP", func() {
+                       It("should report internal IP", func() {
+                               expected := []string{internalIpControl}
+                               addresses, ok := FilterIPAddresses(nodesSingleWithIP)
+                               Expect(ok).To(BeTrue())
+                               Expect(addresses).To(Equal(expected))
+                       })
+               })
+               Context("With node in the cloud", func() {
+                       It("should report all IPs in correct order", func() {
+                               expected := []string{externalIpControl, internalIpControl}
+                               addresses, ok := FilterIPAddresses(nodesSingleWithBothIPs)
+                               Expect(ok).To(BeTrue())
+                               Expect(addresses).To(Equal(expected))
+                       })
+               })
+               Context("With nodes in the mixed cloud", func() {
+                       It("should report external IP as the first one", func() {
+                               addresses, ok := FilterIPAddresses(nodesManyWithMixedIPs)
+                               Expect(ok).To(BeTrue())
+                               Expect(addresses[0]).To(Equal(externalIpControl))
+                       })
+               })
+       })
 })