Skip to content

Commit d4df8fa

Browse files
committed
Add azure as platform and hypershift as subplatform
1 parent 5e022a8 commit d4df8fa

File tree

12 files changed

+663
-14
lines changed

12 files changed

+663
-14
lines changed

hcp-burner.ini

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ batch_size = 1
1010
watcher_delay = 60
1111

1212
enable_workload = False
13+
workload_script = run.sh
1314
workload = cluster-density-ms
14-
workload_repo = "https://github.com/cloud-bulldozer/e2e-benchmarking.git"
15-
workload_script_path = "workloads/kube-burner-ocp-wrapper"
15+
workload_repo = https://github.com/cloud-bulldozer/e2e-benchmarking.git
16+
workload_script_path = workloads/kube-burner-ocp-wrapper
17+
18+
1619
worload_duration = 1h
1720
workload_jobs = 9
1821

@@ -52,3 +55,7 @@ terraform_retry = 5
5255
create_vpcs = True
5356
clusters_per_vpc = 2
5457
terraform_retry = 5
58+
59+
[Platform:Azure]
60+
61+
[Platform:Azure:Hypershiftci]

libs/arguments.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def __init__(self, environment):
2525

2626
self.common_parser.add_argument("--install-clusters", action="store_true", help="Start bringing up clusters")
2727

28-
self.common_parser.add_argument("--platform", action=EnvDefault, env=environment, envvar="HCP_BURNER_PLATFORM", required=True, choices=["rosa"])
28+
self.common_parser.add_argument("--platform", action=EnvDefault, env=environment, envvar="HCP_BURNER_PLATFORM", required=True, choices=["rosa", "azure"])
2929
self.common_parser.add_argument("--subplatform", dest="subplatform", action=EnvDefault, env=environment, envvar="HCP_BURNER_SUBPLATFORM", help="Subplatforms of Platform")
3030

3131
self.common_parser.add_argument("--uuid", action=EnvDefault, env=environment, envvar="HCP_BURNER_UUID")
@@ -53,7 +53,8 @@ def __init__(self, environment):
5353
self.common_parser.add_argument("--enable-workload", action="store_true", help="Execute workload after clusters are installed")
5454
self.common_parser.add_argument("--workload-repo", action=EnvDefault, env=environment, envvar="HCP_BURNER_WORKLOAD_REPO", default="https://github.com/cloud-bulldozer/e2e-benchmarking.git", type=str, help="Git Repo of the workload")
5555
self.common_parser.add_argument("--workload", action=EnvDefault, env=environment, envvar="HCP_BURNER_WORKLOAD", help="Workload to execute after clusters are installed", default="cluster-density-ms")
56-
self.common_parser.add_argument("--workload-script-path", action=EnvDefault, env=environment, envvar="HCP_BURNER_WORKLOAD_SCRIPT_PATH", help="Workload to execute after clusters are installed", default="workloads/kube-burner-ocp-wrapper")
56+
self.common_parser.add_argument("--workload-script", action=EnvDefault, env=environment, envvar="HCP_BURNER_WORKLOAD_SCRIPT", help="Workload script to execute after clusters are installed", default="run.sh")
57+
self.common_parser.add_argument("--workload-script-path", action=EnvDefault, env=environment, envvar="HCP_BURNER_WORKLOAD_SCRIPT_PATH", help="Path to workload script", default="workloads/kube-burner-ocp-wrapper")
5758
self.common_parser.add_argument("--workload-executor", action=EnvDefault, env=environment, envvar="HCP_BURNER_WORKLOAD_EXECUTOR", help="Complete path of binary used to execute the workload", default="/usr/bin/kube-burner")
5859
self.common_parser.add_argument("--workload-duration", action=EnvDefault, env=environment, envvar="HCP_BURNER_WORKLOAD_DURATION", default="1h", type=str, help="Workload execution duration in minutes")
5960
self.common_parser.add_argument("--workload-jobs", action=EnvDefault, env=environment, envvar="HCP_BURNER_WORKLOAD_JOBS", type=int, default=10, help="Jobs per worker.Workload will scale this number to the number of workers of the cluster")

libs/platforms/azure/__init__.py

Whitespace-only changes.

libs/platforms/azure/azure.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
import sys
4+
import json
5+
import configparser
6+
import argparse
7+
from libs.platforms.platform import Platform
8+
from libs.platforms.platform import PlatformArguments
9+
10+
11+
class Azure(Platform):
12+
def __init__(self, arguments, logging, utils, es):
13+
super().__init__(arguments, logging, utils, es)
14+
15+
self.environment["commands"].append("az")
16+
self.environment["azure_region"] = arguments["azure_region"]
17+
self.environment["azure_credentials_file"] = arguments["azure_credentials_file"]
18+
self.environment['azure_mc_cluster_subscription'] = arguments['azure_mc_subscription']
19+
20+
def initialize(self):
21+
super().initialize()
22+
# Verify Azure credentials file
23+
self.logging.info(f"Verifying Azure Credentials File {self.environment['azure_credentials_file']}...")
24+
with open(self.environment["azure_credentials_file"], 'r') as azure_credentials_file:
25+
content = azure_credentials_file.read()
26+
for key in ["tenantId", "subscriptionId", "ClientId", "ClientSecret"]:
27+
if key not in content:
28+
self.logging.error(f"Missing {key} on Azure credentials file {self.environment['azure_credentials_file']}")
29+
sys.exit("Exiting...")
30+
self.logging.info(f"Azure Credentials File {self.environment['azure_credentials_file']} verified")
31+
with open(self.environment["azure_credentials_file"], 'r') as azure_credentials_file:
32+
for line in azure_credentials_file:
33+
if line.startswith('subscriptionId:'):
34+
self.environment['subscription_id'] = line.split(':', 1)[1].strip().strip('"')
35+
# Verify Azure Login and subscription
36+
self.logging.info("Getting azure subscriptions using `az account list`")
37+
az_account_code, az_account_out, az_account_err = self.utils.subprocess_exec("az account list")
38+
sys.exit("Exiting...") if az_account_code != 0 else self.logging.info("`az account list` execution OK")
39+
40+
for subscription in json.loads(az_account_out):
41+
if subscription["id"] == self.environment["subscription_id"]:
42+
az_account_set_code, az_account_set_out, az_account_set_err = self.utils.subprocess_exec("az account set --subscription " + subscription["id"])
43+
if az_account_set_code != 0:
44+
self.logging.error(f"Failed to set {subscription['id']} for user {subscription['user']['name']}")
45+
self.logging.error(az_account_set_out)
46+
self.logging.error(az_account_set_err)
47+
self.logging.debug(subscription)
48+
else:
49+
self.logging.info(F"Set subscription ID {subscription['id']} to user {subscription['user']['name']} OK")
50+
return 0
51+
self.logging.error(f"Subscription ID {self.environment['subscription_id']} not found")
52+
self.logging.debug(json.loads(az_account_out))
53+
sys.exit("Exiting...")
54+
55+
def get_az_aks_cluster_info(self, cluster_name):
56+
if not self.environment['azure_mc_cluster_subscription']:
57+
self.logging.warning(f"MC Cluster subscription is not provided, using subscription from {self.environment['azure_credentials_file']}")
58+
subscription = self.environment['subscription_id']
59+
else:
60+
subscription = self.environment['azure_mc_cluster_subscription']
61+
self.logging.info(f"Finding resource group of AKS cluster {cluster_name}...")
62+
query = f"[?name=='{cluster_name}'].{{resourceGroup:resourceGroup}}"
63+
command = ["az", "aks", "list", "--subscription", subscription, "--query", query, "--output", "tsv"]
64+
rg_code, rg_out, rg_err = self.utils.subprocess_exec(" ".join(str(x) for x in command), extra_params={"universal_newlines": True})
65+
if rg_out:
66+
self.logging.info(f"Found resource group {rg_out} associated to {cluster_name}")
67+
resourcegroup = rg_out
68+
else:
69+
self.logging.error(f"Failed to obtain resource group associated to {cluster_name}")
70+
self.logging.error(rg_out)
71+
self.logging.error(rg_err)
72+
return {}
73+
self.logging.info(f"Get Cluster metadata of {cluster_name}")
74+
resp_code, resp_out, resp_err = self.utils.subprocess_exec("az aks show --subscription " + subscription + " --resource-group " + resourcegroup + " --name " + cluster_name + " --output json", extra_params={"universal_newlines": True})
75+
try:
76+
cluster = json.loads(resp_out)
77+
except Exception as err:
78+
self.logging.error(f"Cannot load metadata for cluster {cluster_name}")
79+
self.logging.error(err)
80+
metadata = {}
81+
metadata['cluster_name'] = cluster.get("name", None)
82+
metadata['infra_id'] = cluster.get("fqdn", None)
83+
metadata['cluster_id'] = cluster.get("id", None)
84+
metadata['version'] = cluster.get("currentKubernetesVersion", None)
85+
metadata['base_domain'] = cluster.get("dnsPrefix", None)
86+
metadata['location'] = cluster.get("location", None)
87+
metadata['network_type'] = cluster.get("networkProfile", {}).get("networkDataplane", None)
88+
for profile in cluster.get("agentPoolProfiles", []):
89+
if profile.get("name", None) == "userpool":
90+
metadata['workers'] = profile.get("count", None)
91+
metadata['workers_min'] = profile.get("minCount", None)
92+
metadata['workers_max'] = profile.get("maxCount", None)
93+
metadata['workers_type'] = profile.get("vmSize", None)
94+
return metadata
95+
96+
def platform_cleanup(self):
97+
super().platform_cleanup()
98+
99+
def create_cluster(self, platform, cluster_name):
100+
super().create_cluster(platform, cluster_name)
101+
102+
def delete_cluster(self, platform, cluster_name):
103+
super().delete_cluster(platform, cluster_name)
104+
105+
def get_workers_ready(self, kubeconfig, cluster_name):
106+
super().get_workers_ready(kubeconfig, cluster_name)
107+
return Platform.get_workers_ready(self, kubeconfig, cluster_name)
108+
109+
def watcher(self):
110+
super().watcher()
111+
112+
113+
class AzureArguments(PlatformArguments):
114+
def __init__(self, parser, config_file, environment):
115+
super().__init__(parser, config_file, environment)
116+
EnvDefault = self.EnvDefault
117+
118+
parser.add_argument("--azure-credentials-file", action=EnvDefault, env=environment, envvar="HCP_BURNER_AZURE_CREDENTIALS_FILE", help="Azure credentials file")
119+
parser.add_argument("--azure-region", action=EnvDefault, env=environment, envvar="HCP_BURNER_AZURE_REGION", default='eastus', help="Azure Region")
120+
parser.add_argument("--azure-mc-subscription", action=EnvDefault, env=environment, envvar="HCP_BURNER_MC_SUBSCRIPTION", help="Azure Subscription where MC Cluster is installed")
121+
122+
if config_file:
123+
config = configparser.ConfigParser()
124+
config.read(config_file)
125+
defaults = {}
126+
defaults.update(dict(config.items("Platform:Azure")))
127+
parser.set_defaults(**defaults)
128+
129+
temp_args, temp_unknown_args = parser.parse_known_args()
130+
if not temp_args.azure_credentials_file:
131+
parser.error("hcp-burner.py: error: the following arguments (or equivalent definition) are required: --azure-credentials-file")
132+
133+
class EnvDefault(argparse.Action):
134+
def __init__(self, env, envvar, default=None, **kwargs):
135+
default = env[envvar] if envvar in env else default
136+
super(AzureArguments.EnvDefault, self).__init__(
137+
default=default, **kwargs
138+
)
139+
140+
def __call__(self, parser, namespace, values, option_string=None):
141+
setattr(namespace, self.dest, values)

libs/platforms/azure/hypershiftcli/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)