Skip to content

Commit a7b0020

Browse files
committed
feature(argus): call client with extra headers
since argus serivce will need more headers for it's to be operational, we'll need to change the calls to it, to pass the needed headers. (cherry picked from commit 6e4e1fb)
1 parent fe35ae5 commit a7b0020

File tree

10 files changed

+130
-41
lines changed

10 files changed

+130
-41
lines changed

argus/client/base.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,20 @@ class Routes():
3434
FETCH_RESULTS = "/testrun/$type/$id/fetch_results"
3535
FINALIZE = "/testrun/$type/$id/finalize"
3636

37-
def __init__(self, auth_token: str, base_url: str, api_version="v1") -> None:
37+
def __init__(self, auth_token: str, base_url: str, api_version="v1", extra_headers: dict | None = None) -> None:
3838
self._auth_token = auth_token
3939
self._base_url = base_url
4040
self._api_ver = api_version
41+
self._extra_headers = extra_headers or {}
4142

4243
@property
4344
def auth_token(self) -> str:
4445
return self._auth_token
4546

47+
@property
48+
def extra_headers(self) -> dict:
49+
return self._extra_headers
50+
4651
def verify_location_params(self, endpoint: str, location_params: dict[str, str]) -> bool:
4752
required_params: list[str] = re.findall(r"\$[\w_]+", endpoint)
4853
for param in required_params:
@@ -88,6 +93,7 @@ def request_headers(self):
8893
"Authorization": f"token {self.auth_token}",
8994
"Accept": "application/json",
9095
"Content-Type": "application/json",
96+
**self.extra_headers,
9197
}
9298

9399
def get(self, endpoint: str, location_params: dict[str, str] = None, params: dict = None) -> requests.Response:

argus/client/driver_matrix_tests/cli.py

+30-23
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from argus.common.enums import TestStatus
77

88
from argus.client.driver_matrix_tests.client import ArgusDriverMatrixClient
9+
from argus.client.generic.cli import validate_extra_headers
910

1011
LOGGER = logging.getLogger(__name__)
1112

@@ -15,86 +16,92 @@ def cli():
1516
pass
1617

1718

18-
def _submit_driver_result_internal(api_key: str, base_url: str, run_id: str, metadata_path: str):
19+
def _submit_driver_result_internal(api_key: str, base_url: str, run_id: str, metadata_path: str, extra_headers: dict):
1920
metadata = json.loads(Path(metadata_path).read_text(encoding="utf-8"))
2021
LOGGER.info("Submitting results for %s [%s/%s] to Argus...", run_id, metadata["driver_name"], metadata["driver_type"])
2122
raw_xml = (Path(metadata_path).parent / metadata["junit_result"]).read_bytes()
22-
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
23+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url, extra_headers=extra_headers)
2324
client.submit_driver_result(driver_name=metadata["driver_name"], driver_type=metadata["driver_type"], raw_junit_data=base64.encodebytes(raw_xml))
2425
LOGGER.info("Done.")
2526

26-
def _submit_driver_failure_internal(api_key: str, base_url: str, run_id: str, metadata_path: str):
27+
def _submit_driver_failure_internal(api_key: str, base_url: str, run_id: str, metadata_path: str, extra_headers: dict):
2728
metadata = json.loads(Path(metadata_path).read_text(encoding="utf-8"))
2829
LOGGER.info("Submitting failure for %s [%s/%s] to Argus...", run_id, metadata["driver_name"], metadata["driver_type"])
29-
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
30+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url, extra_headers=extra_headers)
3031
client.submit_driver_failure(driver_name=metadata["driver_name"], driver_type=metadata["driver_type"], failure_reason=metadata["failure_reason"])
3132
LOGGER.info("Done.")
3233

3334

3435
@click.command("submit-run")
35-
@click.option("--api-key", help="Argus API key for authorization", required=True)
36+
@click.option("--api-key", help="Argus API key for authorization", required=True, envvar='ARGUS_AUTH_TOKEN')
37+
@click.option("--extra-headers", default={}, type=click.UNPROCESSED, callback=validate_extra_headers, help="extra headers to pass to argus, should be in json format", envvar='ARGUS_EXTRA_HEADERS')
3638
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
3739
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
3840
@click.option("--build-id", required=True, help="Unique job identifier in the build system, e.g. scylla-master/group/job for jenkins (The full path)")
3941
@click.option("--build-url", required=True, help="Job URL in the build system")
40-
def submit_driver_matrix_run(api_key: str, base_url: str, run_id: str, build_id: str, build_url: str):
42+
def submit_driver_matrix_run(api_key: str, base_url: str, run_id: str, build_id: str, build_url: str, extra_headers: dict):
4143
LOGGER.info("Submitting %s (%s) to Argus...", build_id, run_id)
42-
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
44+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url, extra_headers=extra_headers)
4345
client.submit_driver_matrix_run(job_name=build_id, job_url=build_url)
4446
LOGGER.info("Done.")
4547

4648

4749
@click.command("submit-driver")
48-
@click.option("--api-key", help="Argus API key for authorization", required=True)
50+
@click.option("--api-key", help="Argus API key for authorization", required=True, envvar='ARGUS_AUTH_TOKEN')
51+
@click.option("--extra-headers", default={}, type=click.UNPROCESSED, callback=validate_extra_headers, help="extra headers to pass to argus, should be in json format", envvar='ARGUS_EXTRA_HEADERS')
4952
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
5053
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
5154
@click.option("--metadata-path", required=True, help="Path to the metadata .json file that contains path to junit xml and other required information")
52-
def submit_driver_result(api_key: str, base_url: str, run_id: str, metadata_path: str):
53-
_submit_driver_result_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path)
55+
def submit_driver_result(api_key: str, base_url: str, run_id: str, metadata_path: str, extra_headers: dict):
56+
_submit_driver_result_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path, extra_headers=extra_headers)
5457

5558

5659
@click.command("fail-driver")
57-
@click.option("--api-key", help="Argus API key for authorization", required=True)
60+
@click.option("--api-key", help="Argus API key for authorization", required=True, envvar='ARGUS_AUTH_TOKEN')
61+
@click.option("--extra-headers", default={}, type=click.UNPROCESSED, callback=validate_extra_headers, help="extra headers to pass to argus, should be in json format", envvar='ARGUS_EXTRA_HEADERS')
5862
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
5963
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
6064
@click.option("--metadata-path", required=True, help="Path to the metadata .json file that contains path to junit xml and other required information")
61-
def submit_driver_failure(api_key: str, base_url: str, run_id: str, metadata_path: str):
62-
_submit_driver_failure_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path)
65+
def submit_driver_failure(api_key: str, base_url: str, run_id: str, metadata_path: str, extra_headers: dict):
66+
_submit_driver_failure_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path, extra_headers=extra_headers)
6367

6468

6569
@click.command("submit-or-fail-driver")
66-
@click.option("--api-key", help="Argus API key for authorization", required=True)
70+
@click.option("--api-key", help="Argus API key for authorization", required=True, envvar='ARGUS_AUTH_TOKEN')
71+
@click.option("--extra-headers", default={}, type=click.UNPROCESSED, callback=validate_extra_headers, help="extra headers to pass to argus, should be in json format", envvar='ARGUS_EXTRA_HEADERS')
6772
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
6873
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
6974
@click.option("--metadata-path", required=True, help="Path to the metadata .json file that contains path to junit xml and other required information")
70-
def submit_or_fail_driver(api_key: str, base_url: str, run_id: str, metadata_path: str):
75+
def submit_or_fail_driver(api_key: str, base_url: str, run_id: str, metadata_path: str, extra_headers: dict):
7176
metadata = json.loads(Path(metadata_path).read_text(encoding="utf-8"))
7277
if metadata.get("failure_reason"):
73-
_submit_driver_failure_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path)
78+
_submit_driver_failure_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path, extra_headers=extra_headers)
7479
else:
75-
_submit_driver_result_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path)
80+
_submit_driver_result_internal(api_key=api_key, base_url=base_url, run_id=run_id, metadata_path=metadata_path, extra_headers=extra_headers)
7681

7782

7883
@click.command("submit-env")
79-
@click.option("--api-key", help="Argus API key for authorization", required=True)
84+
@click.option("--api-key", help="Argus API key for authorization", required=True, envvar='ARGUS_AUTH_TOKEN')
85+
@click.option("--extra-headers", default={}, type=click.UNPROCESSED, callback=validate_extra_headers, help="extra headers to pass to argus, should be in json format", envvar='ARGUS_EXTRA_HEADERS')
8086
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
8187
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
8288
@click.option("--env-path", required=True, help="Path to the Build-00.txt file that contains environment information about Scylla")
83-
def submit_driver_env(api_key: str, base_url: str, run_id: str, env_path: str):
89+
def submit_driver_env(api_key: str, base_url: str, run_id: str, env_path: str, extra_headers: dict):
8490
LOGGER.info("Submitting environment for run %s to Argus...", run_id)
8591
raw_env = Path(env_path).read_text()
86-
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
92+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url, extra_headers=extra_headers)
8793
client.submit_env(raw_env)
8894
LOGGER.info("Done.")
8995

9096

9197
@click.command("finish-run")
92-
@click.option("--api-key", help="Argus API key for authorization", required=True)
98+
@click.option("--api-key", help="Argus API key for authorization", required=True, envvar='ARGUS_AUTH_TOKEN')
99+
@click.option("--extra-headers", default={}, type=click.UNPROCESSED, callback=validate_extra_headers, help="extra headers to pass to argus, should be in json format", envvar='ARGUS_EXTRA_HEADERS')
93100
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
94101
@click.option("--id", "run_id", required=True, help="UUID (v4 or v1) unique to the job")
95102
@click.option("--status", required=True, help="Resulting job status")
96-
def finish_driver_matrix_run(api_key: str, base_url: str, run_id: str, status: str):
97-
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url)
103+
def finish_driver_matrix_run(api_key: str, base_url: str, run_id: str, status: str, extra_headers: dict):
104+
client = ArgusDriverMatrixClient(run_id=run_id, auth_token=api_key, base_url=base_url, extra_headers=extra_headers)
98105
client.finalize_run(run_type=ArgusDriverMatrixClient.test_type, run_id=run_id, body={"status": TestStatus(status)})
99106

100107

argus/client/driver_matrix_tests/client.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ class Routes(ArgusClient.Routes):
1212
SUBMIT_DRIVER_FAILURE = "/driver_matrix/result/fail"
1313
SUBMIT_ENV = "/driver_matrix/env/submit"
1414

15-
def __init__(self, run_id: UUID, auth_token: str, base_url: str, api_version="v1") -> None:
16-
super().__init__(auth_token, base_url, api_version)
15+
def __init__(self, run_id: UUID, auth_token: str, base_url: str, api_version="v1", extra_headers: dict | None = None) -> None:
16+
super().__init__(auth_token, base_url, api_version, extra_headers=extra_headers)
1717
self.run_id = run_id
1818

1919
def submit_driver_matrix_run(self, job_name: str, job_url: str) -> None:

argus/client/generic/cli.py

+44-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
<<<<<<< HEAD
2+
||||||| parent of 6e4e1fbc0 (feature(argus): call client with extra headers)
3+
import json
4+
from pathlib import Path
5+
=======
6+
import json
7+
from json.decoder import JSONDecodeError
8+
from pathlib import Path
9+
>>>>>>> 6e4e1fbc0 (feature(argus): call client with extra headers)
110
import click
211
import logging
312

@@ -6,39 +15,68 @@
615

716
LOGGER = logging.getLogger(__name__)
817

18+
def validate_extra_headers(ctx, param, value):
19+
if isinstance(value, dict):
20+
return value
21+
22+
try:
23+
return json.loads(value)
24+
except JSONDecodeError as ex:
25+
raise click.BadParameter(f"--extra-headers should be in json format:\n\n{value}\n\n{ex}")
26+
927

1028
@click.group
1129
def cli():
1230
pass
1331

1432

1533
@click.command("submit")
16-
@click.option("--api-key", help="Argus API key for authorization", required=True)
34+
@click.option("--api-key", help="Argus API key for authorization", required=True, envvar='ARGUS_AUTH_TOKEN')
1735
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
1836
@click.option("--id", required=True, help="UUID (v4 or v1) unique to the job")
1937
@click.option("--build-id", required=True, help="Unique job identifier in the build system, e.g. scylla-master/group/job for jenkins (The full path)")
2038
@click.option("--build-url", required=True, help="Job URL in the build system")
2139
@click.option("--started-by", required=True, help="Username of the user who started the job")
2240
@click.option("--scylla-version", required=False, default=None, help="Version of Scylla used for this job")
23-
def submit_run(api_key: str, base_url: str, id: str, build_id: str, build_url: str, started_by: str, scylla_version: str = None):
41+
@click.option("--extra-headers", default={}, type=click.UNPROCESSED, callback=validate_extra_headers, help="extra headers to pass to argus, should be in json format", envvar='ARGUS_EXTRA_HEADERS')
42+
def submit_run(api_key: str, base_url: str, id: str, build_id: str, build_url: str, started_by: str, scylla_version: str = None, extra_headers: dict | None = None):
2443
LOGGER.info("Submitting %s (%s) to Argus...", build_id, id)
25-
client = ArgusGenericClient(auth_token=api_key, base_url=base_url)
44+
client = ArgusGenericClient(auth_token=api_key, base_url=base_url, extra_headers=extra_headers)
2645
client.submit_generic_run(build_id=build_id, run_id=id, started_by=started_by, build_url=build_url, scylla_version=scylla_version)
2746
LOGGER.info("Done.")
2847

2948

3049
@click.command("finish")
31-
@click.option("--api-key", help="Argus API key for authorization", required=True)
50+
@click.option("--api-key", help="Argus API key for authorization", required=True, envvar='ARGUS_AUTH_TOKEN')
3251
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
3352
@click.option("--id", required=True, help="UUID (v4 or v1) unique to the job")
3453
@click.option("--status", required=True, help="Resulting job status")
3554
@click.option("--scylla-version", required=False, default=None, help="Version of Scylla used for this job")
36-
def finish_run(api_key: str, base_url: str, id: str, status: str, scylla_version: str = None):
37-
client = ArgusGenericClient(auth_token=api_key, base_url=base_url)
55+
@click.option("--extra-headers", default={}, type=click.UNPROCESSED, callback=validate_extra_headers, help="extra headers to pass to argus, should be in json format", envvar='ARGUS_EXTRA_HEADERS')
56+
def finish_run(api_key: str, base_url: str, id: str, status: str, scylla_version: str = None, extra_headers: dict | None = None):
57+
client = ArgusGenericClient(auth_token=api_key, base_url=base_url, extra_headers=extra_headers)
3858
status = TestStatus(status)
3959
client.finalize_generic_run(run_id=id, status=status, scylla_version=scylla_version)
4060

4161

62+
@click.command("trigger-jobs")
63+
@click.option("--api-key", help="Argus API key for authorization", required=True, envvar='ARGUS_AUTH_TOKEN')
64+
@click.option("--base-url", default="https://argus.scylladb.com", help="Base URL for argus instance")
65+
@click.option("--version", help="Scylla version to filter plans by", default=None, required=False)
66+
@click.option("--plan-id", help="Specific plan id for filtering", default=None, required=False)
67+
@click.option("--release", help="Release name to filter plans by", default=None, required=False)
68+
@click.option("--job-info-file", required=True, help="JSON file with trigger information (see detailed docs)")
69+
@click.option("--extra-headers", default={}, type=click.UNPROCESSED, callback=validate_extra_headers, help="extra headers to pass to argus, should be in json format", envvar='ARGUS_EXTRA_HEADERS')
70+
def trigger_jobs(api_key: str, base_url: str, job_info_file: str, version: str, plan_id: str, release: str, extra_headers: dict | None = None):
71+
client = ArgusGenericClient(auth_token=api_key, base_url=base_url, extra_headers=extra_headers)
72+
path = Path(job_info_file)
73+
if not path.exists():
74+
LOGGER.error("File not found: %s", job_info_file)
75+
exit(128)
76+
payload = json.load(path.open("rt", encoding="utf-8"))
77+
client.trigger_jobs({ "release": release, "version": version, "plan_id": plan_id, **payload })
78+
79+
4280
cli.add_command(submit_run)
4381
cli.add_command(finish_run)
4482

argus/client/generic/client.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77
class ArgusGenericClient(ArgusClient):
88
test_type = "generic"
99
schema_version: None = "v1"
10-
def __init__(self, auth_token: str, base_url: str, api_version="v1") -> None:
11-
super().__init__(auth_token, base_url, api_version)
10+
11+
class Routes(ArgusClient.Routes):
12+
TRIGGER_JOBS = "/planning/plan/trigger"
13+
14+
def __init__(self, auth_token: str, base_url: str, api_version="v1", extra_headers: dict | None = None) -> None:
15+
super().__init__(auth_token, base_url, api_version, extra_headers=extra_headers)
1216

1317
def submit_generic_run(self, build_id: str, run_id: str, started_by: str, build_url: str, scylla_version: str | None = None):
1418
request_body = {
@@ -28,4 +32,4 @@ def finalize_generic_run(self, run_id: str, status: str, scylla_version: str | N
2832
"status": status,
2933
"scylla_version": scylla_version,
3034
})
31-
self.check_response(response)
35+
self.check_response(response)

argus/client/sct/client.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ class Routes(ArgusClient.Routes):
2727
SUBMIT_EVENTS = "/sct/$id/events/submit"
2828
SUBMIT_JUNIT_REPORT = "/sct/$id/junit/submit"
2929

30-
def __init__(self, run_id: UUID, auth_token: str, base_url: str, api_version="v1") -> None:
31-
super().__init__(auth_token, base_url, api_version)
30+
def __init__(self, run_id: UUID, auth_token: str, base_url: str, api_version="v1", extra_headers: dict | None = None) -> None:
31+
super().__init__(auth_token, base_url, api_version, extra_headers=extra_headers)
3232
self.run_id = run_id
3333

3434
def submit_sct_run(self, job_name: str, job_url: str, started_by: str, commit_id: str,

argus/client/sirenada/client.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ class ArgusSirenadaClient(ArgusClient):
4343
"skipped": "skipped"
4444
}
4545

46-
def __init__(self, auth_token: str, base_url: str, api_version="v1") -> None:
46+
def __init__(self, auth_token: str, base_url: str, api_version="v1", extra_headers: dict | None = None) -> None:
4747
self.results_path: Path | None = None
48-
super().__init__(auth_token, base_url, api_version)
48+
super().__init__(auth_token, base_url, api_version, extra_headers=extra_headers)
4949

5050
def _verify_required_files_exist(self, results_path: Path):
5151
assert (results_path / self._junit_xml_filename).exists(), "Missing jUnit XML results file!"

argus/version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.13.0
1+
0.14.2

sdcm/utils/argus.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ def get_argus_client(run_id: UUID | str) -> ArgusSCTClient:
4040
if not is_uuid(run_id):
4141
raise ArgusError("Malformed UUID provided")
4242
creds = KeyStore().get_argus_rest_credentials()
43-
argus_client = ArgusSCTClient(run_id=run_id, auth_token=creds["token"], base_url=creds["baseUrl"])
43+
argus_client = ArgusSCTClient(
44+
run_id=run_id, auth_token=creds["token"], base_url=creds["baseUrl"], extra_headers=creds.get("extra_headers"))
4445

4546
return argus_client
4647

0 commit comments

Comments
 (0)