Merge "Add k8s ingress and metallb features"
diff --git a/tcp_tests/managers/k8smanager.py b/tcp_tests/managers/k8smanager.py
index d84451f..7ca518e 100644
--- a/tcp_tests/managers/k8smanager.py
+++ b/tcp_tests/managers/k8smanager.py
@@ -112,6 +112,41 @@
         names.sort()
         return names[0]
 
+    @property
+    def controller_minion_id(self):
+        """ Return node name of controller node that used for all actions """
+        minion_ids = [minion_id['minion_id'] for minion_id in
+                      self.get_controllers()]
+        # we want to return same controller name every time
+        minion_ids.sort()
+        return minion_ids[0]
+
+    @property
+    def is_metallb_enabled(self):
+        ctl_tgt = self.controller_minion_id
+        LOG.debug("Controller target: {}".format(ctl_tgt))
+
+        result = self._salt.get_pillar(
+            tgt=ctl_tgt,
+            pillar='kubernetes:common:addons:metallb:enabled')
+        metallb = result[0].get(ctl_tgt, False)
+        LOG.info("{} kubernetes:common:addons:metallb:enabled: {}"
+                 .format(ctl_tgt, bool(metallb)))
+        return metallb
+
+    @property
+    def is_ingress_nginx_enabled(self):
+        ctl_tgt = self.controller_minion_id
+        LOG.debug("Controller target: {}".format(ctl_tgt))
+
+        result = self._salt.get_pillar(
+            tgt=ctl_tgt,
+            pillar='kubernetes:common:addons:ingress-nginx:enabled')
+        ingress_nginx = result[0].get(ctl_tgt, False)
+        LOG.info("{} kubernetes:common:addons:ingress-nginx:enabled: {}"
+                 .format(ctl_tgt, bool(ingress_nginx)))
+        return ingress_nginx
+
     def controller_check_call(self, cmd, **kwargs):
         """ Run command on controller and return result """
         LOG.info("running cmd on k8s controller: {}".format(cmd))
diff --git a/tcp_tests/managers/sl_manager.py b/tcp_tests/managers/sl_manager.py
index 3bb0a1f..f3ccef8 100644
--- a/tcp_tests/managers/sl_manager.py
+++ b/tcp_tests/managers/sl_manager.py
@@ -41,7 +41,6 @@
     def install(self, commands, label='Install SL services'):
         self.execute_commands(commands, label=label)
         self.__config.stack_light.stacklight_installed = True
-        self.__config.stack_light.sl_vip_host = self.get_sl_vip()
 
     def get_sl_vip(self):
         tgt = 'I@prometheus:server:enabled:True'
@@ -76,6 +75,7 @@
     @property
     def api(self):
         if self._p_client is None:
+            self.__config.stack_light.sl_vip_host = self.get_sl_vip()
             self._p_client = prometheus_client.PrometheusClient(
                 host=self.__config.stack_light.sl_vip_host,
                 port=self.__config.stack_light.sl_prometheus_port,
diff --git a/tcp_tests/templates/cookied-bm-k8s-contrail/salt-context-cookiecutter-k8s-contrail.yaml b/tcp_tests/templates/cookied-bm-k8s-contrail/salt-context-cookiecutter-k8s-contrail.yaml
index 570000a..9e62bbf 100644
--- a/tcp_tests/templates/cookied-bm-k8s-contrail/salt-context-cookiecutter-k8s-contrail.yaml
+++ b/tcp_tests/templates/cookied-bm-k8s-contrail/salt-context-cookiecutter-k8s-contrail.yaml
@@ -111,6 +111,10 @@
   kubernetes_compute_single_address_ranges: 10.167.8.103-10.167.8.104
   kubernetes_compute_tenant_address_ranges: 10.167.8.103-10.167.8.104
   kubernetes_network_opencontrail_enabled: 'True'
+  kubernetes_metallb_enabled: 'False'  # Not used with opencontrail
+  metallb_addresses: 172.17.41.160-172.17.41.180
+  kubernetes_ingressnginx_enabled: 'True'
+  kubernetes_ingressnginx_controller_replicas: 2
   local_repositories: 'False'
   maas_deploy_address: 172.16.49.66
   maas_deploy_range_end: 10.0.0.254
diff --git a/tcp_tests/templates/cookied-cicd-k8s-calico-sl/cookiecutter-context-k8s-sl.yaml b/tcp_tests/templates/cookied-cicd-k8s-calico-sl/cookiecutter-context-k8s-sl.yaml
index e27cc19..061b4db 100644
--- a/tcp_tests/templates/cookied-cicd-k8s-calico-sl/cookiecutter-context-k8s-sl.yaml
+++ b/tcp_tests/templates/cookied-cicd-k8s-calico-sl/cookiecutter-context-k8s-sl.yaml
@@ -135,6 +135,10 @@
   kubernetes_proxy_address: 10.167.4.220
   kubernetes_proxy_node01_address: 10.167.4.221
   kubernetes_proxy_node02_address: 10.167.4.222
+  kubernetes_metallb_enabled: 'True'
+  metallb_addresses: 172.17.16.150-172.17.16.190
+  kubernetes_ingressnginx_enabled: 'True'
+  kubernetes_ingressnginx_controller_replicas: 2
   local_repositories: 'False'
   maas_deploy_address: 10.167.5.15
   maas_deploy_range_end: 10.167.5.199
diff --git a/tcp_tests/templates/cookied-cicd-k8s-calico-sl/environment-context-k8s-sl.yaml b/tcp_tests/templates/cookied-cicd-k8s-calico-sl/environment-context-k8s-sl.yaml
index 2d4689c..4abe271 100644
--- a/tcp_tests/templates/cookied-cicd-k8s-calico-sl/environment-context-k8s-sl.yaml
+++ b/tcp_tests/templates/cookied-cicd-k8s-calico-sl/environment-context-k8s-sl.yaml
@@ -9,6 +9,8 @@
           role: single_dhcp
         ens4:
           role: single_static_ctl
+        ens5:
+          role: single_storage_dhcp
 
     kvm01:
       reclass_storage_name: infra_kvm_node01
@@ -86,6 +88,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl_calico
+        ens5:
+          role: single_storage_dhcp
 
     ctl02:
       reclass_storage_name: kubernetes_control_node02
@@ -97,6 +101,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl_calico
+        ens5:
+          role: single_storage_dhcp
 
     ctl03:
       reclass_storage_name: kubernetes_control_node03
@@ -108,6 +114,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl_calico
+        ens5:
+          role: single_storage_dhcp
 
     prx01:
       reclass_storage_name: kubernetes_proxy_node01
@@ -119,6 +127,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl
+        ens5:
+          role: single_storage_dhcp
 
     prx02:
       reclass_storage_name: kubernetes_proxy_node02
@@ -130,6 +140,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl
+        ens5:
+          role: single_storage_dhcp
 
     # Generator-based computes. For compatibility only
     cmp<<count>>:
@@ -143,6 +155,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl_calico
+        ens5:
+          role: single_storage_dhcp
 
     mon01:
       reclass_storage_name: stacklight_server_node01
diff --git a/tcp_tests/templates/cookied-cicd-k8s-calico-sl/underlay.yaml b/tcp_tests/templates/cookied-cicd-k8s-calico-sl/underlay.yaml
index 6f69b81..132a382 100644
--- a/tcp_tests/templates/cookied-cicd-k8s-calico-sl/underlay.yaml
+++ b/tcp_tests/templates/cookied-cicd-k8s-calico-sl/underlay.yaml
@@ -135,6 +135,13 @@
             default_{{ HOSTNAME_CID01 }}: +91
             default_{{ HOSTNAME_CID02 }}: +92
             default_{{ HOSTNAME_CID03 }}: +93
+            default_{{ HOSTNAME_CTL01 }}: +11
+            default_{{ HOSTNAME_CTL02 }}: +12
+            default_{{ HOSTNAME_CTL03 }}: +13
+            default_{{ HOSTNAME_CMP01 }}: +101
+            default_{{ HOSTNAME_CMP02 }}: +102
+            default_{{ HOSTNAME_CMP03 }}: +103
+            default_{{ HOSTNAME_CMP04 }}: +104
             default_{{ HOSTNAME_PRX01 }}: +221
             default_{{ HOSTNAME_PRX02 }}: +222
 
@@ -176,7 +183,7 @@
 
           external:
             address_pool: external-pool01
-            dhcp: false
+            dhcp: true
             forward:
               mode: nat
 
@@ -212,20 +219,26 @@
                   bus: ide
                   # source_image: !os_env CFG01_CONFIG_PATH # no source image required.
                                                             # it will be uploaded after config drive generation
-              interfaces:
+              interfaces: &all_interfaces
                 - label: ens3
                   l2_network_device: admin
                   interface_model: *interface_model
                 - label: ens4
                   l2_network_device: private
                   interface_model: *interface_model
-              network_config:
+                - label: ens5
+                  l2_network_device: external
+                  interface_model: *interface_model
+              network_config: &all_network_config
                 ens3:
                   networks:
                     - admin
                 ens4:
                   networks:
                     - private
+                ens5:
+                  networks:
+                    - external
 
           - name: {{ HOSTNAME_KVM01 }}
             role: salt_minion
@@ -418,8 +431,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CTL02 }}
             role: salt_minion
@@ -444,8 +457,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CTL03 }}
             role: salt_minion
@@ -470,8 +483,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CMP01 }}
             role: salt_minion
@@ -496,8 +509,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CMP02 }}
             role: salt_minion
@@ -522,8 +535,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CMP03 }}
             role: salt_minion
@@ -548,8 +561,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CMP04 }}
             role: salt_minion
@@ -574,8 +587,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_MON01 }}
             role: salt_minion
@@ -834,8 +847,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604_swp
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_PRX02 }}
             role: salt_minion
@@ -860,5 +873,5 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604_swp
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
diff --git a/tcp_tests/templates/cookied-cicd-k8s-genie/cookiecutter-context-k8s-genie.yaml b/tcp_tests/templates/cookied-cicd-k8s-genie/cookiecutter-context-k8s-genie.yaml
index e163fec..7352614 100644
--- a/tcp_tests/templates/cookied-cicd-k8s-genie/cookiecutter-context-k8s-genie.yaml
+++ b/tcp_tests/templates/cookied-cicd-k8s-genie/cookiecutter-context-k8s-genie.yaml
@@ -134,6 +134,10 @@
   kubernetes_proxy_address: 10.167.4.220
   kubernetes_proxy_node01_address: 10.167.4.221
   kubernetes_proxy_node02_address: 10.167.4.222
+  kubernetes_metallb_enabled: 'True'
+  metallb_addresses: 172.17.16.150-172.17.16.190
+  kubernetes_ingressnginx_enabled: 'True'
+  kubernetes_ingressnginx_controller_replicas: 2
   local_repositories: 'False'
   maas_deploy_address: 10.167.5.15
   maas_deploy_range_end: 10.167.5.199
@@ -180,5 +184,3 @@
   kubernetes_network_genie_enabled: 'True'
   kubernetes_genie_default_plugin: 'calico'
   kubernetes_virtlet_enabled: 'True'
-  kubernetes_compute_node01_hostname: cmp001
-  kubernetes_compute_node02_hostname: cmp002
diff --git a/tcp_tests/templates/cookied-cicd-k8s-genie/environment-context-k8s-genie.yaml b/tcp_tests/templates/cookied-cicd-k8s-genie/environment-context-k8s-genie.yaml
index d13627b..807d07f 100644
--- a/tcp_tests/templates/cookied-cicd-k8s-genie/environment-context-k8s-genie.yaml
+++ b/tcp_tests/templates/cookied-cicd-k8s-genie/environment-context-k8s-genie.yaml
@@ -9,6 +9,8 @@
           role: single_dhcp
         ens4:
           role: single_static_ctl
+        ens5:
+          role: single_storage_dhcp
 
     kvm01:
       reclass_storage_name: infra_kvm_node01
@@ -86,6 +88,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl_calico
+        ens5:
+          role: single_storage_dhcp
 
     ctl02:
       reclass_storage_name: kubernetes_control_node02
@@ -97,6 +101,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl_calico
+        ens5:
+          role: single_storage_dhcp
 
     ctl03:
       reclass_storage_name: kubernetes_control_node03
@@ -108,6 +114,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl_calico
+        ens5:
+          role: single_storage_dhcp
 
     prx01:
       reclass_storage_name: kubernetes_proxy_node01
@@ -119,6 +127,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl
+        ens5:
+          role: single_storage_dhcp
 
     prx02:
       reclass_storage_name: kubernetes_proxy_node02
@@ -130,6 +140,8 @@
           role: single_dhcp
         ens4:
           role: single_ctl
+        ens5:
+          role: single_storage_dhcp
 
     # Generator-based computes. For compatibility only
     cmp<<count>>:
@@ -143,3 +155,5 @@
           role: single_dhcp
         ens4:
           role: single_ctl_calico
+        ens5:
+          role: single_storage_dhcp
diff --git a/tcp_tests/templates/cookied-cicd-k8s-genie/underlay.yaml b/tcp_tests/templates/cookied-cicd-k8s-genie/underlay.yaml
index 3211906..ee69506 100644
--- a/tcp_tests/templates/cookied-cicd-k8s-genie/underlay.yaml
+++ b/tcp_tests/templates/cookied-cicd-k8s-genie/underlay.yaml
@@ -114,6 +114,13 @@
             default_{{ HOSTNAME_CID01 }}: +91
             default_{{ HOSTNAME_CID02 }}: +92
             default_{{ HOSTNAME_CID03 }}: +93
+            default_{{ HOSTNAME_CTL01 }}: +11
+            default_{{ HOSTNAME_CTL02 }}: +12
+            default_{{ HOSTNAME_CTL03 }}: +13
+            default_{{ HOSTNAME_CMP01 }}: +101
+            default_{{ HOSTNAME_CMP02 }}: +102
+            default_{{ HOSTNAME_CMP03 }}: +103
+            default_{{ HOSTNAME_CMP04 }}: +104
             default_{{ HOSTNAME_PRX01 }}: +221
             default_{{ HOSTNAME_PRX02 }}: +222
 
@@ -155,7 +162,7 @@
 
           external:
             address_pool: external-pool01
-            dhcp: false
+            dhcp: true
             forward:
               mode: nat
 
@@ -191,20 +198,26 @@
                   bus: ide
                   # source_image: !os_env CFG01_CONFIG_PATH # no source image required.
                                                             # it will be uploaded after config drive generation
-              interfaces:
+              interfaces: &all_interfaces
                 - label: ens3
                   l2_network_device: admin
                   interface_model: *interface_model
                 - label: ens4
                   l2_network_device: private
                   interface_model: *interface_model
-              network_config:
+                - label: ens5
+                  l2_network_device: external
+                  interface_model: *interface_model
+              network_config: &all_network_config
                 ens3:
                   networks:
                     - admin
                 ens4:
                   networks:
                     - private
+                ens5:
+                  networks:
+                    - external
 
           - name: {{ HOSTNAME_KVM01 }}
             role: salt_minion
@@ -397,8 +410,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CTL02 }}
             role: salt_minion
@@ -423,8 +436,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CTL03 }}
             role: salt_minion
@@ -449,8 +462,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CMP01 }}
             role: salt_minion
@@ -475,8 +488,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CMP02 }}
             role: salt_minion
@@ -501,8 +514,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CMP03 }}
             role: salt_minion
@@ -527,8 +540,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_CMP04 }}
             role: salt_minion
@@ -553,8 +566,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_PRX01 }}
             role: salt_minion
@@ -579,8 +592,8 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604_swp
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
 
           - name: {{ HOSTNAME_PRX02 }}
             role: salt_minion
@@ -605,5 +618,5 @@
                   cloudinit_meta_data: *cloudinit_meta_data
                   cloudinit_user_data: *cloudinit_user_data_1604_swp
 
-              interfaces: *interfaces
-              network_config: *network_config
+              interfaces: *all_interfaces
+              network_config: *all_network_config
diff --git a/tcp_tests/tests/system/test_install_k8s.py b/tcp_tests/tests/system/test_install_k8s.py
index 8066cd9..ba5a81d 100644
--- a/tcp_tests/tests/system/test_install_k8s.py
+++ b/tcp_tests/tests/system/test_install_k8s.py
@@ -106,7 +106,11 @@
             # todo (tleontovich) add asserts here and extend the tests
             # with acceptance criteria
         show_step(10)
+
         # Run SL component tests
+        stacklight_deployed.setup_sl_functional_tests(
+                'cfg01',
+        )
         stacklight_deployed.run_sl_functional_tests(
             'cfg01',
             '/root/stacklight-pytest/stacklight_tests/',
@@ -163,6 +167,9 @@
         stacklight_deployed.check_prometheus_targets(mon_nodes)
         show_step(6)
         # Run SL component tests
+        stacklight_deployed.setup_sl_functional_tests(
+                'cfg01',
+        )
         stacklight_deployed.run_sl_functional_tests(
             'cfg01',
             '/root/stacklight-pytest/stacklight_tests/',
diff --git a/tcp_tests/tests/system/test_k8s_actions.py b/tcp_tests/tests/system/test_k8s_actions.py
index 066a476..6467a8a 100644
--- a/tcp_tests/tests/system/test_k8s_actions.py
+++ b/tcp_tests/tests/system/test_k8s_actions.py
@@ -144,6 +144,7 @@
 
     @pytest.mark.grab_versions
     @pytest.mark.fail_snapshot
+    @pytest.mark.k8s_metallb
     def test_k8s_metallb(self, show_step, config, k8s_deployed):
         """Enable metallb in cluster and do basic tests
 
@@ -158,7 +159,7 @@
             8. Delete deployments
         """
         show_step(1)
-        if not config.k8s_deploy.kubernetes_metallb_enabled:
+        if not k8s_deployed.is_metallb_enabled:
             pytest.skip("Test requires metallb addon enabled")
 
         show_step(2)
@@ -317,6 +318,7 @@
 
     @pytest.mark.grab_versions
     @pytest.mark.fail_snapshot
+    @pytest.mark.k8s_dashboard
     def test_k8s_dashboard(self, show_step, config,
                            salt_deployed, k8s_deployed):
         """Test dashboard setup
@@ -392,6 +394,7 @@
 
     @pytest.mark.grab_versions
     @pytest.mark.fail_snapshot
+    @pytest.mark.k8s_ingress_nginx
     def test_k8s_ingress_nginx(self, show_step, config,
                                salt_deployed, k8s_deployed):
         """Test ingress-nginx configured and working with metallb
@@ -406,9 +409,9 @@
             6. Try to reach test1 and test2 deployment services endpoints
         """
         show_step(1)
-        if not config.k8s_deploy.kubernetes_metallb_enabled:
+        if not k8s_deployed.is_metallb_enabled:
             pytest.skip("Test requires metallb addon enabled")
-        if not config.k8s_deploy.kubernetes_ingressnginx_enabled:
+        if not k8s_deployed.is_ingress_nginx_enabled:
             pytest.skip("Test requires ingress-nginx addon enabled")
 
         show_step(2)