-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathdisable_autosync.py
More file actions
147 lines (119 loc) · 4.62 KB
/
disable_autosync.py
File metadata and controls
147 lines (119 loc) · 4.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import argparse
import json
import os
import sys
import requests
from helpers import credential
from understack_workflows.helpers import setup_logger
logger = setup_logger(__name__)
def argument_parser():
parser = argparse.ArgumentParser(
prog=os.path.basename(__file__),
description="Switch auto-sync status on an Application",
)
parser.add_argument(
"--automated-sync",
type=bool,
required=True,
help="Requested state of automated sync",
)
parser.add_argument(
"--app-name", type=str, required=True, help="Name of the Application"
)
return parser
APP_NAME = "understack"
REQUEST_TIMEOUT_LOGIN = 30
REQUEST_TIMEOUT_PATCH = 10
# TODO: we may need to change this to True and provide appropriate CA certificate
VERIFY_SSL = False
if not VERIFY_SSL:
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def argocd_credentials():
"""Reads ArgoCD server, username, and password from mounted secret files."""
argocd_server_host = credential(APP_NAME, "server_host")
argocd_user = credential(APP_NAME, "user")
argocd_pass = credential(APP_NAME, "password")
if not all([argocd_server_host, argocd_user, argocd_pass]):
logger.error(
"One or more ArgoCD credentials are empty after reading from secret."
)
sys.exit(1)
return argocd_server_host, argocd_user, argocd_pass
def get_argocd_token(session, api_base_url, username, password):
"""Logs into ArgoCD and returns an authentication token."""
logger.info("Logging into ArgoCD...")
session_url = f"{api_base_url}/session"
login_data = {"username": username, "password": password}
try:
response = session.post(
session_url, json=login_data, timeout=REQUEST_TIMEOUT_LOGIN
)
response.raise_for_status()
token_data = response.json()
token = token_data.get("token")
if not token:
logger.error("Failed to retrieve ArgoCD token from login response.")
sys.exit(1)
logger.debug("Successfully obtained ArgoCD token.")
return token
except requests.exceptions.RequestException as e:
logger.error("ArgoCD login failed: %s", e)
sys.exit(1)
def patch_argocd_application(session, api_base_url, app_name, token, action):
"""Patches the specified ArgoCD application."""
app_patch_url = f"{api_base_url}/applications/{app_name}"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
payload = {
"patchType": "application/merge-patch+json",
"patch": '{"spec": {"syncPolicy": {"automated": {"selfHeal": action}}}}',
}
logger.debug(
"Patching Application '%(app_name)s' to '%(action)s'.Payload: %(payload)s",
extra=dict(app_name=app_name, action=action, payload=json.dumps(payload)),
)
try:
response = session.patch(
app_patch_url, json=payload, headers=headers, timeout=REQUEST_TIMEOUT_PATCH
)
response.raise_for_status()
logger.debug(
"Successfully patched Application '%(app_name)s'. "
"Action: '%(action)s'. Status: %(code)s",
extra=dict(action=action, app_name=app_name, code=response.status_code),
)
return True
except requests.exceptions.RequestException as e:
logger.error("Failed to patch ArgoCD Application '%s': %s", app_name, e)
if hasattr(e, "response") and e.response is not None:
logger.error("Error Response: %s", e.response.text)
return False
def main():
"""Switch auto-sync status on an Application.
This updates an Application syncPolicy to a requested state.
"""
args = argument_parser().parse_args()
action = "enable" if args.automated_sync else "disable"
logger.info(
"changing syncPolicy to '%s' for ArgoCD Application: %s", action, args.app_name
)
argocd_server_host, argocd_user, argocd_pass = argocd_credentials()
api_base_url = f"https://{argocd_server_host}/api/v1"
logger.info("ArgoCD API URL: %s, User: %s", api_base_url, argocd_user)
with requests.Session() as http_session:
http_session.verify = VERIFY_SSL
token = get_argocd_token(http_session, api_base_url, argocd_user, argocd_pass)
if not patch_argocd_application(
http_session, api_base_url, args.app_name, token, args.automated_sync
):
sys.exit(1)
logger.info(
"Action '%s' completed successfully for Application '%s'.",
action,
args.app_name,
)
if __name__ == "__main__":
main()