qontract-reconcile 0.10.2.dev231__py3-none-any.whl → 0.10.2.dev232__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.dev231.dist-info → qontract_reconcile-0.10.2.dev232.dist-info}/METADATA +1 -2
- {qontract_reconcile-0.10.2.dev231.dist-info → qontract_reconcile-0.10.2.dev232.dist-info}/RECORD +6 -8
- reconcile/cli.py +0 -25
- reconcile/utils/jinja2/utils.py +11 -1
- reconcile/github_users.py +0 -158
- reconcile/utils/template.py +0 -12
- {qontract_reconcile-0.10.2.dev231.dist-info → qontract_reconcile-0.10.2.dev232.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev231.dist-info → qontract_reconcile-0.10.2.dev232.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev231.dist-info → qontract_reconcile-0.10.2.dev232.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.dev232
|
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
|
@@ -160,7 +160,6 @@ OpenShift templates can be found [here](/openshift/qontract-reconcile.yaml). In
|
|
160
160
|
github-repo-permissions-validator
|
161
161
|
Validates permissions in github
|
162
162
|
repositories.
|
163
|
-
github-users Validate compliance of GitHub user profiles.
|
164
163
|
github-validator Validates GitHub organization settings.
|
165
164
|
gitlab-fork-compliance Ensures that forks of App Interface are
|
166
165
|
compliant.
|
{qontract_reconcile-0.10.2.dev231.dist-info → qontract_reconcile-0.10.2.dev232.dist-info}/RECORD
RENAMED
@@ -9,7 +9,7 @@ reconcile/aws_iam_password_reset.py,sha256=O0JX2N5kNRKs3u2xzu4NNrI6p0ag5JWy3MTsv
|
|
9
9
|
reconcile/aws_support_cases_sos.py,sha256=PDhilxQ4TBxVnxUPIUdTbKEaNUI0wzPiEsB91oHT2fY,3384
|
10
10
|
reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=O1wFp52EyF538c6txaWBs8eMtUIy19gyHZ6VzJ6QXS8,3512
|
11
11
|
reconcile/checkpoint.py,sha256=_JhMxrye5BgkRMxWYuf7Upli6XayPINKSsuo3ynHTRc,5010
|
12
|
-
reconcile/cli.py,sha256=
|
12
|
+
reconcile/cli.py,sha256=bDNLgSAIMkv1zE637ZJSO76nVdfjmhEsTA88jDuX50k,113598
|
13
13
|
reconcile/closedbox_endpoint_monitoring_base.py,sha256=al7m8EgnnYx90rY1REryW3byN_ItfJfAzEeLtjbCfi0,4921
|
14
14
|
reconcile/cluster_deployment_mapper.py,sha256=5gumAaRCcFXsabUJ1dnuUy9WrP_FEEM5JnOnE8ch9sE,2326
|
15
15
|
reconcile/dashdotdb_base.py,sha256=83ZWIf5JJk3P_D69y2TmXRcQr6ELJGlv10OM0h7fJVs,4767
|
@@ -26,7 +26,6 @@ reconcile/github_org.py,sha256=Wc5cZamatuWsW2ZJT2ib5ps8l3iY3RXHwNUxVJerqz0,14173
|
|
26
26
|
reconcile/github_owners.py,sha256=viE1KJ-zaTxuZ5yItg2C263J0brn-Q-3hR_DkYDMbhY,3122
|
27
27
|
reconcile/github_repo_invites.py,sha256=U9UCzNVwrZ7MqODtFah8ogH0NNY-XjBin7G9gqHtCUY,2690
|
28
28
|
reconcile/github_repo_permissions_validator.py,sha256=PNqL4dqa2OaNBy-NmLVN-t1HZa6eS6HgSYmfOunYqtA,1798
|
29
|
-
reconcile/github_users.py,sha256=ZeYNMyvZPVMx6mh5TiKEUQy4W1uw3VmUZOHiXus5I0Y,5073
|
30
29
|
reconcile/github_validator.py,sha256=-j17tn3csFVjPMSPL3te48iWVkPZCncRXdeKeLdGjjQ,931
|
31
30
|
reconcile/gitlab_fork_compliance.py,sha256=RbHckzLnE9zkOFHJANzoejEMMbMAivmqJVs3Suvp9lU,4591
|
32
31
|
reconcile/gitlab_housekeeping.py,sha256=JEnerWbirICkJQy91ZVepcHge2XWrVUazfIeKnZ94ZQ,26345
|
@@ -662,7 +661,6 @@ reconcile/utils/smtp_client.py,sha256=0xefB4I9E5eBB-FlxFJYjvz3Kvuqi_K3Ma_Wk0NAQK
|
|
662
661
|
reconcile/utils/sqs_gateway.py,sha256=XNIf3PY4UCPNufP2Ul0UJj3fKlt5larBba-VTT-41Fg,2265
|
663
662
|
reconcile/utils/state.py,sha256=az4tBmZ0EdbFcAGiBVUxs3cr2-BVWsuDQiNTvjjQq8s,16378
|
664
663
|
reconcile/utils/structs.py,sha256=LcbLEg8WxfRqM6nW7NhcWN0YeqF7SQzxOgntmLs1SgY,352
|
665
|
-
reconcile/utils/template.py,sha256=wTvRU4AnAV_o042tD4Mwls2dwWMuk7MKnde3MaCjaYg,331
|
666
664
|
reconcile/utils/terraform_client.py,sha256=IDlrNvGEc2i6ElZIL_fzaJEad1nRC3DkP9_VXhJXmU0,37329
|
667
665
|
reconcile/utils/terrascript_aws_client.py,sha256=RkiYjRietHFNXtfA1-WEZ1lZbJFBA_XCtTOsZUij5VM,292360
|
668
666
|
reconcile/utils/three_way_diff_strategy.py,sha256=oQcHXd9LVhirJfoaOBoHUYuZVGfyL2voKr6KVI34zZE,4833
|
@@ -700,7 +698,7 @@ reconcile/utils/internal_groups/models.py,sha256=y_IqBVqfGqNXiu0VudvBWFrm_-uafVm
|
|
700
698
|
reconcile/utils/jinja2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
701
699
|
reconcile/utils/jinja2/extensions.py,sha256=7K-uo6G2eCWa98MHT8fRPYIKCLQB_5D2keqQ_LyAfHM,1293
|
702
700
|
reconcile/utils/jinja2/filters.py,sha256=JfO_14APySBPidsMvHXG-8dULNPddZCE15Umjk_aSBk,4830
|
703
|
-
reconcile/utils/jinja2/utils.py,sha256=
|
701
|
+
reconcile/utils/jinja2/utils.py,sha256=1ucq5RHn9BV6bLvu9L6ji1X7Aus61Y6kU9HU-UicXfk,9053
|
704
702
|
reconcile/utils/jobcontroller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
705
703
|
reconcile/utils/jobcontroller/controller.py,sha256=Vh08lZuCSIIceWGSDhBB00iFwTI9eeKZW1sfHlkAvSo,15373
|
706
704
|
reconcile/utils/jobcontroller/models.py,sha256=x9YIvWfYOOvXNKToFVx1H7qDrZb0Sa1KI_4Y0gl7rMM,6336
|
@@ -803,7 +801,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
803
801
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
|
804
802
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
805
803
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
806
|
-
qontract_reconcile-0.10.2.
|
807
|
-
qontract_reconcile-0.10.2.
|
808
|
-
qontract_reconcile-0.10.2.
|
809
|
-
qontract_reconcile-0.10.2.
|
804
|
+
qontract_reconcile-0.10.2.dev232.dist-info/METADATA,sha256=tnLkovENBUt8KdPD7fs4Sr3JJweV3mXEbw0IrFobGy4,24352
|
805
|
+
qontract_reconcile-0.10.2.dev232.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
806
|
+
qontract_reconcile-0.10.2.dev232.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
807
|
+
qontract_reconcile-0.10.2.dev232.dist-info/RECORD,,
|
reconcile/cli.py
CHANGED
@@ -759,31 +759,6 @@ def github_owners(ctx: click.Context) -> None:
|
|
759
759
|
run_integration(reconcile.github_owners, ctx)
|
760
760
|
|
761
761
|
|
762
|
-
@integration.command(short_help="Validate compliance of GitHub user profiles.")
|
763
|
-
@gitlab_project_id
|
764
|
-
@threaded()
|
765
|
-
@enable_deletion(default=False)
|
766
|
-
@send_mails(default=False)
|
767
|
-
@click.pass_context
|
768
|
-
def github_users(
|
769
|
-
ctx: click.Context,
|
770
|
-
gitlab_project_id: str | None,
|
771
|
-
thread_pool_size: int,
|
772
|
-
enable_deletion: bool,
|
773
|
-
send_mails: bool,
|
774
|
-
) -> None:
|
775
|
-
import reconcile.github_users
|
776
|
-
|
777
|
-
run_integration(
|
778
|
-
reconcile.github_users,
|
779
|
-
ctx,
|
780
|
-
gitlab_project_id,
|
781
|
-
thread_pool_size,
|
782
|
-
enable_deletion,
|
783
|
-
send_mails,
|
784
|
-
)
|
785
|
-
|
786
|
-
|
787
762
|
@integration.command(short_help="Validates GitHub organization settings.")
|
788
763
|
@click.pass_context
|
789
764
|
def github_validator(ctx: click.Context) -> None:
|
reconcile/utils/jinja2/utils.py
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
import datetime
|
2
|
+
import os
|
2
3
|
from functools import cache
|
3
4
|
from typing import Any, Self
|
4
5
|
|
5
6
|
import jinja2
|
7
|
+
from github import Github
|
6
8
|
from jinja2.sandbox import SandboxedEnvironment
|
7
9
|
from pydantic import BaseModel
|
8
10
|
from sretoolbox.utils import retry
|
9
11
|
|
10
12
|
from reconcile import queries
|
11
13
|
from reconcile.checkpoint import url_makes_sense
|
12
|
-
from reconcile.
|
14
|
+
from reconcile.github_org import get_default_config
|
13
15
|
from reconcile.utils import gql
|
14
16
|
from reconcile.utils.aws_api import AWSApi
|
15
17
|
from reconcile.utils.github_api import GithubRepositoryApi
|
@@ -97,6 +99,14 @@ def compile_jinja2_template(
|
|
97
99
|
return jinja_env.from_string(body)
|
98
100
|
|
99
101
|
|
102
|
+
GH_BASE_URL = os.environ.get("GITHUB_API", "https://api.github.com")
|
103
|
+
|
104
|
+
|
105
|
+
def init_github() -> Github:
|
106
|
+
token = get_default_config()["token"]
|
107
|
+
return Github(token, base_url=GH_BASE_URL)
|
108
|
+
|
109
|
+
|
100
110
|
def lookup_github_file_content(
|
101
111
|
repo: str,
|
102
112
|
path: str,
|
reconcile/github_users.py
DELETED
@@ -1,158 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
import os
|
3
|
-
import re
|
4
|
-
from collections import defaultdict
|
5
|
-
from collections.abc import Callable
|
6
|
-
|
7
|
-
from github import Github
|
8
|
-
from github.GithubException import GithubException
|
9
|
-
from requests.exceptions import ReadTimeout
|
10
|
-
from sretoolbox.utils import (
|
11
|
-
retry,
|
12
|
-
threaded,
|
13
|
-
)
|
14
|
-
|
15
|
-
from reconcile import (
|
16
|
-
mr_client_gateway,
|
17
|
-
queries,
|
18
|
-
typed_queries,
|
19
|
-
)
|
20
|
-
from reconcile.github_org import get_default_config
|
21
|
-
from reconcile.utils.defer import defer
|
22
|
-
from reconcile.utils.mr import CreateDeleteUserAppInterface
|
23
|
-
from reconcile.utils.mr.user_maintenance import PathSpec, PathTypes
|
24
|
-
from reconcile.utils.secret_reader import SecretReader
|
25
|
-
from reconcile.utils.smtp_client import (
|
26
|
-
DEFAULT_SMTP_TIMEOUT,
|
27
|
-
SmtpClient,
|
28
|
-
get_smtp_server_connection,
|
29
|
-
)
|
30
|
-
|
31
|
-
GH_BASE_URL = os.environ.get("GITHUB_API", "https://api.github.com")
|
32
|
-
|
33
|
-
QONTRACT_INTEGRATION = "github-users"
|
34
|
-
|
35
|
-
UserAndCompany = tuple[str, str | None]
|
36
|
-
|
37
|
-
|
38
|
-
def init_github() -> Github:
|
39
|
-
token = get_default_config()["token"]
|
40
|
-
return Github(token, base_url=GH_BASE_URL)
|
41
|
-
|
42
|
-
|
43
|
-
def init_users_and_paths() -> list[dict[str, list]]:
|
44
|
-
app_int_users = queries.get_users(refs=True)
|
45
|
-
|
46
|
-
users = defaultdict(list)
|
47
|
-
for user in app_int_users:
|
48
|
-
u = user["org_username"]
|
49
|
-
item = PathSpec(type=PathTypes.USER, path=user["path"])
|
50
|
-
users[u].append(item)
|
51
|
-
for r in user.get("requests"):
|
52
|
-
item = PathSpec(type=PathTypes.REQUEST, path=r["path"])
|
53
|
-
users[u].append(item)
|
54
|
-
for q in user.get("queries"):
|
55
|
-
item = PathSpec(type=PathTypes.QUERY, path=q["path"])
|
56
|
-
users[u].append(item)
|
57
|
-
for g in user.get("gabi_instances"):
|
58
|
-
item = PathSpec(type=PathTypes.GABI, path=g["path"])
|
59
|
-
users[u].append(item)
|
60
|
-
for a in user.get("aws_accounts", []):
|
61
|
-
item = PathSpec(type=PathTypes.AWS_ACCOUNTS, path=a["path"])
|
62
|
-
users[u].append(item)
|
63
|
-
for s in user.get("schedules"):
|
64
|
-
item = PathSpec(type=PathTypes.SCHEDULE, path=s["path"])
|
65
|
-
users[u].append(item)
|
66
|
-
|
67
|
-
return [{"username": username, "paths": paths} for username, paths in users.items()]
|
68
|
-
|
69
|
-
|
70
|
-
@retry(exceptions=(GithubException, ReadTimeout))
|
71
|
-
def get_user_company(user: dict, github: Github) -> UserAndCompany:
|
72
|
-
gh_user = github.get_user(login=user["github_username"])
|
73
|
-
return user["org_username"], gh_user.company
|
74
|
-
|
75
|
-
|
76
|
-
def get_users_to_delete(results: list[UserAndCompany]) -> list[dict]:
|
77
|
-
pattern = r"^.*[Rr]ed ?[Hh]at.*$"
|
78
|
-
org_usernames_to_delete = [
|
79
|
-
u for u, c in results if c is None or not re.search(pattern, c)
|
80
|
-
]
|
81
|
-
users_and_paths = init_users_and_paths()
|
82
|
-
return [u for u in users_and_paths if u["username"] in org_usernames_to_delete]
|
83
|
-
|
84
|
-
|
85
|
-
def send_email_notification(user: dict, smtp_client: SmtpClient) -> None:
|
86
|
-
msg_template = """
|
87
|
-
Hello,
|
88
|
-
|
89
|
-
This is an automated message coming from App-Interface.
|
90
|
-
|
91
|
-
The App SRE team adheres to the OpenShift GitHub policy:
|
92
|
-
https://mojo.redhat.com/docs/DOC-1200784
|
93
|
-
|
94
|
-
Your GitHub profile does not comply with the following requirements:
|
95
|
-
|
96
|
-
- Company field should contain "Red Hat".
|
97
|
-
|
98
|
-
|
99
|
-
For any questions, please ping @app-sre-ic on #sd-app-sre in CoreOS Slack,
|
100
|
-
or mail us at sd-app-sre@redhat.com.
|
101
|
-
|
102
|
-
App-Interface repository: https://gitlab.cee.redhat.com/service/app-interface
|
103
|
-
|
104
|
-
"""
|
105
|
-
to = user["username"]
|
106
|
-
subject = "App-Interface compliance - GitHub profile"
|
107
|
-
body = msg_template
|
108
|
-
smtp_client.send_mail([to], subject, body)
|
109
|
-
|
110
|
-
|
111
|
-
@defer
|
112
|
-
def run(
|
113
|
-
dry_run: bool,
|
114
|
-
gitlab_project_id: str | None = None,
|
115
|
-
thread_pool_size: int = 10,
|
116
|
-
enable_deletion: bool = False,
|
117
|
-
send_mails: bool = False,
|
118
|
-
defer: Callable | None = None,
|
119
|
-
) -> None:
|
120
|
-
smtp_settings = typed_queries.smtp.settings()
|
121
|
-
smtp_client = SmtpClient(
|
122
|
-
server=get_smtp_server_connection(
|
123
|
-
secret_reader=SecretReader(settings=queries.get_secret_reader_settings()),
|
124
|
-
secret=smtp_settings.credentials,
|
125
|
-
),
|
126
|
-
mail_address=smtp_settings.mail_address,
|
127
|
-
timeout=smtp_settings.timeout or DEFAULT_SMTP_TIMEOUT,
|
128
|
-
)
|
129
|
-
users = queries.get_users()
|
130
|
-
g = init_github()
|
131
|
-
|
132
|
-
results = threaded.run(get_user_company, users, thread_pool_size, github=g)
|
133
|
-
|
134
|
-
users_to_delete = get_users_to_delete(results)
|
135
|
-
|
136
|
-
if not dry_run and enable_deletion:
|
137
|
-
mr_cli = mr_client_gateway.init(gitlab_project_id=gitlab_project_id)
|
138
|
-
if defer:
|
139
|
-
defer(mr_cli.cleanup)
|
140
|
-
|
141
|
-
for user in users_to_delete:
|
142
|
-
username = user["username"]
|
143
|
-
paths = user["paths"]
|
144
|
-
logging.info(["delete_user", username])
|
145
|
-
|
146
|
-
if not dry_run:
|
147
|
-
if send_mails:
|
148
|
-
send_email_notification(user, smtp_client)
|
149
|
-
elif enable_deletion:
|
150
|
-
mr = CreateDeleteUserAppInterface(username, paths)
|
151
|
-
mr.submit(cli=mr_cli)
|
152
|
-
else:
|
153
|
-
msg = (
|
154
|
-
"'delete' action is not enabled. "
|
155
|
-
"Please run the integration manually "
|
156
|
-
"with the '--enable-deletion' flag."
|
157
|
-
)
|
158
|
-
logging.warning(msg)
|
reconcile/utils/template.py
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
|
3
|
-
import jinja2
|
4
|
-
|
5
|
-
from reconcile import templates
|
6
|
-
|
7
|
-
|
8
|
-
def get_package_environment():
|
9
|
-
"""Loads templates from the current Python package"""
|
10
|
-
templates_dir = os.path.dirname(templates.__file__)
|
11
|
-
template_loader = jinja2.FileSystemLoader(searchpath=templates_dir)
|
12
|
-
return jinja2.Environment(loader=template_loader)
|
{qontract_reconcile-0.10.2.dev231.dist-info → qontract_reconcile-0.10.2.dev232.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|