qontract-reconcile 0.10.2.dev241__py3-none-any.whl → 0.10.2.dev243__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.dev241.dist-info → qontract_reconcile-0.10.2.dev243.dist-info}/METADATA +1 -3
- {qontract_reconcile-0.10.2.dev241.dist-info → qontract_reconcile-0.10.2.dev243.dist-info}/RECORD +9 -10
- reconcile/checkpoint.py +1 -1
- reconcile/cli.py +0 -8
- reconcile/openshift_rhcs_certs.py +4 -0
- reconcile/queries.py +0 -56
- reconcile/utils/sharding.py +0 -14
- reconcile/jira_watcher.py +0 -131
- {qontract_reconcile-0.10.2.dev241.dist-info → qontract_reconcile-0.10.2.dev243.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev241.dist-info → qontract_reconcile-0.10.2.dev243.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev241.dist-info → qontract_reconcile-0.10.2.dev243.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.2.
|
3
|
+
Version: 0.10.2.dev243
|
4
4
|
Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
|
5
5
|
Project-URL: homepage, https://github.com/app-sre/qontract-reconcile
|
6
6
|
Project-URL: repository, https://github.com/app-sre/qontract-reconcile
|
@@ -190,8 +190,6 @@ OpenShift templates can be found [here](/openshift/qontract-reconcile.yaml). In
|
|
190
190
|
instances.
|
191
191
|
jenkins-worker-fleets Manage Jenkins worker fleets via JCasC.
|
192
192
|
jira-permissions-validator Validate permissions in Jira.
|
193
|
-
jira-watcher Watch for changes in Jira boards and notify
|
194
|
-
on Slack.
|
195
193
|
ldap-groups Manages LDAP groups based on App-Interface
|
196
194
|
roles.
|
197
195
|
ldap-users Removes users which are not found in LDAP
|
{qontract_reconcile-0.10.2.dev241.dist-info → qontract_reconcile-0.10.2.dev243.dist-info}/RECORD
RENAMED
@@ -7,8 +7,8 @@ reconcile/aws_iam_keys.py,sha256=mw_lvmWqpJkzYW8Za6lHfxEMkT-_DOzWiCPhJAmYPIQ,398
|
|
7
7
|
reconcile/aws_iam_password_reset.py,sha256=O0JX2N5kNRKs3u2xzu4NNrI6p0ag5JWy3MTsvZmtleg,3173
|
8
8
|
reconcile/aws_support_cases_sos.py,sha256=PDhilxQ4TBxVnxUPIUdTbKEaNUI0wzPiEsB91oHT2fY,3384
|
9
9
|
reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=O1wFp52EyF538c6txaWBs8eMtUIy19gyHZ6VzJ6QXS8,3512
|
10
|
-
reconcile/checkpoint.py,sha256=
|
11
|
-
reconcile/cli.py,sha256=
|
10
|
+
reconcile/checkpoint.py,sha256=gjtS8g6KIyKFYlHMSZjAqDUOlVh83nh4go-9yNrhWZU,5016
|
11
|
+
reconcile/cli.py,sha256=kp-YLjPfnqwyJdXDfVPE0lmfaRWDO1_ocTlZDCuVUOI,113061
|
12
12
|
reconcile/closedbox_endpoint_monitoring_base.py,sha256=al7m8EgnnYx90rY1REryW3byN_ItfJfAzEeLtjbCfi0,4921
|
13
13
|
reconcile/cluster_deployment_mapper.py,sha256=5gumAaRCcFXsabUJ1dnuUy9WrP_FEEM5JnOnE8ch9sE,2326
|
14
14
|
reconcile/dashdotdb_base.py,sha256=83ZWIf5JJk3P_D69y2TmXRcQr6ELJGlv10OM0h7fJVs,4767
|
@@ -44,7 +44,6 @@ reconcile/jenkins_webhooks.py,sha256=KANd1ExYw6jp6F-d-QEbX1L1CNbRF270yL2ppDCAjio
|
|
44
44
|
reconcile/jenkins_webhooks_cleaner.py,sha256=tFbAzsFGvJ6UrHRZFdIuLdqG-Ocd5_OknfsbtN-eyFY,1619
|
45
45
|
reconcile/jenkins_worker_fleets.py,sha256=L2wEXpd4xuEHrXGss4iH788nG8UlLSYduZe1EY2IVw4,5377
|
46
46
|
reconcile/jira_permissions_validator.py,sha256=nVHZg7kNn04Q-ryNM20wthMrhXos28g3O9b0ahzxAKc,14690
|
47
|
-
reconcile/jira_watcher.py,sha256=S3xbnyo-Xdn64eY_TyHv1TnuoS9_H4z6HwiLn6De6pc,4135
|
48
47
|
reconcile/ldap_users.py,sha256=oP1CAxmgSi3zDJ3vKTPySjap6WmEX1U469FmFrov5l4,4599
|
49
48
|
reconcile/mr_client_gateway.py,sha256=WhjMd-sIXDFCV8-rt8CEjurJ5OYB1pOD0K3o0tZRXQg,1885
|
50
49
|
reconcile/ocm_additional_routers.py,sha256=KfcFDVbNoc6n5dHWjYdAf1_DiVqVG6Tw23WLKoV8cdg,3306
|
@@ -70,7 +69,7 @@ reconcile/openshift_prometheus_rules.py,sha256=onowXab248zmHH8SbYDTc1W1bl7JiqRFU
|
|
70
69
|
reconcile/openshift_resourcequotas.py,sha256=yUi56PiOn3inMMfq_x_FEHmaW-reGipzoorjdar372g,2415
|
71
70
|
reconcile/openshift_resources.py,sha256=I2nO_C37mG3rfyGrd4cGwN3mVseVGuTAHAyhFzLyqF4,1518
|
72
71
|
reconcile/openshift_resources_base.py,sha256=728-5nEmWMviSnhQH-EbEp_876VI2PGgC8LnrIfbD3U,42890
|
73
|
-
reconcile/openshift_rhcs_certs.py,sha256=
|
72
|
+
reconcile/openshift_rhcs_certs.py,sha256=NEHOuSztYkNn7GFqUg2On7kmi3VajDJ5zHZt08Xa24A,10230
|
74
73
|
reconcile/openshift_rolebindings.py,sha256=9mlJ2FjWUoH-rsjtasreA_hV-K5Z_YR00qR_RR60OZM,6555
|
75
74
|
reconcile/openshift_routes.py,sha256=fXvuPSjcjVw1X3j2EQvUAdbOepmIFdKk-M3qP8QzPiw,1075
|
76
75
|
reconcile/openshift_saas_deploy.py,sha256=T1dvb9zajisaJNjbnR6-AZHU-itscHtr4oCqLj8KCK0,13037
|
@@ -92,7 +91,7 @@ reconcile/quay_mirror.py,sha256=PBooiA0ShZpWYfO6oeKFqYYT6Syi7Q8JJD9kj0wRRLg,1403
|
|
92
91
|
reconcile/quay_mirror_org.py,sha256=I-tEqRHLL6uFqbSi7qCfPuDNoae7EAI2U68NbDOhmv8,10809
|
93
92
|
reconcile/quay_permissions.py,sha256=9KOutS1w4RFQqkvMSy54VtsKNx56-phzP6yI_rEW-B8,4244
|
94
93
|
reconcile/quay_repos.py,sha256=cuEYG0HUe0ut5yvLdEwOF5-CmccpXQHRb_wDazvDrvQ,6895
|
95
|
-
reconcile/queries.py,sha256=
|
94
|
+
reconcile/queries.py,sha256=4ljTNPmRwzJQz14RXHMH-GLW3uOTdoXMwvgJmnSJP7I,49924
|
96
95
|
reconcile/query_validator.py,sha256=MSh5pKLBksws4AqfuvT8nrIGucIbqX-IOzYyPYTLO7k,1491
|
97
96
|
reconcile/requests_sender.py,sha256=914iluuF4UVgG3VyxxtnHOu4yf6YKS2fIy6PViSsFTQ,3875
|
98
97
|
reconcile/resource_scraper.py,sha256=znXCHrU7YwPfKuxGBiUrV7T1tYtn4vlz9qmZlfy6Flg,2307
|
@@ -653,7 +652,7 @@ reconcile/utils/rhcsv2_certs.py,sha256=ZnlUlEI2k6UrljGarkm1ey0znMlQtjeZB7VEfCH1A
|
|
653
652
|
reconcile/utils/ruamel.py,sha256=FzL4_L0FnMOUZmgThrZSMJs5MTdXwiy-E9MZWfk8bh8,397
|
654
653
|
reconcile/utils/secret_reader.py,sha256=MaP56KZaAE35EyYbgAitdm6fUSxdzWeGFSOym9qiZkw,10206
|
655
654
|
reconcile/utils/semver_helper.py,sha256=-WfPOMSA2v1h7hT3PwVf-Htg7wOsoKlQC1JdmDX2Ars,1268
|
656
|
-
reconcile/utils/sharding.py,sha256=
|
655
|
+
reconcile/utils/sharding.py,sha256=CNyU9mkSbt7FRANEhOOZpWJl7L-YliHhaxr898gmX8c,573
|
657
656
|
reconcile/utils/slack_api.py,sha256=IcnXmQrKXQwYEhKfXTBmOeuYKxpSG2Wvc1Fq-Nf1Xgg,17551
|
658
657
|
reconcile/utils/slo_document_manager.py,sha256=CPgM2oH4AVzBqenakWo59R5yfwB62tnxSnSOHgir7l8,9500
|
659
658
|
reconcile/utils/smtp_client.py,sha256=0xefB4I9E5eBB-FlxFJYjvz3Kvuqi_K3Ma_Wk0NAQKM,2779
|
@@ -800,7 +799,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
800
799
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
|
801
800
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
802
801
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
803
|
-
qontract_reconcile-0.10.2.
|
804
|
-
qontract_reconcile-0.10.2.
|
805
|
-
qontract_reconcile-0.10.2.
|
806
|
-
qontract_reconcile-0.10.2.
|
802
|
+
qontract_reconcile-0.10.2.dev243.dist-info/METADATA,sha256=6xA4naj3WZA1ys-EcVERD6rXI3ickOb_Qahp0lakNOI,24167
|
803
|
+
qontract_reconcile-0.10.2.dev243.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
804
|
+
qontract_reconcile-0.10.2.dev243.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
805
|
+
qontract_reconcile-0.10.2.dev243.dist-info/RECORD,,
|
reconcile/checkpoint.py
CHANGED
@@ -133,7 +133,7 @@ def report_invalid_metadata(
|
|
133
133
|
:param path: path in app-interface to said app
|
134
134
|
|
135
135
|
:param board: JIRA board description, as per
|
136
|
-
queries.
|
136
|
+
queries.JIRA_BOARDS_QUICK_QUERY
|
137
137
|
|
138
138
|
:param settings: app-interface settings (necessary to log into the
|
139
139
|
JIRA instance)
|
reconcile/cli.py
CHANGED
@@ -1146,14 +1146,6 @@ def jira_permissions_validator(
|
|
1146
1146
|
)
|
1147
1147
|
|
1148
1148
|
|
1149
|
-
@integration.command(short_help="Watch for changes in Jira boards and notify on Slack.")
|
1150
|
-
@click.pass_context
|
1151
|
-
def jira_watcher(ctx: click.Context) -> None:
|
1152
|
-
import reconcile.jira_watcher
|
1153
|
-
|
1154
|
-
run_integration(reconcile.jira_watcher, ctx)
|
1155
|
-
|
1156
|
-
|
1157
1149
|
@integration.command(
|
1158
1150
|
short_help="Watches for OpenShift upgrades and sends notifications."
|
1159
1151
|
)
|
@@ -59,6 +59,7 @@ class OpenshiftRhcsCertExpiration(GaugeMetric):
|
|
59
59
|
cert_name: str
|
60
60
|
cluster: str
|
61
61
|
namespace: str
|
62
|
+
renewal_threshold_days: str
|
62
63
|
|
63
64
|
@classmethod
|
64
65
|
def name(cls) -> str:
|
@@ -200,6 +201,9 @@ def fetch_openshift_resource_for_cert_resource(
|
|
200
201
|
cert_name=cert_resource.secret_name,
|
201
202
|
namespace=ns.name,
|
202
203
|
cluster=ns.cluster.name,
|
204
|
+
renewal_threshold_days=str(
|
205
|
+
cert_resource.auto_renew_threshold_days or 7
|
206
|
+
),
|
203
207
|
),
|
204
208
|
int(vault_cert_secret["expiration_timestamp"]),
|
205
209
|
)
|
reconcile/queries.py
CHANGED
@@ -2137,62 +2137,6 @@ def get_pipelines_providers():
|
|
2137
2137
|
return pipelines_providers
|
2138
2138
|
|
2139
2139
|
|
2140
|
-
JIRA_BOARDS_QUERY = """
|
2141
|
-
{
|
2142
|
-
jira_boards: jira_boards_v1 {
|
2143
|
-
path
|
2144
|
-
name
|
2145
|
-
server {
|
2146
|
-
serverUrl
|
2147
|
-
token {
|
2148
|
-
path
|
2149
|
-
field
|
2150
|
-
version
|
2151
|
-
format
|
2152
|
-
}
|
2153
|
-
}
|
2154
|
-
{% if with_slack %}
|
2155
|
-
slack {
|
2156
|
-
workspace {
|
2157
|
-
name
|
2158
|
-
integrations {
|
2159
|
-
name
|
2160
|
-
token {
|
2161
|
-
path
|
2162
|
-
field
|
2163
|
-
version
|
2164
|
-
format
|
2165
|
-
}
|
2166
|
-
channel
|
2167
|
-
icon_emoji
|
2168
|
-
username
|
2169
|
-
}
|
2170
|
-
api_client {
|
2171
|
-
global {
|
2172
|
-
max_retries
|
2173
|
-
timeout
|
2174
|
-
}
|
2175
|
-
methods {
|
2176
|
-
name
|
2177
|
-
args
|
2178
|
-
}
|
2179
|
-
}
|
2180
|
-
}
|
2181
|
-
channel
|
2182
|
-
}
|
2183
|
-
{% endif %}
|
2184
|
-
}
|
2185
|
-
}
|
2186
|
-
"""
|
2187
|
-
|
2188
|
-
|
2189
|
-
def get_jira_boards(with_slack: bool | None = True):
|
2190
|
-
"""Returns Jira boards resources defined in app-interface"""
|
2191
|
-
gqlapi = gql.get_api()
|
2192
|
-
query = Template(JIRA_BOARDS_QUERY).render(with_slack=with_slack)
|
2193
|
-
return gqlapi.query(query)["jira_boards"]
|
2194
|
-
|
2195
|
-
|
2196
2140
|
# Use APATH as the place holder because Python formatting interferes
|
2197
2141
|
# with graphql use of curly braces
|
2198
2142
|
JIRA_BOARDS_QUICK_QUERY = """
|
reconcile/utils/sharding.py
CHANGED
@@ -25,17 +25,3 @@ def is_in_shard(value):
|
|
25
25
|
LOG.debug("IN_SHARD FALSE: %s", value)
|
26
26
|
|
27
27
|
return in_shard
|
28
|
-
|
29
|
-
|
30
|
-
def is_in_shard_round_robin(value, index):
|
31
|
-
if SHARDS == 1:
|
32
|
-
return True
|
33
|
-
|
34
|
-
in_shard = index % SHARDS == SHARD_ID
|
35
|
-
|
36
|
-
if in_shard:
|
37
|
-
LOG.debug("IN_SHARD TRUE: %s", value)
|
38
|
-
else:
|
39
|
-
LOG.debug("IN_SHARD FALSE: %s", value)
|
40
|
-
|
41
|
-
return in_shard
|
reconcile/jira_watcher.py
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
from collections.abc import Callable, Mapping, Sequence
|
3
|
-
from typing import Any
|
4
|
-
|
5
|
-
from reconcile import queries
|
6
|
-
from reconcile.slack_base import slackapi_from_slack_workspace
|
7
|
-
from reconcile.utils.defer import defer
|
8
|
-
from reconcile.utils.jira_client import JiraClient
|
9
|
-
from reconcile.utils.secret_reader import SecretReader
|
10
|
-
from reconcile.utils.sharding import is_in_shard_round_robin
|
11
|
-
from reconcile.utils.slack_api import SlackApi
|
12
|
-
from reconcile.utils.state import (
|
13
|
-
State,
|
14
|
-
init_state,
|
15
|
-
)
|
16
|
-
|
17
|
-
QONTRACT_INTEGRATION = "jira-watcher"
|
18
|
-
|
19
|
-
|
20
|
-
def fetch_current_state(
|
21
|
-
jira_board: Mapping, settings: Mapping
|
22
|
-
) -> tuple[JiraClient, dict[str, dict[str, str]]]:
|
23
|
-
jira = JiraClient(jira_board, settings=settings)
|
24
|
-
issues = jira.get_issues(fields=["key", "status", "summary"])
|
25
|
-
return jira, {
|
26
|
-
issue.key: {"status": issue.fields.status.name, "summary": issue.fields.summary}
|
27
|
-
for issue in issues
|
28
|
-
}
|
29
|
-
|
30
|
-
|
31
|
-
def fetch_previous_state(state: State, project: str) -> dict:
|
32
|
-
return state.get(project, {})
|
33
|
-
|
34
|
-
|
35
|
-
def format_message(
|
36
|
-
server: str,
|
37
|
-
key: str,
|
38
|
-
data: Mapping,
|
39
|
-
event: str,
|
40
|
-
previous_state: Mapping | None = None,
|
41
|
-
current_state: Mapping | None = None,
|
42
|
-
) -> str:
|
43
|
-
summary = data["summary"]
|
44
|
-
info = (
|
45
|
-
": {} -> {}".format(previous_state["status"], current_state["status"])
|
46
|
-
if previous_state and current_state
|
47
|
-
else ""
|
48
|
-
)
|
49
|
-
url = f"{server}/browse/{key}"
|
50
|
-
return f"{url} ({summary}) {event}{info}"
|
51
|
-
|
52
|
-
|
53
|
-
def calculate_diff(
|
54
|
-
server: str, current_state: Mapping, previous_state: Mapping
|
55
|
-
) -> list[str]:
|
56
|
-
messages = []
|
57
|
-
new_issues = [
|
58
|
-
format_message(server, key, data, "created")
|
59
|
-
for key, data in current_state.items()
|
60
|
-
if key not in previous_state
|
61
|
-
]
|
62
|
-
messages.extend(new_issues)
|
63
|
-
|
64
|
-
deleted_issues = [
|
65
|
-
format_message(server, key, data, "deleted")
|
66
|
-
for key, data in previous_state.items()
|
67
|
-
if key not in current_state
|
68
|
-
]
|
69
|
-
messages.extend(deleted_issues)
|
70
|
-
|
71
|
-
updated_issues = [
|
72
|
-
format_message(server, key, data, "status change", previous_state[key], data)
|
73
|
-
for key, data in current_state.items()
|
74
|
-
if key in previous_state and data["status"] != previous_state[key]["status"]
|
75
|
-
]
|
76
|
-
messages.extend(updated_issues)
|
77
|
-
|
78
|
-
return messages
|
79
|
-
|
80
|
-
|
81
|
-
def init_slack(jira_board: Mapping[str, Any]) -> SlackApi:
|
82
|
-
secret_reader = SecretReader(queries.get_secret_reader_settings())
|
83
|
-
slack_info = jira_board["slack"]
|
84
|
-
|
85
|
-
return slackapi_from_slack_workspace(
|
86
|
-
slack_info,
|
87
|
-
secret_reader,
|
88
|
-
QONTRACT_INTEGRATION,
|
89
|
-
channel=slack_info.get("channel"),
|
90
|
-
init_usergroups=False,
|
91
|
-
)
|
92
|
-
|
93
|
-
|
94
|
-
def act(dry_run: bool, jira_board: Mapping[str, str], diffs: Sequence[str]) -> None:
|
95
|
-
if not dry_run and diffs:
|
96
|
-
slack = init_slack(jira_board)
|
97
|
-
|
98
|
-
for diff in reversed(diffs):
|
99
|
-
logging.info(diff)
|
100
|
-
if not dry_run:
|
101
|
-
slack.chat_post_message(diff)
|
102
|
-
|
103
|
-
|
104
|
-
def write_state(state: State, project: str, state_to_write: Mapping) -> None:
|
105
|
-
state.add(project, value=state_to_write, force=True)
|
106
|
-
|
107
|
-
|
108
|
-
@defer
|
109
|
-
def run(dry_run: bool, defer: Callable | None = None) -> None:
|
110
|
-
jira_boards = [j for j in queries.get_jira_boards() if j.get("slack")]
|
111
|
-
settings = queries.get_app_interface_settings()
|
112
|
-
state = init_state(integration=QONTRACT_INTEGRATION)
|
113
|
-
if defer:
|
114
|
-
defer(state.cleanup)
|
115
|
-
for index, jira_board in enumerate(jira_boards):
|
116
|
-
if not is_in_shard_round_robin(jira_board["name"], index):
|
117
|
-
continue
|
118
|
-
jira, current_state = fetch_current_state(jira_board, settings)
|
119
|
-
if not current_state:
|
120
|
-
logging.warning(
|
121
|
-
"not acting on empty Jira boards. "
|
122
|
-
+ "please create a ticket to get started."
|
123
|
-
)
|
124
|
-
continue
|
125
|
-
previous_state = fetch_previous_state(state, jira.project)
|
126
|
-
if previous_state:
|
127
|
-
assert jira.server
|
128
|
-
diffs = calculate_diff(jira.server, current_state, previous_state)
|
129
|
-
act(dry_run, jira_board, diffs)
|
130
|
-
if not dry_run:
|
131
|
-
write_state(state, jira.project, current_state)
|
{qontract_reconcile-0.10.2.dev241.dist-info → qontract_reconcile-0.10.2.dev243.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|