Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
310 changes: 276 additions & 34 deletions harvester_robot_tests/keywords/rancher.resource

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions harvester_robot_tests/keywords/variables.resource
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ ${INGRESS_CONTROLLER} %{INGRESS_CONTROLLER=traefik}
# Chart Repository for import clusters
${CHART_REPO_URL} %{CHART_REPO_URL=https://github.com/rancher/charts}
${CHART_REPO_BRANCH} %{CHART_REPO_BRANCH=release-v2.14}
${CSI_CHART_VERSION} %{CSI_CHART_VERSION=}
${CP_CHART_VERSION} %{CP_CHART_VERSION=}

# IP Pool for LoadBalancer tests
${IP_POOL_SUBNET} %{IP_POOL_SUBNET=192.168.1.0/24}
Expand Down
114 changes: 110 additions & 4 deletions harvester_robot_tests/libs/keywords/rancher_keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,41 @@ def wait_for_deployment_deleted(self, cluster_id, namespace, name, timeout=DEFAU
cluster_id, namespace, name, int(timeout)
)

def scale_deployment(self, cluster_id, namespace, name, replicas):
"""
Scale a deployment in a guest cluster to the given replica count

Args:
cluster_id: Cluster ID
namespace: Namespace
name: Deployment name
replicas: Desired replica count
"""
logging(f"Scaling deployment {name} to {replicas} replicas")
return self.rancher.scale_deployment(
cluster_id, namespace, name, int(replicas)
)

def wait_for_deployment_scaled(self, cluster_id, namespace, name,
replicas, timeout=DEFAULT_TIMEOUT):
"""
Wait for a deployment to reach the given ready replica count

Args:
cluster_id: Cluster ID
namespace: Namespace
name: Deployment name
replicas: Expected ready replica count
timeout: Timeout in seconds

Returns:
dict: Deployment data when scaled
"""
logging(f"Waiting for deployment {name} to scale to {replicas}")
return self.rancher.wait_for_deployment_scaled(
cluster_id, namespace, name, int(replicas), int(timeout)
)

# PVC Operations
def create_pvc(self, cluster_id, name, size="1Gi", storage_class=None):
"""
Expand Down Expand Up @@ -971,6 +1006,72 @@ def install_chart(self, cluster_id, repo_name, chart_name, version,
release_name, namespace, values
)

def upgrade_chart(self, cluster_id, repo_name, chart_name, version,
release_name, namespace, values=None):
"""
Upgrade an installed Helm chart on a guest cluster.

Args:
cluster_id: Rancher management cluster ID
repo_name: Chart repository name
chart_name: Chart name
version: Target chart version (empty string for latest)
release_name: Helm release name
namespace: Target namespace
values: Optional dict of chart values overrides
"""
if not version:
versions = self.rancher.get_chart_versions(
repo_name, chart_name, cluster_id
)
if not versions:
raise Exception(
f"No versions found for chart {chart_name} "
f"in {repo_name}"
)
version = versions[0]
logging(f"Using latest chart version: {version}")

logging(f"Upgrading chart {chart_name} to v{version} as "
f"{release_name} in {namespace}")
return self.rancher.upgrade_chart(
cluster_id, repo_name, chart_name, version,
release_name, namespace, values
)

def uninstall_chart(self, cluster_id, release_name, namespace):
"""
Uninstall a Helm chart (app) from a guest cluster.

Args:
cluster_id: Rancher management cluster ID
release_name: Helm release name
namespace: Namespace where the chart is installed
"""
logging(f"Uninstalling chart {release_name} from {namespace}")
return self.rancher.uninstall_chart(
cluster_id, release_name, namespace
)

def wait_for_chart_app_deleted(self, cluster_id, release_name, namespace,
timeout=DEFAULT_TIMEOUT):
"""
Wait for a chart app to be fully removed from a guest cluster.

Args:
cluster_id: Rancher management cluster ID
release_name: Helm release name
namespace: Namespace where the chart was installed
timeout: Timeout in seconds

Returns:
bool: True when deleted
"""
logging(f"Waiting for chart app {release_name} to be deleted")
return self.rancher.wait_for_chart_app_deleted(
cluster_id, release_name, namespace, int(timeout)
)

def get_chart_versions(self, repo_name, chart_name, cluster_id=None):
"""
Get available versions for a chart from a Rancher chart repository.
Expand Down Expand Up @@ -1020,18 +1121,21 @@ def create_cluster_repo(self, cluster_id, repo_name, git_url, git_branch):
)

def wait_for_cluster_repo_ready(self, cluster_id, repo_name,
timeout=DEFAULT_TIMEOUT):
timeout=DEFAULT_TIMEOUT,
expected_git_branch=None):
"""
Wait for a ClusterRepo to finish downloading on a guest cluster.

Args:
cluster_id: Rancher management cluster ID
repo_name: ClusterRepo name
timeout: Maximum wait time in seconds
expected_git_branch: When set, verify spec.gitBranch matches and
re-apply if Rancher has reconciled it back
"""
logging(f"Waiting for ClusterRepo {repo_name} to be ready")
return self.rancher.wait_for_cluster_repo_ready(
cluster_id, repo_name, timeout
cluster_id, repo_name, timeout, expected_git_branch
)

def create_cloud_config_secret(self, cluster_id, secret_name,
Expand Down Expand Up @@ -1066,7 +1170,8 @@ def write_cloud_config_to_nodes(self, cluster_id, secret_name, namespace):
)

def wait_for_chart_app_ready(self, cluster_id, release_name,
namespace, timeout=DEFAULT_TIMEOUT):
namespace, timeout=DEFAULT_TIMEOUT,
expected_version=None):
"""
Wait for a chart app to be deployed and ready.

Expand All @@ -1075,10 +1180,11 @@ def wait_for_chart_app_ready(self, cluster_id, release_name,
release_name: Helm release name
namespace: Namespace where chart was installed
timeout: Timeout in seconds
expected_version: If set, also wait for this exact chart version
"""
logging(f"Waiting for chart app {release_name} to be ready")
return self.rancher.wait_for_chart_app_ready(
cluster_id, release_name, namespace, int(timeout)
cluster_id, release_name, namespace, int(timeout), expected_version
)

# RWX Volume / StorageClass / StatefulSet Operations
Expand Down
33 changes: 31 additions & 2 deletions harvester_robot_tests/libs/rancher/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,17 @@ def wait_for_deployment_deleted(self, cluster_id, namespace, name, timeout):
"""Wait for deployment to be deleted"""
pass

@abstractmethod
def scale_deployment(self, cluster_id, namespace, name, replicas):
"""Scale a deployment in a guest cluster to the given replica count"""
pass

@abstractmethod
def wait_for_deployment_scaled(self, cluster_id, namespace, name,
replicas, timeout):
"""Wait for a deployment to reach the given ready replica count"""
pass

# PVC Operations
@abstractmethod
def create_pvc(self, cluster_id, name, size="1Gi", storage_class=None):
Expand Down Expand Up @@ -385,13 +396,31 @@ def install_chart(self, cluster_id, repo_name, chart_name, version,
"""Install a Helm chart on a guest cluster via Rancher catalog API."""
pass

@abstractmethod
def upgrade_chart(self, cluster_id, repo_name, chart_name, version,
release_name, namespace, values=None):
"""Upgrade an installed Helm chart on a guest cluster."""
pass

@abstractmethod
def uninstall_chart(self, cluster_id, release_name, namespace):
"""Uninstall a Helm chart (app) from a guest cluster."""
pass

@abstractmethod
def wait_for_chart_app_deleted(self, cluster_id, release_name,
namespace, timeout):
"""Wait for a chart app to be fully removed from a guest cluster."""
pass

@abstractmethod
def create_cluster_repo(self, cluster_id, repo_name, git_url, git_branch):
"""Create a ClusterRepo on a guest cluster."""
pass

@abstractmethod
def wait_for_cluster_repo_ready(self, cluster_id, repo_name, timeout):
def wait_for_cluster_repo_ready(self, cluster_id, repo_name, timeout,
expected_git_branch=None):
"""Wait for a ClusterRepo to finish downloading on a guest cluster."""
pass

Expand All @@ -418,7 +447,7 @@ def write_cloud_config_to_nodes(self, cluster_id, secret_name, namespace):

@abstractmethod
def wait_for_chart_app_ready(self, cluster_id, release_name,
namespace, timeout):
namespace, timeout, expected_version=None):
"""Wait for a chart app to be deployed and ready."""
pass

Expand Down
Loading
Loading