qontract-reconcile 0.10.2.dev56__py3-none-any.whl → 0.10.2.dev58__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qontract_reconcile-0.10.2.dev56.dist-info → qontract_reconcile-0.10.2.dev58.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev56.dist-info → qontract_reconcile-0.10.2.dev58.dist-info}/RECORD +8 -8
- reconcile/utils/output.py +6 -3
- tools/app_interface_reporter.py +70 -44
- tools/cli_commands/gpg_encrypt.py +2 -2
- tools/qontract_cli.py +230 -291
- {qontract_reconcile-0.10.2.dev56.dist-info → qontract_reconcile-0.10.2.dev58.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev56.dist-info → qontract_reconcile-0.10.2.dev58.dist-info}/entry_points.txt +0 -0
tools/qontract_cli.py
CHANGED
@@ -10,7 +10,6 @@ import sys
|
|
10
10
|
import tempfile
|
11
11
|
import textwrap
|
12
12
|
from collections import defaultdict
|
13
|
-
from collections.abc import Callable, Mapping
|
14
13
|
from datetime import (
|
15
14
|
UTC,
|
16
15
|
datetime,
|
@@ -55,6 +54,7 @@ from reconcile.change_owners.bundle import NoOpFileDiffResolver
|
|
55
54
|
from reconcile.change_owners.change_log_tracking import (
|
56
55
|
BUNDLE_DIFFS_OBJ,
|
57
56
|
ChangeLog,
|
57
|
+
ChangeLogItem,
|
58
58
|
)
|
59
59
|
from reconcile.change_owners.change_owners import (
|
60
60
|
fetch_change_type_processors,
|
@@ -81,7 +81,6 @@ from reconcile.gql_definitions.app_sre_tekton_access_revalidation.roles import (
|
|
81
81
|
from reconcile.gql_definitions.common.app_interface_vault_settings import (
|
82
82
|
AppInterfaceSettingsV1,
|
83
83
|
)
|
84
|
-
from reconcile.gql_definitions.common.clusters import ClusterSpecROSAV1
|
85
84
|
from reconcile.gql_definitions.fragments.aus_organization import AUSOCMOrganization
|
86
85
|
from reconcile.gql_definitions.integrations import integrations as integrations_gql
|
87
86
|
from reconcile.gql_definitions.maintenance import maintenances as maintenances_gql
|
@@ -153,7 +152,6 @@ from reconcile.utils.oc_map import (
|
|
153
152
|
init_oc_map_from_clusters,
|
154
153
|
)
|
155
154
|
from reconcile.utils.ocm import OCM_PRODUCT_ROSA, OCMMap
|
156
|
-
from reconcile.utils.ocm.upgrades import get_upgrade_policies
|
157
155
|
from reconcile.utils.ocm_base_client import init_ocm_base_client
|
158
156
|
from reconcile.utils.output import print_output
|
159
157
|
from reconcile.utils.saasherder.models import TargetSpec
|
@@ -192,7 +190,7 @@ else:
|
|
192
190
|
CopySourceTypeDef = object
|
193
191
|
|
194
192
|
|
195
|
-
def output(function
|
193
|
+
def output(function):
|
196
194
|
function = click.option(
|
197
195
|
"--output",
|
198
196
|
"-o",
|
@@ -203,14 +201,14 @@ def output(function: Callable) -> Callable:
|
|
203
201
|
return function
|
204
202
|
|
205
203
|
|
206
|
-
def sort(function
|
204
|
+
def sort(function):
|
207
205
|
function = click.option(
|
208
206
|
"--sort", "-s", help="sort output", default=True, type=bool
|
209
207
|
)(function)
|
210
208
|
return function
|
211
209
|
|
212
210
|
|
213
|
-
def to_string(function
|
211
|
+
def to_string(function):
|
214
212
|
function = click.option(
|
215
213
|
"--to-string", help="stringify output", default=False, type=bool
|
216
214
|
)(function)
|
@@ -220,14 +218,14 @@ def to_string(function: Callable) -> Callable:
|
|
220
218
|
@click.group()
|
221
219
|
@config_file
|
222
220
|
@click.pass_context
|
223
|
-
def root(ctx
|
221
|
+
def root(ctx, configfile):
|
224
222
|
ctx.ensure_object(dict)
|
225
223
|
config.init_from_toml(configfile)
|
226
224
|
gql.init_from_config()
|
227
225
|
|
228
226
|
|
229
227
|
@root.result_callback()
|
230
|
-
def exit_cli(ctx
|
228
|
+
def exit_cli(ctx, configfile):
|
231
229
|
GqlApiSingleton.close()
|
232
230
|
|
233
231
|
|
@@ -236,7 +234,7 @@ def exit_cli(ctx: click.Context, configfile: str) -> None:
|
|
236
234
|
@sort
|
237
235
|
@to_string
|
238
236
|
@click.pass_context
|
239
|
-
def get(ctx
|
237
|
+
def get(ctx, output, sort, to_string):
|
240
238
|
ctx.obj["options"] = {
|
241
239
|
"output": output,
|
242
240
|
"sort": sort,
|
@@ -247,7 +245,7 @@ def get(ctx: click.Context, output: str, sort: bool, to_string: bool) -> None:
|
|
247
245
|
@root.group()
|
248
246
|
@output
|
249
247
|
@click.pass_context
|
250
|
-
def describe(ctx
|
248
|
+
def describe(ctx, output):
|
251
249
|
ctx.obj["options"] = {
|
252
250
|
"output": output,
|
253
251
|
}
|
@@ -255,7 +253,7 @@ def describe(ctx: click.Context, output: str) -> None:
|
|
255
253
|
|
256
254
|
@get.command()
|
257
255
|
@click.pass_context
|
258
|
-
def settings(ctx
|
256
|
+
def settings(ctx):
|
259
257
|
settings = queries.get_app_interface_settings()
|
260
258
|
columns = ["vault", "kubeBinary", "mergeRequestGateway"]
|
261
259
|
print_output(ctx.obj["options"], [settings], columns)
|
@@ -264,7 +262,7 @@ def settings(ctx: click.Context) -> None:
|
|
264
262
|
@get.command()
|
265
263
|
@click.argument("name", default="")
|
266
264
|
@click.pass_context
|
267
|
-
def aws_accounts(ctx
|
265
|
+
def aws_accounts(ctx, name):
|
268
266
|
accounts = queries.get_aws_accounts(name=name)
|
269
267
|
if not accounts:
|
270
268
|
print("no aws accounts found")
|
@@ -276,7 +274,7 @@ def aws_accounts(ctx: click.Context, name: str) -> None:
|
|
276
274
|
@get.command()
|
277
275
|
@click.argument("name", default="")
|
278
276
|
@click.pass_context
|
279
|
-
def clusters(ctx
|
277
|
+
def clusters(ctx, name):
|
280
278
|
clusters = queries.get_clusters()
|
281
279
|
if name:
|
282
280
|
clusters = [c for c in clusters if c["name"] == name]
|
@@ -293,7 +291,7 @@ def clusters(ctx: click.Context, name: str) -> None:
|
|
293
291
|
@get.command()
|
294
292
|
@click.argument("name", default="")
|
295
293
|
@click.pass_context
|
296
|
-
def cluster_upgrades(ctx
|
294
|
+
def cluster_upgrades(ctx, name):
|
297
295
|
settings = queries.get_app_interface_settings()
|
298
296
|
|
299
297
|
clusters = queries.get_clusters()
|
@@ -324,11 +322,12 @@ def cluster_upgrades(ctx: click.Context, name: str) -> None:
|
|
324
322
|
if data.get("upgradePolicy") == "automatic":
|
325
323
|
data["schedule"] = c["upgradePolicy"]["schedule"]
|
326
324
|
ocm = ocm_map.get(c["name"])
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
325
|
+
if ocm:
|
326
|
+
upgrade_policy = ocm.get_upgrade_policies(c["name"])
|
327
|
+
if upgrade_policy and len(upgrade_policy) > 0:
|
328
|
+
next_run = upgrade_policy[0].get("next_run")
|
329
|
+
if next_run:
|
330
|
+
data["next_run"] = next_run
|
332
331
|
else:
|
333
332
|
data["upgradePolicy"] = "manual"
|
334
333
|
|
@@ -342,7 +341,7 @@ def cluster_upgrades(ctx: click.Context, name: str) -> None:
|
|
342
341
|
@get.command()
|
343
342
|
@environ(["APP_INTERFACE_STATE_BUCKET", "APP_INTERFACE_STATE_BUCKET_ACCOUNT"])
|
344
343
|
@click.pass_context
|
345
|
-
def version_history(ctx
|
344
|
+
def version_history(ctx):
|
346
345
|
import reconcile.aus.ocm_upgrade_scheduler as ous
|
347
346
|
|
348
347
|
clusters = aus_clusters_query(query_func=gql.get_api().query).clusters or []
|
@@ -378,11 +377,11 @@ def version_history(ctx: click.Context) -> None:
|
|
378
377
|
|
379
378
|
def get_upgrade_policies_data(
|
380
379
|
org_upgrade_specs: list[OrganizationUpgradeSpec],
|
381
|
-
md_output
|
382
|
-
integration
|
383
|
-
workload
|
384
|
-
show_only_soaking_upgrades
|
385
|
-
by_workload
|
380
|
+
md_output,
|
381
|
+
integration,
|
382
|
+
workload=None,
|
383
|
+
show_only_soaking_upgrades=False,
|
384
|
+
by_workload=False,
|
386
385
|
) -> list:
|
387
386
|
if not org_upgrade_specs:
|
388
387
|
return []
|
@@ -563,12 +562,12 @@ more than 6 hours will be highlighted.
|
|
563
562
|
)
|
564
563
|
@click.pass_context
|
565
564
|
def cluster_upgrade_policies(
|
566
|
-
ctx
|
567
|
-
cluster
|
568
|
-
workload
|
569
|
-
show_only_soaking_upgrades
|
570
|
-
by_workload
|
571
|
-
)
|
565
|
+
ctx,
|
566
|
+
cluster=None,
|
567
|
+
workload=None,
|
568
|
+
show_only_soaking_upgrades=False,
|
569
|
+
by_workload=False,
|
570
|
+
):
|
572
571
|
print(
|
573
572
|
"https://grafana.app-sre.devshift.net/d/ukLXCSwVz/aus-cluster-upgrade-overview"
|
574
573
|
)
|
@@ -583,7 +582,9 @@ def inherit_version_data_text(org: AUSOCMOrganization) -> str:
|
|
583
582
|
|
584
583
|
@get.command()
|
585
584
|
@click.pass_context
|
586
|
-
def ocm_fleet_upgrade_policies(
|
585
|
+
def ocm_fleet_upgrade_policies(
|
586
|
+
ctx,
|
587
|
+
):
|
587
588
|
from reconcile.aus.ocm_upgrade_scheduler_org import (
|
588
589
|
OCMClusterUpgradeSchedulerOrgIntegration,
|
589
590
|
)
|
@@ -616,12 +617,7 @@ def ocm_fleet_upgrade_policies(ctx: click.Context) -> None:
|
|
616
617
|
help="Ignore STS clusters",
|
617
618
|
)
|
618
619
|
@click.pass_context
|
619
|
-
def aus_fleet_upgrade_policies(
|
620
|
-
ctx: click.Context,
|
621
|
-
ocm_env: str | None,
|
622
|
-
ocm_org_ids: str | None,
|
623
|
-
ignore_sts_clusters: bool,
|
624
|
-
) -> None:
|
620
|
+
def aus_fleet_upgrade_policies(ctx, ocm_env, ocm_org_ids, ignore_sts_clusters):
|
625
621
|
from reconcile.aus.advanced_upgrade_service import AdvancedUpgradeServiceIntegration
|
626
622
|
|
627
623
|
parsed_ocm_org_ids = set(ocm_org_ids.split(",")) if ocm_org_ids else None
|
@@ -638,8 +634,8 @@ def aus_fleet_upgrade_policies(
|
|
638
634
|
|
639
635
|
|
640
636
|
def generate_fleet_upgrade_policices_report(
|
641
|
-
ctx
|
642
|
-
)
|
637
|
+
ctx, aus_integration: AdvancedUpgradeSchedulerBaseIntegration
|
638
|
+
):
|
643
639
|
md_output = ctx.obj["options"]["output"] == "md"
|
644
640
|
|
645
641
|
org_upgrade_specs: dict[str, OrganizationUpgradeSpec] = {}
|
@@ -957,7 +953,7 @@ def upgrade_cluster_addon(
|
|
957
953
|
)
|
958
954
|
|
959
955
|
|
960
|
-
def has_cluster_account_access(cluster: dict[str, Any])
|
956
|
+
def has_cluster_account_access(cluster: dict[str, Any]):
|
961
957
|
spec = cluster.get("spec") or {}
|
962
958
|
account = spec.get("account")
|
963
959
|
return account or cluster.get("awsInfrastructureManagementAccounts") is not None
|
@@ -966,7 +962,7 @@ def has_cluster_account_access(cluster: dict[str, Any]) -> bool:
|
|
966
962
|
@get.command()
|
967
963
|
@click.argument("name", default="")
|
968
964
|
@click.pass_context
|
969
|
-
def clusters_network(ctx
|
965
|
+
def clusters_network(ctx, name):
|
970
966
|
settings = queries.get_app_interface_settings()
|
971
967
|
clusters = [
|
972
968
|
c
|
@@ -1029,7 +1025,7 @@ def clusters_network(ctx: click.Context, name: str) -> None:
|
|
1029
1025
|
|
1030
1026
|
@get.command()
|
1031
1027
|
@click.pass_context
|
1032
|
-
def network_reservations(ctx
|
1028
|
+
def network_reservations(ctx) -> None:
|
1033
1029
|
from reconcile.typed_queries.reserved_networks import get_networks
|
1034
1030
|
|
1035
1031
|
columns = [
|
@@ -1042,10 +1038,11 @@ def network_reservations(ctx: click.Context) -> None:
|
|
1042
1038
|
]
|
1043
1039
|
network_table = []
|
1044
1040
|
|
1045
|
-
def md_link(url
|
1041
|
+
def md_link(url) -> str:
|
1046
1042
|
if ctx.obj["options"]["output"] == "md":
|
1047
1043
|
return f"[{url}]({url})"
|
1048
|
-
|
1044
|
+
else:
|
1045
|
+
return url
|
1049
1046
|
|
1050
1047
|
for network in get_networks():
|
1051
1048
|
parentAddress = "none"
|
@@ -1086,7 +1083,7 @@ def network_reservations(ctx: click.Context) -> None:
|
|
1086
1083
|
default=24,
|
1087
1084
|
)
|
1088
1085
|
@click.pass_context
|
1089
|
-
def cidr_blocks(ctx
|
1086
|
+
def cidr_blocks(ctx, for_cluster: int, mask: int) -> None:
|
1090
1087
|
import ipaddress
|
1091
1088
|
|
1092
1089
|
from reconcile.typed_queries.aws_vpcs import get_aws_vpcs
|
@@ -1212,7 +1209,7 @@ def ocm_aws_infrastructure_access_switch_role_links_data() -> list[dict]:
|
|
1212
1209
|
|
1213
1210
|
@get.command()
|
1214
1211
|
@click.pass_context
|
1215
|
-
def ocm_aws_infrastructure_access_switch_role_links_flat(ctx
|
1212
|
+
def ocm_aws_infrastructure_access_switch_role_links_flat(ctx):
|
1216
1213
|
results = ocm_aws_infrastructure_access_switch_role_links_data()
|
1217
1214
|
columns = ["cluster", "user_arn", "access_level", "switch_role_link"]
|
1218
1215
|
print_output(ctx.obj["options"], results, columns)
|
@@ -1220,11 +1217,11 @@ def ocm_aws_infrastructure_access_switch_role_links_flat(ctx: click.Context) ->
|
|
1220
1217
|
|
1221
1218
|
@get.command()
|
1222
1219
|
@click.pass_context
|
1223
|
-
def ocm_aws_infrastructure_access_switch_role_links(ctx
|
1220
|
+
def ocm_aws_infrastructure_access_switch_role_links(ctx):
|
1224
1221
|
if ctx.obj["options"]["output"] != "md":
|
1225
1222
|
raise Exception(f"Unupported output: {ctx.obj['options']['output']}")
|
1226
1223
|
results = ocm_aws_infrastructure_access_switch_role_links_data()
|
1227
|
-
by_user
|
1224
|
+
by_user = {}
|
1228
1225
|
for r in results:
|
1229
1226
|
by_user.setdefault(r["user"], []).append(r)
|
1230
1227
|
columns = ["cluster", "source_login", "access_level", "switch_role_link"]
|
@@ -1238,7 +1235,7 @@ def ocm_aws_infrastructure_access_switch_role_links(ctx: click.Context) -> None:
|
|
1238
1235
|
|
1239
1236
|
@get.command()
|
1240
1237
|
@click.pass_context
|
1241
|
-
def clusters_aws_account_ids(ctx
|
1238
|
+
def clusters_aws_account_ids(ctx):
|
1242
1239
|
settings = queries.get_app_interface_settings()
|
1243
1240
|
clusters = [c for c in queries.get_clusters() if c.get("ocm") is not None]
|
1244
1241
|
ocm_map = OCMMap(clusters=clusters, settings=settings)
|
@@ -1268,7 +1265,7 @@ def clusters_aws_account_ids(ctx: click.Context) -> None:
|
|
1268
1265
|
@root.command()
|
1269
1266
|
@click.argument("account_name")
|
1270
1267
|
@click.pass_context
|
1271
|
-
def user_credentials_migrate_output(ctx
|
1268
|
+
def user_credentials_migrate_output(ctx, account_name) -> None:
|
1272
1269
|
accounts = queries.get_state_aws_accounts()
|
1273
1270
|
state = init_state(integration="account-notifier")
|
1274
1271
|
skip_accounts, appsre_pgp_key, _ = tfu.get_reencrypt_settings()
|
@@ -1310,7 +1307,7 @@ def user_credentials_migrate_output(ctx: click.Context, account_name: str) -> No
|
|
1310
1307
|
|
1311
1308
|
@get.command()
|
1312
1309
|
@click.pass_context
|
1313
|
-
def aws_route53_zones(ctx
|
1310
|
+
def aws_route53_zones(ctx):
|
1314
1311
|
zones = queries.get_dns_zones()
|
1315
1312
|
|
1316
1313
|
results = []
|
@@ -1333,7 +1330,7 @@ def aws_route53_zones(ctx: click.Context) -> None:
|
|
1333
1330
|
@click.argument("cluster_name")
|
1334
1331
|
@click.option("--cluster-admin/--no-cluster-admin", default=False)
|
1335
1332
|
@click.pass_context
|
1336
|
-
def bot_login(ctx
|
1333
|
+
def bot_login(ctx, cluster_name, cluster_admin):
|
1337
1334
|
settings = queries.get_app_interface_settings()
|
1338
1335
|
secret_reader = SecretReader(settings=settings)
|
1339
1336
|
clusters = queries.get_clusters()
|
@@ -1356,7 +1353,7 @@ def bot_login(ctx: click.Context, cluster_name: str, cluster_admin: bool) -> Non
|
|
1356
1353
|
)
|
1357
1354
|
@click.argument("org_name")
|
1358
1355
|
@click.pass_context
|
1359
|
-
def ocm_login(ctx
|
1356
|
+
def ocm_login(ctx, org_name):
|
1360
1357
|
settings = queries.get_app_interface_settings()
|
1361
1358
|
secret_reader = SecretReader(settings=settings)
|
1362
1359
|
ocms = [
|
@@ -1383,7 +1380,7 @@ def ocm_login(ctx: click.Context, org_name: str) -> None:
|
|
1383
1380
|
)
|
1384
1381
|
@click.argument("account_name")
|
1385
1382
|
@click.pass_context
|
1386
|
-
def aws_creds(ctx
|
1383
|
+
def aws_creds(ctx, account_name):
|
1387
1384
|
settings = queries.get_app_interface_settings()
|
1388
1385
|
secret_reader = SecretReader(settings=settings)
|
1389
1386
|
accounts = queries.get_aws_accounts(name=account_name)
|
@@ -1426,14 +1423,8 @@ def aws_creds(ctx: click.Context, account_name: str) -> None:
|
|
1426
1423
|
)
|
1427
1424
|
@click.pass_context
|
1428
1425
|
def copy_tfstate(
|
1429
|
-
ctx
|
1430
|
-
|
1431
|
-
source_object_path: str,
|
1432
|
-
account_uid: str,
|
1433
|
-
rename: str | None,
|
1434
|
-
region: str | None,
|
1435
|
-
force: bool,
|
1436
|
-
) -> None:
|
1426
|
+
ctx, source_bucket, source_object_path, account_uid, rename, region, force
|
1427
|
+
):
|
1437
1428
|
settings = queries.get_app_interface_settings()
|
1438
1429
|
secret_reader = SecretReader(settings=settings)
|
1439
1430
|
accounts = queries.get_aws_accounts(uid=account_uid, terraform_state=True)
|
@@ -1454,6 +1445,7 @@ def copy_tfstate(
|
|
1454
1445
|
)
|
1455
1446
|
return
|
1456
1447
|
|
1448
|
+
dest_filename = ""
|
1457
1449
|
if rename:
|
1458
1450
|
dest_filename = rename.removesuffix(".tfstate")
|
1459
1451
|
else:
|
@@ -1514,26 +1506,20 @@ def copy_tfstate(
|
|
1514
1506
|
@get.command(short_help='obtain "rosa create cluster" command by cluster name')
|
1515
1507
|
@click.argument("cluster_name")
|
1516
1508
|
@click.pass_context
|
1517
|
-
def rosa_create_cluster_command(ctx
|
1509
|
+
def rosa_create_cluster_command(ctx, cluster_name):
|
1518
1510
|
clusters = [c for c in get_clusters() if c.name == cluster_name]
|
1519
|
-
|
1511
|
+
try:
|
1512
|
+
cluster = clusters[0]
|
1513
|
+
except IndexError:
|
1520
1514
|
print(f"{cluster_name} not found.")
|
1521
1515
|
sys.exit(1)
|
1522
|
-
cluster = clusters[0]
|
1523
1516
|
|
1524
|
-
if
|
1525
|
-
not cluster.spec
|
1526
|
-
or cluster.spec.product != OCM_PRODUCT_ROSA
|
1527
|
-
or not isinstance(cluster.spec, ClusterSpecROSAV1)
|
1528
|
-
):
|
1517
|
+
if cluster.spec.product != OCM_PRODUCT_ROSA:
|
1529
1518
|
print("must be a rosa cluster.")
|
1530
1519
|
sys.exit(1)
|
1531
1520
|
|
1532
1521
|
settings = queries.get_app_interface_settings()
|
1533
1522
|
account = cluster.spec.account
|
1534
|
-
if not account:
|
1535
|
-
print("account not found.")
|
1536
|
-
sys.exit(1)
|
1537
1523
|
|
1538
1524
|
if account.billing_account:
|
1539
1525
|
billing_account = account.billing_account.uid
|
@@ -1543,19 +1529,6 @@ def rosa_create_cluster_command(ctx: click.Context, cluster_name: str) -> None:
|
|
1543
1529
|
) as aws_api:
|
1544
1530
|
billing_account = aws_api.get_organization_billing_account(account.name)
|
1545
1531
|
|
1546
|
-
if not cluster.spec.oidc_endpoint_url:
|
1547
|
-
print("oidc_endpoint_url not set.")
|
1548
|
-
sys.exit(1)
|
1549
|
-
if not cluster.spec.subnet_ids:
|
1550
|
-
print("subnet_ids not set.")
|
1551
|
-
sys.exit(1)
|
1552
|
-
if not cluster.network:
|
1553
|
-
print("network not set.")
|
1554
|
-
sys.exit(1)
|
1555
|
-
if not cluster.machine_pools:
|
1556
|
-
print("machine_pools not set.")
|
1557
|
-
sys.exit(1)
|
1558
|
-
|
1559
1532
|
print(
|
1560
1533
|
" ".join([
|
1561
1534
|
"rosa create cluster",
|
@@ -1609,9 +1582,7 @@ def rosa_create_cluster_command(ctx: click.Context, cluster_name: str) -> None:
|
|
1609
1582
|
@click.argument("jumphost_hostname", required=False)
|
1610
1583
|
@click.argument("cluster_name", required=False)
|
1611
1584
|
@click.pass_context
|
1612
|
-
def sshuttle_command(
|
1613
|
-
ctx: click.Context, jumphost_hostname: str | None, cluster_name: str | None
|
1614
|
-
) -> None:
|
1585
|
+
def sshuttle_command(ctx, jumphost_hostname: str | None, cluster_name: str | None):
|
1615
1586
|
jumphosts_query_data = queries.get_jumphosts(hostname=jumphost_hostname)
|
1616
1587
|
jumphosts = jumphosts_query_data.jumphosts or []
|
1617
1588
|
for jh in jumphosts:
|
@@ -1633,9 +1604,7 @@ def sshuttle_command(
|
|
1633
1604
|
@click.argument("instance_name")
|
1634
1605
|
@click.argument("job_name")
|
1635
1606
|
@click.pass_context
|
1636
|
-
def jenkins_job_vault_secrets(
|
1637
|
-
ctx: click.Context, instance_name: str, job_name: str
|
1638
|
-
) -> None:
|
1607
|
+
def jenkins_job_vault_secrets(ctx, instance_name: str, job_name: str) -> None:
|
1639
1608
|
secret_reader = SecretReader(queries.get_secret_reader_settings())
|
1640
1609
|
jjb: JJB = init_jjb(secret_reader, instance_name, config_name=None, print_only=True)
|
1641
1610
|
jobs = jjb.get_all_jobs([job_name], instance_name)[instance_name]
|
@@ -1660,7 +1629,7 @@ def jenkins_job_vault_secrets(
|
|
1660
1629
|
@get.command()
|
1661
1630
|
@click.argument("name", default="")
|
1662
1631
|
@click.pass_context
|
1663
|
-
def namespaces(ctx
|
1632
|
+
def namespaces(ctx, name):
|
1664
1633
|
namespaces = queries.get_namespaces()
|
1665
1634
|
if name:
|
1666
1635
|
namespaces = [ns for ns in namespaces if ns["name"] == name]
|
@@ -1672,7 +1641,7 @@ def namespaces(ctx: click.Context, name: str) -> None:
|
|
1672
1641
|
print_output(ctx.obj["options"], namespaces, columns)
|
1673
1642
|
|
1674
1643
|
|
1675
|
-
def add_resource(item
|
1644
|
+
def add_resource(item, resource, columns):
|
1676
1645
|
provider = resource["provider"]
|
1677
1646
|
if provider not in columns:
|
1678
1647
|
columns.append(provider)
|
@@ -1683,11 +1652,11 @@ def add_resource(item: dict, resource: Mapping, columns: list[str]) -> None:
|
|
1683
1652
|
|
1684
1653
|
@get.command
|
1685
1654
|
@click.pass_context
|
1686
|
-
def cluster_openshift_resources(ctx
|
1655
|
+
def cluster_openshift_resources(ctx):
|
1687
1656
|
gqlapi = gql.get_api()
|
1688
1657
|
namespaces = gqlapi.query(orb.NAMESPACES_QUERY)["namespaces"]
|
1689
1658
|
columns = ["name", "total"]
|
1690
|
-
results
|
1659
|
+
results = {}
|
1691
1660
|
for ns_info in namespaces:
|
1692
1661
|
cluster_name = ns_info["cluster"]["name"]
|
1693
1662
|
item = {"name": cluster_name, "total": 0}
|
@@ -1708,10 +1677,10 @@ def cluster_openshift_resources(ctx: click.Context) -> None:
|
|
1708
1677
|
|
1709
1678
|
@get.command
|
1710
1679
|
@click.pass_context
|
1711
|
-
def aws_terraform_resources(ctx
|
1680
|
+
def aws_terraform_resources(ctx):
|
1712
1681
|
namespaces = tfr.get_namespaces()
|
1713
1682
|
columns = ["name", "total"]
|
1714
|
-
results
|
1683
|
+
results = {}
|
1715
1684
|
for ns_info in namespaces:
|
1716
1685
|
specs = (
|
1717
1686
|
get_external_resource_specs(
|
@@ -1763,7 +1732,7 @@ def rds_region(
|
|
1763
1732
|
|
1764
1733
|
@get.command
|
1765
1734
|
@click.pass_context
|
1766
|
-
def rds(ctx
|
1735
|
+
def rds(ctx):
|
1767
1736
|
namespaces = tfr.get_namespaces()
|
1768
1737
|
accounts = {a["name"]: a for a in queries.get_aws_accounts()}
|
1769
1738
|
results = []
|
@@ -1841,7 +1810,7 @@ You can view the source of this Markdown to extract the JSON data.
|
|
1841
1810
|
|
1842
1811
|
@get.command
|
1843
1812
|
@click.pass_context
|
1844
|
-
def rds_recommendations(ctx
|
1813
|
+
def rds_recommendations(ctx):
|
1845
1814
|
IGNORED_STATUSES = ("resolved",)
|
1846
1815
|
IGNORED_SEVERITIES = ("informational",)
|
1847
1816
|
|
@@ -1920,7 +1889,7 @@ def rds_recommendations(ctx: click.Context) -> None:
|
|
1920
1889
|
|
1921
1890
|
@get.command()
|
1922
1891
|
@click.pass_context
|
1923
|
-
def products(ctx
|
1892
|
+
def products(ctx):
|
1924
1893
|
products = queries.get_products()
|
1925
1894
|
columns = ["name", "description"]
|
1926
1895
|
print_output(ctx.obj["options"], products, columns)
|
@@ -1929,7 +1898,7 @@ def products(ctx: click.Context) -> None:
|
|
1929
1898
|
@describe.command()
|
1930
1899
|
@click.argument("name")
|
1931
1900
|
@click.pass_context
|
1932
|
-
def product(ctx
|
1901
|
+
def product(ctx, name):
|
1933
1902
|
products = queries.get_products()
|
1934
1903
|
products = [p for p in products if p["name"].lower() == name.lower()]
|
1935
1904
|
if len(products) != 1:
|
@@ -1944,7 +1913,7 @@ def product(ctx: click.Context, name: str) -> None:
|
|
1944
1913
|
|
1945
1914
|
@get.command()
|
1946
1915
|
@click.pass_context
|
1947
|
-
def environments(ctx
|
1916
|
+
def environments(ctx):
|
1948
1917
|
environments = queries.get_environments()
|
1949
1918
|
columns = ["name", "description", "product.name"]
|
1950
1919
|
# TODO(mafriedm): fix this
|
@@ -1956,7 +1925,7 @@ def environments(ctx: click.Context) -> None:
|
|
1956
1925
|
@describe.command()
|
1957
1926
|
@click.argument("name")
|
1958
1927
|
@click.pass_context
|
1959
|
-
def environment(ctx
|
1928
|
+
def environment(ctx, name):
|
1960
1929
|
environments = queries.get_environments()
|
1961
1930
|
environments = [e for e in environments if e["name"].lower() == name.lower()]
|
1962
1931
|
if len(environments) != 1:
|
@@ -1974,7 +1943,7 @@ def environment(ctx: click.Context, name: str) -> None:
|
|
1974
1943
|
|
1975
1944
|
@get.command()
|
1976
1945
|
@click.pass_context
|
1977
|
-
def services(ctx
|
1946
|
+
def services(ctx):
|
1978
1947
|
apps = queries.get_apps()
|
1979
1948
|
columns = ["name", "path", "onboardingStatus"]
|
1980
1949
|
print_output(ctx.obj["options"], apps, columns)
|
@@ -1982,15 +1951,17 @@ def services(ctx: click.Context) -> None:
|
|
1982
1951
|
|
1983
1952
|
@get.command()
|
1984
1953
|
@click.pass_context
|
1985
|
-
def repos(ctx
|
1954
|
+
def repos(ctx):
|
1986
1955
|
repos = queries.get_repos()
|
1987
|
-
|
1956
|
+
repos = [{"url": r} for r in repos]
|
1957
|
+
columns = ["url"]
|
1958
|
+
print_output(ctx.obj["options"], repos, columns)
|
1988
1959
|
|
1989
1960
|
|
1990
1961
|
@get.command()
|
1991
1962
|
@click.argument("org_username")
|
1992
1963
|
@click.pass_context
|
1993
|
-
def roles(ctx
|
1964
|
+
def roles(ctx, org_username):
|
1994
1965
|
users = queries.get_roles()
|
1995
1966
|
users = [u for u in users if u["org_username"] == org_username]
|
1996
1967
|
|
@@ -2001,7 +1972,7 @@ def roles(ctx: click.Context, org_username: str) -> None:
|
|
2001
1972
|
user = users[0]
|
2002
1973
|
|
2003
1974
|
# type, name, resource, [ref]
|
2004
|
-
roles: dict[
|
1975
|
+
roles: dict[(str, str, str), set] = defaultdict(set)
|
2005
1976
|
|
2006
1977
|
for role in user["roles"]:
|
2007
1978
|
role_name = role["path"]
|
@@ -2055,7 +2026,7 @@ def roles(ctx: click.Context, org_username: str) -> None:
|
|
2055
2026
|
@get.command()
|
2056
2027
|
@click.argument("org_username", default="")
|
2057
2028
|
@click.pass_context
|
2058
|
-
def users(ctx
|
2029
|
+
def users(ctx, org_username):
|
2059
2030
|
users = queries.get_users()
|
2060
2031
|
if org_username:
|
2061
2032
|
users = [u for u in users if u["org_username"] == org_username]
|
@@ -2066,7 +2037,7 @@ def users(ctx: click.Context, org_username: str) -> None:
|
|
2066
2037
|
|
2067
2038
|
@get.command()
|
2068
2039
|
@click.pass_context
|
2069
|
-
def integrations(ctx
|
2040
|
+
def integrations(ctx):
|
2070
2041
|
environments = queries.get_integrations()
|
2071
2042
|
columns = ["name", "description"]
|
2072
2043
|
print_output(ctx.obj["options"], environments, columns)
|
@@ -2074,7 +2045,7 @@ def integrations(ctx: click.Context) -> None:
|
|
2074
2045
|
|
2075
2046
|
@get.command()
|
2076
2047
|
@click.pass_context
|
2077
|
-
def quay_mirrors(ctx
|
2048
|
+
def quay_mirrors(ctx):
|
2078
2049
|
apps = queries.get_quay_repos()
|
2079
2050
|
|
2080
2051
|
mirrors = []
|
@@ -2112,9 +2083,7 @@ def quay_mirrors(ctx: click.Context) -> None:
|
|
2112
2083
|
@click.argument("kind")
|
2113
2084
|
@click.argument("name")
|
2114
2085
|
@click.pass_context
|
2115
|
-
def root_owner(
|
2116
|
-
ctx: click.Context, cluster: str, namespace: str, kind: str, name: str
|
2117
|
-
) -> None:
|
2086
|
+
def root_owner(ctx, cluster, namespace, kind, name):
|
2118
2087
|
settings = queries.get_app_interface_settings()
|
2119
2088
|
clusters = [c for c in queries.get_clusters(minimal=True) if c["name"] == cluster]
|
2120
2089
|
oc_map = OC_Map(
|
@@ -2144,9 +2113,7 @@ def root_owner(
|
|
2144
2113
|
@click.argument("aws_account")
|
2145
2114
|
@click.argument("identifier")
|
2146
2115
|
@click.pass_context
|
2147
|
-
def service_owners_for_rds_instance(
|
2148
|
-
ctx: click.Context, aws_account: str, identifier: str
|
2149
|
-
) -> None:
|
2116
|
+
def service_owners_for_rds_instance(ctx, aws_account, identifier):
|
2150
2117
|
namespaces = queries.get_namespaces()
|
2151
2118
|
service_owners = []
|
2152
2119
|
for namespace_info in namespaces:
|
@@ -2168,7 +2135,7 @@ def service_owners_for_rds_instance(
|
|
2168
2135
|
|
2169
2136
|
@get.command()
|
2170
2137
|
@click.pass_context
|
2171
|
-
def sre_checkpoints(ctx
|
2138
|
+
def sre_checkpoints(ctx):
|
2172
2139
|
apps = queries.get_apps()
|
2173
2140
|
|
2174
2141
|
parent_apps = {app["parentApp"]["path"] for app in apps if app.get("parentApp")}
|
@@ -2192,14 +2159,13 @@ def sre_checkpoints(ctx: click.Context) -> None:
|
|
2192
2159
|
|
2193
2160
|
@get.command()
|
2194
2161
|
@click.pass_context
|
2195
|
-
def app_interface_merge_queue(ctx
|
2162
|
+
def app_interface_merge_queue(ctx):
|
2196
2163
|
import reconcile.gitlab_housekeeping as glhk
|
2197
2164
|
|
2198
2165
|
settings = queries.get_app_interface_settings()
|
2199
2166
|
instance = queries.get_gitlab_instance()
|
2200
2167
|
gl = GitLabApi(instance, project_url=settings["repoUrl"], settings=settings)
|
2201
|
-
|
2202
|
-
merge_requests = glhk.get_merge_requests(True, gl, state=state)
|
2168
|
+
merge_requests = glhk.get_merge_requests(True, gl, state=None)
|
2203
2169
|
|
2204
2170
|
columns = [
|
2205
2171
|
"id",
|
@@ -2234,7 +2200,7 @@ def app_interface_merge_queue(ctx: click.Context) -> None:
|
|
2234
2200
|
|
2235
2201
|
@get.command()
|
2236
2202
|
@click.pass_context
|
2237
|
-
def app_interface_review_queue(ctx
|
2203
|
+
def app_interface_review_queue(ctx) -> None:
|
2238
2204
|
import reconcile.gitlab_housekeeping as glhk
|
2239
2205
|
|
2240
2206
|
settings = queries.get_app_interface_settings()
|
@@ -2251,7 +2217,7 @@ def app_interface_review_queue(ctx: click.Context) -> None:
|
|
2251
2217
|
"labels",
|
2252
2218
|
]
|
2253
2219
|
|
2254
|
-
def get_mrs(repo
|
2220
|
+
def get_mrs(repo, url) -> list[dict[str, str]]:
|
2255
2221
|
gl = GitLabApi(instance, project_url=url, settings=settings)
|
2256
2222
|
merge_requests = gl.get_merge_requests(state=MRState.OPENED)
|
2257
2223
|
try:
|
@@ -2346,7 +2312,7 @@ def app_interface_review_queue(ctx: click.Context) -> None:
|
|
2346
2312
|
|
2347
2313
|
@get.command()
|
2348
2314
|
@click.pass_context
|
2349
|
-
def app_interface_open_selfserviceable_mr_queue(ctx
|
2315
|
+
def app_interface_open_selfserviceable_mr_queue(ctx):
|
2350
2316
|
settings = queries.get_app_interface_settings()
|
2351
2317
|
instance = queries.get_gitlab_instance()
|
2352
2318
|
gl = GitLabApi(instance, project_url=settings["repoUrl"], settings=settings)
|
@@ -2409,7 +2375,7 @@ def app_interface_open_selfserviceable_mr_queue(ctx: click.Context) -> None:
|
|
2409
2375
|
|
2410
2376
|
@get.command()
|
2411
2377
|
@click.pass_context
|
2412
|
-
def change_types(ctx
|
2378
|
+
def change_types(ctx) -> None:
|
2413
2379
|
"""List all change types."""
|
2414
2380
|
change_types = fetch_change_type_processors(gql.get_api(), NoOpFileDiffResolver())
|
2415
2381
|
|
@@ -2434,7 +2400,7 @@ def change_types(ctx: click.Context) -> None:
|
|
2434
2400
|
|
2435
2401
|
@get.command()
|
2436
2402
|
@click.pass_context
|
2437
|
-
def app_interface_merge_history(ctx
|
2403
|
+
def app_interface_merge_history(ctx):
|
2438
2404
|
settings = queries.get_app_interface_settings()
|
2439
2405
|
instance = queries.get_gitlab_instance()
|
2440
2406
|
gl = GitLabApi(instance, project_url=settings["repoUrl"], settings=settings)
|
@@ -2471,7 +2437,7 @@ def app_interface_merge_history(ctx: click.Context) -> None:
|
|
2471
2437
|
)
|
2472
2438
|
@use_jump_host()
|
2473
2439
|
@click.pass_context
|
2474
|
-
def selectorsyncset_managed_resources(ctx
|
2440
|
+
def selectorsyncset_managed_resources(ctx, use_jump_host):
|
2475
2441
|
vault_settings = get_app_interface_vault_settings()
|
2476
2442
|
secret_reader = create_secret_reader(use_vault=vault_settings.vault)
|
2477
2443
|
clusters = get_clusters()
|
@@ -2529,9 +2495,7 @@ def selectorsyncset_managed_resources(ctx: click.Context, use_jump_host: bool) -
|
|
2529
2495
|
)
|
2530
2496
|
@use_jump_host()
|
2531
2497
|
@click.pass_context
|
2532
|
-
def selectorsyncset_managed_hypershift_resources(
|
2533
|
-
ctx: click.Context, use_jump_host: bool
|
2534
|
-
) -> None:
|
2498
|
+
def selectorsyncset_managed_hypershift_resources(ctx, use_jump_host):
|
2535
2499
|
vault_settings = get_app_interface_vault_settings()
|
2536
2500
|
secret_reader = create_secret_reader(use_vault=vault_settings.vault)
|
2537
2501
|
clusters = get_clusters()
|
@@ -2609,12 +2573,7 @@ def selectorsyncset_managed_hypershift_resources(
|
|
2609
2573
|
default=os.environ.get("QONTRACT_CLI_EC2_JENKINS_WORKER_AWS_REGION", "us-east-1"),
|
2610
2574
|
)
|
2611
2575
|
@click.pass_context
|
2612
|
-
def ec2_jenkins_workers(
|
2613
|
-
ctx: click.Context,
|
2614
|
-
aws_access_key_id: str,
|
2615
|
-
aws_secret_access_key: str,
|
2616
|
-
aws_region: str,
|
2617
|
-
) -> None:
|
2576
|
+
def ec2_jenkins_workers(ctx, aws_access_key_id, aws_secret_access_key, aws_region):
|
2618
2577
|
"""Prints a list of jenkins workers and their status."""
|
2619
2578
|
if not aws_access_key_id or not aws_secret_access_key:
|
2620
2579
|
raise click.ClickException(
|
@@ -2661,9 +2620,9 @@ def ec2_jenkins_workers(
|
|
2661
2620
|
url = ""
|
2662
2621
|
for t in instance.tags:
|
2663
2622
|
if t.get("Key") == "os":
|
2664
|
-
os = t
|
2623
|
+
os = t.get("Value")
|
2665
2624
|
if t.get("Key") == "jenkins_controller":
|
2666
|
-
url = f"https://{t
|
2625
|
+
url = f"https://{t.get('Value').replace('-', '.')}.devshift.net/computer/{instance.id}"
|
2667
2626
|
image = ec2.Image(instance.image_id)
|
2668
2627
|
commit_url = ""
|
2669
2628
|
for t in image.tags:
|
@@ -2690,7 +2649,7 @@ def ec2_jenkins_workers(
|
|
2690
2649
|
@get.command()
|
2691
2650
|
@click.argument("status-board-instance")
|
2692
2651
|
@click.pass_context
|
2693
|
-
def slo_document_services(ctx
|
2652
|
+
def slo_document_services(ctx, status_board_instance):
|
2694
2653
|
"""Print SLO Documents Services"""
|
2695
2654
|
columns = [
|
2696
2655
|
"slo_doc_name",
|
@@ -2719,7 +2678,7 @@ def slo_document_services(ctx: click.Context, status_board_instance: str) -> Non
|
|
2719
2678
|
slodocs = []
|
2720
2679
|
for slodoc in get_slo_documents():
|
2721
2680
|
products = [ns.namespace.environment.product.name for ns in slodoc.namespaces]
|
2722
|
-
for slo in slodoc.slos
|
2681
|
+
for slo in slodoc.slos:
|
2723
2682
|
for product in products:
|
2724
2683
|
if slodoc.app.parent_app:
|
2725
2684
|
app = f"{slodoc.app.parent_app.name}-{slodoc.app.name}"
|
@@ -2745,7 +2704,7 @@ def slo_document_services(ctx: click.Context, status_board_instance: str) -> Non
|
|
2745
2704
|
"target_unit": slo.slo_target_unit,
|
2746
2705
|
"window": slo.slo_parameters.window,
|
2747
2706
|
"statusBoardService": f"{product}/{slodoc.app.name}/{slo.name}",
|
2748
|
-
"statusBoardEnabled": "statusBoard" in
|
2707
|
+
"statusBoardEnabled": "statusBoard" in slodoc.labels,
|
2749
2708
|
}
|
2750
2709
|
slodocs.append(item)
|
2751
2710
|
|
@@ -2755,7 +2714,7 @@ def slo_document_services(ctx: click.Context, status_board_instance: str) -> Non
|
|
2755
2714
|
@get.command()
|
2756
2715
|
@click.argument("file_path")
|
2757
2716
|
@click.pass_context
|
2758
|
-
def alerts(ctx
|
2717
|
+
def alerts(ctx, file_path):
|
2759
2718
|
BIG_NUMBER = 10
|
2760
2719
|
|
2761
2720
|
def sort_by_threshold(item: dict[str, str]) -> int:
|
@@ -2829,7 +2788,7 @@ def alerts(ctx: click.Context, file_path: str) -> None:
|
|
2829
2788
|
@get.command()
|
2830
2789
|
@click.pass_context
|
2831
2790
|
@thread_pool_size(default=5)
|
2832
|
-
def aws_cost_report(ctx
|
2791
|
+
def aws_cost_report(ctx, thread_pool_size):
|
2833
2792
|
command = AwsCostReportCommand.create(thread_pool_size=thread_pool_size)
|
2834
2793
|
print(command.execute())
|
2835
2794
|
|
@@ -2837,7 +2796,7 @@ def aws_cost_report(ctx: click.Context, thread_pool_size: int) -> None:
|
|
2837
2796
|
@get.command()
|
2838
2797
|
@click.pass_context
|
2839
2798
|
@thread_pool_size(default=5)
|
2840
|
-
def openshift_cost_report(ctx
|
2799
|
+
def openshift_cost_report(ctx, thread_pool_size):
|
2841
2800
|
command = OpenShiftCostReportCommand.create(thread_pool_size=thread_pool_size)
|
2842
2801
|
print(command.execute())
|
2843
2802
|
|
@@ -2845,9 +2804,7 @@ def openshift_cost_report(ctx: click.Context, thread_pool_size: int) -> None:
|
|
2845
2804
|
@get.command()
|
2846
2805
|
@click.pass_context
|
2847
2806
|
@thread_pool_size(default=5)
|
2848
|
-
def openshift_cost_optimization_report(
|
2849
|
-
ctx: click.Context, thread_pool_size: int
|
2850
|
-
) -> None:
|
2807
|
+
def openshift_cost_optimization_report(ctx, thread_pool_size):
|
2851
2808
|
command = OpenShiftCostOptimizationReportCommand.create(
|
2852
2809
|
thread_pool_size=thread_pool_size
|
2853
2810
|
)
|
@@ -2856,7 +2813,7 @@ def openshift_cost_optimization_report(
|
|
2856
2813
|
|
2857
2814
|
@get.command()
|
2858
2815
|
@click.pass_context
|
2859
|
-
def osd_component_versions(ctx
|
2816
|
+
def osd_component_versions(ctx):
|
2860
2817
|
osd_environments = [
|
2861
2818
|
e["name"] for e in queries.get_environments() if e["product"]["name"] == "OSDv4"
|
2862
2819
|
]
|
@@ -2892,7 +2849,7 @@ def osd_component_versions(ctx: click.Context) -> None:
|
|
2892
2849
|
|
2893
2850
|
@get.command()
|
2894
2851
|
@click.pass_context
|
2895
|
-
def maintenances(ctx
|
2852
|
+
def maintenances(ctx):
|
2896
2853
|
now = datetime.now(UTC)
|
2897
2854
|
maintenances = maintenances_gql.query(gql.get_api().query).maintenances or []
|
2898
2855
|
data = [
|
@@ -2955,7 +2912,7 @@ class MigrationStatusCount:
|
|
2955
2912
|
|
2956
2913
|
@get.command()
|
2957
2914
|
@click.pass_context
|
2958
|
-
def hcp_migration_status(ctx
|
2915
|
+
def hcp_migration_status(ctx):
|
2959
2916
|
counts: dict[str, MigrationStatusCount] = {}
|
2960
2917
|
total_count = MigrationStatusCount("total")
|
2961
2918
|
saas_files = get_saas_files()
|
@@ -2994,7 +2951,7 @@ def hcp_migration_status(ctx: click.Context) -> None:
|
|
2994
2951
|
|
2995
2952
|
@get.command()
|
2996
2953
|
@click.pass_context
|
2997
|
-
def systems_and_tools(ctx
|
2954
|
+
def systems_and_tools(ctx):
|
2998
2955
|
print(
|
2999
2956
|
f"This report is obtained from app-interface Graphql endpoint available at: {config.get_config()['graphql']['server']}"
|
3000
2957
|
)
|
@@ -3008,7 +2965,7 @@ def systems_and_tools(ctx: click.Context) -> None:
|
|
3008
2965
|
"--environment_name", default="production", help="environment to get logs from"
|
3009
2966
|
)
|
3010
2967
|
@click.pass_context
|
3011
|
-
def logs(ctx
|
2968
|
+
def logs(ctx, integration_name: str, environment_name: str):
|
3012
2969
|
integrations = [
|
3013
2970
|
i
|
3014
2971
|
for i in integrations_gql.query(query_func=gql.get_api().query).integrations
|
@@ -3047,7 +3004,7 @@ def logs(ctx: click.Context, integration_name: str, environment_name: str) -> No
|
|
3047
3004
|
|
3048
3005
|
@get.command
|
3049
3006
|
@click.pass_context
|
3050
|
-
def jenkins_jobs(ctx
|
3007
|
+
def jenkins_jobs(ctx):
|
3051
3008
|
jenkins_configs = queries.get_jenkins_configs()
|
3052
3009
|
|
3053
3010
|
# stats dicts
|
@@ -3117,9 +3074,9 @@ You can view the source of this Markdown to extract the JSON data.
|
|
3117
3074
|
|
3118
3075
|
@get.command
|
3119
3076
|
@click.pass_context
|
3120
|
-
def container_image_details(ctx
|
3077
|
+
def container_image_details(ctx):
|
3121
3078
|
apps = get_apps_quay_repos_escalation_policies()
|
3122
|
-
data: list[dict[str, str
|
3079
|
+
data: list[dict[str, str]] = []
|
3123
3080
|
for app in apps:
|
3124
3081
|
app_name = f"{app.parent_app.name}/{app.name}" if app.parent_app else app.name
|
3125
3082
|
ep_channels = app.escalation_policy.channels
|
@@ -3131,7 +3088,7 @@ def container_image_details(ctx: click.Context) -> None:
|
|
3131
3088
|
if repo.mirror:
|
3132
3089
|
continue
|
3133
3090
|
repository = f"quay.io/{org_name}/{repo.name}"
|
3134
|
-
item
|
3091
|
+
item = {
|
3135
3092
|
"app": app_name,
|
3136
3093
|
"repository": repository,
|
3137
3094
|
"email": email,
|
@@ -3144,25 +3101,27 @@ def container_image_details(ctx: click.Context) -> None:
|
|
3144
3101
|
|
3145
3102
|
@get.command
|
3146
3103
|
@click.pass_context
|
3147
|
-
def change_log_tracking(ctx
|
3104
|
+
def change_log_tracking(ctx):
|
3148
3105
|
repo_url = get_app_interface_repo_url()
|
3149
3106
|
change_types = fetch_change_type_processors(gql.get_api(), NoOpFileDiffResolver())
|
3150
3107
|
state = init_state(integration=cl.QONTRACT_INTEGRATION)
|
3151
3108
|
change_log = ChangeLog(**state.get(BUNDLE_DIFFS_OBJ))
|
3152
3109
|
data: list[dict[str, str]] = []
|
3153
|
-
for
|
3110
|
+
for item in change_log.items:
|
3111
|
+
change_log_item = ChangeLogItem(**item)
|
3154
3112
|
commit = change_log_item.commit
|
3155
3113
|
covered_change_types_descriptions = [
|
3156
3114
|
ct.description
|
3157
3115
|
for ct in change_types
|
3158
3116
|
if ct.name in change_log_item.change_types
|
3159
3117
|
]
|
3160
|
-
|
3118
|
+
item = {
|
3161
3119
|
"commit": f"[{commit[:7]}]({repo_url}/commit/{commit})",
|
3162
3120
|
"merged_at": change_log_item.merged_at,
|
3163
3121
|
"apps": ", ".join(change_log_item.apps),
|
3164
3122
|
"changes": ", ".join(covered_change_types_descriptions),
|
3165
|
-
}
|
3123
|
+
}
|
3124
|
+
data.append(item)
|
3166
3125
|
|
3167
3126
|
# TODO(mafriedm): Fix this
|
3168
3127
|
ctx.obj["options"]["sort"] = False
|
@@ -3173,7 +3132,7 @@ def change_log_tracking(ctx: click.Context) -> None:
|
|
3173
3132
|
@root.group(name="set")
|
3174
3133
|
@output
|
3175
3134
|
@click.pass_context
|
3176
|
-
def set_command(ctx
|
3135
|
+
def set_command(ctx, output):
|
3177
3136
|
ctx.obj["output"] = output
|
3178
3137
|
|
3179
3138
|
|
@@ -3182,9 +3141,7 @@ def set_command(ctx: click.Context, output: str) -> None:
|
|
3182
3141
|
@click.argument("usergroup")
|
3183
3142
|
@click.argument("username")
|
3184
3143
|
@click.pass_context
|
3185
|
-
def slack_usergroup(
|
3186
|
-
ctx: click.Context, workspace: str, usergroup: str, username: str
|
3187
|
-
) -> None:
|
3144
|
+
def slack_usergroup(ctx, workspace, usergroup, username):
|
3188
3145
|
"""Update users in a slack usergroup.
|
3189
3146
|
Use an org_username as the username.
|
3190
3147
|
To empty a slack usergroup, pass '' (empty string) as the username.
|
@@ -3192,8 +3149,6 @@ def slack_usergroup(
|
|
3192
3149
|
settings = queries.get_app_interface_settings()
|
3193
3150
|
slack = slackapi_from_queries("qontract-cli")
|
3194
3151
|
ugid = slack.get_usergroup_id(usergroup)
|
3195
|
-
if not ugid:
|
3196
|
-
raise click.ClickException(f"Usergroup {usergroup} not found.")
|
3197
3152
|
if username:
|
3198
3153
|
mail_address = settings["smtp"]["mailAddress"]
|
3199
3154
|
users = [slack.get_user_id_by_name(username, mail_address)]
|
@@ -3202,17 +3157,33 @@ def slack_usergroup(
|
|
3202
3157
|
slack.update_usergroup_users(ugid, users)
|
3203
3158
|
|
3204
3159
|
|
3160
|
+
@set_command.command()
|
3161
|
+
@click.argument("org_name")
|
3162
|
+
@click.argument("cluster_name")
|
3163
|
+
@click.pass_context
|
3164
|
+
def cluster_admin(ctx, org_name, cluster_name):
|
3165
|
+
settings = queries.get_app_interface_settings()
|
3166
|
+
ocms = [
|
3167
|
+
o for o in queries.get_openshift_cluster_managers() if o["name"] == org_name
|
3168
|
+
]
|
3169
|
+
ocm_map = OCMMap(ocms=ocms, settings=settings)
|
3170
|
+
ocm = ocm_map[org_name]
|
3171
|
+
enabled = ocm.is_cluster_admin_enabled(cluster_name)
|
3172
|
+
if not enabled:
|
3173
|
+
ocm.enable_cluster_admin(cluster_name)
|
3174
|
+
|
3175
|
+
|
3205
3176
|
@root.group()
|
3206
3177
|
@environ(["APP_INTERFACE_STATE_BUCKET"])
|
3207
3178
|
@click.pass_context
|
3208
|
-
def state(ctx
|
3179
|
+
def state(ctx):
|
3209
3180
|
pass
|
3210
3181
|
|
3211
3182
|
|
3212
3183
|
@state.command()
|
3213
3184
|
@click.argument("integration", default="")
|
3214
3185
|
@click.pass_context
|
3215
|
-
def ls(ctx
|
3186
|
+
def ls(ctx, integration):
|
3216
3187
|
state = init_state(integration=integration)
|
3217
3188
|
keys = state.ls()
|
3218
3189
|
# if integration in not defined the 2th token will be the integration name
|
@@ -3233,7 +3204,7 @@ def ls(ctx: click.Context, integration: str) -> None:
|
|
3233
3204
|
@click.argument("integration")
|
3234
3205
|
@click.argument("key")
|
3235
3206
|
@click.pass_context
|
3236
|
-
def state_get(ctx
|
3207
|
+
def state_get(ctx, integration, key):
|
3237
3208
|
state = init_state(integration=integration)
|
3238
3209
|
value = state.get(key)
|
3239
3210
|
print(value)
|
@@ -3243,7 +3214,7 @@ def state_get(ctx: click.Context, integration: str, key: str) -> None:
|
|
3243
3214
|
@click.argument("integration")
|
3244
3215
|
@click.argument("key")
|
3245
3216
|
@click.pass_context
|
3246
|
-
def add(ctx
|
3217
|
+
def add(ctx, integration, key):
|
3247
3218
|
state = init_state(integration=integration)
|
3248
3219
|
state.add(key)
|
3249
3220
|
|
@@ -3253,7 +3224,7 @@ def add(ctx: click.Context, integration: str, key: str) -> None:
|
|
3253
3224
|
@click.argument("key")
|
3254
3225
|
@click.argument("value")
|
3255
3226
|
@click.pass_context
|
3256
|
-
def state_set(ctx
|
3227
|
+
def state_set(ctx, integration, key, value):
|
3257
3228
|
state = init_state(integration=integration)
|
3258
3229
|
state.add(key, value=value, force=True)
|
3259
3230
|
|
@@ -3262,7 +3233,7 @@ def state_set(ctx: click.Context, integration: str, key: str, value: str) -> Non
|
|
3262
3233
|
@click.argument("integration")
|
3263
3234
|
@click.argument("key")
|
3264
3235
|
@click.pass_context
|
3265
|
-
def rm(ctx
|
3236
|
+
def rm(ctx, integration, key):
|
3266
3237
|
state = init_state(integration=integration)
|
3267
3238
|
state.rm(key)
|
3268
3239
|
|
@@ -3270,7 +3241,7 @@ def rm(ctx: click.Context, integration: str, key: str) -> None:
|
|
3270
3241
|
@root.group()
|
3271
3242
|
@environ(["APP_INTERFACE_STATE_BUCKET"])
|
3272
3243
|
@click.pass_context
|
3273
|
-
def early_exit_cache(ctx
|
3244
|
+
def early_exit_cache(ctx):
|
3274
3245
|
pass
|
3275
3246
|
|
3276
3247
|
|
@@ -3306,13 +3277,13 @@ def early_exit_cache(ctx: click.Context) -> None:
|
|
3306
3277
|
)
|
3307
3278
|
@click.pass_context
|
3308
3279
|
def early_exit_cache_head(
|
3309
|
-
ctx
|
3310
|
-
integration
|
3311
|
-
integration_version
|
3312
|
-
dry_run
|
3313
|
-
cache_source
|
3314
|
-
shard
|
3315
|
-
)
|
3280
|
+
ctx,
|
3281
|
+
integration,
|
3282
|
+
integration_version,
|
3283
|
+
dry_run,
|
3284
|
+
cache_source,
|
3285
|
+
shard,
|
3286
|
+
):
|
3316
3287
|
with EarlyExitCache.build() as cache:
|
3317
3288
|
cache_key = CacheKey(
|
3318
3289
|
integration=integration,
|
@@ -3358,13 +3329,13 @@ def early_exit_cache_head(
|
|
3358
3329
|
)
|
3359
3330
|
@click.pass_context
|
3360
3331
|
def early_exit_cache_get(
|
3361
|
-
ctx
|
3362
|
-
integration
|
3363
|
-
integration_version
|
3364
|
-
dry_run
|
3365
|
-
cache_source
|
3366
|
-
shard
|
3367
|
-
)
|
3332
|
+
ctx,
|
3333
|
+
integration,
|
3334
|
+
integration_version,
|
3335
|
+
dry_run,
|
3336
|
+
cache_source,
|
3337
|
+
shard,
|
3338
|
+
):
|
3368
3339
|
with EarlyExitCache.build() as cache:
|
3369
3340
|
cache_key = CacheKey(
|
3370
3341
|
integration=integration,
|
@@ -3441,18 +3412,18 @@ def early_exit_cache_get(
|
|
3441
3412
|
)
|
3442
3413
|
@click.pass_context
|
3443
3414
|
def early_exit_cache_set(
|
3444
|
-
ctx
|
3445
|
-
integration
|
3446
|
-
integration_version
|
3447
|
-
dry_run
|
3448
|
-
cache_source
|
3449
|
-
shard
|
3450
|
-
payload
|
3451
|
-
log_output
|
3452
|
-
applied_count
|
3453
|
-
ttl
|
3454
|
-
latest_cache_source_digest
|
3455
|
-
)
|
3415
|
+
ctx,
|
3416
|
+
integration,
|
3417
|
+
integration_version,
|
3418
|
+
dry_run,
|
3419
|
+
cache_source,
|
3420
|
+
shard,
|
3421
|
+
payload,
|
3422
|
+
log_output,
|
3423
|
+
applied_count,
|
3424
|
+
ttl,
|
3425
|
+
latest_cache_source_digest,
|
3426
|
+
):
|
3456
3427
|
with EarlyExitCache.build() as cache:
|
3457
3428
|
cache_key = CacheKey(
|
3458
3429
|
integration=integration,
|
@@ -3501,13 +3472,13 @@ def early_exit_cache_set(
|
|
3501
3472
|
)
|
3502
3473
|
@click.pass_context
|
3503
3474
|
def early_exit_cache_delete(
|
3504
|
-
ctx
|
3505
|
-
integration
|
3506
|
-
integration_version
|
3507
|
-
dry_run
|
3508
|
-
cache_source_digest
|
3509
|
-
shard
|
3510
|
-
)
|
3475
|
+
ctx,
|
3476
|
+
integration,
|
3477
|
+
integration_version,
|
3478
|
+
dry_run,
|
3479
|
+
cache_source_digest,
|
3480
|
+
shard,
|
3481
|
+
):
|
3511
3482
|
with EarlyExitCache.build() as cache:
|
3512
3483
|
cache_key_with_digest = CacheKeyWithDigest(
|
3513
3484
|
integration=integration,
|
@@ -3538,33 +3509,25 @@ def early_exit_cache_delete(
|
|
3538
3509
|
type=click.Choice(["config", "vault"]),
|
3539
3510
|
)
|
3540
3511
|
@click.pass_context
|
3541
|
-
def template(
|
3542
|
-
ctx: click.Context,
|
3543
|
-
cluster: str,
|
3544
|
-
namespace: str,
|
3545
|
-
kind: str,
|
3546
|
-
name: str,
|
3547
|
-
path: str,
|
3548
|
-
secret_reader: str,
|
3549
|
-
) -> None:
|
3512
|
+
def template(ctx, cluster, namespace, kind, name, path, secret_reader):
|
3550
3513
|
gqlapi = gql.get_api()
|
3551
3514
|
namespaces = gqlapi.query(orb.NAMESPACES_QUERY)["namespaces"]
|
3552
|
-
|
3515
|
+
namespace_info = [
|
3553
3516
|
n
|
3554
3517
|
for n in namespaces
|
3555
3518
|
if n["cluster"]["name"] == cluster and n["name"] == namespace
|
3556
3519
|
]
|
3557
|
-
if len(
|
3520
|
+
if len(namespace_info) != 1:
|
3558
3521
|
print(f"{cluster}/{namespace} error")
|
3559
3522
|
sys.exit(1)
|
3560
3523
|
|
3561
|
-
namespace_info = namespaces_info[0]
|
3562
3524
|
settings = queries.get_app_interface_settings()
|
3563
3525
|
settings["vault"] = secret_reader == "vault"
|
3564
3526
|
|
3565
3527
|
if path and path.startswith("resources"):
|
3566
3528
|
path = path.replace("resources", "", 1)
|
3567
3529
|
|
3530
|
+
[namespace_info] = namespace_info
|
3568
3531
|
ob.aggregate_shared_resources(namespace_info, "openshiftResources")
|
3569
3532
|
openshift_resources = namespace_info.get("openshiftResources")
|
3570
3533
|
for r in openshift_resources:
|
@@ -3605,9 +3568,7 @@ def template(
|
|
3605
3568
|
type=click.Choice(["config", "vault"]),
|
3606
3569
|
)
|
3607
3570
|
@click.pass_context
|
3608
|
-
def run_prometheus_test(
|
3609
|
-
ctx: click.Context, path: str, cluster: str, namespace: str, secret_reader: str
|
3610
|
-
) -> None:
|
3571
|
+
def run_prometheus_test(ctx, path, cluster, namespace, secret_reader):
|
3611
3572
|
"""Run prometheus tests for the rule associated with the test in the PATH from given
|
3612
3573
|
CLUSTER/NAMESPACE"""
|
3613
3574
|
|
@@ -3693,17 +3654,17 @@ def run_prometheus_test(
|
|
3693
3654
|
)
|
3694
3655
|
@click.pass_context
|
3695
3656
|
def alert_to_receiver(
|
3696
|
-
ctx
|
3697
|
-
cluster
|
3698
|
-
namespace
|
3699
|
-
rules_path
|
3700
|
-
alert_name
|
3701
|
-
alertmanager_secret_path
|
3702
|
-
alertmanager_namespace
|
3703
|
-
alertmanager_secret_key
|
3704
|
-
secret_reader
|
3705
|
-
additional_label
|
3706
|
-
)
|
3657
|
+
ctx,
|
3658
|
+
cluster,
|
3659
|
+
namespace,
|
3660
|
+
rules_path,
|
3661
|
+
alert_name,
|
3662
|
+
alertmanager_secret_path,
|
3663
|
+
alertmanager_namespace,
|
3664
|
+
alertmanager_secret_key,
|
3665
|
+
secret_reader,
|
3666
|
+
additional_label,
|
3667
|
+
):
|
3707
3668
|
additional_labels = {}
|
3708
3669
|
for al in additional_label:
|
3709
3670
|
try:
|
@@ -3795,12 +3756,12 @@ def alert_to_receiver(
|
|
3795
3756
|
print(f"Cannot find alert {alert_name} in rules {rules_path}")
|
3796
3757
|
sys.exit(1)
|
3797
3758
|
|
3798
|
-
for
|
3799
|
-
result = amtool.config_routes_test(am_config,
|
3759
|
+
for al in alert_labels:
|
3760
|
+
result = amtool.config_routes_test(am_config, al)
|
3800
3761
|
if not result:
|
3801
3762
|
print(f"Error running amtool: {result}")
|
3802
3763
|
sys.exit(1)
|
3803
|
-
print("|".join([
|
3764
|
+
print("|".join([al["alertname"], str(result)]))
|
3804
3765
|
|
3805
3766
|
|
3806
3767
|
@root.command()
|
@@ -3808,12 +3769,7 @@ def alert_to_receiver(
|
|
3808
3769
|
@click.option("--saas-file-name", default=None, help="saas-file to act on.")
|
3809
3770
|
@click.option("--env-name", default=None, help="environment to use for parameters.")
|
3810
3771
|
@click.pass_context
|
3811
|
-
def saas_dev(
|
3812
|
-
ctx: click.Context,
|
3813
|
-
app_name: str | None = None,
|
3814
|
-
saas_file_name: str | None = None,
|
3815
|
-
env_name: str | None = None,
|
3816
|
-
) -> None:
|
3772
|
+
def saas_dev(ctx, app_name=None, saas_file_name=None, env_name=None) -> None:
|
3817
3773
|
if not env_name:
|
3818
3774
|
print("env-name must be defined")
|
3819
3775
|
return
|
@@ -3861,7 +3817,7 @@ def saas_dev(
|
|
3861
3817
|
@click.option("--app-name", default=None, help="app to act on.")
|
3862
3818
|
@click.pass_context
|
3863
3819
|
def saas_targets(
|
3864
|
-
ctx
|
3820
|
+
ctx, saas_file_name: str | None = None, app_name: str | None = None
|
3865
3821
|
) -> None:
|
3866
3822
|
"""Resolve namespaceSelectors and print all resulting targets of a saas file."""
|
3867
3823
|
console = Console()
|
@@ -3925,7 +3881,7 @@ def saas_targets(
|
|
3925
3881
|
default="json",
|
3926
3882
|
type=click.Choice(["json", "yaml"]),
|
3927
3883
|
)
|
3928
|
-
def query(output
|
3884
|
+
def query(output, query):
|
3929
3885
|
"""Run a raw GraphQL query"""
|
3930
3886
|
gqlapi = gql.get_api()
|
3931
3887
|
result = gqlapi.query(query)
|
@@ -3939,7 +3895,7 @@ def query(output: str, query: str) -> None:
|
|
3939
3895
|
@root.command()
|
3940
3896
|
@click.argument("cluster")
|
3941
3897
|
@click.argument("query")
|
3942
|
-
def promquery(cluster
|
3898
|
+
def promquery(cluster, query):
|
3943
3899
|
"""Run a PromQL query"""
|
3944
3900
|
config_data = config.get_config()
|
3945
3901
|
auth = {"path": config_data["promql-auth"]["secret_path"], "field": "token"}
|
@@ -3990,13 +3946,8 @@ def promquery(cluster: str, query: str) -> None:
|
|
3990
3946
|
default=False,
|
3991
3947
|
)
|
3992
3948
|
def sre_checkpoint_metadata(
|
3993
|
-
app_path
|
3994
|
-
|
3995
|
-
jiraboard: str,
|
3996
|
-
jiradef: str,
|
3997
|
-
create_parent_ticket: bool,
|
3998
|
-
dry_run: bool,
|
3999
|
-
) -> None:
|
3949
|
+
app_path, parent_ticket, jiraboard, jiradef, create_parent_ticket, dry_run
|
3950
|
+
):
|
4000
3951
|
"""Check an app path for checkpoint-related metadata."""
|
4001
3952
|
data = queries.get_app_metadata(app_path)
|
4002
3953
|
settings = queries.get_app_interface_settings()
|
@@ -4035,13 +3986,8 @@ def sre_checkpoint_metadata(
|
|
4035
3986
|
required=True,
|
4036
3987
|
)
|
4037
3988
|
def gpg_encrypt(
|
4038
|
-
vault_path
|
4039
|
-
|
4040
|
-
file_path: str,
|
4041
|
-
openshift_path: str,
|
4042
|
-
output: str,
|
4043
|
-
for_user: str,
|
4044
|
-
) -> None:
|
3989
|
+
vault_path, vault_secret_version, file_path, openshift_path, output, for_user
|
3990
|
+
):
|
4045
3991
|
"""
|
4046
3992
|
Encrypt the specified secret (local file, vault or openshift) with a
|
4047
3993
|
given users gpg key. This is intended for easily sharing secrets with
|
@@ -4064,7 +4010,7 @@ def gpg_encrypt(
|
|
4064
4010
|
@click.option("--channel", help="the channel that state is part of")
|
4065
4011
|
@click.option("--sha", help="the commit sha we want state for")
|
4066
4012
|
@environ(["APP_INTERFACE_STATE_BUCKET"])
|
4067
|
-
def get_promotion_state(channel: str, sha: str)
|
4013
|
+
def get_promotion_state(channel: str, sha: str):
|
4068
4014
|
from tools.saas_promotion_state.saas_promotion_state import (
|
4069
4015
|
SaasPromotionState,
|
4070
4016
|
)
|
@@ -4089,7 +4035,7 @@ def get_promotion_state(channel: str, sha: str) -> None:
|
|
4089
4035
|
@click.option("--sha", help="the commit sha we want state for")
|
4090
4036
|
@click.option("--publisher-id", help="the publisher id we want state for")
|
4091
4037
|
@environ(["APP_INTERFACE_STATE_BUCKET"])
|
4092
|
-
def mark_promotion_state_successful(channel: str, sha: str, publisher_id: str)
|
4038
|
+
def mark_promotion_state_successful(channel: str, sha: str, publisher_id: str):
|
4093
4039
|
from tools.saas_promotion_state.saas_promotion_state import (
|
4094
4040
|
SaasPromotionState,
|
4095
4041
|
)
|
@@ -4113,9 +4059,7 @@ def mark_promotion_state_successful(channel: str, sha: str, publisher_id: str) -
|
|
4113
4059
|
help="filesystem path to a local app-interface repo",
|
4114
4060
|
default=os.environ.get("APP_INTERFACE_PATH", None),
|
4115
4061
|
)
|
4116
|
-
def test_change_type(
|
4117
|
-
change_type_name: str, role_name: str, app_interface_path: str
|
4118
|
-
) -> None:
|
4062
|
+
def test_change_type(change_type_name: str, role_name: str, app_interface_path: str):
|
4119
4063
|
from reconcile.change_owners import tester
|
4120
4064
|
|
4121
4065
|
# tester.test_change_type(change_type_name, datafile_path)
|
@@ -4124,7 +4068,7 @@ def test_change_type(
|
|
4124
4068
|
|
4125
4069
|
@root.group()
|
4126
4070
|
@click.pass_context
|
4127
|
-
def sso_client(ctx
|
4071
|
+
def sso_client(ctx):
|
4128
4072
|
"""SSO client commands"""
|
4129
4073
|
|
4130
4074
|
|
@@ -4160,7 +4104,7 @@ def sso_client(ctx: click.Context) -> None:
|
|
4160
4104
|
)
|
4161
4105
|
@click.pass_context
|
4162
4106
|
def create(
|
4163
|
-
ctx
|
4107
|
+
ctx,
|
4164
4108
|
client_name: str,
|
4165
4109
|
contact_email: str,
|
4166
4110
|
keycloak_instance_vault_path: str,
|
@@ -4194,7 +4138,7 @@ def create(
|
|
4194
4138
|
@sso_client.command()
|
4195
4139
|
@click.argument("sso-client-vault-secret-path", required=True)
|
4196
4140
|
@click.pass_context
|
4197
|
-
def remove(ctx
|
4141
|
+
def remove(ctx, sso_client_vault_secret_path: str):
|
4198
4142
|
"""Remove an existing SSO client"""
|
4199
4143
|
vault_settings = get_app_interface_vault_settings()
|
4200
4144
|
secret_reader = create_secret_reader(use_vault=vault_settings.vault)
|
@@ -4241,12 +4185,8 @@ def remove(ctx: click.Context, sso_client_vault_secret_path: str) -> None:
|
|
4241
4185
|
)
|
4242
4186
|
@click.pass_context
|
4243
4187
|
def external_resources(
|
4244
|
-
ctx:
|
4245
|
-
|
4246
|
-
provisioner: str,
|
4247
|
-
provider: str,
|
4248
|
-
identifier: str,
|
4249
|
-
) -> None:
|
4188
|
+
ctx, provision_provider: str, provisioner: str, provider: str, identifier: str
|
4189
|
+
):
|
4250
4190
|
"""External resources commands"""
|
4251
4191
|
ctx.obj["provision_provider"] = provision_provider
|
4252
4192
|
ctx.obj["provisioner"] = provisioner
|
@@ -4258,7 +4198,7 @@ def external_resources(
|
|
4258
4198
|
|
4259
4199
|
@external_resources.command()
|
4260
4200
|
@click.pass_context
|
4261
|
-
def get_input(ctx
|
4201
|
+
def get_input(ctx):
|
4262
4202
|
"""Gets the input data for an external resource asset. Input data is what is used
|
4263
4203
|
in the Reconciliation Job to manage the resource."""
|
4264
4204
|
erv2cli = Erv2Cli(
|
@@ -4273,7 +4213,7 @@ def get_input(ctx: click.Context) -> None:
|
|
4273
4213
|
|
4274
4214
|
@external_resources.command()
|
4275
4215
|
@click.pass_context
|
4276
|
-
def request_reconciliation(ctx
|
4216
|
+
def request_reconciliation(ctx):
|
4277
4217
|
"""Marks a resource as it needs to get reconciled. The itegration will reconcile the resource at
|
4278
4218
|
its next iteration."""
|
4279
4219
|
erv2cli = Erv2Cli(
|
@@ -4300,7 +4240,7 @@ def request_reconciliation(ctx: click.Context) -> None:
|
|
4300
4240
|
default=False,
|
4301
4241
|
)
|
4302
4242
|
@click.pass_context
|
4303
|
-
def migrate(ctx
|
4243
|
+
def migrate(ctx, dry_run: bool, skip_build: bool) -> None:
|
4304
4244
|
"""Migrate an existing external resource managed by terraform-resources to ERv2.
|
4305
4245
|
|
4306
4246
|
|
@@ -4406,7 +4346,7 @@ def migrate(ctx: click.Context, dry_run: bool, skip_build: bool) -> None:
|
|
4406
4346
|
@external_resources.command()
|
4407
4347
|
@binary(["docker"])
|
4408
4348
|
@click.pass_context
|
4409
|
-
def debug_shell(ctx
|
4349
|
+
def debug_shell(ctx) -> None:
|
4410
4350
|
"""Enter an ERv2 debug shell to manually migrate resources."""
|
4411
4351
|
# use a temporary directory in $HOME. The MacOS colima default configuration allows docker mounts from $HOME.
|
4412
4352
|
with tempfile.TemporaryDirectory(dir=Path.home(), prefix="erv2-debug.") as _tempdir:
|
@@ -4445,7 +4385,7 @@ def debug_shell(ctx: click.Context) -> None:
|
|
4445
4385
|
prompt=True,
|
4446
4386
|
)
|
4447
4387
|
@click.pass_context
|
4448
|
-
def force_unlock(ctx
|
4388
|
+
def force_unlock(ctx, lock_id: str) -> None:
|
4449
4389
|
"""Manually unlock the ERv2 terraform state."""
|
4450
4390
|
# use a temporary directory in $HOME. The MacOS colima default configuration allows docker mounts from $HOME.
|
4451
4391
|
with tempfile.TemporaryDirectory(
|
@@ -4486,14 +4426,14 @@ def force_unlock(ctx: click.Context, lock_id: str) -> None:
|
|
4486
4426
|
@click.option("--include-pattern", help="Only include images that match this pattern")
|
4487
4427
|
@click.pass_context
|
4488
4428
|
def container_images(
|
4489
|
-
ctx
|
4490
|
-
cluster_name
|
4491
|
-
namespace_name
|
4492
|
-
thread_pool_size
|
4493
|
-
use_jump_host
|
4494
|
-
exclude_pattern
|
4495
|
-
include_pattern
|
4496
|
-
)
|
4429
|
+
ctx,
|
4430
|
+
cluster_name,
|
4431
|
+
namespace_name,
|
4432
|
+
thread_pool_size,
|
4433
|
+
use_jump_host,
|
4434
|
+
exclude_pattern,
|
4435
|
+
include_pattern,
|
4436
|
+
):
|
4497
4437
|
from tools.cli_commands.container_images_report import get_all_pods_images
|
4498
4438
|
|
4499
4439
|
results = get_all_pods_images(
|
@@ -4540,7 +4480,7 @@ You can view the source of this Markdown to extract the JSON data.
|
|
4540
4480
|
@get.command(help="Get all app tekton pipelines providers roles and users")
|
4541
4481
|
@click.argument("app-name")
|
4542
4482
|
@click.pass_context
|
4543
|
-
def tekton_roles_and_users(ctx
|
4483
|
+
def tekton_roles_and_users(ctx, app_name):
|
4544
4484
|
pp_namespaces = {
|
4545
4485
|
p.namespace.path
|
4546
4486
|
for p in get_tekton_pipeline_providers()
|
@@ -4567,7 +4507,6 @@ def tekton_roles_and_users(ctx: click.Context, app_name: str) -> None:
|
|
4567
4507
|
if not seen:
|
4568
4508
|
seen = True
|
4569
4509
|
|
4570
|
-
users: str | list[str]
|
4571
4510
|
if ctx.obj["options"]["output"] == "table":
|
4572
4511
|
users = ", ".join([u.org_username for u in r.users])
|
4573
4512
|
else:
|
@@ -4587,7 +4526,7 @@ def tekton_roles_and_users(ctx: click.Context, app_name: str) -> None:
|
|
4587
4526
|
)
|
4588
4527
|
@click.argument("aws-account")
|
4589
4528
|
@click.pass_context
|
4590
|
-
def log_group_usage(ctx
|
4529
|
+
def log_group_usage(ctx, aws_account):
|
4591
4530
|
accounts = queries.get_aws_accounts(name=aws_account)
|
4592
4531
|
if not accounts:
|
4593
4532
|
print("no aws account found with that name")
|
@@ -4597,7 +4536,7 @@ def log_group_usage(ctx: click.Context, aws_account: str) -> None:
|
|
4597
4536
|
settings = queries.get_app_interface_settings()
|
4598
4537
|
secret_reader = SecretReader(settings=settings)
|
4599
4538
|
columns = ["log_group", "stored_bytes", "retention_days"]
|
4600
|
-
results
|
4539
|
+
results = []
|
4601
4540
|
|
4602
4541
|
with AWSApi(1, [account], settings, secret_reader) as aws:
|
4603
4542
|
session = aws.get_session(account["name"])
|