add test_k8s_dashboard_access test steps part1
with the test setup done, this change adds the necessary code to create a k8s token which will be used to login via the k8s dashboard URL. Change-Id: I44b3690306f1522c4f2b94af83e2a816f22e9573 Signed-off-by: Gabriel Calixto <Gabriel.CalixtodePaula@windriver.com>
This commit is contained in:
@@ -4,23 +4,25 @@ from keywords.k8s.k8s_command_wrapper import export_k8s_config
|
|||||||
|
|
||||||
|
|
||||||
class KubectlFileApplyKeywords(BaseKeyword):
|
class KubectlFileApplyKeywords(BaseKeyword):
|
||||||
"""_summary_
|
"""
|
||||||
|
K8s file apply keywords
|
||||||
Args:
|
|
||||||
BaseKeyword (_type_): _description_
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, ssh_connection: SSHConnection):
|
def __init__(self, ssh_connection: SSHConnection):
|
||||||
|
"""
|
||||||
|
Initializes the class with an SSH connection.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ssh_connection (SSHConnection): An instance of SSHConnection to be used for SSH operations.
|
||||||
|
"""
|
||||||
self.ssh_connection = ssh_connection
|
self.ssh_connection = ssh_connection
|
||||||
|
|
||||||
def dashboard_apply_from_yaml(self, yaml_file: str):
|
def apply_resource_from_yaml(self, yaml_file: str):
|
||||||
"""
|
"""
|
||||||
Does a dashboard apply using the given yaml file
|
Applies a Kubernetes resource using the given YAML file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
yaml_file (): the yaml file to appy
|
yaml_file (str): The path to the YAML file containing the resource definition.
|
||||||
|
|
||||||
Returns:
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.ssh_connection.send(export_k8s_config(f"kubectl apply -f {yaml_file}"))
|
self.ssh_connection.send(export_k8s_config(f"kubectl apply -f {yaml_file}"))
|
||||||
self.validate_success_return_code(self.ssh_connection)
|
self.validate_success_return_code(self.ssh_connection)
|
||||||
|
@@ -0,0 +1,60 @@
|
|||||||
|
from framework.logging.automation_logger import get_logger
|
||||||
|
from framework.ssh.ssh_connection import SSHConnection
|
||||||
|
from keywords.base_keyword import BaseKeyword
|
||||||
|
from keywords.k8s.k8s_command_wrapper import export_k8s_config
|
||||||
|
|
||||||
|
|
||||||
|
class KubectlDeleteServiceAccountKeywords(BaseKeyword):
|
||||||
|
"""
|
||||||
|
Delete ServiceAccount keywords
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, ssh_connection: SSHConnection):
|
||||||
|
"""
|
||||||
|
Constructor for KubectlDeleteServiceAccountKeywords.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ssh_connection (SSHConnection): An SSH connection object used to execute commands on the Kubernetes cluster.
|
||||||
|
"""
|
||||||
|
self.ssh_connection = ssh_connection
|
||||||
|
|
||||||
|
def delete_serviceaccount(self, serviceaccount_name: str, nspace: str = None) -> str:
|
||||||
|
"""
|
||||||
|
Deletes the specified Kubernetes service account.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
serviceaccount_name (str): The name of the service account to delete.
|
||||||
|
nspace (str, optional): The namespace of the service account. Defaults to None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The output of the kubectl delete command.
|
||||||
|
"""
|
||||||
|
args = ""
|
||||||
|
if nspace:
|
||||||
|
args += f" -n {nspace} "
|
||||||
|
args += f"{serviceaccount_name}"
|
||||||
|
output = self.ssh_connection.send(export_k8s_config(f"kubectl delete serviceaccount {args}"))
|
||||||
|
self.validate_success_return_code(self.ssh_connection)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def cleanup_serviceaccount(self, serviceaccount_name: str, nspace: str = None) -> str:
|
||||||
|
"""
|
||||||
|
Deletes a Kubernetes ServiceAccount,method is used for cleanup purposes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
serviceaccount_name (str): The name of the ServiceAccount to delete.
|
||||||
|
nspace (str, optional): The namespace of the ServiceAccount. Defaults to None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The output of the command.
|
||||||
|
"""
|
||||||
|
args = ""
|
||||||
|
if nspace:
|
||||||
|
args += f" -n {nspace} "
|
||||||
|
args += f"{serviceaccount_name}"
|
||||||
|
self.ssh_connection.send(export_k8s_config(f"kubectl delete serviceaccount {args}"))
|
||||||
|
rc = self.ssh_connection.get_return_code()
|
||||||
|
if rc != 0:
|
||||||
|
get_logger().log_error(f"ServiceAccount {serviceaccount_name} failed to delete")
|
||||||
|
return rc
|
35
keywords/k8s/token/kubectl_create_token_keywords.py
Normal file
35
keywords/k8s/token/kubectl_create_token_keywords.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
from framework.ssh.ssh_connection import SSHConnection
|
||||||
|
from keywords.base_keyword import BaseKeyword
|
||||||
|
from keywords.k8s.k8s_command_wrapper import export_k8s_config
|
||||||
|
|
||||||
|
|
||||||
|
class KubectlCreateTokenKeywords(BaseKeyword):
|
||||||
|
"""
|
||||||
|
Keywords for creating a token with kubectl
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, ssh_connection: SSHConnection):
|
||||||
|
"""
|
||||||
|
Initializes the KubectlCreateTokenKeywords class with an SSH connection.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ssh_connection (SSHConnection): An object representing the SSH connection.
|
||||||
|
"""
|
||||||
|
self.ssh_connection = ssh_connection
|
||||||
|
|
||||||
|
def create_token(self, nspace: str, user: str) -> str:
|
||||||
|
"""
|
||||||
|
Creates a Kubernetes token for a specified user in a given namespace.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nspace (str): The Kubernetes namespace where the token will be created.
|
||||||
|
user (str): The user for whom the token will be created.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The output from the command execution.
|
||||||
|
|
||||||
|
"""
|
||||||
|
args = f"{user} -n {nspace}"
|
||||||
|
output = self.ssh_connection.send(export_k8s_config(f"kubectl create token {args}"))
|
||||||
|
self.validate_success_return_code(self.ssh_connection)
|
||||||
|
return output
|
@@ -20,6 +20,8 @@ from keywords.k8s.namespace.kubectl_get_namespaces_keywords import KubectlGetNam
|
|||||||
from keywords.k8s.patch.kubectl_apply_patch_keywords import KubectlApplyPatchKeywords
|
from keywords.k8s.patch.kubectl_apply_patch_keywords import KubectlApplyPatchKeywords
|
||||||
from keywords.k8s.secret.kubectl_create_secret_keywords import KubectlCreateSecretsKeywords
|
from keywords.k8s.secret.kubectl_create_secret_keywords import KubectlCreateSecretsKeywords
|
||||||
from keywords.k8s.secret.kubectl_delete_secret_keywords import KubectlDeleteSecretsKeywords
|
from keywords.k8s.secret.kubectl_delete_secret_keywords import KubectlDeleteSecretsKeywords
|
||||||
|
from keywords.k8s.serviceaccount.kubectl_delete_serviceaccount_keywords import KubectlDeleteServiceAccountKeywords
|
||||||
|
from keywords.k8s.token.kubectl_create_token_keywords import KubectlCreateTokenKeywords
|
||||||
from keywords.openssl.openssl_keywords import OpenSSLKeywords
|
from keywords.openssl.openssl_keywords import OpenSSLKeywords
|
||||||
|
|
||||||
|
|
||||||
@@ -38,11 +40,12 @@ def check_url_access(url: str) -> tuple:
|
|||||||
return req.response.status_code, req.response.text
|
return req.response.status_code, req.response.text
|
||||||
|
|
||||||
|
|
||||||
def copy_k8s_files(ssh_connection: SSHConnection):
|
def copy_k8s_files(request: fixture, ssh_connection: SSHConnection):
|
||||||
"""
|
"""
|
||||||
Copy the necessary k8s dashboard yaml files
|
Copy the necessary k8s dashboard yaml files
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
request (fixture): pytest fixture
|
||||||
ssh_connection (SSHConnection): ssh connection object
|
ssh_connection (SSHConnection): ssh connection object
|
||||||
"""
|
"""
|
||||||
k8s_dashboard_dir = "k8s_dashboard"
|
k8s_dashboard_dir = "k8s_dashboard"
|
||||||
@@ -53,6 +56,12 @@ def copy_k8s_files(ssh_connection: SSHConnection):
|
|||||||
local_path = get_stx_resource_path(f"resources/cloud_platform/containers/k8s_dashboard/{dashboard_file_name}")
|
local_path = get_stx_resource_path(f"resources/cloud_platform/containers/k8s_dashboard/{dashboard_file_name}")
|
||||||
FileKeywords(ssh_connection).upload_file(local_path, f"/home/sysadmin/{k8s_dashboard_dir}/{dashboard_file_name}")
|
FileKeywords(ssh_connection).upload_file(local_path, f"/home/sysadmin/{k8s_dashboard_dir}/{dashboard_file_name}")
|
||||||
|
|
||||||
|
def teardown():
|
||||||
|
get_logger().log_info("Deleting k8s_dashboard directory")
|
||||||
|
FileKeywords(ssh_connection).delete_folder_with_sudo(f"/home/sysadmin/{k8s_dashboard_dir}")
|
||||||
|
|
||||||
|
request.addfinalizer(teardown)
|
||||||
|
|
||||||
|
|
||||||
def create_k8s_dashboard(request: fixture, namespace: str, con_ssh: SSHConnection):
|
def create_k8s_dashboard(request: fixture, namespace: str, con_ssh: SSHConnection):
|
||||||
"""
|
"""
|
||||||
@@ -91,14 +100,12 @@ def create_k8s_dashboard(request: fixture, namespace: str, con_ssh: SSHConnectio
|
|||||||
KubectlCreateSecretsKeywords(ssh_connection=con_ssh).create_secret_generic(secret_name=secrets_name, tls_crt=crt, tls_key=key, namespace=namespace)
|
KubectlCreateSecretsKeywords(ssh_connection=con_ssh).create_secret_generic(secret_name=secrets_name, tls_crt=crt, tls_key=key, namespace=namespace)
|
||||||
|
|
||||||
get_logger().log_info(f"Creating resource from file {k8s_dashboard_file_path}")
|
get_logger().log_info(f"Creating resource from file {k8s_dashboard_file_path}")
|
||||||
KubectlFileApplyKeywords(ssh_connection=con_ssh).dashboard_apply_from_yaml(k8s_dashboard_file_path)
|
KubectlFileApplyKeywords(ssh_connection=con_ssh).apply_resource_from_yaml(k8s_dashboard_file_path)
|
||||||
|
|
||||||
def teardown():
|
def teardown():
|
||||||
KubectlFileDeleteKeywords(ssh_connection=con_ssh).delete_resources(k8s_dashboard_file_path)
|
KubectlFileDeleteKeywords(ssh_connection=con_ssh).delete_resources(k8s_dashboard_file_path)
|
||||||
# delete created dashboard secret
|
# delete created dashboard secret
|
||||||
KubectlDeleteSecretsKeywords(con_ssh).cleanup_secret(namespace=namespace, secret_name=secrets_name)
|
KubectlDeleteSecretsKeywords(con_ssh).cleanup_secret(namespace=namespace, secret_name=secrets_name)
|
||||||
get_logger().log_info("Deleting k8s_dashboard directory")
|
|
||||||
con_ssh.send(f"rm -rf {home_k8s}")
|
|
||||||
|
|
||||||
get_logger().log_info(f"Updating {name} service to be exposed on port {port}")
|
get_logger().log_info(f"Updating {name} service to be exposed on port {port}")
|
||||||
arg_port = '{"spec":{"type":"NodePort","ports":[{"port":443, "nodePort": ' + str(port) + "}]}}"
|
arg_port = '{"spec":{"type":"NodePort","ports":[{"port":443, "nodePort": ' + str(port) + "}]}}"
|
||||||
@@ -115,6 +122,44 @@ def create_k8s_dashboard(request: fixture, namespace: str, con_ssh: SSHConnectio
|
|||||||
raise KeywordException(detailed_message=f"Kubernetes dashboard returned status code {status_code}")
|
raise KeywordException(detailed_message=f"Kubernetes dashboard returned status code {status_code}")
|
||||||
|
|
||||||
|
|
||||||
|
def get_k8s_token(request: fixture, con_ssh: SSHConnection) -> str:
|
||||||
|
"""
|
||||||
|
Get token for login to dashboard.
|
||||||
|
|
||||||
|
For Kubernetes versions above 1.24.4, create an admin-user service-account
|
||||||
|
in the kube-system namespace and bind the cluster-admin ClusterRoleBinding
|
||||||
|
to this user. Then, create a token for this user in the kube-system namespace.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request (fixture): pytest fixture
|
||||||
|
con_ssh (SSHConnection): SSH connection object
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Token for login to the dashboard
|
||||||
|
"""
|
||||||
|
get_logger().log_info("Create the admin-user service-account in kube-system and bind the " "cluster-admin ClusterRoleBinding to this user")
|
||||||
|
adminuserfile = "admin-user.yaml"
|
||||||
|
serviceaccount = "admin-user"
|
||||||
|
home_k8s = "/home/sysadmin/k8s_dashboard"
|
||||||
|
|
||||||
|
admin_user_file_path = os.path.join(home_k8s, adminuserfile)
|
||||||
|
|
||||||
|
get_logger().log_info("Creating the admin-user service-account")
|
||||||
|
KubectlFileApplyKeywords(ssh_connection=con_ssh).apply_resource_from_yaml(admin_user_file_path)
|
||||||
|
|
||||||
|
get_logger().log_info("Creating the token for admin-user")
|
||||||
|
token = KubectlCreateTokenKeywords(ssh_connection=con_ssh).create_token(nspace="kube-system", user=serviceaccount)
|
||||||
|
|
||||||
|
def teardown():
|
||||||
|
get_logger().log_info(f"Removing serviceaccount {serviceaccount} in kube-system")
|
||||||
|
KubectlDeleteServiceAccountKeywords(ssh_connection=con_ssh).cleanup_serviceaccount(serviceaccount_name=serviceaccount, nspace="kube-system")
|
||||||
|
|
||||||
|
request.addfinalizer(teardown)
|
||||||
|
|
||||||
|
get_logger().log_info(f"Token for login to dashboard: {token}")
|
||||||
|
return token
|
||||||
|
|
||||||
|
|
||||||
@mark.p0
|
@mark.p0
|
||||||
def test_k8s_dashboard_access(request):
|
def test_k8s_dashboard_access(request):
|
||||||
"""
|
"""
|
||||||
@@ -139,7 +184,7 @@ def test_k8s_dashboard_access(request):
|
|||||||
# Defines dashboard file name, source (local) and destination (remote) file paths.
|
# Defines dashboard file name, source (local) and destination (remote) file paths.
|
||||||
# Opens an SSH session to active controller.
|
# Opens an SSH session to active controller.
|
||||||
ssh_connection = LabConnectionKeywords().get_active_controller_ssh()
|
ssh_connection = LabConnectionKeywords().get_active_controller_ssh()
|
||||||
copy_k8s_files(ssh_connection)
|
copy_k8s_files(request, ssh_connection)
|
||||||
# Create Dashboard namespace
|
# Create Dashboard namespace
|
||||||
namespace_name = "kubernetes-dashboard"
|
namespace_name = "kubernetes-dashboard"
|
||||||
kubectl_create_ns_keyword = KubectlCreateNamespacesKeywords(ssh_connection)
|
kubectl_create_ns_keyword = KubectlCreateNamespacesKeywords(ssh_connection)
|
||||||
@@ -159,3 +204,6 @@ def test_k8s_dashboard_access(request):
|
|||||||
# Step 2: Create the necessary k8s dashboard resources
|
# Step 2: Create the necessary k8s dashboard resources
|
||||||
test_namespace = "kubernetes-dashboard"
|
test_namespace = "kubernetes-dashboard"
|
||||||
create_k8s_dashboard(request, namespace=test_namespace, con_ssh=ssh_connection)
|
create_k8s_dashboard(request, namespace=test_namespace, con_ssh=ssh_connection)
|
||||||
|
|
||||||
|
# Step 3: Create the token for the dashboard
|
||||||
|
get_k8s_token(request=request, con_ssh=ssh_connection)
|
||||||
|
Reference in New Issue
Block a user