yellowdog-python-examples 7.8.1__tar.gz → 7.8.3__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 (77) hide show
  1. {yellowdog-python-examples-7.8.1/yellowdog_python_examples.egg-info → yellowdog-python-examples-7.8.3}/PKG-INFO +3 -3
  2. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/README.md +16 -13
  3. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/requirements.txt +2 -2
  4. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/tests/test_create_remove.py +7 -0
  5. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/tests/test_demos.py +22 -0
  6. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/tests/test_entrypoints.py +6 -0
  7. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/tests/test_list.py +4 -0
  8. yellowdog-python-examples-7.8.3/yd_commands/__init__.py +1 -0
  9. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/args.py +27 -11
  10. yellowdog-python-examples-7.8.3/yd_commands/boost.py +38 -0
  11. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/cloudwizard_aws.py +79 -69
  12. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/cloudwizard_azure.py +7 -5
  13. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/cloudwizard_common.py +8 -6
  14. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/cloudwizard_gcp.py +9 -7
  15. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/create.py +74 -44
  16. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/interactive.py +2 -6
  17. yellowdog-python-examples-7.8.3/yd_commands/items.py +47 -0
  18. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/list.py +7 -5
  19. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/load_config.py +9 -8
  20. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/object_utilities.py +34 -31
  21. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/printing.py +164 -132
  22. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/remove.py +42 -20
  23. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/start_hold_common.py +26 -20
  24. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/variables.py +6 -4
  25. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3/yellowdog_python_examples.egg-info}/PKG-INFO +3 -3
  26. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yellowdog_python_examples.egg-info/SOURCES.txt +1 -0
  27. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yellowdog_python_examples.egg-info/requires.txt +2 -2
  28. yellowdog-python-examples-7.8.1/yd_commands/__init__.py +0 -1
  29. yellowdog-python-examples-7.8.1/yd_commands/boost.py +0 -33
  30. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/LICENSE +0 -0
  31. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/PYPI_README.md +0 -0
  32. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/pyproject.toml +0 -0
  33. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/setup.cfg +0 -0
  34. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/setup.py +0 -0
  35. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/tests/test_dryruns.py +0 -0
  36. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/tests/test_gui.py +0 -0
  37. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/tests/test_objects.py +0 -0
  38. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/tests/test_variable_processing.py +0 -0
  39. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/abort.py +0 -0
  40. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/admin.py +0 -0
  41. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/cancel.py +0 -0
  42. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/check_imports.py +0 -0
  43. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/cloudwizard.py +0 -0
  44. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/cloudwizard_aws_types.py +0 -0
  45. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/compact_json.py +0 -0
  46. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/config_types.py +0 -0
  47. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/csv_data.py +0 -0
  48. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/delete.py +0 -0
  49. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/download.py +0 -0
  50. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/follow.py +0 -0
  51. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/follow_utils.py +0 -0
  52. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/format_json.py +0 -0
  53. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/hold.py +0 -0
  54. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/id_utils.py +0 -0
  55. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/instantiate.py +0 -0
  56. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/jsonnet2json.py +0 -0
  57. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/load_resources.py +0 -0
  58. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/property_names.py +0 -0
  59. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/provision.py +0 -0
  60. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/provision_utils.py +0 -0
  61. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/resize.py +0 -0
  62. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/settings.py +0 -0
  63. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/shutdown.py +0 -0
  64. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/start.py +0 -0
  65. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/submit.py +0 -0
  66. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/submit_utils.py +0 -0
  67. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/terminate.py +0 -0
  68. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/type_check.py +0 -0
  69. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/upload.py +0 -0
  70. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/upload_utils.py +0 -0
  71. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/utils.py +0 -0
  72. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/validate_properties.py +0 -0
  73. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/version.py +0 -0
  74. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yd_commands/wrapper.py +0 -0
  75. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yellowdog_python_examples.egg-info/dependency_links.txt +0 -0
  76. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/yellowdog_python_examples.egg-info/entry_points.txt +0 -0
  77. {yellowdog-python-examples-7.8.1 → yellowdog-python-examples-7.8.3}/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.8.1
3
+ Version: 7.8.3
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
@@ -15,11 +15,11 @@ Classifier: Development Status :: 4 - Beta
15
15
  Requires-Python: >=3.7
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: yellowdog-sdk>=7.7.0
18
+ Requires-Dist: yellowdog-sdk>=8.0.0
19
19
  Requires-Dist: toml
20
20
  Requires-Dist: tabulate>=0.9.0
21
21
  Requires-Dist: PyPAC>=0.16.4
22
- Requires-Dist: rich>=13.5.2
22
+ Requires-Dist: rich>=13.7.1
23
23
  Requires-Dist: requests
24
24
  Requires-Dist: boto3
25
25
  Requires-Dist: google-cloud-compute
@@ -85,6 +85,7 @@
85
85
  * [Image Families](#image-families)
86
86
  * [Namespace Storage Configurations](#namespace-storage-configurations)
87
87
  * [Configured Worker Pools](#configured-worker-pools)
88
+ * [Allowances](#allowances)
88
89
  * [Jsonnet Support](#jsonnet-support)
89
90
  * [Jsonnet Installation](#jsonnet-installation)
90
91
  * [Variable Substitutions in Jsonnet Files](#variable-substitutions-in-jsonnet-files)
@@ -109,9 +110,10 @@
109
110
  * [yd-follow](#yd-follow)
110
111
  * [yd-start](#yd-start)
111
112
  * [yd-hold](#yd-hold)
113
+ * [yd-boost](#yd-boost)
112
114
 
113
115
  <!-- Created by https://github.com/ekalinin/github-markdown-toc -->
114
- <!-- Added by: pwt, at: Sun Feb 18 17:40:36 GMT 2024 -->
116
+ <!-- Added by: pwt, at: Fri Mar 22 14:38:21 GMT 2024 -->
115
117
 
116
118
  <!--te-->
117
119
 
@@ -1801,7 +1803,7 @@ However, this means that **caution is required** when updating or removing resou
1801
1803
 
1802
1804
  The JSON specification used to define each type of resource can be found by inspecting the YellowDog Platform REST API documentation at https://docs.yellowdog.co/api.
1803
1805
 
1804
- For example, to obtain the JSON schema for creating a Compute Source Template, take a look at the REST API call for adding a new Compute Source template: https://docs.yellowdog.co/api/?urls.primaryName=Compute%20API#/Compute/addComputeSourceTemplate. This will display an **Example Value**, and an adjacent tab will show the **Schema**.
1806
+ For example, to obtain the JSON schema for creating a Compute Source Template, take a look at the REST API call for adding a new Compute Source template: https://docs.yellowdog.co/api/?spec=Compute%20API#tag/compute/post/compute/templates/sources. This will display an **Example Value**, and an adjacent tab will show the **Schema**.
1805
1807
 
1806
1808
  When using the `yd-create` and `yd-remove` commands, note that an additional property `resource` must be supplied, to identify the type of resource being specified. The `"resource"` property can take the following values:
1807
1809
 
@@ -1829,7 +1831,7 @@ Below, we'll discuss each item type with example specifications.
1829
1831
 
1830
1832
  ## Keyrings
1831
1833
 
1832
- The Keyring example and schema can be found at: https://docs.yellowdog.co/api/?urls.primaryName=Account%20API#/Keyring/createKeyring.
1834
+ The Keyring example and schema can be found at: https://docs.yellowdog.co/api/?spec=Account%20API#tag/keyring/post/keyrings.
1833
1835
 
1834
1836
  An example Keyring specification is shown below:
1835
1837
 
@@ -1857,7 +1859,7 @@ Note that Keyrings **cannot be updated**; they must instead be removed and recre
1857
1859
 
1858
1860
  ## Credentials
1859
1861
 
1860
- The Credential example and schema can be found at: https://docs.yellowdog.co/api/?urls.primaryName=Account%20API#/Keyring/putCredential.
1862
+ The Credential example and schema can be found at: https://docs.yellowdog.co/api/?spec=Account%20API#tag/keyring/put/keyrings/%7BkeyringName%7D/credentials.
1861
1863
 
1862
1864
  For example, to add a single AWS credential to a Keyring, the following resource specification might be used:
1863
1865
 
@@ -1878,7 +1880,7 @@ To **update** a Credential, make the modifications to the resource specification
1878
1880
 
1879
1881
  ## Compute Source Templates
1880
1882
 
1881
- The Compute Source Template example and schema can be found at: https://docs.yellowdog.co/api/?urls.primaryName=Compute%20API#/Compute/addComputeSourceTemplate.
1883
+ The Compute Source Template example and schema can be found at: https://docs.yellowdog.co/api/?spec=Compute%20API#tag/compute/post/compute/templates/sources.
1882
1884
 
1883
1885
  An example Compute Source resource specification is found below:
1884
1886
 
@@ -1916,7 +1918,7 @@ In the Compute Source Template `imageId` property, an Image Family **name** may
1916
1918
 
1917
1919
  ## Compute Requirement Templates
1918
1920
 
1919
- The Compute Requirement Template example and schema can be found at: https://docs.yellowdog.co/api/?urls.primaryName=Compute%20API#/Compute/addComputeRequirementTemplate.
1921
+ The Compute Requirement Template example and schema can be found at: https://docs.yellowdog.co/api/?spec=Compute%20API#tag/compute/post/compute/templates/requirements.
1920
1922
 
1921
1923
  An example Compute Requirement resource specification is found below, for a **static** tempate:
1922
1924
 
@@ -1991,7 +1993,7 @@ A **dynamic** template example is:
1991
1993
 
1992
1994
  ## Image Families
1993
1995
 
1994
- The Image Family example and schema can be found at: https://docs.yellowdog.co/api/?urls.primaryName=Images%20API#/Images/addImageFamily.
1996
+ The Image Family example and schema can be found at: https://docs.yellowdog.co/api/?spec=Images%20API#tag/images/post/images/families.
1995
1997
 
1996
1998
  An example specification, illustrating a containment hierarchy of Image Family -> Image Group -> Image, is shown below:
1997
1999
 
@@ -2037,7 +2039,7 @@ Note that if the name of an Image Group or an Image is changed in the resource s
2037
2039
 
2038
2040
  ## Namespace Storage Configurations
2039
2041
 
2040
- The Namespace Storage Configuration example and schema can be found at: https://docs.yellowdog.co/api/?urls.primaryName=Object%20Store%20API#/Object%20Store/putNamespaceStorageConfiguration.
2042
+ The Namespace Storage Configuration example and schema can be found at: https://docs.yellowdog.co/api/?spec=Object%20Store%20API#tag/object-store/put/objectstore/configurations.
2041
2043
 
2042
2044
  Example:
2043
2045
 
@@ -2054,7 +2056,7 @@ Example:
2054
2056
 
2055
2057
  ## Configured Worker Pools
2056
2058
 
2057
- The Configured Worker Pool example and schema can be found at: https://docs.yellowdog.co/api/?urls.primaryName=Scheduler%20API#/Worker%20Pools/addConfiguredWorkerPool.
2059
+ The Configured Worker Pool example and schema can be found at: https://docs.yellowdog.co/api/?spec=Scheduler%20API#tag/worker-pools/post/workerPools/configured.
2058
2060
 
2059
2061
  Example:
2060
2062
 
@@ -2084,7 +2086,7 @@ Example:
2084
2086
 
2085
2087
  ## Allowances
2086
2088
 
2087
- The Allowances example and schema can be found at: https://docs.yellowdog.co/api/?urls.primaryName=Usage%20API#/Allowances/addAllowance.
2089
+ The Allowances example and schema can be found at: https://docs.yellowdog.co/api/?spec=Usage%20API#tag/allowances/post/allowances.
2088
2090
 
2089
2091
  Example:
2090
2092
  ```json
@@ -2106,12 +2108,13 @@ Example:
2106
2108
 
2107
2109
  The `effectiveFrom` and `effectiveUntil` date-time string fields can use any format supported by the **[dateparser](https://dateparser.readthedocs.io/en/latest/)** library, including some natural language formulations.
2108
2110
 
2109
- Compute Source Template and Compute Requirement Template IDs can use names instead of IDs, and the IDs will be substituted by `yd-create`. However, if a Source allowance is created (type `co.yellowdog.platform.model.SourceAllowance`), then the Compute Source ID must be used in the `sourceId` property.
2111
+ Compute Source Template and Compute Requirement Template IDs can use names instead of IDs, and the IDs will be substituted by `yd-create`. However, if a Source allowance is created (type `co.yellowdog.platform.model.SourceAllowance`), then the Compute Source ID (note: **not** the Compute Source Template ID) itself must be used in the `sourceId` property.
2110
2112
 
2111
- Allowances **cannot be updated** (edited) once they have been created; they can only be removed and recreated. However, Allowances can be **boosted** (have extra hours added to the Allowance) using the `yd-boost` command.
2113
+ Allowances **cannot be updated** (edited) once they have been created; they can only be removed and recreated. However, if using `yd-create` to update existing Allowances, the `--match-allowances-by-description`/`-M` option can be used, in which case Allowances will be matched using their `description` property. If matches are found, these can optionally be removed before new Allowances are created. If multiple existing, matching Allowances are found, the user will be asked to select which ones (if any) to remove.
2112
2114
 
2113
- Allowances can currently only be **removed** by their IDs (`yd-remove --ids <allowance_id> [<allowance_id>]`), not by using the JSON resource specification. This is because allowances don't have a `name` property on which to match the resource.
2115
+ When using `yd-remove`, Allowances are again matched using their `description` property only if `--match-allowances-by-description`/`-M` is used. As with other resources, Allowances can also be removed by their IDs (`yd-remove --ids <allowance_id> [<allowance_id>]`).
2114
2116
 
2117
+ Allowances can be **boosted** (have extra hours added to the Allowance) using the `yd-boost` command.
2115
2118
 
2116
2119
  # Jsonnet Support
2117
2120
 
@@ -1,8 +1,8 @@
1
- yellowdog-sdk >= 7.7.0
1
+ yellowdog-sdk >= 8.0.0
2
2
  toml
3
3
  tabulate >= 0.9.0
4
4
  PyPAC >= 0.16.4
5
- rich >= 13.5.2
5
+ rich >= 13.7.1
6
6
  requests
7
7
  boto3
8
8
  google-cloud-compute
@@ -46,3 +46,10 @@ class TestCreateRemove:
46
46
  assert result.exit_code == 0
47
47
  result = shell(f"yd-remove -y {resources}")
48
48
  assert result.exit_code == 0
49
+
50
+ def test_allowance(self):
51
+ resources = f"{RESOURCE_DIR}/allowances.json"
52
+ result = shell(f"yd-create {resources}")
53
+ assert result.exit_code == 0
54
+ result = shell(f"yd-remove -My {resources}")
55
+ assert result.exit_code == 0
@@ -8,6 +8,7 @@ from cli_test_helpers import shell
8
8
 
9
9
  DEMO_DIR = "../python-examples-demos"
10
10
  CMD_SEQ = "yd-provision && yd-submit -f && yd-terminate -y && yd-delete -y"
11
+ NEXTFLOW = "/Users/pwt/nextflow/nextflow"
11
12
 
12
13
 
13
14
  @pytest.mark.demos
@@ -51,3 +52,24 @@ class TestDemos:
51
52
  def test_cmd_exe(self):
52
53
  result = shell(f"cd {DEMO_DIR}/cmd.exe && {CMD_SEQ}")
53
54
  assert result.exit_code == 0
55
+
56
+ def test_nextflow_image_montage(self):
57
+ result = shell(
58
+ f"cd {DEMO_DIR}/nextflow/image-montage && {NEXTFLOW} main.nf "
59
+ "&& cd .. && ./cleanup.sh"
60
+ )
61
+ assert result.exit_code == 0
62
+
63
+ def test_nextflow_salmon_rna(self):
64
+ result = shell(
65
+ f"cd {DEMO_DIR}/nextflow/salmon-rna && {NEXTFLOW} main.nf "
66
+ "&& cd .. && ./cleanup.sh"
67
+ )
68
+ assert result.exit_code == 0
69
+
70
+ def test_cmd_modelled_on_premise(self):
71
+ result = shell(
72
+ f"cd {DEMO_DIR}/modelled-on-premise && yd-instantiate "
73
+ "&& sleep 120 && yd-terminate -y"
74
+ )
75
+ assert result.exit_code == 0
@@ -42,3 +42,9 @@ def test_entrypoints():
42
42
  assert result.exit_code == 0
43
43
  result = shell("yd-cloudwizard --help")
44
44
  assert result.exit_code == 0
45
+ result = shell("yd-start --help")
46
+ assert result.exit_code == 0
47
+ result = shell("yd-hold --help")
48
+ assert result.exit_code == 0
49
+ result = shell("yd-boost --help")
50
+ assert result.exit_code == 0
@@ -53,3 +53,7 @@ class TestList:
53
53
  def test_namespaces(self):
54
54
  result = shell("yd-list -N -n='' -t=''")
55
55
  assert result.exit_code == 0
56
+
57
+ def test_allowances(self):
58
+ result = shell("yd-list -A -n='' -t=''")
59
+ assert result.exit_code == 0
@@ -0,0 +1 @@
1
+ __version__ = "7.8.3"
@@ -131,8 +131,6 @@ class CLIParser:
131
131
  "remove",
132
132
  "cloudwizard",
133
133
  "follow",
134
- "hold",
135
- "start",
136
134
  ]
137
135
  ):
138
136
  parser.add_argument(
@@ -338,6 +336,8 @@ class CLIParser:
338
336
  "resize",
339
337
  "cloudwizard",
340
338
  "boost",
339
+ "hold",
340
+ "start",
341
341
  ]
342
342
  ):
343
343
  parser.add_argument(
@@ -345,7 +345,7 @@ class CLIParser:
345
345
  "-y",
346
346
  action="store_true",
347
347
  required=False,
348
- help="perform destructive actions without requiring user confirmation",
348
+ help="perform modifying actions without requiring user confirmation",
349
349
  )
350
350
 
351
351
  if any(module in sys.argv[0] for module in ["delete", "download"]):
@@ -639,18 +639,19 @@ class CLIParser:
639
639
  )
640
640
 
641
641
  if "boost" in sys.argv[0]:
642
- parser.add_argument(
643
- "allowance",
644
- metavar="<allowance-ID>",
645
- type=str,
646
- help=("the YellowDog ID of the allowance to boost"),
647
- )
648
642
  parser.add_argument(
649
643
  "boost_hours",
650
644
  metavar="<boost hours>",
651
645
  type=int,
652
646
  help="the number of hours to boost the allowance by",
653
647
  )
648
+ parser.add_argument(
649
+ "allowances",
650
+ metavar="<allowance-ID> [<allowance-ID>]",
651
+ nargs="+",
652
+ type=str,
653
+ help="the YellowDog ID(s) of the allowance(s) to boost",
654
+ )
654
655
 
655
656
  if "shutdown" in sys.argv[0]:
656
657
  parser.add_argument(
@@ -763,6 +764,16 @@ class CLIParser:
763
764
  required=False,
764
765
  help="allow updates without user confirmation",
765
766
  )
767
+ parser.add_argument(
768
+ "--match-allowances-by-description",
769
+ "-M",
770
+ action="store_true",
771
+ required=False,
772
+ help=(
773
+ "match using the 'description' property when updating "
774
+ "(using yd-create) or removing allowances"
775
+ ),
776
+ )
766
777
  if "create" in sys.argv[0]:
767
778
  parser.add_argument(
768
779
  "--show-keyring-passwords",
@@ -1391,8 +1402,8 @@ class CLIParser:
1391
1402
 
1392
1403
  @property
1393
1404
  @allow_missing_attribute
1394
- def allowance(self) -> str:
1395
- return self.args.allowance
1405
+ def allowance_list(self) -> List[str]:
1406
+ return self.args.allowances
1396
1407
 
1397
1408
  @property
1398
1409
  @allow_missing_attribute
@@ -1404,6 +1415,11 @@ class CLIParser:
1404
1415
  def no_resequence(self) -> Optional[bool]:
1405
1416
  return self.args.no_resequence
1406
1417
 
1418
+ @property
1419
+ @allow_missing_attribute
1420
+ def match_allowances_by_description(self) -> Optional[bool]:
1421
+ return self.args.match_allowances_by_description
1422
+
1407
1423
 
1408
1424
  def lookup_module_description(module_name: str) -> Optional[str]:
1409
1425
  """
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """
4
+ A script to boost allowances.
5
+ """
6
+
7
+ from yd_commands.interactive import confirmed
8
+ from yd_commands.printing import print_error, print_log
9
+ from yd_commands.wrapper import ARGS_PARSER, CLIENT, main_wrapper
10
+
11
+
12
+ @main_wrapper
13
+ def main():
14
+
15
+ count = 0
16
+ for allowance in ARGS_PARSER.allowance_list:
17
+ if not confirmed(
18
+ f"Boost Allowance {allowance} by {ARGS_PARSER.boost_hours} hours?"
19
+ ):
20
+ continue
21
+ try:
22
+ CLIENT.allowances_client.boost_allowance_by_id(
23
+ allowance, ARGS_PARSER.boost_hours
24
+ )
25
+ print_log(
26
+ f"Boosted Allowance {allowance} by {ARGS_PARSER.boost_hours} hours"
27
+ )
28
+ count += 1
29
+ except Exception as e:
30
+ print_error(f"Unable to boost Allowance {allowance}: {e}")
31
+
32
+ if count > 1:
33
+ print_log(f"Boosted {count} allowances by {ARGS_PARSER.boost_hours} hours")
34
+
35
+
36
+ # Standalone entry point
37
+ if __name__ == "__main__":
38
+ main()
@@ -79,42 +79,44 @@ AWS_YD_IMAGE_REGIONS = [
79
79
 
80
80
  YELLOWDOG_POLICY = {
81
81
  "Version": "2012-10-17",
82
- "Statement": [{
83
- "Sid": "VisualEditor0",
84
- "Effect": "Allow",
85
- "Action": [
86
- "EC2:CancelSpotInstanceRequests",
87
- "EC2:CreateFleet",
88
- "EC2:CreateLaunchTemplate",
89
- "EC2:CreatePlacementGroup",
90
- "EC2:CreateTags",
91
- "EC2:DeleteFleets",
92
- "EC2:DeleteLaunchTemplate",
93
- "EC2:DeletePlacementGroup",
94
- "EC2:DescribeFleets",
95
- "EC2:DescribeInstanceTypes",
96
- "EC2:DescribeInstances",
97
- "EC2:DescribeLaunchTemplates",
98
- "EC2:DescribePlacementGroups",
99
- "EC2:DescribeSpotInstanceRequests",
100
- "EC2:ModifyFleet",
101
- "EC2:RebootInstances",
102
- "EC2:RequestSpotInstances",
103
- "EC2:RunInstances",
104
- "EC2:StartInstances",
105
- "EC2:StopInstances",
106
- "EC2:TerminateInstances",
107
- "S3:AbortMultipartUpload",
108
- "S3:CreateBucket",
109
- "S3:DeleteBucket",
110
- "S3:DeleteObject",
111
- "S3:GetObject",
112
- "S3:ListBucketMultipartUploads",
113
- "S3:ListMultipartUploadParts",
114
- "S3:PutObject",
115
- ],
116
- "Resource": "*",
117
- }],
82
+ "Statement": [
83
+ {
84
+ "Sid": "VisualEditor0",
85
+ "Effect": "Allow",
86
+ "Action": [
87
+ "EC2:CancelSpotInstanceRequests",
88
+ "EC2:CreateFleet",
89
+ "EC2:CreateLaunchTemplate",
90
+ "EC2:CreatePlacementGroup",
91
+ "EC2:CreateTags",
92
+ "EC2:DeleteFleets",
93
+ "EC2:DeleteLaunchTemplate",
94
+ "EC2:DeletePlacementGroup",
95
+ "EC2:DescribeFleets",
96
+ "EC2:DescribeInstanceTypes",
97
+ "EC2:DescribeInstances",
98
+ "EC2:DescribeLaunchTemplates",
99
+ "EC2:DescribePlacementGroups",
100
+ "EC2:DescribeSpotInstanceRequests",
101
+ "EC2:ModifyFleet",
102
+ "EC2:RebootInstances",
103
+ "EC2:RequestSpotInstances",
104
+ "EC2:RunInstances",
105
+ "EC2:StartInstances",
106
+ "EC2:StopInstances",
107
+ "EC2:TerminateInstances",
108
+ "S3:AbortMultipartUpload",
109
+ "S3:CreateBucket",
110
+ "S3:DeleteBucket",
111
+ "S3:DeleteObject",
112
+ "S3:GetObject",
113
+ "S3:ListBucketMultipartUploads",
114
+ "S3:ListMultipartUploadParts",
115
+ "S3:PutObject",
116
+ ],
117
+ "Resource": "*",
118
+ }
119
+ ],
118
120
  }
119
121
 
120
122
 
@@ -182,12 +184,14 @@ class AWSConfig(CommonCloudConfig):
182
184
  A list of regions can be supplied as an argument.
183
185
  The 'operation' argument must be 'add-ssh' or 'remove-ssh'.
184
186
  """
185
- ssh_ipv4_ingress_rule = [{
186
- "IpProtocol": "tcp",
187
- "FromPort": 22,
188
- "ToPort": 22,
189
- "IpRanges": [{"CidrIp": f"0.0.0.0/0"}],
190
- }]
187
+ ssh_ipv4_ingress_rule = [
188
+ {
189
+ "IpProtocol": "tcp",
190
+ "FromPort": 22,
191
+ "ToPort": 22,
192
+ "IpRanges": [{"CidrIp": f"0.0.0.0/0"}],
193
+ }
194
+ ]
191
195
  for region in (
192
196
  AWS_YD_IMAGE_REGIONS if selected_region is None else [selected_region]
193
197
  ):
@@ -359,11 +363,13 @@ class AWSConfig(CommonCloudConfig):
359
363
  "Creating YellowDog Namespace Configuration"
360
364
  f" 'S3:{self._get_s3_bucket_name()}' -> '{YD_NAMESPACE}'"
361
365
  )
362
- create_resources([
363
- self._generate_yd_namespace_configuration(
364
- namespace=YD_NAMESPACE, s3_bucket_name=self._get_s3_bucket_name()
365
- )
366
- ])
366
+ create_resources(
367
+ [
368
+ self._generate_yd_namespace_configuration(
369
+ namespace=YD_NAMESPACE, s3_bucket_name=self._get_s3_bucket_name()
370
+ )
371
+ ]
372
+ )
367
373
 
368
374
  # Sequence the Compute Requirement Templates before the Compute Source
369
375
  # Templates for subsequent removals.
@@ -390,11 +396,13 @@ class AWSConfig(CommonCloudConfig):
390
396
  self._remove_keyring(keyring_name=YD_KEYRING_NAME)
391
397
 
392
398
  # Remove the Namespace Configuration
393
- remove_resources([
394
- self._generate_yd_namespace_configuration(
395
- YD_NAMESPACE, self._get_s3_bucket_name()
396
- )
397
- ])
399
+ remove_resources(
400
+ [
401
+ self._generate_yd_namespace_configuration(
402
+ YD_NAMESPACE, self._get_s3_bucket_name()
403
+ )
404
+ ]
405
+ )
398
406
 
399
407
  def _gather_aws_network_information(self):
400
408
  """
@@ -961,23 +969,25 @@ class AWSConfig(CommonCloudConfig):
961
969
  """
962
970
  assert self._aws_user is not None
963
971
  s3_bucket_name = self._get_s3_bucket_name()
964
- return json.dumps({
965
- "Version": "2012-10-17",
966
- "Statement": [
967
- {
968
- "Effect": "Allow",
969
- "Principal": {"AWS": self._aws_user.arn},
970
- "Action": "s3:*",
971
- "Resource": f"arn:aws:s3:::{s3_bucket_name}/*",
972
- },
973
- {
974
- "Effect": "Allow",
975
- "Principal": {"AWS": self._aws_user.arn},
976
- "Action": "s3:ListBucket",
977
- "Resource": f"arn:aws:s3:::{s3_bucket_name}",
978
- },
979
- ],
980
- })
972
+ return json.dumps(
973
+ {
974
+ "Version": "2012-10-17",
975
+ "Statement": [
976
+ {
977
+ "Effect": "Allow",
978
+ "Principal": {"AWS": self._aws_user.arn},
979
+ "Action": "s3:*",
980
+ "Resource": f"arn:aws:s3:::{s3_bucket_name}/*",
981
+ },
982
+ {
983
+ "Effect": "Allow",
984
+ "Principal": {"AWS": self._aws_user.arn},
985
+ "Action": "s3:ListBucket",
986
+ "Resource": f"arn:aws:s3:::{s3_bucket_name}",
987
+ },
988
+ ],
989
+ }
990
+ )
981
991
 
982
992
  def _get_s3_bucket_name(self) -> str:
983
993
  """
@@ -491,11 +491,13 @@ class AzureConfig(CommonCloudConfig):
491
491
 
492
492
  # Create namespace configuration (Keyring/Credential creation must come first)
493
493
  print_log(f"Creating YellowDog Namespace Configuration '{YD_NAMESPACE}'")
494
- create_resources([
495
- self._generate_yd_namespace_configuration(
496
- namespace=YD_NAMESPACE, storage_blob_name=STORAGE_BLOB_NAME
497
- )
498
- ])
494
+ create_resources(
495
+ [
496
+ self._generate_yd_namespace_configuration(
497
+ namespace=YD_NAMESPACE, storage_blob_name=STORAGE_BLOB_NAME
498
+ )
499
+ ]
500
+ )
499
501
 
500
502
  # Save the list of resources
501
503
  # Sequence the Compute Requirement Templates before the Compute Source
@@ -186,12 +186,14 @@ class CommonCloudConfig(ABC):
186
186
  "type": "co.yellowdog.platform.model.StringAttributeConstraint",
187
187
  },
188
188
  ],
189
- "preferences": [{
190
- "attribute": "yd.cost",
191
- "rankOrder": "PREFER_LOWER",
192
- "type": "co.yellowdog.platform.model.NumericAttributePreference",
193
- "weight": 1,
194
- }],
189
+ "preferences": [
190
+ {
191
+ "attribute": "yd.cost",
192
+ "rankOrder": "PREFER_LOWER",
193
+ "type": "co.yellowdog.platform.model.NumericAttributePreference",
194
+ "weight": 1,
195
+ }
196
+ ],
195
197
  "maximumSourceCount": 5,
196
198
  "minimumSourceCount": 1,
197
199
  "strategyType": f"co.yellowdog.platform.model.{strategy}ProvisionStrategy",
@@ -158,13 +158,15 @@ class GCPConfig(CommonCloudConfig):
158
158
  client=self._client, name_prefix=YD_RESOURCE_PREFIX
159
159
  )
160
160
  self._remove_keyring(YD_KEYRING_NAME)
161
- remove_resources([
162
- self._generate_namespace_configuration(
163
- YD_NAMESPACE,
164
- self._generate_bucket_name(),
165
- credential_name=f"{YD_KEYRING_NAME}/{YD_CREDENTIAL_NAME}",
166
- )
167
- ])
161
+ remove_resources(
162
+ [
163
+ self._generate_namespace_configuration(
164
+ YD_NAMESPACE,
165
+ self._generate_bucket_name(),
166
+ credential_name=f"{YD_KEYRING_NAME}/{YD_CREDENTIAL_NAME}",
167
+ )
168
+ ]
169
+ )
168
170
 
169
171
  def _gather_regions(self):
170
172
  """