Add test_k8s_dashboard test

Add 'cluster role binding' api wrapper
Add method in TestMCPK8sActions to read testdata yamls

Change-Id: I7b9f7a74ce74ea5e722cb4c958bd60b6a64b6a0c
Related-PROD: PROD-22249
diff --git a/tcp_tests/tests/system/test_k8s_actions.py b/tcp_tests/tests/system/test_k8s_actions.py
index 6510a67..364361c 100644
--- a/tcp_tests/tests/system/test_k8s_actions.py
+++ b/tcp_tests/tests/system/test_k8s_actions.py
@@ -15,6 +15,7 @@
 import pytest
 import netaddr
 import os
+import json
 
 from tcp_tests import logger
 from tcp_tests import settings
@@ -27,6 +28,10 @@
 class TestMCPK8sActions(object):
     """Test class for different k8s actions"""
 
+    def __read_testdata_yaml(self, name):
+        dir = os.path.join(os.path.dirname(__file__), 'testdata/k8s')
+        return read_yaml_file(dir, name)
+
     @pytest.mark.grab_versions
     @pytest.mark.fail_snapshot
     @pytest.mark.cz8116
@@ -235,9 +240,8 @@
             namespace="kube-system", name_prefix="kube-flannel-") > 0
 
         show_step(3)
-        data_dir = os.path.join(os.path.dirname(__file__), 'testdata/k8s')
         flannel_pod = k8s_deployed.api.pods.create(
-            body=read_yaml_file(data_dir, 'pod-sample-flannel.yaml'))
+            body=self.__read_testdata_yaml('pod-sample-flannel.yaml'))
         flannel_pod.wait_running()
 
         show_step(4)
@@ -247,7 +251,7 @@
 
         show_step(5)
         calico_pod = k8s_deployed.api.pods.create(
-            body=read_yaml_file(data_dir, 'pod-sample-calico.yaml'))
+            body=self.__read_testdata_yaml('pod-sample-calico.yaml'))
         calico_pod.wait_running()
 
         show_step(6)
@@ -257,7 +261,7 @@
 
         show_step(7)
         multicni_pod = k8s_deployed.api.pods.create(
-            body=read_yaml_file(data_dir, 'pod-sample-multicni.yaml'))
+            body=self.__read_testdata_yaml('pod-sample-multicni.yaml'))
         multicni_pod.wait_running()
 
         show_step(8)
@@ -270,7 +274,7 @@
 
         show_step(9)
         nocni_pod = k8s_deployed.api.pods.create(
-            body=read_yaml_file(data_dir, 'pod-sample.yaml'))
+            body=self.__read_testdata_yaml('pod-sample.yaml'))
         nocni_pod.wait_running()
 
         show_step(10)
@@ -305,3 +309,78 @@
         calico_pod.delete()
         multicni_pod.delete()
         nocni_pod.delete()
+
+    @pytest.mark.grap_versions
+    @pytest.mark.fail_snapshot
+    def test_k8s_dashboard(self, show_step, config,
+                           salt_deployed, k8s_deployed):
+        """Test dashboard setup
+
+        Scenario:
+            1. Setup Kubernetes cluster
+            2. Try to curl login status api
+            3. Create a test-admin-user account
+            4. Try to login in dashboard using test-admin-user account
+            5. Get and check list of namespaces using dashboard api
+        """
+        show_step(1)
+
+        show_step(2)
+        system_ns = 'kube-system'
+        dashboard_service = \
+            k8s_deployed.api.services.get('kubernetes-dashboard', system_ns)
+        dashboard_url = 'https://{}'.format(dashboard_service.get_ip())
+
+        def dashboard_curl(url, data=None, headers=None):
+            """ Using curl command on controller node. Alternatives:
+                - connect_{get,post}_namespaced_service_proxy_with_path -
+                    k8s lib does not provide way to pass headers or POST data
+                - raw rest k8s api - need to auth somehow
+                - new load-balancer svc for dashboard + requests python lib -
+                    requires working metallb or other load-balancer
+            """
+            args = ['--insecure']
+            for name in headers or {}:
+                args.append('--header')
+                args.append("{0}: {1}".format(name, headers[name]))
+            if data is not None:
+                args.append('--data')
+                args.append(data)
+            return ''.join(k8s_deployed.curl(dashboard_url + url, *args))
+
+        assert 'tokenPresent' in \
+            json.loads(dashboard_curl('/api/v1/login/status'))
+
+        show_step(3)
+        account = k8s_deployed.api.serviceaccounts.create(
+            namespace=system_ns,
+            body=self.__read_testdata_yaml('test-admin-user-account.yaml'))
+        account.wait_secret_generation()
+
+        k8s_deployed.api.clusterrolebindings.create(
+            body=self.__read_testdata_yaml(
+                'test-admin-user-cluster-role-bind.yaml'))
+
+        account_secret = account.read().secrets[0]
+        account_token = k8s_deployed.api.secrets.get(
+            namespace=system_ns, name=account_secret.name).read().data['token']
+
+        show_step(4)
+        csrf_token = \
+            json.loads(dashboard_curl('/api/v1/csrftoken/login'))['token']
+        login_headers = {'X-CSRF-TOKEN': csrf_token,
+                         'Content-Type': 'application/json'}
+        jwe_token = json.loads(dashboard_curl(
+            '/api/v1/login', headers=login_headers,
+            data=json.dumps({'token': account_token.decode('base64')})
+        ))['jweToken']
+        headers = {'jweToken': jwe_token}
+
+        show_step(5)
+        dashboard_namespaces = json.loads(
+            dashboard_curl('/api/v1/namespace', headers=headers))['namespaces']
+
+        namespaces_names_list = \
+            [ns.name for ns in k8s_deployed.api.namespaces.list()]
+        for namespace in dashboard_namespaces:
+            assert namespace['objectMeta']['name'] in namespaces_names_list