kubernetes-watch 0.1.12__py3-none-any.whl → 0.1.14__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.
@@ -146,7 +146,45 @@ def restart_deployment(deployment, namespace):
146
146
  api_response = v1.patch_namespaced_deployment(name=deployment, namespace=namespace, body=body)
147
147
  logger.info(f"Deployment restarted. Name: {api_response.metadata.name}")
148
148
  except ApiException as e:
149
- logger.error(f"Exception when restarting deployment: {e}")
149
+ logger.error(
150
+ "Failed to restart deployment. status=%s reason=%s body=%s",
151
+ e.status, e.reason, e.body
152
+ )
153
+ # raise
154
+
155
+ except Exception as e:
156
+ # Everything else: connectivity, config, TLS, serialization, etc.
157
+ logger.error("Unexpected error restarting deployment: %s", e)
158
+ # raise
159
+
160
+
161
+ def delete_pod(namespace: str, label_selector: str, max_pods: int | None = 1):
162
+ v1 = client.CoreV1Api()
163
+
164
+
165
+ pods = v1.list_namespaced_pod(namespace=namespace, label_selector=label_selector)
166
+ if not pods.items:
167
+ raise RuntimeError(f"No pods found for selector: {label_selector}")
168
+
169
+
170
+ for i, pod in enumerate(pods.items):
171
+ if max_pods is not None and i >= max_pods:
172
+ break
173
+
174
+ try:
175
+ v1.delete_namespaced_pod(
176
+ name=pod,
177
+ namespace=namespace,
178
+ grace_period_seconds=30,
179
+ )
180
+ print(f"Deleted pod: {pod}")
181
+ except ApiException as e:
182
+ logger.error(f"Failed to delete pod: status={e.status} reason={e.reason} body={e.body}")
183
+ # raise
184
+ except Exception as e:
185
+ # Everything else: connectivity, config, TLS, serialization, etc.
186
+ logger.error("Unexpected error restarting deployment: %s", e)
187
+ # raise
150
188
 
151
189
 
152
190
  def has_mismatch_image_digest(repo_digest, label_selector, namespace):
@@ -1,12 +1,13 @@
1
- from typing import Union
1
+ from typing import Union, Optional
2
2
  from pydantic import BaseModel
3
3
 
4
4
  class TableQuery(BaseModel):
5
- name: str
5
+ table_name: str
6
6
  column_name: str
7
- db_host: str
8
- db_port: int
9
- db_name: str
10
- db_user: str
11
- db_pass: str
7
+ db_url: Optional[str] = None
8
+ db_host: Optional[str] = None
9
+ db_port: Optional[int] = None
10
+ db_name: Optional[str] = None
11
+ db_user: Optional[str] = None
12
+ db_pass: Optional[str] = None
12
13
 
@@ -1,23 +1,26 @@
1
1
  import psycopg2
2
2
  import psycopg2.extras
3
3
  from prefect import get_run_logger
4
+ from urllib.parse import urlparse, unquote
4
5
 
5
6
  from .model import TableQuery
6
7
 
7
8
  logger = get_run_logger()
8
9
 
9
10
 
10
- def execute_query(db_user, db_pass, db_query, db_host="localhost", db_port=5432, db_name="postgres"):
11
+ def execute_query(db_query, db_url=None, db_user=None, db_pass=None, db_host="localhost", db_port=5432, db_name="postgres"):
11
12
  """
12
13
  Connect to PostgreSQL database, execute a query, and return status message.
13
14
 
14
15
  Args:
15
- db_user (str): Database username
16
- db_pass (str): Database password
17
16
  db_query (str): SQL query to execute
18
- db_host (str): Database host (default: localhost)
19
- db_port (int): Database port (default: 5432)
20
- db_name (str): Database name (default: postgres)
17
+ db_url (str, optional): Database connection URL (e.g., postgresql://user:pass@host:port/dbname)
18
+ Supports postgresql+asyncpg:// format as well
19
+ db_user (str, optional): Database username (used if db_url is not provided)
20
+ db_pass (str, optional): Database password (used if db_url is not provided)
21
+ db_host (str): Database host (default: localhost, used if db_url is not provided)
22
+ db_port (int): Database port (default: 5432, used if db_url is not provided)
23
+ db_name (str): Database name (default: postgres, used if db_url is not provided)
21
24
 
22
25
  Returns:
23
26
  dict: Status message with success/failure information
@@ -26,6 +29,18 @@ def execute_query(db_user, db_pass, db_query, db_host="localhost", db_port=5432,
26
29
  cursor = None
27
30
 
28
31
  try:
32
+ # Parse connection URL if provided
33
+ if db_url:
34
+ # Handle SQLAlchemy-style URLs (postgresql+asyncpg://)
35
+ url = db_url.replace('postgresql+asyncpg://', 'postgresql://')
36
+ parsed = urlparse(url)
37
+
38
+ db_host = parsed.hostname
39
+ db_port = parsed.port or 5432
40
+ db_name = parsed.path.lstrip('/')
41
+ db_user = unquote(parsed.username) if parsed.username else None
42
+ db_pass = unquote(parsed.password) if parsed.password else None
43
+
29
44
  # Establish database connection
30
45
  connection = psycopg2.connect(
31
46
  host=db_host,
@@ -125,19 +140,37 @@ def delete_on_retention_period(table_delete: dict, batch_size: int = 100000, int
125
140
  table_query = TableQuery(**table_delete)
126
141
  except Exception as e:
127
142
  logger.error(f"Error creating TableQuery object: {str(e)}")
128
- raise ValueError("Invalid table_delete data format. Expected a dictionary with 'name', 'column_name', 'db_host', 'db_port', 'db_name', 'db_user', and 'db_pass' keys.")
143
+ raise ValueError("Invalid table_delete data format. Expected a dictionary with 'table_name', 'column_name', and either 'db_url' or ('db_host', 'db_port', 'db_name', 'db_user', 'db_pass') keys.")
129
144
 
130
145
  connection = None
131
146
  cursor = None
132
147
 
133
148
  try:
149
+ # Parse connection URL if provided
150
+ if table_query.db_url:
151
+ # Handle SQLAlchemy-style URLs (postgresql+asyncpg://)
152
+ url = table_query.db_url.replace('postgresql+asyncpg://', 'postgresql://')
153
+ parsed = urlparse(url)
154
+
155
+ db_host = parsed.hostname
156
+ db_port = parsed.port or 5432
157
+ db_name = parsed.path.lstrip('/')
158
+ db_user = unquote(parsed.username) if parsed.username else None
159
+ db_pass = unquote(parsed.password) if parsed.password else None
160
+ else:
161
+ db_host = table_query.db_host
162
+ db_port = table_query.db_port
163
+ db_name = table_query.db_name
164
+ db_user = table_query.db_user
165
+ db_pass = table_query.db_pass
166
+
134
167
  # Establish database connection
135
168
  connection = psycopg2.connect(
136
- host=table_query.db_host,
137
- port=table_query.db_port,
138
- database=table_query.db_name,
139
- user=table_query.db_user,
140
- password=table_query.db_pass
169
+ host=db_host,
170
+ port=db_port,
171
+ database=db_name,
172
+ user=db_user,
173
+ password=db_pass
141
174
  )
142
175
 
143
176
  cursor = connection.cursor()
@@ -1,33 +1,65 @@
1
1
  import os
2
2
  import shutil
3
+ import time
3
4
  import subprocess
4
5
  import tempfile
5
6
  from pathlib import Path
6
7
 
8
+ import jwt
9
+ import requests
10
+ from git import Repo
11
+
7
12
  from prefect import get_run_logger
8
13
 
9
14
  logger = get_run_logger()
10
15
 
11
16
 
12
- def clone_pat_repo(git_pat, git_url, clone_base_path):
17
+ def is_ssh_clone(git_method: str) -> bool:
18
+ """ Determine if the git clone method is SSH based on the provided method string. """
19
+ result = git_method.lower() == 'ssh'
20
+ logger.info(f"Checking if git method '{git_method}' is SSH: {result}")
21
+ return result
22
+
23
+ def is_pat_clone(git_method: str) -> bool:
24
+ """ Determine if the git clone method is PAT based on the provided method string. """
25
+ result = git_method.lower() == 'pat'
26
+ logger.info(f"Checking if git method '{git_method}' is PAT: {result}")
27
+ return result
28
+
29
+ def is_gh_apps_clone(git_method: str) -> bool:
30
+ """ Determine if the git clone method is GitHub App based on the provided method string. """
31
+ result = git_method.lower() == 'apps'
32
+ logger.info(f"Checking if git method '{git_method}' is GitHub Apps: {result}")
33
+ return result
34
+
35
+
36
+ def clone_repo_pat(git_pat, git_url, clone_base_path):
13
37
  """ Clone a Git repository using a Personal Access Token (PAT) for authentication."""
38
+ logger.info(f"Starting PAT-based git clone for URL: {git_url}")
39
+ logger.info(f"Clone base path: {clone_base_path}")
40
+
14
41
  # Retrieve environment variables
15
42
  access_token = git_pat # os.environ.get('GIT_PAT')
16
43
  repo_url = git_url # os.environ.get('GIT_URL')
17
44
 
18
45
  if not access_token or not repo_url:
46
+ logger.error("Missing required parameters: git_pat or git_url")
19
47
  raise ValueError("Environment variables GIT_PAT or GIT_URL are not set")
20
48
 
21
49
  # Correctly format the URL with the PAT
50
+ logger.info("Formatting URL with PAT authentication")
22
51
  if 'https://' in repo_url:
23
52
  # Splitting the URL and inserting the PAT
24
53
  parts = repo_url.split('https://', 1)
25
54
  repo_url = f'https://{access_token}@{parts[1]}'
55
+ logger.info("Successfully formatted URL with PAT")
26
56
  else:
57
+ logger.error(f"Invalid URL format: {repo_url}. Must begin with https://")
27
58
  raise ValueError("URL must begin with https:// for PAT authentication")
28
59
 
29
60
  # Directory where the repo will be cloned
30
61
  repo_path = os.path.join(clone_base_path, 'manifest-repo')
62
+ logger.info(f"Target repository path: {repo_path}")
31
63
 
32
64
  # Clone the repository
33
65
  if not os.path.exists(repo_path):
@@ -38,7 +70,7 @@ def clone_pat_repo(git_pat, git_url, clone_base_path):
38
70
  logger.info(f"Repository already exists at {repo_path}")
39
71
 
40
72
 
41
- def clone_ssh_repo(
73
+ def clone_repo_ssh(
42
74
  git_url: str,
43
75
  clone_base_path: str,
44
76
  repo_dir_name: str = "manifest-repo",
@@ -51,23 +83,33 @@ def clone_ssh_repo(
51
83
  - GIT_SSH_PRIVATE_KEY: full private key (BEGIN/END ...)
52
84
  - GIT_SSH_KNOWN_HOSTS: lines from `ssh-keyscan github.com`
53
85
  """
86
+ logger.info(f"Starting SSH-based git clone for URL: {git_url}")
87
+ logger.info(f"Clone base path: {clone_base_path}, repo directory: {repo_dir_name}")
88
+ logger.info(f"Clone depth: {depth}")
89
+
54
90
  if not git_url.startswith("git@"):
91
+ logger.error(f"Invalid SSH URL format: {git_url}")
55
92
  raise ValueError("git_url must be an SSH URL like 'git@github.com:org/repo.git'")
56
93
 
94
+ logger.info(f"Reading SSH credentials from environment variables: {ssh_key_env}, {known_hosts_env}")
57
95
  priv_key = os.environ.get(ssh_key_env)
58
96
  kh_data = os.environ.get(known_hosts_env)
59
97
  if not priv_key:
98
+ logger.error(f"Missing SSH private key environment variable: {ssh_key_env}")
60
99
  raise ValueError(f"Missing env var {ssh_key_env}")
61
100
  if not kh_data:
101
+ logger.error(f"Missing SSH known hosts environment variable: {known_hosts_env}")
62
102
  raise ValueError(f"Missing env var {known_hosts_env}")
63
103
 
64
104
  base = Path(clone_base_path).expanduser().resolve()
65
105
  base.mkdir(parents=True, exist_ok=True)
66
106
  repo_path = base / repo_dir_name
107
+ logger.info(f"Target repository path: {repo_path}")
67
108
 
68
109
  tmpdir = Path(tempfile.mkdtemp(prefix="git_ssh_"))
69
110
  key_path = tmpdir / "id_rsa"
70
111
  kh_path = tmpdir / "known_hosts"
112
+ logger.info(f"Created temporary directory for SSH keys: {tmpdir}")
71
113
 
72
114
  try:
73
115
  key_path.write_text(priv_key, encoding="utf-8")
@@ -88,18 +130,28 @@ def clone_ssh_repo(
88
130
  env["GIT_SSH_COMMAND"] = ssh_cmd
89
131
 
90
132
  if not repo_path.exists():
133
+ logger.info(f"Repository doesn't exist, performing fresh clone")
91
134
  cmd = ["git", "clone"]
92
135
  if depth and depth > 0:
93
136
  cmd += ["--depth", str(depth)]
94
137
  cmd += [git_url, str(repo_path)]
138
+ logger.info(f"Executing git clone command: {' '.join(cmd[:-1])} <repo_path>")
95
139
  subprocess.check_call(cmd, env=env)
140
+ logger.info("Git clone completed successfully")
96
141
  else:
142
+ logger.info(f"Repository already exists at {repo_path}, updating existing repo")
97
143
  if not (repo_path / ".git").exists():
144
+ logger.error(f"Path exists but is not a git repository: {repo_path}")
98
145
  raise RuntimeError(f"Path exists but is not a git repo: {repo_path}")
146
+ logger.info("Updating remote URL")
99
147
  subprocess.check_call(["git", "remote", "set-url", "origin", git_url], cwd=repo_path, env=env)
148
+ logger.info("Fetching latest changes")
100
149
  subprocess.check_call(["git", "fetch", "--all", "--prune"], cwd=repo_path, env=env)
150
+ logger.info("Pulling latest changes")
101
151
  subprocess.check_call(["git", "pull", "--ff-only", "origin"], cwd=repo_path, env=env)
152
+ logger.info("Repository update completed successfully")
102
153
 
154
+ logger.info(f"SSH clone operation completed, returning path: {repo_path}")
103
155
  return repo_path
104
156
 
105
157
  finally:
@@ -107,3 +159,151 @@ def clone_ssh_repo(
107
159
  shutil.rmtree(tmpdir)
108
160
  except Exception:
109
161
  pass
162
+
163
+
164
+
165
+ def _ghapp_installation_token(app_id: str, installation_id: str, private_key_pem: str) -> str:
166
+ """Create an App-signed JWT and exchange it for a short-lived installation token (~1h)."""
167
+ logger.info(f"Creating GitHub App installation token for app_id: {app_id}, installation_id: {installation_id}")
168
+
169
+ now = int(time.time())
170
+ payload = {"iat": now - 60, "exp": now + 9 * 60, "iss": app_id} # JWT max 10m
171
+ app_jwt = jwt.encode(payload, private_key_pem, algorithm="RS256")
172
+ logger.info("JWT token created successfully")
173
+
174
+ headers = {"Authorization": f"Bearer {app_jwt}", "Accept": "application/vnd.github+json"}
175
+ logger.info("Requesting installation access token from GitHub API")
176
+ resp = requests.post(
177
+ f"https://api.github.com/app/installations/{installation_id}/access_tokens",
178
+ headers=headers,
179
+ timeout=20,
180
+ )
181
+ resp.raise_for_status()
182
+ logger.info("Installation access token retrieved successfully")
183
+ return resp.json()["token"] # valid ~1 hour
184
+
185
+
186
+ def _to_https_url(git_url: str) -> str:
187
+ """
188
+ Accepts either SSH ('git@github.com:org/repo.git') or HTTPS.
189
+ Returns HTTPS form required for GitHub App tokens:
190
+ 'https://github.com/org/repo.git'
191
+ """
192
+ logger.info(f"Converting git URL to HTTPS format: {git_url}")
193
+
194
+ if git_url.startswith("git@github.com:"):
195
+ org_repo = git_url.split("git@github.com:", 1)[1]
196
+ https_url = f"https://github.com/{org_repo}"
197
+ logger.info(f"Converted SSH URL to HTTPS: {https_url}")
198
+ return https_url
199
+ if git_url.startswith("https://"):
200
+ logger.info("URL is already in HTTPS format")
201
+ return git_url
202
+
203
+ logger.error(f"Invalid git URL format: {git_url}")
204
+ raise ValueError("git_url must be an SSH url for github.com or an https:// URL")
205
+
206
+
207
+ def clone_repo_github_app(
208
+ git_url: str,
209
+ clone_base_path: str,
210
+ repo_dir_name: str = "manifest-repo",
211
+ depth: int = 1,
212
+ app_id_env: str = "GITHUB_APP_ID",
213
+ installation_id_env: str = "GITHUB_INSTALLATION_ID",
214
+ private_key_env: str = "GITHUB_APP_PRIVATE_KEY",
215
+ ) -> Path:
216
+ """
217
+ Clone/update a repo using a GitHub App installation token (HTTPS).
218
+
219
+ Env vars required:
220
+ - GITHUB_APP_ID : the App ID (numeric string)
221
+ - GITHUB_INSTALLATION_ID : the installation ID (numeric string)
222
+ - GITHUB_APP_PRIVATE_KEY : the App private key PEM (BEGIN/END ...)
223
+
224
+ Notes:
225
+ - Token is minted on the fly and embedded in the clone URL:
226
+ https://x-access-token:<token>@github.com/org/repo.git
227
+ - No SSH keys / known_hosts needed.
228
+ """
229
+ logger.info(f"Starting GitHub App-based git clone for URL: {git_url}")
230
+ logger.info(f"Clone base path: {clone_base_path}, repo directory: {repo_dir_name}")
231
+ logger.info(f"Clone depth: {depth}")
232
+
233
+ logger.info(f"Reading GitHub App credentials from environment variables: {app_id_env}, {installation_id_env}, {private_key_env}")
234
+ app_id = os.environ.get(app_id_env)
235
+ inst_id = os.environ.get(installation_id_env)
236
+ pem = os.environ.get(private_key_env)
237
+
238
+ if not app_id or not inst_id or not pem:
239
+ logger.error(f"Missing GitHub App environment variables. Required: {app_id_env}, {installation_id_env}, {private_key_env}")
240
+ raise ValueError(f"Missing one of env vars: {app_id_env}, {installation_id_env}, {private_key_env}")
241
+
242
+ https_url = _to_https_url(git_url)
243
+ logger.info("Obtaining GitHub App installation token")
244
+ token = _ghapp_installation_token(app_id, inst_id, pem)
245
+
246
+ # Build an authenticated URL (avoids credential helpers)
247
+ authed_url = f"https://x-access-token:{token}@{https_url.split('https://',1)[1]}"
248
+ logger.info("Successfully created authenticated URL with installation token")
249
+
250
+ base = Path(clone_base_path).expanduser().resolve()
251
+ base.mkdir(parents=True, exist_ok=True)
252
+ repo_path = base / repo_dir_name
253
+ logger.info(f"Target repository path: {repo_path}")
254
+
255
+ # Ensure git won't prompt for creds in CI
256
+ env = os.environ.copy()
257
+ env.setdefault("GIT_TERMINAL_PROMPT", "0")
258
+ env.setdefault("GCM_INTERACTIVE", "Never") # in case Git Credential Manager is present
259
+
260
+ if not repo_path.exists():
261
+ logger.info(f"Repository doesn't exist, performing fresh clone")
262
+ cmd = ["git", "clone"]
263
+ if depth and depth > 0:
264
+ cmd += ["--depth", str(depth)]
265
+ cmd += [authed_url, str(repo_path)]
266
+ logger.info(f"Executing git clone command with GitHub App authentication")
267
+ subprocess.check_call(cmd, env=env)
268
+ logger.info("Git clone completed successfully")
269
+ else:
270
+ logger.info(f"Repository already exists at {repo_path}, updating existing repo")
271
+ if not (repo_path / ".git").exists():
272
+ logger.error(f"Path exists but is not a git repository: {repo_path}")
273
+ raise RuntimeError(f"Path exists but is not a git repo: {repo_path}")
274
+ # Refresh remote URL & pull default branch
275
+ logger.info("Updating remote URL with new GitHub App token")
276
+ subprocess.check_call(["git", "remote", "set-url", "origin", authed_url], cwd=repo_path, env=env)
277
+ logger.info("Fetching latest changes")
278
+ subprocess.check_call(["git", "fetch", "--all", "--prune"], cwd=repo_path, env=env)
279
+ logger.info("Pulling latest changes")
280
+ subprocess.check_call(["git", "pull", "--ff-only", "origin"], cwd=repo_path, env=env)
281
+ logger.info("Repository update completed successfully")
282
+
283
+ logger.info(f"GitHub App clone operation completed, returning path: {repo_path}")
284
+ return repo_path
285
+
286
+
287
+
288
+ def generate_github_creds(
289
+ app_id_env: str = "GITHUB_APP_ID",
290
+ installation_id_env: str = "GITHUB_INSTALLATION_ID",
291
+ private_key_env: str = "GITHUB_APP_PRIVATE_KEY",
292
+ ):
293
+ """
294
+ Generate GitHub credentials using a GitHub App installation token.
295
+ """
296
+ app_id = os.environ.get(app_id_env)
297
+ installation_id = os.environ.get(installation_id_env)
298
+ private_key = os.environ.get(private_key_env)
299
+
300
+ if not app_id or not installation_id or not private_key:
301
+ logger.error("Missing GitHub App environment variables.")
302
+ raise ValueError(f"Missing one of env vars: {app_id_env}, {installation_id_env}, {private_key_env}")
303
+
304
+ token = _ghapp_installation_token(app_id, installation_id, private_key)
305
+
306
+ return {
307
+ "username": "x-access-token",
308
+ "password": token
309
+ }
@@ -92,7 +92,7 @@ def insert_gn_record(session, xsrf_token, xml_string):
92
92
  }
93
93
 
94
94
  # Send a put request to the endpoint to create record
95
- response = session.put(GN_URL + '/geonetwork/srv/api/0.1/records',
95
+ response = session.put(GN_URL + '/geonetwork/srv/api/records',
96
96
  data=xml_string,
97
97
  params=params,
98
98
  auth=(GN_USERNAME, GN_PASSWORD),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kubernetes-watch
3
- Version: 0.1.12
3
+ Version: 0.1.14
4
4
  Summary:
5
5
  Author: bmotevalli
6
6
  Author-email: b.motevalli@gmail.com
@@ -9,10 +9,10 @@ kube_watch/models/common.py,sha256=FQktpX552zSCigMxEzm4S07SvrHv5RA7YwVJHgv7uuI,5
9
9
  kube_watch/models/workflow.py,sha256=ZFBMz_LmYgROcbz2amSvms38K770njnyZC6h1bpTXGU,1634
10
10
  kube_watch/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  kube_watch/modules/clusters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- kube_watch/modules/clusters/kube.py,sha256=ZvWpLrdgftLHexuigil8aa23BjqTZDmyeb6ZCAW6Y7w,10205
12
+ kube_watch/modules/clusters/kube.py,sha256=DiHhXiX8p4UX7fbyu1xhjNWcZPm3nkHTI_NPW-JeLb4,11467
13
13
  kube_watch/modules/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- kube_watch/modules/database/model.py,sha256=MWG9UW6g0KuBzW6MjzPBtknAk7GmuncQrdAq6HHarTo,207
15
- kube_watch/modules/database/postgre.py,sha256=1Sq2YFwgCJM_FWKabV2S1bFAIl2GBwytTtPCuLfVhu8,8182
14
+ kube_watch/modules/database/model.py,sha256=sHJdDykrEGqBemCTAlPt0_sqSz1l30FPrfxgAvJAOtw,341
15
+ kube_watch/modules/database/postgre.py,sha256=EK5LlYDarsHquNH4NOh9kh4ernj3RJ890PPKElTrELg,9905
16
16
  kube_watch/modules/logic/actions.py,sha256=hMvqqzR2EzcZ68_O8GdyLaPSLftA-tWAPaJnKdUMj-k,2416
17
17
  kube_watch/modules/logic/checks.py,sha256=7tIR5ipZgnYsAI3ref0qfeFmzXpSyWJNclnO45OUizs,327
18
18
  kube_watch/modules/logic/load.py,sha256=XC-SsWIChhW-QXJeCGMsLuLsn9v5nRni5Y6utwYLt48,781
@@ -23,14 +23,14 @@ kube_watch/modules/mock/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
23
23
  kube_watch/modules/mock/mock_generator.py,sha256=BKKQFCxxQgFW_GFgeIbkyIbuNU4328xTTaFfTwFLsS8,1262
24
24
  kube_watch/modules/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  kube_watch/modules/providers/aws.py,sha256=qKL7oGKeKOUO5AQRQqcrR35kzOpq42uNXuXumeU-gtw,10224
26
- kube_watch/modules/providers/git.py,sha256=5d7vkeTbVD_XN-mpCoPTRmM6lwgrwkDwcCIsjqYwmaQ,3778
26
+ kube_watch/modules/providers/git.py,sha256=E1XJ1QN0ekoud7XQkwRkQTuZo3_5F-v7c_NJ9CjTos4,12934
27
27
  kube_watch/modules/providers/github.py,sha256=eQY8sLy2U6bOWMpFxA73DFCPVuswhTXSG25KmYSuo5s,5212
28
28
  kube_watch/modules/providers/vault.py,sha256=etzzHbTrUDsTUpeUN-xg0Xh8ulqC0-1FA3tHRZinIOo,7193
29
- kube_watch/standalone/metarecogen/ckan_to_gn.py,sha256=LWd7ikyxRIC1IGt6CtALnDOEoyuG07a8NoDHhgMkX4o,4635
29
+ kube_watch/standalone/metarecogen/ckan_to_gn.py,sha256=OcA2jkjIVhgrdaCmjEpAdR60-XTGYvY2uGJPd3bkHTA,4631
30
30
  kube_watch/watch/__init__.py,sha256=9KE0Sf1nLUTNaFvXbiQCgf11vpG8Xgmb5ddeMAmak3Q,88
31
31
  kube_watch/watch/helpers.py,sha256=8BQnQ6AeLHs0JEq54iKYDvWURb1F-kROJxwIcl_nv_Y,6276
32
32
  kube_watch/watch/workflow.py,sha256=CaXHFuEWVsFjBv5dU4IfVMeTlGJWyKaE1But9-YzVWk,9769
33
- kubernetes_watch-0.1.12.dist-info/LICENSE,sha256=_H2QdL-2dXbivDmOpJ11DnqJewSFhSJwGpHx_WAE-CA,1075
34
- kubernetes_watch-0.1.12.dist-info/METADATA,sha256=zG9wEStvXgfYthz6Aa5i05Oyoh7ygmIMWtI8kdzRM00,5600
35
- kubernetes_watch-0.1.12.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
- kubernetes_watch-0.1.12.dist-info/RECORD,,
33
+ kubernetes_watch-0.1.14.dist-info/LICENSE,sha256=_H2QdL-2dXbivDmOpJ11DnqJewSFhSJwGpHx_WAE-CA,1075
34
+ kubernetes_watch-0.1.14.dist-info/METADATA,sha256=-cY70V1_b1yFRYc7ovGyLWGl69Hlwub7b4HnrVtogOM,5600
35
+ kubernetes_watch-0.1.14.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
+ kubernetes_watch-0.1.14.dist-info/RECORD,,