qontract-reconcile 0.10.1rc1181__py3-none-any.whl → 0.10.1rc1182__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.1rc1181.dist-info → qontract_reconcile-0.10.1rc1182.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc1181.dist-info → qontract_reconcile-0.10.1rc1182.dist-info}/RECORD +8 -6
- tools/cli_commands/container_images_report.py +129 -0
- tools/qontract_cli.py +71 -1
- tools/test/test_get_container_images.py +187 -0
- {qontract_reconcile-0.10.1rc1181.dist-info → qontract_reconcile-0.10.1rc1182.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc1181.dist-info → qontract_reconcile-0.10.1rc1182.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc1181.dist-info → qontract_reconcile-0.10.1rc1182.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc1181.dist-info → qontract_reconcile-0.10.1rc1182.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.1rc1182
|
4
4
|
Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
|
5
5
|
Home-page: https://github.com/app-sre/qontract-reconcile
|
6
6
|
Author: Red Hat App-SRE Team
|
{qontract_reconcile-0.10.1rc1181.dist-info → qontract_reconcile-0.10.1rc1182.dist-info}/RECORD
RENAMED
@@ -838,10 +838,11 @@ tools/app_interface_metrics_exporter.py,sha256=zkwkxdAUAxjdc-pzx2_oJXG25fo0Fnyd5
|
|
838
838
|
tools/app_interface_reporter.py,sha256=oZPib4HPq0aZ2Zui1QGJGk6qQdfpeihujGDBnSdKyGE,17627
|
839
839
|
tools/glitchtip_access_reporter.py,sha256=oPBnk_YoDuljU3v0FaChzOwwnk4vap1xEE67QEjzdqs,2948
|
840
840
|
tools/glitchtip_access_revalidation.py,sha256=8kbBJk04mkq28kWoRDDkfCGIF3GRg3pJrFAh1sW0dbk,2821
|
841
|
-
tools/qontract_cli.py,sha256=
|
841
|
+
tools/qontract_cli.py,sha256=KfmjfaCuyd8F68oY1hHd2tEf0PY0kLd6t8sWqR81nmc,142498
|
842
842
|
tools/sd_app_sre_alert_report.py,sha256=e9vAdyenUz2f5c8-z-5WY0wv-SJ9aePKDH2r4IwB6pc,5063
|
843
843
|
tools/template_validation.py,sha256=qpKYaTgk0GOPGa2Ct5_5sKdwIHtCAKIBGzsMPuJU5fw,3371
|
844
844
|
tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
845
|
+
tools/cli_commands/container_images_report.py,sha256=PCJIzvUqiYmTdn5xJFcxHocCYp6dprrsJ_lkYdl3ET8,4417
|
845
846
|
tools/cli_commands/erv2.py,sha256=469qdhyaf7thpPQ4hJSurvmxBqYDJsoI8H4AigQIF7U,20737
|
846
847
|
tools/cli_commands/gpg_encrypt.py,sha256=x02JOMn834z89YSNvr5B-oJky7rR1C0begCkPh45eHk,4958
|
847
848
|
tools/cli_commands/systems_and_tools.py,sha256=EMHOF1AtUDaoSk0bbjl6oUKYAz4rTZjIBaF-6E6GspM,16816
|
@@ -876,12 +877,13 @@ tools/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
876
877
|
tools/test/conftest.py,sha256=CsDbu4otrxb7X7kXKKGyV3ZEzu3pCkgjCoCGiHNx6zc,2401
|
877
878
|
tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvftCWEEf-g1mfXOtgCog-g,1271
|
878
879
|
tools/test/test_erv2.py,sha256=EAS7QuJkHisRVO9bMGxm662L5B6i66wF_mT9PAjVzrU,3128
|
880
|
+
tools/test/test_get_container_images.py,sha256=L2XzfmYAd6WZ17UXNnr8Z4iwoGcCvQ0vN6gxAZ7gEws,6097
|
879
881
|
tools/test/test_qontract_cli.py,sha256=iuzKbQ6ahinvjoQmQLBrG4shey0z-1rB6qCgS8T6dgU,5789
|
880
882
|
tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
|
881
883
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
882
884
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
883
|
-
qontract_reconcile-0.10.
|
884
|
-
qontract_reconcile-0.10.
|
885
|
-
qontract_reconcile-0.10.
|
886
|
-
qontract_reconcile-0.10.
|
887
|
-
qontract_reconcile-0.10.
|
885
|
+
qontract_reconcile-0.10.1rc1182.dist-info/METADATA,sha256=gdReu60z2THXeO2P__JA2nYHErSt6uI8EoVgnxsl5ro,2213
|
886
|
+
qontract_reconcile-0.10.1rc1182.dist-info/WHEEL,sha256=bFJAMchF8aTQGUgMZzHJyDDMPTO3ToJ7x23SLJa1SVo,92
|
887
|
+
qontract_reconcile-0.10.1rc1182.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
|
888
|
+
qontract_reconcile-0.10.1rc1182.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
889
|
+
qontract_reconcile-0.10.1rc1182.dist-info/RECORD,,
|
@@ -0,0 +1,129 @@
|
|
1
|
+
import re
|
2
|
+
from collections import defaultdict
|
3
|
+
from collections.abc import Sequence
|
4
|
+
from typing import Any
|
5
|
+
|
6
|
+
from pydantic import BaseModel
|
7
|
+
from sretoolbox.utils import threaded
|
8
|
+
|
9
|
+
from reconcile.gql_definitions.common.namespaces_minimal import NamespaceV1
|
10
|
+
from reconcile.typed_queries.app_interface_vault_settings import (
|
11
|
+
get_app_interface_vault_settings,
|
12
|
+
)
|
13
|
+
from reconcile.typed_queries.namespaces_minimal import get_namespaces_minimal
|
14
|
+
from reconcile.utils.oc_filters import filter_namespaces_by_cluster_and_namespace
|
15
|
+
from reconcile.utils.oc_map import OCMap, init_oc_map_from_namespaces
|
16
|
+
from reconcile.utils.secret_reader import create_secret_reader
|
17
|
+
|
18
|
+
IMAGE_NAME_REGEX = re.compile(r"^(?P<name>[a-zA-Z0-9][a-zA-Z0-9/_.-]+)(?:@sha256)?:.+$")
|
19
|
+
|
20
|
+
|
21
|
+
class NamespaceImages(BaseModel):
|
22
|
+
namespace_name: str
|
23
|
+
image_names: list[str]
|
24
|
+
|
25
|
+
|
26
|
+
def get_all_pods_images(
|
27
|
+
cluster_name: Sequence[str] | None = None,
|
28
|
+
namespace_name: Sequence[str] | None = None,
|
29
|
+
thread_pool_size: int = 10,
|
30
|
+
use_jump_host: bool = True,
|
31
|
+
include_pattern: str | None = None,
|
32
|
+
exclude_pattern: str | None = None,
|
33
|
+
) -> list[dict[str, Any]]:
|
34
|
+
"""Gets all the images in the clusters/namespaces given. Returns a list of dicts
|
35
|
+
with the following keys:
|
36
|
+
* name: image name
|
37
|
+
* namespaces: a comma separated list of namespaces where the instance is used
|
38
|
+
* count: number of uses of the image
|
39
|
+
"""
|
40
|
+
all_namespaces = get_namespaces_minimal()
|
41
|
+
namespaces = filter_namespaces_by_cluster_and_namespace(
|
42
|
+
namespaces=all_namespaces,
|
43
|
+
cluster_names=cluster_name,
|
44
|
+
namespace_names=namespace_name,
|
45
|
+
)
|
46
|
+
vault_settings = get_app_interface_vault_settings()
|
47
|
+
secret_reader = create_secret_reader(use_vault=vault_settings.vault)
|
48
|
+
oc_map = init_oc_map_from_namespaces(
|
49
|
+
namespaces=namespaces,
|
50
|
+
integration="qontract-cli-get-namespace_images",
|
51
|
+
secret_reader=secret_reader,
|
52
|
+
use_jump_host=use_jump_host,
|
53
|
+
thread_pool_size=thread_pool_size,
|
54
|
+
init_projects=True,
|
55
|
+
)
|
56
|
+
|
57
|
+
return fetch_pods_images_from_namespaces(
|
58
|
+
namespaces=namespaces,
|
59
|
+
oc_map=oc_map,
|
60
|
+
exclude_pattern=exclude_pattern,
|
61
|
+
include_pattern=include_pattern,
|
62
|
+
thread_pool_size=thread_pool_size,
|
63
|
+
)
|
64
|
+
|
65
|
+
|
66
|
+
def fetch_pods_images_from_namespaces(
|
67
|
+
namespaces: list[NamespaceV1],
|
68
|
+
oc_map: OCMap,
|
69
|
+
include_pattern: str | None = None,
|
70
|
+
exclude_pattern: str | None = None,
|
71
|
+
thread_pool_size: int = 10,
|
72
|
+
) -> list[dict[str, Any]]:
|
73
|
+
all_namespace_images = threaded.run(
|
74
|
+
func=_get_namespace_images,
|
75
|
+
iterable=namespaces,
|
76
|
+
thread_pool_size=thread_pool_size,
|
77
|
+
oc_map=oc_map,
|
78
|
+
)
|
79
|
+
|
80
|
+
result: defaultdict = defaultdict(_get_all_images_default)
|
81
|
+
for ni in all_namespace_images:
|
82
|
+
for name in ni.image_names:
|
83
|
+
result[name]["namespaces"].add(ni.namespace_name)
|
84
|
+
result[name]["count"] += 1
|
85
|
+
|
86
|
+
exclude_pattern_compiled: re.Pattern | None = None
|
87
|
+
if exclude_pattern:
|
88
|
+
exclude_pattern_compiled = re.compile(exclude_pattern)
|
89
|
+
|
90
|
+
include_pattern_compiled: re.Pattern | None = None
|
91
|
+
if include_pattern:
|
92
|
+
include_pattern_compiled = re.compile(include_pattern)
|
93
|
+
|
94
|
+
result_filtered_flattened: list[dict[str, Any]] = []
|
95
|
+
for name, value in result.items():
|
96
|
+
if include_pattern_compiled and not include_pattern_compiled.match(name):
|
97
|
+
continue
|
98
|
+
if exclude_pattern_compiled and exclude_pattern_compiled.match(name):
|
99
|
+
continue
|
100
|
+
|
101
|
+
result_filtered_flattened.append({
|
102
|
+
"name": name,
|
103
|
+
"namespaces": ",".join(sorted(value["namespaces"])),
|
104
|
+
"count": value["count"],
|
105
|
+
})
|
106
|
+
|
107
|
+
return result_filtered_flattened
|
108
|
+
|
109
|
+
|
110
|
+
def _get_all_images_default() -> dict[str, Any]:
|
111
|
+
return {"namespaces": set(), "count": 0}
|
112
|
+
|
113
|
+
|
114
|
+
def _get_namespace_images(ns: NamespaceV1, oc_map: OCMap) -> NamespaceImages:
|
115
|
+
image_names = []
|
116
|
+
oc = oc_map.get_cluster(ns.cluster.name)
|
117
|
+
pod_items = oc.get_items("Pod", namespace=ns.name)
|
118
|
+
for pod in pod_items:
|
119
|
+
containers = pod.get("spec", {}).get("containers", [])
|
120
|
+
containers.extend(pod.get("spec", {}).get("initContainers", []))
|
121
|
+
|
122
|
+
for c in containers:
|
123
|
+
if m := IMAGE_NAME_REGEX.match(c["image"]):
|
124
|
+
image_names.append(m.group("name"))
|
125
|
+
|
126
|
+
return NamespaceImages(
|
127
|
+
namespace_name=ns.name,
|
128
|
+
image_names=image_names,
|
129
|
+
)
|
tools/qontract_cli.py
CHANGED
@@ -63,9 +63,14 @@ from reconcile.checkpoint import report_invalid_metadata
|
|
63
63
|
from reconcile.cli import (
|
64
64
|
TERRAFORM_VERSION,
|
65
65
|
TERRAFORM_VERSION_REGEX,
|
66
|
+
cluster_name,
|
66
67
|
config_file,
|
68
|
+
namespace_name,
|
67
69
|
use_jump_host,
|
68
70
|
)
|
71
|
+
from reconcile.cli import (
|
72
|
+
threaded as thread_pool_size,
|
73
|
+
)
|
69
74
|
from reconcile.gql_definitions.advanced_upgrade_service.aus_clusters import (
|
70
75
|
query as aus_clusters_query,
|
71
76
|
)
|
@@ -136,7 +141,9 @@ from reconcile.utils.oc import (
|
|
136
141
|
OC_Map,
|
137
142
|
OCLogMsg,
|
138
143
|
)
|
139
|
-
from reconcile.utils.oc_map import
|
144
|
+
from reconcile.utils.oc_map import (
|
145
|
+
init_oc_map_from_clusters,
|
146
|
+
)
|
140
147
|
from reconcile.utils.ocm import OCM_PRODUCT_ROSA, OCMMap
|
141
148
|
from reconcile.utils.ocm_base_client import init_ocm_base_client
|
142
149
|
from reconcile.utils.output import print_output
|
@@ -4313,5 +4320,68 @@ def migrate(ctx, dry_run: bool, skip_build: bool) -> None:
|
|
4313
4320
|
rich_print(f"[b red]Please remove the temporary directory ({tempdir}) manually!")
|
4314
4321
|
|
4315
4322
|
|
4323
|
+
@get.command(help="Get all container images in app-interface defined namespaces")
|
4324
|
+
@cluster_name
|
4325
|
+
@namespace_name
|
4326
|
+
@thread_pool_size()
|
4327
|
+
@use_jump_host()
|
4328
|
+
@click.option("--exclude-pattern", help="Exclude images that match this pattern")
|
4329
|
+
@click.option("--include-pattern", help="Only include images that match this pattern")
|
4330
|
+
@click.pass_context
|
4331
|
+
def container_images(
|
4332
|
+
ctx,
|
4333
|
+
cluster_name,
|
4334
|
+
namespace_name,
|
4335
|
+
thread_pool_size,
|
4336
|
+
use_jump_host,
|
4337
|
+
exclude_pattern,
|
4338
|
+
include_pattern,
|
4339
|
+
):
|
4340
|
+
from tools.cli_commands.container_images_report import get_all_pods_images
|
4341
|
+
|
4342
|
+
results = get_all_pods_images(
|
4343
|
+
cluster_name=cluster_name,
|
4344
|
+
namespace_name=namespace_name,
|
4345
|
+
thread_pool_size=thread_pool_size,
|
4346
|
+
use_jump_host=use_jump_host,
|
4347
|
+
exclude_pattern=exclude_pattern,
|
4348
|
+
include_pattern=include_pattern,
|
4349
|
+
)
|
4350
|
+
|
4351
|
+
if ctx.obj["options"]["output"] == "md":
|
4352
|
+
json_table = {
|
4353
|
+
"filter": True,
|
4354
|
+
"fields": [
|
4355
|
+
{"key": "name", "sortable": True},
|
4356
|
+
{"key": "namespaces", "sortable": True},
|
4357
|
+
{"key": "count", "sortable": True},
|
4358
|
+
],
|
4359
|
+
"items": results,
|
4360
|
+
}
|
4361
|
+
|
4362
|
+
print(
|
4363
|
+
f"""
|
4364
|
+
You can view the source of this Markdown to extract the JSON data.
|
4365
|
+
|
4366
|
+
{len(results)} container images found.
|
4367
|
+
|
4368
|
+
exclude-pattern = {exclude_pattern}
|
4369
|
+
include-pattern = {include_pattern}
|
4370
|
+
|
4371
|
+
```json:table
|
4372
|
+
{json.dumps(json_table)}
|
4373
|
+
```
|
4374
|
+
"""
|
4375
|
+
)
|
4376
|
+
else:
|
4377
|
+
columns = [
|
4378
|
+
"name",
|
4379
|
+
"namespaces",
|
4380
|
+
"count",
|
4381
|
+
]
|
4382
|
+
ctx.obj["options"]["sort"] = False
|
4383
|
+
print_output(ctx.obj["options"], results, columns)
|
4384
|
+
|
4385
|
+
|
4316
4386
|
if __name__ == "__main__":
|
4317
4387
|
root() # pylint: disable=no-value-for-parameter
|
@@ -0,0 +1,187 @@
|
|
1
|
+
import pytest
|
2
|
+
from pytest_mock import MockerFixture
|
3
|
+
|
4
|
+
from reconcile.gql_definitions.common.namespaces_minimal import ClusterV1, NamespaceV1
|
5
|
+
from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
|
6
|
+
from reconcile.test.fixtures import Fixtures
|
7
|
+
from reconcile.utils.oc import OCNative
|
8
|
+
from reconcile.utils.oc_map import OCMap
|
9
|
+
from tools.cli_commands.container_images_report import (
|
10
|
+
fetch_pods_images_from_namespaces,
|
11
|
+
)
|
12
|
+
|
13
|
+
fxt = Fixtures("container_images_report")
|
14
|
+
|
15
|
+
|
16
|
+
@pytest.fixture
|
17
|
+
def observability_pods() -> list[dict]:
|
18
|
+
return fxt.get_anymarkup("app-sre-observability-stage-pods.yaml")
|
19
|
+
|
20
|
+
|
21
|
+
@pytest.fixture
|
22
|
+
def pipeline_pods() -> list[dict]:
|
23
|
+
return fxt.get_anymarkup("app-sre-pipelines-pods.yaml")
|
24
|
+
|
25
|
+
|
26
|
+
@pytest.fixture
|
27
|
+
def namespaces() -> list[NamespaceV1]:
|
28
|
+
return [
|
29
|
+
NamespaceV1(
|
30
|
+
name="app-sre-observability-stage",
|
31
|
+
delete=None,
|
32
|
+
labels="{}",
|
33
|
+
clusterAdmin=None,
|
34
|
+
cluster=ClusterV1(
|
35
|
+
name="appsres09ue1",
|
36
|
+
serverUrl="https://api.appsres09ue1.24ep.p3.openshiftapps.com:443",
|
37
|
+
insecureSkipTLSVerify=None,
|
38
|
+
jumpHost=None,
|
39
|
+
automationToken=VaultSecret(
|
40
|
+
path="app-sre/integrations-output/openshift-cluster-bots/appsres09ue1",
|
41
|
+
field="token",
|
42
|
+
version=None,
|
43
|
+
format=None,
|
44
|
+
),
|
45
|
+
clusterAdminAutomationToken=VaultSecret(
|
46
|
+
path="app-sre/integrations-output/openshift-cluster-bots/appsres09ue1-cluster-admin",
|
47
|
+
field="token",
|
48
|
+
version=None,
|
49
|
+
format=None,
|
50
|
+
),
|
51
|
+
internal=True,
|
52
|
+
disable=None,
|
53
|
+
),
|
54
|
+
),
|
55
|
+
NamespaceV1(
|
56
|
+
name="app-sre-pipelines",
|
57
|
+
delete=None,
|
58
|
+
labels='{"provider": "tekton"}',
|
59
|
+
clusterAdmin=None,
|
60
|
+
cluster=ClusterV1(
|
61
|
+
name="appsres09ue1",
|
62
|
+
serverUrl="https://api.appsres09ue1.24ep.p3.openshiftapps.com:443",
|
63
|
+
insecureSkipTLSVerify=None,
|
64
|
+
jumpHost=None,
|
65
|
+
automationToken=VaultSecret(
|
66
|
+
path="app-sre/integrations-output/openshift-cluster-bots/appsres09ue1",
|
67
|
+
field="token",
|
68
|
+
version=None,
|
69
|
+
format=None,
|
70
|
+
),
|
71
|
+
clusterAdminAutomationToken=VaultSecret(
|
72
|
+
path="app-sre/integrations-output/openshift-cluster-bots/appsres09ue1-cluster-admin",
|
73
|
+
field="token",
|
74
|
+
version=None,
|
75
|
+
format=None,
|
76
|
+
),
|
77
|
+
internal=True,
|
78
|
+
disable=None,
|
79
|
+
),
|
80
|
+
),
|
81
|
+
]
|
82
|
+
|
83
|
+
|
84
|
+
@pytest.fixture
|
85
|
+
def oc(
|
86
|
+
mocker: MockerFixture,
|
87
|
+
observability_pods: list[dict],
|
88
|
+
pipeline_pods: list[dict],
|
89
|
+
) -> OCNative:
|
90
|
+
oc = mocker.patch("reconcile.utils.oc.OCNative", autospec=True)
|
91
|
+
oc.get_items.side_effect = [observability_pods, pipeline_pods]
|
92
|
+
return oc
|
93
|
+
|
94
|
+
|
95
|
+
@pytest.fixture
|
96
|
+
def oc_map(mocker: MockerFixture, oc: OCNative) -> OCMap:
|
97
|
+
oc_map = mocker.patch("reconcile.utils.oc_map.OCMap", autospec=True)
|
98
|
+
oc_map.get_cluster.return_value = oc
|
99
|
+
return oc_map
|
100
|
+
|
101
|
+
|
102
|
+
# convert a list of dicts into a set of tuples to use it in assertions
|
103
|
+
def _to_set(list_of_dicts: list[dict]) -> set[tuple]:
|
104
|
+
return {tuple(d.items()) for d in list_of_dicts}
|
105
|
+
|
106
|
+
|
107
|
+
def testfetch_no_filter(namespaces: list[NamespaceV1], oc_map: OCMap) -> None:
|
108
|
+
images = fetch_pods_images_from_namespaces(
|
109
|
+
namespaces=namespaces,
|
110
|
+
oc_map=oc_map,
|
111
|
+
thread_pool_size=2,
|
112
|
+
)
|
113
|
+
|
114
|
+
assert _to_set(images) == _to_set([
|
115
|
+
{
|
116
|
+
"name": "quay.io/prometheus/blackbox-exporter",
|
117
|
+
"namespaces": "app-sre-observability-stage",
|
118
|
+
"count": 1,
|
119
|
+
},
|
120
|
+
{
|
121
|
+
"name": "quay.io/redhat-services-prod/app-sre-tenant/gitlab-project-exporter-main/gitlab-project-exporter-main",
|
122
|
+
"namespaces": "app-sre-observability-stage",
|
123
|
+
"count": 1,
|
124
|
+
},
|
125
|
+
{
|
126
|
+
"name": "quay.io/app-sre/internal-redhat-ca",
|
127
|
+
"namespaces": "app-sre-observability-stage,app-sre-pipelines",
|
128
|
+
"count": 3,
|
129
|
+
},
|
130
|
+
{
|
131
|
+
"name": "quay.io/app-sre/clamav",
|
132
|
+
"namespaces": "app-sre-pipelines",
|
133
|
+
"count": 1,
|
134
|
+
},
|
135
|
+
{
|
136
|
+
"name": "quay.io/redhat-appstudio/clamav-db",
|
137
|
+
"namespaces": "app-sre-pipelines",
|
138
|
+
"count": 1,
|
139
|
+
},
|
140
|
+
{
|
141
|
+
"name": "registry.redhat.io/openshift-pipelines/pipelines-entrypoint-rhel8",
|
142
|
+
"namespaces": "app-sre-pipelines",
|
143
|
+
"count": 3,
|
144
|
+
},
|
145
|
+
{
|
146
|
+
"name": "quay.io/redhatproductsecurity/rapidast",
|
147
|
+
"namespaces": "app-sre-pipelines",
|
148
|
+
"count": 1,
|
149
|
+
},
|
150
|
+
])
|
151
|
+
|
152
|
+
|
153
|
+
def testfetch_exclude_pattern(namespaces: list[NamespaceV1], oc_map: OCMap) -> None:
|
154
|
+
images = fetch_pods_images_from_namespaces(
|
155
|
+
namespaces=namespaces,
|
156
|
+
oc_map=oc_map,
|
157
|
+
thread_pool_size=2,
|
158
|
+
exclude_pattern="quay.io/redhat|quay.io/app-sre",
|
159
|
+
)
|
160
|
+
assert _to_set(images) == _to_set([
|
161
|
+
{
|
162
|
+
"name": "quay.io/prometheus/blackbox-exporter",
|
163
|
+
"namespaces": "app-sre-observability-stage",
|
164
|
+
"count": 1,
|
165
|
+
},
|
166
|
+
{
|
167
|
+
"name": "registry.redhat.io/openshift-pipelines/pipelines-entrypoint-rhel8",
|
168
|
+
"namespaces": "app-sre-pipelines",
|
169
|
+
"count": 3,
|
170
|
+
},
|
171
|
+
])
|
172
|
+
|
173
|
+
|
174
|
+
def testfetch_include_pattern(namespaces: list[NamespaceV1], oc_map: OCMap) -> None:
|
175
|
+
images = fetch_pods_images_from_namespaces(
|
176
|
+
namespaces=namespaces,
|
177
|
+
oc_map=oc_map,
|
178
|
+
thread_pool_size=2,
|
179
|
+
include_pattern="^registry.redhat.io",
|
180
|
+
)
|
181
|
+
assert images == [
|
182
|
+
{
|
183
|
+
"name": "registry.redhat.io/openshift-pipelines/pipelines-entrypoint-rhel8",
|
184
|
+
"namespaces": "app-sre-pipelines",
|
185
|
+
"count": 3,
|
186
|
+
},
|
187
|
+
]
|
{qontract_reconcile-0.10.1rc1181.dist-info → qontract_reconcile-0.10.1rc1182.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|
File without changes
|