Skip to content

Commit 1da6c99

Browse files
committed
formatting
1 parent d37558c commit 1da6c99

3 files changed

Lines changed: 61 additions & 63 deletions

File tree

src/mas/devops/backup.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,5 +228,3 @@ def backupResources(dynClient: DynamicClient, kind: str, api_version: str, backu
228228
logger.error(f"Error backing up {kind} resources: {e}")
229229
failed_count = 1
230230
return (backed_up_count, not_found_count, failed_count, discovered_secrets)
231-
232-

src/mas/devops/restore.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
def loadYamlFile(file_path: str):
1919
"""
2020
Load YAML content from a file
21-
21+
2222
Args:
2323
file_path: Path to the YAML file
24-
24+
2525
Returns:
2626
dict: Parsed YAML content or None if error
2727
"""
@@ -40,13 +40,13 @@ def restoreResource(dynClient: DynamicClient, resource_data: dict, namespace=Non
4040
If the resource exists and replace_resource is True, it will be updated (replaced).
4141
If the resource exists and replace_resource is False, it will be skipped.
4242
If the resource doesn't exist, it will be created.
43-
43+
4444
Args:
4545
dynClient: Kubernetes dynamic client
4646
resource_data: Dictionary containing the resource definition
4747
namespace: Optional namespace override (uses resource's namespace if not provided)
4848
replace_resource: If True, replace existing resources; if False, skip them (default: True)
49-
49+
5050
Returns:
5151
tuple: (success: bool, resource_name: str, status_message: str or None)
5252
- success: True if created, updated, or skipped; False if failed
@@ -60,18 +60,18 @@ def restoreResource(dynClient: DynamicClient, resource_data: dict, namespace=Non
6060
metadata = resource_data.get('metadata', {})
6161
resource_name = metadata.get('name')
6262
resource_namespace = namespace or metadata.get('namespace')
63-
63+
6464
if not kind or not api_version or not resource_name:
6565
error_msg = "Resource missing required fields (kind, apiVersion, or name)"
6666
logger.error(error_msg)
6767
return (False, resource_name or 'unknown', error_msg)
68-
68+
6969
# Get the resource API
7070
resourceAPI = dynClient.resources.get(api_version=api_version, kind=kind)
71-
71+
7272
# Determine scope description for logging
7373
scope_desc = f"namespace '{resource_namespace}'" if resource_namespace else "cluster-level"
74-
74+
7575
# Check if resource already exists
7676
resource_exists = False
7777
existing_resource = None
@@ -83,14 +83,14 @@ def restoreResource(dynClient: DynamicClient, resource_data: dict, namespace=Non
8383
resource_exists = existing_resource is not None
8484
except NotFoundError:
8585
resource_exists = False
86-
86+
8787
# Apply the resource (create, update, or skip)
8888
try:
8989
if resource_exists:
9090
if replace_resource:
9191
# Resource exists - update it using strategic merge patch
9292
logger.info(f"Patching existing {kind} '{resource_name}' in {scope_desc}")
93-
93+
9494
if resource_namespace:
9595
resourceAPI.patch(body=resource_data, name=resource_name, namespace=resource_namespace, content_type='application/merge-patch+json')
9696
else:
@@ -115,8 +115,8 @@ def restoreResource(dynClient: DynamicClient, resource_data: dict, namespace=Non
115115
error_msg = f"Failed to {action} {kind} '{resource_name}': {e}"
116116
logger.error(error_msg)
117117
return (False, resource_name, error_msg)
118-
118+
119119
except Exception as e:
120120
error_msg = f"Error restoring resource: {e}"
121121
logger.error(error_msg)
122-
return (False, resource_data.get('metadata', {}).get('name', 'unknown'), error_msg)
122+
return (False, resource_data.get('metadata', {}).get('name', 'unknown'), error_msg)

test/src/test_restore.py

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ def test_load_valid_yaml_file(self, tmp_path):
2828
'namespace': 'test-ns'
2929
}
3030
}
31-
31+
3232
yaml_file = tmp_path / "test.yaml"
3333
with open(yaml_file, 'w') as f:
3434
yaml.dump(yaml_content, f)
35-
35+
3636
result = loadYamlFile(str(yaml_file))
37-
37+
3838
assert result is not None
3939
assert result['kind'] == 'ConfigMap'
4040
assert result['metadata']['name'] == 'test-config'
@@ -43,33 +43,33 @@ def test_load_empty_yaml_file(self, tmp_path):
4343
"""Test loading an empty YAML file"""
4444
yaml_file = tmp_path / "empty.yaml"
4545
yaml_file.write_text("")
46-
46+
4747
result = loadYamlFile(str(yaml_file))
48-
48+
4949
assert result is None
5050

5151
def test_load_nonexistent_file(self):
5252
"""Test loading a non-existent file"""
5353
result = loadYamlFile("/nonexistent/path/file.yaml")
54-
54+
5555
assert result is None
5656

5757
def test_load_invalid_yaml_file(self, tmp_path):
5858
"""Test loading an invalid YAML file"""
5959
yaml_file = tmp_path / "invalid.yaml"
6060
yaml_file.write_text("invalid: yaml: content: [")
61-
61+
6262
result = loadYamlFile(str(yaml_file))
63-
63+
6464
assert result is None
6565

6666
def test_load_yaml_with_multiple_documents(self, tmp_path):
6767
"""Test loading YAML file with multiple documents returns None (not supported)"""
6868
yaml_file = tmp_path / "multi.yaml"
6969
yaml_file.write_text("---\nkey1: value1\n---\nkey2: value2")
70-
70+
7171
result = loadYamlFile(str(yaml_file))
72-
72+
7373
# yaml.safe_load() doesn't support multiple documents, so it should return None
7474
assert result is None
7575

@@ -96,12 +96,12 @@ def test_create_new_namespaced_resource(self):
9696
'key': 'value'
9797
}
9898
}
99-
99+
100100
# Resource doesn't exist
101101
self.mock_resource_api.get.side_effect = NotFoundError(Mock())
102-
102+
103103
success, name, status = restoreResource(self.mock_client, resource_data)
104-
104+
105105
assert success is True
106106
assert name == 'test-config'
107107
assert status is None
@@ -119,12 +119,12 @@ def test_create_new_cluster_resource(self):
119119
'name': 'test-namespace'
120120
}
121121
}
122-
122+
123123
# Resource doesn't exist
124124
self.mock_resource_api.get.side_effect = NotFoundError(Mock())
125-
125+
126126
success, name, status = restoreResource(self.mock_client, resource_data)
127-
127+
128128
assert success is True
129129
assert name == 'test-namespace'
130130
assert status is None
@@ -145,7 +145,7 @@ def test_update_existing_resource_with_replace_true(self):
145145
'key': 'new-value'
146146
}
147147
}
148-
148+
149149
# Resource exists
150150
existing_resource = {
151151
'metadata': {
@@ -154,9 +154,9 @@ def test_update_existing_resource_with_replace_true(self):
154154
}
155155
}
156156
self.mock_resource_api.get.return_value = existing_resource
157-
157+
158158
success, name, status = restoreResource(self.mock_client, resource_data, replace_resource=True)
159-
159+
160160
assert success is True
161161
assert name == 'test-config'
162162
assert status == 'updated'
@@ -177,13 +177,13 @@ def test_skip_existing_resource_with_replace_false(self):
177177
'namespace': 'test-ns'
178178
}
179179
}
180-
180+
181181
# Resource exists
182182
existing_resource = {'metadata': {'name': 'test-config'}}
183183
self.mock_resource_api.get.return_value = existing_resource
184-
184+
185185
success, name, status = restoreResource(self.mock_client, resource_data, replace_resource=False)
186-
186+
187187
assert success is True
188188
assert name == 'test-config'
189189
assert status == 'skipped'
@@ -200,16 +200,16 @@ def test_namespace_override(self):
200200
'namespace': 'original-ns'
201201
}
202202
}
203-
203+
204204
# Resource doesn't exist
205205
self.mock_resource_api.get.side_effect = NotFoundError(Mock())
206-
206+
207207
success, name, status = restoreResource(
208208
self.mock_client,
209209
resource_data,
210210
namespace='override-ns'
211211
)
212-
212+
213213
assert success is True
214214
self.mock_resource_api.create.assert_called_once_with(
215215
body=resource_data,
@@ -224,9 +224,9 @@ def test_missing_kind_field(self):
224224
'name': 'test-resource'
225225
}
226226
}
227-
227+
228228
success, name, status = restoreResource(self.mock_client, resource_data)
229-
229+
230230
assert success is False
231231
assert name == 'test-resource'
232232
assert 'missing required fields' in status.lower()
@@ -239,9 +239,9 @@ def test_missing_api_version_field(self):
239239
'name': 'test-resource'
240240
}
241241
}
242-
242+
243243
success, name, status = restoreResource(self.mock_client, resource_data)
244-
244+
245245
assert success is False
246246
assert name == 'test-resource'
247247
assert 'missing required fields' in status.lower()
@@ -253,9 +253,9 @@ def test_missing_name_field(self):
253253
'kind': 'ConfigMap',
254254
'metadata': {}
255255
}
256-
256+
257257
success, name, status = restoreResource(self.mock_client, resource_data)
258-
258+
259259
assert success is False
260260
assert name == 'unknown'
261261
assert 'missing required fields' in status.lower()
@@ -270,14 +270,14 @@ def test_create_failure(self):
270270
'namespace': 'test-ns'
271271
}
272272
}
273-
273+
274274
# Resource doesn't exist
275275
self.mock_resource_api.get.side_effect = NotFoundError(Mock())
276276
# Create fails
277277
self.mock_resource_api.create.side_effect = Exception("Create failed")
278-
278+
279279
success, name, status = restoreResource(self.mock_client, resource_data)
280-
280+
281281
assert success is False
282282
assert name == 'test-config'
283283
assert 'Failed to create' in status
@@ -293,15 +293,15 @@ def test_patch_failure(self):
293293
'namespace': 'test-ns'
294294
}
295295
}
296-
296+
297297
# Resource exists
298298
existing_resource = {'metadata': {'name': 'test-config'}}
299299
self.mock_resource_api.get.return_value = existing_resource
300300
# Patch fails
301301
self.mock_resource_api.patch.side_effect = Exception("Patch failed")
302-
302+
303303
success, name, status = restoreResource(self.mock_client, resource_data, replace_resource=True)
304-
304+
305305
assert success is False
306306
assert name == 'test-config'
307307
assert 'Failed to update' in status
@@ -316,12 +316,12 @@ def test_resource_api_get_failure(self):
316316
'name': 'test-config'
317317
}
318318
}
319-
319+
320320
# Getting resource API fails
321321
self.mock_client.resources.get.side_effect = Exception("API not found")
322-
322+
323323
success, name, status = restoreResource(self.mock_client, resource_data)
324-
324+
325325
assert success is False
326326
assert name == 'test-config'
327327
assert 'Error restoring resource' in status
@@ -335,13 +335,13 @@ def test_update_cluster_scoped_resource(self):
335335
'name': 'test-namespace'
336336
}
337337
}
338-
338+
339339
# Resource exists
340340
existing_resource = {'metadata': {'name': 'test-namespace'}}
341341
self.mock_resource_api.get.return_value = existing_resource
342-
342+
343343
success, name, status = restoreResource(self.mock_client, resource_data, replace_resource=True)
344-
344+
345345
assert success is True
346346
assert name == 'test-namespace'
347347
assert status == 'updated'
@@ -358,9 +358,9 @@ def test_malformed_resource_data(self):
358358
'kind': 'ConfigMap'
359359
# Missing metadata entirely
360360
}
361-
361+
362362
success, name, status = restoreResource(self.mock_client, resource_data)
363-
363+
364364
assert success is False
365365
assert name == 'unknown'
366366
assert 'missing required fields' in status.lower()
@@ -385,13 +385,13 @@ def test_resource_with_complex_metadata(self):
385385
'replicas': 3
386386
}
387387
}
388-
388+
389389
# Resource doesn't exist
390390
self.mock_resource_api.get.side_effect = NotFoundError(Mock())
391-
391+
392392
success, name, status = restoreResource(self.mock_client, resource_data)
393-
393+
394394
assert success is True
395395
assert name == 'test-deployment'
396396
assert status is None
397-
self.mock_resource_api.create.assert_called_once()
397+
self.mock_resource_api.create.assert_called_once()

0 commit comments

Comments
 (0)