|
3 | 3 | import os |
4 | 4 | import re |
5 | 5 | import shlex |
| 6 | +import stat |
| 7 | +import tarfile |
6 | 8 | import tempfile |
| 9 | +import zipfile |
7 | 10 | from contextlib import contextmanager |
8 | 11 | from functools import cache |
9 | 12 | from typing import Any, Generator, Optional, Set, Callable |
10 | 13 | from json import JSONDecodeError |
11 | 14 |
|
12 | 15 | import kubernetes |
| 16 | +import platform |
13 | 17 | import pytest |
| 18 | +import requests |
| 19 | +from _pytest._py.path import LocalPath |
14 | 20 | from _pytest.fixtures import FixtureRequest |
15 | 21 | from kubernetes.dynamic import DynamicClient |
16 | 22 | from kubernetes.dynamic.exceptions import ( |
|
20 | 26 | from ocp_resources.catalog_source import CatalogSource |
21 | 27 | from ocp_resources.cluster_service_version import ClusterServiceVersion |
22 | 28 | from ocp_resources.config_map import ConfigMap |
| 29 | +from ocp_resources.console_cli_download import ConsoleCLIDownload |
23 | 30 | from ocp_resources.data_science_cluster import DataScienceCluster |
24 | 31 | from ocp_resources.deployment import Deployment |
25 | 32 | from ocp_resources.dsc_initialization import DSCInitialization |
@@ -1140,3 +1147,88 @@ def switch_user_context(context_name: str) -> Generator[None, None, None]: |
1140 | 1147 | # Restore original context |
1141 | 1148 | run_command(command=["oc", "config", "use-context", current_context], check=True) |
1142 | 1149 | LOGGER.info(f"Restored context: {current_context}") |
| 1150 | + |
| 1151 | + |
| 1152 | +def get_machine_platform() -> str: |
| 1153 | + os_machine_type = platform.machine() |
| 1154 | + return "amd64" if os_machine_type == "x86_64" else os_machine_type |
| 1155 | + |
| 1156 | + |
| 1157 | +def get_os_system() -> str: |
| 1158 | + os_system = platform.system().lower() |
| 1159 | + if os_system == "darwin" and platform.mac_ver()[0]: |
| 1160 | + os_system = "mac" |
| 1161 | + return os_system |
| 1162 | + |
| 1163 | + |
| 1164 | +def get_oc_console_cli_download_link() -> str: |
| 1165 | + oc_console_cli_download = ConsoleCLIDownload(name="oc-cli-downloads", ensure_exists=True) |
| 1166 | + os_system = get_os_system() |
| 1167 | + machine_platform = get_machine_platform() |
| 1168 | + oc_links = oc_console_cli_download.instance.spec.links |
| 1169 | + all_links = [ |
| 1170 | + link_ref.href |
| 1171 | + for link_ref in oc_links |
| 1172 | + if link_ref.href.endswith(("oc.tar", "oc.zip")) |
| 1173 | + and os_system in link_ref.href |
| 1174 | + and machine_platform in link_ref.href |
| 1175 | + ] |
| 1176 | + LOGGER.info(f"All oc console cli download links: {all_links}") |
| 1177 | + if not all_links: |
| 1178 | + raise ValueError(f"No oc console cli download link found for {os_system} {machine_platform} in {oc_links}") |
| 1179 | + |
| 1180 | + return all_links[0] |
| 1181 | + |
| 1182 | + |
| 1183 | +def get_server_cert(tmpdir: LocalPath) -> str: |
| 1184 | + data = ConfigMap(name="kube-root-ca.crt", namespace="openshift-apiserver", ensure_exists=True).instance.data[ |
| 1185 | + "ca.crt" |
| 1186 | + ] |
| 1187 | + file_path = os.path.join(tmpdir, "cluster-ca.cert") |
| 1188 | + with open(file_path, "w") as fd: |
| 1189 | + fd.write(data) |
| 1190 | + return file_path |
| 1191 | + |
| 1192 | + |
| 1193 | +def download_oc_console_cli(tmpdir: LocalPath) -> str: |
| 1194 | + """ |
| 1195 | + Download and extract the OpenShift CLI binary. |
| 1196 | +
|
| 1197 | + Args: |
| 1198 | + tmpdir (str): Directory to download and extract the binary to |
| 1199 | +
|
| 1200 | + Returns: |
| 1201 | + str: Path to the extracted binary |
| 1202 | +
|
| 1203 | + Raises: |
| 1204 | + ValueError: If multiple files are found in the archive or if no download link is found |
| 1205 | + """ |
| 1206 | + oc_console_cli_download_link = get_oc_console_cli_download_link() |
| 1207 | + LOGGER.info(f"Downloading archive using: url={oc_console_cli_download_link}") |
| 1208 | + cert_file = get_server_cert(tmpdir=tmpdir) |
| 1209 | + local_file_name = os.path.join(tmpdir, oc_console_cli_download_link.split("/")[-1]) |
| 1210 | + with requests.get(oc_console_cli_download_link, verify=cert_file, stream=True) as created_request: |
| 1211 | + created_request.raise_for_status() |
| 1212 | + with open(local_file_name, "wb") as file_downloaded: |
| 1213 | + for chunk in created_request.iter_content(chunk_size=8192): |
| 1214 | + file_downloaded.write(chunk) |
| 1215 | + LOGGER.info("Extract the downloaded archive.") |
| 1216 | + extracted_filenames = [] |
| 1217 | + if oc_console_cli_download_link.endswith(".zip"): |
| 1218 | + zip_file = zipfile.ZipFile(file=local_file_name) |
| 1219 | + zip_file.extractall(path=tmpdir) |
| 1220 | + extracted_filenames = zip_file.namelist() |
| 1221 | + else: |
| 1222 | + with tarfile.open(name=local_file_name, mode="r") as tar_file: |
| 1223 | + tar_file.extractall(path=tmpdir) |
| 1224 | + extracted_filenames = tar_file.getnames() |
| 1225 | + LOGGER.info(f"Downloaded file: {extracted_filenames}") |
| 1226 | + |
| 1227 | + if len(extracted_filenames) > 1: |
| 1228 | + raise ValueError(f"Multiple files found in {extracted_filenames}") |
| 1229 | + # Remove the downloaded file |
| 1230 | + if os.path.isfile(local_file_name): |
| 1231 | + os.remove(local_file_name) |
| 1232 | + binary_path = os.path.join(tmpdir, extracted_filenames[0]) |
| 1233 | + os.chmod(binary_path, stat.S_IRUSR | stat.S_IXUSR) |
| 1234 | + return binary_path |
0 commit comments