yellowdog-python-examples 7.4.9__tar.gz → 7.4.10__tar.gz

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.
Files changed (71) hide show
  1. {yellowdog-python-examples-7.4.9/yellowdog_python_examples.egg-info → yellowdog-python-examples-7.4.10}/PKG-INFO +1 -1
  2. yellowdog-python-examples-7.4.10/yd_commands/__init__.py +1 -0
  3. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/azure_cloudwizard.py +121 -44
  4. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10/yellowdog_python_examples.egg-info}/PKG-INFO +1 -1
  5. yellowdog-python-examples-7.4.9/yd_commands/__init__.py +0 -1
  6. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/LICENSE +0 -0
  7. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/PYPI_README.md +0 -0
  8. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/README.md +0 -0
  9. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/pyproject.toml +0 -0
  10. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/requirements.txt +0 -0
  11. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/setup.cfg +0 -0
  12. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/setup.py +0 -0
  13. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/tests/test_create_remove.py +0 -0
  14. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/tests/test_demos.py +0 -0
  15. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/tests/test_dryruns.py +0 -0
  16. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/tests/test_entrypoints.py +0 -0
  17. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/tests/test_gui.py +0 -0
  18. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/tests/test_list.py +0 -0
  19. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/tests/test_objects.py +0 -0
  20. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/tests/test_variable_processing.py +0 -0
  21. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/abort.py +0 -0
  22. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/admin.py +0 -0
  23. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/args.py +0 -0
  24. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/aws_cloudwizard.py +0 -0
  25. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/aws_types.py +0 -0
  26. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/cancel.py +0 -0
  27. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/check_imports.py +0 -0
  28. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/cloudwizard.py +0 -0
  29. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/common_cloudwizard.py +0 -0
  30. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/compact_json.py +0 -0
  31. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/config_types.py +0 -0
  32. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/create.py +0 -0
  33. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/csv_data.py +0 -0
  34. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/delete.py +0 -0
  35. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/download.py +0 -0
  36. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/follow.py +0 -0
  37. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/follow_utils.py +0 -0
  38. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/gcp_cloudwizard.py +0 -0
  39. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/id_utils.py +0 -0
  40. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/instantiate.py +0 -0
  41. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/interactive.py +0 -0
  42. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/jsonnet2json.py +0 -0
  43. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/list.py +0 -0
  44. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/load_config.py +0 -0
  45. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/load_resources.py +0 -0
  46. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/object_utilities.py +0 -0
  47. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/printing.py +0 -0
  48. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/property_names.py +0 -0
  49. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/provision.py +0 -0
  50. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/provision_utils.py +0 -0
  51. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/reformat_json.py +0 -0
  52. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/remove.py +0 -0
  53. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/resize.py +0 -0
  54. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/settings.py +0 -0
  55. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/shutdown.py +0 -0
  56. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/submit.py +0 -0
  57. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/submit_utils.py +0 -0
  58. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/terminate.py +0 -0
  59. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/type_check.py +0 -0
  60. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/upload.py +0 -0
  61. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/upload_utils.py +0 -0
  62. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/utils.py +0 -0
  63. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/validate_properties.py +0 -0
  64. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/variables.py +0 -0
  65. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/version.py +0 -0
  66. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yd_commands/wrapper.py +0 -0
  67. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yellowdog_python_examples.egg-info/SOURCES.txt +0 -0
  68. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yellowdog_python_examples.egg-info/dependency_links.txt +0 -0
  69. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yellowdog_python_examples.egg-info/entry_points.txt +0 -0
  70. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yellowdog_python_examples.egg-info/requires.txt +0 -0
  71. {yellowdog-python-examples-7.4.9 → yellowdog-python-examples-7.4.10}/yellowdog_python_examples.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: yellowdog-python-examples
3
- Version: 7.4.9
3
+ Version: 7.4.10
4
4
  Summary: Example Python commands using the YellowDog Python SDK
5
5
  Home-page: https://github.com/yellowdog/python-examples
6
6
  Author: YellowDog Limited
@@ -0,0 +1 @@
1
+ __version__ = "7.4.10"
@@ -88,7 +88,7 @@ class AzureConfig(CommonCloudConfig):
88
88
  YD_DEFAULT_INSTANCE_TYPE if instance_type is None else instance_type
89
89
  )
90
90
  self._selected_regions: List[str] = []
91
- self._resource_groups: List[str] = []
91
+ self._created_regions: List[str] = []
92
92
  self._subscription_id = environ[AZURE_SUBSCRIPTION_ID]
93
93
  self._resource_client = ResourceManagementClient(
94
94
  self._credential, self._subscription_id
@@ -133,7 +133,7 @@ class AzureConfig(CommonCloudConfig):
133
133
  print_log("Creating YellowDog resources in the Azure account")
134
134
  print_log(
135
135
  "Please select the Azure regions in which to create resource groups and"
136
- " network resources."
136
+ " network resources"
137
137
  )
138
138
  print_log(
139
139
  "*** Note that only the following region(s) contain"
@@ -166,11 +166,6 @@ class AzureConfig(CommonCloudConfig):
166
166
  if self._storage_region not in regions:
167
167
  regions.append(self._storage_region)
168
168
  storage_region_added = True
169
- rg_name = self._generate_resource_group_name(self._storage_region)
170
- resource_group_added_msg = (
171
- f"Note: Resource group '{rg_name}' is added in order to contain the"
172
- " Azure storage account"
173
- )
174
169
  else:
175
170
  storage_region_added = False
176
171
 
@@ -180,14 +175,15 @@ class AzureConfig(CommonCloudConfig):
180
175
  # Does the resource group already exist?
181
176
  try:
182
177
  if self._resource_client.resource_groups.check_existence(rg_name):
183
- print_warning(f"Azure resource group '{rg_name}' already exists")
184
- self._resource_groups.append(rg_name)
185
178
  if region == self._storage_region and storage_region_added:
186
- print_log(resource_group_added_msg)
187
179
  continue
188
- self._create_network_resources(
180
+ print_warning(f"Azure resource group '{rg_name}' already exists")
181
+ if self._create_network_resources(
189
182
  resource_group_name=rg_name, region=region
190
- )
183
+ ):
184
+ self._created_regions.append(region)
185
+ else:
186
+ self._remove_resource_group_by_name(rg_name)
191
187
  continue
192
188
  except Exception as e:
193
189
  print_warning(
@@ -201,22 +197,44 @@ class AzureConfig(CommonCloudConfig):
201
197
  rg_result = self._resource_client.resource_groups.create_or_update(
202
198
  rg_name, {"location": region}
203
199
  )
204
- self._resource_groups.append(rg_name)
205
200
  print_log(
206
201
  f"Created (or updated) Azure resource group '{rg_result.name}' in"
207
202
  f" region '{rg_result.location}'"
208
203
  )
209
204
  if region == self._storage_region and storage_region_added:
210
- print_log(resource_group_added_msg)
205
+ print_log(
206
+ f"Note: Resource group '{rg_name}' is automatically created to"
207
+ " contain the Azure storage account"
208
+ )
211
209
  continue
212
- self._create_network_resources(
210
+ if self._create_network_resources(
213
211
  resource_group_name=rg_name, region=region
214
- )
212
+ ):
213
+ self._created_regions.append(region)
214
+ else:
215
+ self._remove_resource_group_by_name(rg_name)
216
+
215
217
  except Exception as e:
216
- print_error(
217
- f"Failed to create Azure resource group '{rg_name}' in region"
218
- f" '{region}': {e}"
219
- )
218
+ if "LocationNotAvailable" in str(e):
219
+ print_warning(
220
+ f"Region '{region}' is not available for Resource Group"
221
+ " creation; excluding this region"
222
+ )
223
+ elif "DisallowedLocation" in str(e):
224
+ print_warning(
225
+ f"Region '{region}' is disallowed for Resource Group"
226
+ " creation; excluding this region"
227
+ )
228
+ elif "ResourceGroupBeingDeleted" in str(e):
229
+ print_warning(
230
+ f"Existing Resource Group '{rg_name}' is in the process of"
231
+ " being deleted; please try again later"
232
+ )
233
+ else:
234
+ print_error(
235
+ f"Failed to create Azure resource group '{rg_name}' in region"
236
+ f" '{region}': {e}"
237
+ )
220
238
  continue
221
239
 
222
240
  def _remove_resource_groups(self):
@@ -244,10 +262,17 @@ class AzureConfig(CommonCloudConfig):
244
262
  )
245
263
  count += 1
246
264
  except Exception as e:
247
- print_error(
248
- "Unable to delete Azure resource group"
249
- f" '{resource_group.name}': {e}"
250
- )
265
+ if "ResourceGroupNotFound" in str(e):
266
+ print_warning(
267
+ f"Resource Group '{resource_group.name}' not found; it"
268
+ " may have already been in the process of being"
269
+ " deleted"
270
+ )
271
+ else:
272
+ print_error(
273
+ "Unable to delete Azure resource group"
274
+ f" '{resource_group.name}': {e}"
275
+ )
251
276
  continue
252
277
 
253
278
  if count == 0:
@@ -255,10 +280,42 @@ class AzureConfig(CommonCloudConfig):
255
280
  else:
256
281
  print_log(f"{count} Azure resource group(s) deleted")
257
282
 
283
+ def _remove_resource_group_by_name(self, rg_name: str):
284
+ """
285
+ Remove a resource group by its name.
286
+ """
287
+ try:
288
+ self._resource_client.resource_groups.begin_delete(rg_name)
289
+ print_log(f"Requested deletion of Azure resource group '{rg_name}'")
290
+ except:
291
+ print_warning(f"Unable to delete Azure resource group '{rg_name}'")
292
+
258
293
  def _create_network_resources(self, resource_group_name: str, region: str):
259
294
  """
260
295
  Create a virtual network and subnet in a resource group in a region.
261
296
  """
297
+
298
+ def _location_not_available_for_resource_type(
299
+ e: Exception, resource_name: str
300
+ ) -> bool:
301
+ if "LocationNotAvailableForResourceType" in str(e):
302
+ print_warning(
303
+ f"Location '{region}' is not available for creation of resource"
304
+ f" '{resource_name}'; excluding this region"
305
+ )
306
+ return True
307
+ return False
308
+
309
+ def _resource_group_being_deleted(e: Exception, resource_name: str) -> bool:
310
+ if "ResourceGroupBeingDeleted" in str(e):
311
+ print_warning(
312
+ f"Resource Group '{resource_group_name}' is in the process of being"
313
+ f" deleted and resource '{resource_name}' cannot be created;"
314
+ " excluding this region"
315
+ )
316
+ return True
317
+ return False
318
+
262
319
  vnet_name = self._generate_vnet_name(region)
263
320
  address_prefixes = [ADDRESS_PREFIX]
264
321
  try:
@@ -275,8 +332,13 @@ class AzureConfig(CommonCloudConfig):
275
332
  f" prefixes {address_prefixes}"
276
333
  )
277
334
  except Exception as e:
278
- print_error(f"Failed to create Azure virtual network '{vnet_name}': {e}")
279
- return
335
+ if _location_not_available_for_resource_type(e, vnet_name):
336
+ return False
337
+ if not _resource_group_being_deleted(e, vnet_name):
338
+ print_error(
339
+ f"Failed to create Azure virtual network '{vnet_name}': {e}"
340
+ )
341
+ return False
280
342
 
281
343
  # Create network security group
282
344
  security_group_name = self._generate_security_group_name(region)
@@ -293,19 +355,23 @@ class AzureConfig(CommonCloudConfig):
293
355
  f" '{security_group_name}'"
294
356
  )
295
357
  except Exception as e:
296
- print_error(
297
- "Unable to create Azure network security group"
298
- f" '{security_group_name}': {e}"
299
- )
300
- return
358
+ if _location_not_available_for_resource_type(e, security_group_name):
359
+ return False
360
+ if not _resource_group_being_deleted(e, security_group_name):
361
+ print_error(
362
+ "Unable to create Azure network security group"
363
+ f" '{security_group_name}': {e}"
364
+ )
365
+ return False
301
366
 
302
367
  # Add an outbound HTTPS rule to allow the Agent to reach the platform
303
368
  address_prefix = ADDRESS_PREFIX
369
+ security_rule_name = "https-outbound-rule"
304
370
  try:
305
371
  self._network_client.security_rules.begin_create_or_update(
306
372
  resource_group_name=resource_group_name,
307
373
  network_security_group_name=security_group_name,
308
- security_rule_name="https-outbound",
374
+ security_rule_name=security_rule_name,
309
375
  security_rule_parameters={
310
376
  "properties": {
311
377
  "access": "Allow",
@@ -324,10 +390,14 @@ class AzureConfig(CommonCloudConfig):
324
390
  f" '{security_group_name}'"
325
391
  )
326
392
  except Exception as e:
327
- print_error(
328
- "Unable to add outbound HTTPS rule to Azure security group"
329
- f" '{security_group_name}': {e}"
330
- )
393
+ if _location_not_available_for_resource_type(e, security_rule_name):
394
+ return False
395
+ if not _resource_group_being_deleted(e, security_rule_name):
396
+ print_error(
397
+ "Unable to add outbound HTTPS rule to Azure security group"
398
+ f" '{security_group_name}': {e}"
399
+ )
400
+ return False
331
401
 
332
402
  # Create subnet and associate the security group
333
403
  subnet_name = self._generate_subnet_name(region)
@@ -355,8 +425,13 @@ class AzureConfig(CommonCloudConfig):
355
425
  f" '{address_prefix}'"
356
426
  )
357
427
  except Exception as e:
358
- print_error(f"Failed to create Azure subnet '{subnet_name}': {e}")
359
- return
428
+ if _location_not_available_for_resource_type(e, subnet_name):
429
+ return False
430
+ if not _resource_group_being_deleted(e, subnet_name):
431
+ print_error(f"Failed to create Azure subnet '{subnet_name}': {e}")
432
+ return False
433
+
434
+ return True
360
435
 
361
436
  def _create_yellowdog_resources(self):
362
437
  """
@@ -364,7 +439,7 @@ class AzureConfig(CommonCloudConfig):
364
439
  """
365
440
  print_log("Creating Azure resources in the YellowDog account")
366
441
 
367
- for region in self._selected_regions:
442
+ for region in self._created_regions:
368
443
  name = f"{YD_RESOURCE_PREFIX}-{region}-ondemand"
369
444
  self._source_template_resources.append(
370
445
  self._generate_azure_compute_source_template(
@@ -607,7 +682,7 @@ class AzureConfig(CommonCloudConfig):
607
682
  self, keyring_name: str, credential_name: str
608
683
  ) -> Dict:
609
684
  """
610
- Generate an Azure Credential resource definition.
685
+ Generate an Azure Storage Credential resource definition.
611
686
  """
612
687
  return {
613
688
  "resource": "Credential",
@@ -708,9 +783,11 @@ class AzureConfig(CommonCloudConfig):
708
783
  Generate the list of regions supported by this subscription.
709
784
  """
710
785
  try:
711
- locations = self._subscription_client.subscriptions.list_locations(
712
- self._subscription_id
713
- )
714
- return [location.name for location in locations]
786
+ return [
787
+ location.name
788
+ for location in self._subscription_client.subscriptions.list_locations(
789
+ self._subscription_id
790
+ )
791
+ ]
715
792
  except Exception as e:
716
793
  raise Exception(f"Unable to obtain list of Azure regions: {e}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: yellowdog-python-examples
3
- Version: 7.4.9
3
+ Version: 7.4.10
4
4
  Summary: Example Python commands using the YellowDog Python SDK
5
5
  Home-page: https://github.com/yellowdog/python-examples
6
6
  Author: YellowDog Limited
@@ -1 +0,0 @@
1
- __version__ = "7.4.9"