yellowdog-python-examples 8.2.1__py3-none-any.whl → 8.3.1__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.
- yellowdog_cli/__init__.py +1 -1
- yellowdog_cli/abort.py +11 -11
- yellowdog_cli/admin.py +2 -2
- yellowdog_cli/application.py +104 -0
- yellowdog_cli/boost.py +3 -3
- yellowdog_cli/cancel.py +9 -9
- yellowdog_cli/cloudwizard.py +4 -4
- yellowdog_cli/compare.py +6 -6
- yellowdog_cli/create.py +56 -54
- yellowdog_cli/delete.py +10 -10
- yellowdog_cli/download.py +15 -15
- yellowdog_cli/finish.py +9 -9
- yellowdog_cli/instantiate.py +19 -17
- yellowdog_cli/list.py +45 -43
- yellowdog_cli/provision.py +28 -28
- yellowdog_cli/remove.py +28 -26
- yellowdog_cli/resize.py +9 -9
- yellowdog_cli/show.py +29 -27
- yellowdog_cli/shutdown.py +9 -9
- yellowdog_cli/submit.py +29 -29
- yellowdog_cli/terminate.py +8 -8
- yellowdog_cli/upload.py +11 -11
- yellowdog_cli/utils/args.py +2 -0
- yellowdog_cli/utils/cloudwizard_aws.py +32 -32
- yellowdog_cli/utils/cloudwizard_azure.py +27 -27
- yellowdog_cli/utils/cloudwizard_common.py +12 -10
- yellowdog_cli/utils/cloudwizard_gcp.py +8 -8
- yellowdog_cli/utils/csv_data.py +7 -7
- yellowdog_cli/utils/entity_utils.py +85 -20
- yellowdog_cli/utils/follow_utils.py +5 -5
- yellowdog_cli/utils/interactive.py +8 -8
- yellowdog_cli/utils/load_config.py +11 -11
- yellowdog_cli/utils/load_resources.py +4 -4
- yellowdog_cli/utils/misc_utils.py +6 -3
- yellowdog_cli/utils/printing.py +10 -9
- yellowdog_cli/utils/provision_utils.py +2 -2
- yellowdog_cli/utils/settings.py +1 -0
- yellowdog_cli/utils/start_hold_common.py +7 -7
- yellowdog_cli/utils/submit_utils.py +5 -5
- yellowdog_cli/utils/upload_utils.py +3 -3
- yellowdog_cli/utils/variables.py +5 -5
- yellowdog_cli/utils/wrapper.py +32 -53
- {yellowdog_python_examples-8.2.1.dist-info → yellowdog_python_examples-8.3.1.dist-info}/METADATA +3 -2
- yellowdog_python_examples-8.3.1.dist-info/RECORD +65 -0
- {yellowdog_python_examples-8.2.1.dist-info → yellowdog_python_examples-8.3.1.dist-info}/entry_points.txt +1 -0
- yellowdog_python_examples-8.2.1.dist-info/RECORD +0 -64
- {yellowdog_python_examples-8.2.1.dist-info → yellowdog_python_examples-8.3.1.dist-info}/WHEEL +0 -0
- {yellowdog_python_examples-8.2.1.dist-info → yellowdog_python_examples-8.3.1.dist-info}/licenses/LICENSE +0 -0
- {yellowdog_python_examples-8.2.1.dist-info → yellowdog_python_examples-8.3.1.dist-info}/top_level.txt +0 -0
yellowdog_cli/instantiate.py
CHANGED
|
@@ -26,7 +26,7 @@ from yellowdog_cli.utils.misc_utils import (
|
|
|
26
26
|
from yellowdog_cli.utils.printing import (
|
|
27
27
|
print_compute_template_test_result,
|
|
28
28
|
print_error,
|
|
29
|
-
|
|
29
|
+
print_info,
|
|
30
30
|
print_yd_object,
|
|
31
31
|
)
|
|
32
32
|
from yellowdog_cli.utils.provision_utils import (
|
|
@@ -76,7 +76,7 @@ def main():
|
|
|
76
76
|
cr_json_file = CONFIG_WP.compute_requirement_data_file
|
|
77
77
|
|
|
78
78
|
if cr_json_file is not None:
|
|
79
|
-
|
|
79
|
+
print_info(f"Loading Compute Requirement data from: '{cr_json_file}'")
|
|
80
80
|
_create_compute_requirement_from_json(
|
|
81
81
|
cr_json_file, WP_VARIABLES_PREFIX, WP_VARIABLES_POSTFIX
|
|
82
82
|
)
|
|
@@ -97,7 +97,7 @@ def main():
|
|
|
97
97
|
)
|
|
98
98
|
|
|
99
99
|
if not ARGS_PARSER.report:
|
|
100
|
-
|
|
100
|
+
print_info(
|
|
101
101
|
"Provisioning Compute Requirement with "
|
|
102
102
|
f"{CONFIG_WP.target_instance_count:,d} instance(s)"
|
|
103
103
|
)
|
|
@@ -109,7 +109,7 @@ def main():
|
|
|
109
109
|
|
|
110
110
|
num_batches = len(batches)
|
|
111
111
|
if num_batches > 1 and not ARGS_PARSER.report:
|
|
112
|
-
|
|
112
|
+
print_info(f"Batching into {num_batches} Compute Requirements")
|
|
113
113
|
|
|
114
114
|
compute_requirement_ids: List[str] = []
|
|
115
115
|
for batch_number in range(num_batches):
|
|
@@ -120,12 +120,12 @@ def main():
|
|
|
120
120
|
)
|
|
121
121
|
if not (ARGS_PARSER.dry_run or ARGS_PARSER.report):
|
|
122
122
|
if num_batches > 1:
|
|
123
|
-
|
|
123
|
+
print_info(
|
|
124
124
|
f"Provisioning Compute Requirement {batch_number + 1} '{CONFIG_COMMON.namespace}/{id}'"
|
|
125
125
|
f"with {batches[batch_number].target_instances:,d} instance(s)"
|
|
126
126
|
)
|
|
127
127
|
else:
|
|
128
|
-
|
|
128
|
+
print_info(
|
|
129
129
|
f"Provisioning Compute Requirement '{CONFIG_COMMON.namespace}/{id}'"
|
|
130
130
|
)
|
|
131
131
|
|
|
@@ -147,7 +147,7 @@ def main():
|
|
|
147
147
|
)
|
|
148
148
|
|
|
149
149
|
if ARGS_PARSER.report:
|
|
150
|
-
|
|
150
|
+
print_info("Generating provisioning report only")
|
|
151
151
|
try:
|
|
152
152
|
test_result: ComputeRequirementTemplateTestResult = (
|
|
153
153
|
CLIENT.compute_client.test_compute_requirement_template(
|
|
@@ -163,7 +163,9 @@ def main():
|
|
|
163
163
|
)
|
|
164
164
|
)
|
|
165
165
|
if "No sources" in http_error.response.text:
|
|
166
|
-
|
|
166
|
+
print_info(
|
|
167
|
+
"No Compute Sources match the Template's constraints"
|
|
168
|
+
)
|
|
167
169
|
else:
|
|
168
170
|
raise http_error
|
|
169
171
|
return
|
|
@@ -177,15 +179,15 @@ def main():
|
|
|
177
179
|
compute_requirement_ids.append(compute_requirement.id)
|
|
178
180
|
if ARGS_PARSER.quiet:
|
|
179
181
|
print(compute_requirement.id)
|
|
180
|
-
|
|
182
|
+
print_info(
|
|
181
183
|
f"Provisioned {link_entity(CONFIG_COMMON.url, compute_requirement)}"
|
|
182
184
|
)
|
|
183
|
-
|
|
185
|
+
print_info(f"YellowDog ID is '{compute_requirement.id}'")
|
|
184
186
|
|
|
185
187
|
else:
|
|
186
|
-
|
|
188
|
+
print_info("Dry-run: Printing JSON Compute Requirement specification")
|
|
187
189
|
print_yd_object(compute_requirement_template_usage)
|
|
188
|
-
|
|
190
|
+
print_info("Dry-run: Complete")
|
|
189
191
|
|
|
190
192
|
except Exception as e:
|
|
191
193
|
raise Exception(
|
|
@@ -288,7 +290,7 @@ def _create_compute_requirement_from_json(
|
|
|
288
290
|
("maintainInstanceCount", CONFIG_WP.maintainInstanceCount),
|
|
289
291
|
]:
|
|
290
292
|
if cr_data.get(key) is None and value is not None:
|
|
291
|
-
|
|
293
|
+
print_info(f"Setting '{key}' to '{value}'")
|
|
292
294
|
cr_data[key] = value
|
|
293
295
|
|
|
294
296
|
except KeyError as e:
|
|
@@ -308,9 +310,9 @@ def _create_compute_requirement_from_json(
|
|
|
308
310
|
)
|
|
309
311
|
|
|
310
312
|
if ARGS_PARSER.dry_run:
|
|
311
|
-
|
|
313
|
+
print_info("Dry-run: Printing JSON Compute Requirement specification")
|
|
312
314
|
print_yd_object(cr_data)
|
|
313
|
-
|
|
315
|
+
print_info("Dry-run: Complete")
|
|
314
316
|
return
|
|
315
317
|
|
|
316
318
|
response = requests.post(
|
|
@@ -321,13 +323,13 @@ def _create_compute_requirement_from_json(
|
|
|
321
323
|
name = cr_data["requirementName"]
|
|
322
324
|
if response.status_code == 200:
|
|
323
325
|
id = response.json()["id"]
|
|
324
|
-
|
|
326
|
+
print_info(
|
|
325
327
|
f"Provisioned Compute Requirement '{cr_data['requirementNamespace']}/{name}' ({id})"
|
|
326
328
|
)
|
|
327
329
|
if ARGS_PARSER.quiet:
|
|
328
330
|
print(id)
|
|
329
331
|
if ARGS_PARSER.follow:
|
|
330
|
-
|
|
332
|
+
print_info("Following Compute Requirement event stream")
|
|
331
333
|
follow_events(id, YDIDType.COMPUTE_REQUIREMENT)
|
|
332
334
|
else:
|
|
333
335
|
print_error(f"Failed to provision Compute Requirement '{name}'")
|
yellowdog_cli/list.py
CHANGED
|
@@ -52,7 +52,7 @@ from yellowdog_cli.utils.entity_utils import (
|
|
|
52
52
|
get_all_groups,
|
|
53
53
|
get_all_roles,
|
|
54
54
|
get_all_users,
|
|
55
|
-
|
|
55
|
+
get_application_group_summaries,
|
|
56
56
|
get_compute_requirement_summaries,
|
|
57
57
|
get_compute_requirement_templates,
|
|
58
58
|
get_compute_source_templates,
|
|
@@ -70,8 +70,8 @@ from yellowdog_cli.utils.interactive import confirmed, select
|
|
|
70
70
|
from yellowdog_cli.utils.misc_utils import unpack_namespace_in_prefix
|
|
71
71
|
from yellowdog_cli.utils.printing import (
|
|
72
72
|
indent,
|
|
73
|
+
print_info,
|
|
73
74
|
print_json,
|
|
74
|
-
print_log,
|
|
75
75
|
print_numbered_object_list,
|
|
76
76
|
print_table_core,
|
|
77
77
|
print_warning,
|
|
@@ -111,11 +111,11 @@ def main():
|
|
|
111
111
|
or ARGS_PARSER.substitute_ids
|
|
112
112
|
or ARGS_PARSER.output_file
|
|
113
113
|
) and not ARGS_PARSER.details:
|
|
114
|
-
|
|
114
|
+
print_info("Automatically setting the '--details' option")
|
|
115
115
|
ARGS_PARSER.details = True
|
|
116
116
|
|
|
117
117
|
if ARGS_PARSER.details and ARGS_PARSER.strip_ids:
|
|
118
|
-
|
|
118
|
+
print_info("Stripping YellowDog IDs (etc.) from detailed JSON objects")
|
|
119
119
|
|
|
120
120
|
if ARGS_PARSER.output_file and ARGS_PARSER.details:
|
|
121
121
|
if exists(ARGS_PARSER.output_file):
|
|
@@ -205,12 +205,12 @@ def list_work_requirements():
|
|
|
205
205
|
This function falls through from WRs to TGs to Tasks, depending on the
|
|
206
206
|
options chosen.
|
|
207
207
|
"""
|
|
208
|
-
|
|
208
|
+
print_info(
|
|
209
209
|
f"Listing Work Requirements in namespace '{CONFIG_COMMON.namespace}' "
|
|
210
210
|
f"with '{CONFIG_COMMON.name_tag}' in tag",
|
|
211
211
|
)
|
|
212
212
|
if ARGS_PARSER.active_only:
|
|
213
|
-
|
|
213
|
+
print_info("Listing active Work Requirements only")
|
|
214
214
|
|
|
215
215
|
exclude_filter = (
|
|
216
216
|
[
|
|
@@ -230,7 +230,7 @@ def list_work_requirements():
|
|
|
230
230
|
)
|
|
231
231
|
)
|
|
232
232
|
if len(work_requirement_summaries) == 0:
|
|
233
|
-
|
|
233
|
+
print_info("No matching Work Requirements")
|
|
234
234
|
return
|
|
235
235
|
|
|
236
236
|
work_requirement_summaries = sorted_objects(work_requirement_summaries)
|
|
@@ -252,7 +252,7 @@ def list_work_requirements():
|
|
|
252
252
|
CLIENT, work_requirement_summaries, single_result=True
|
|
253
253
|
)
|
|
254
254
|
for work_summary in selected_work_summaries:
|
|
255
|
-
|
|
255
|
+
print_info(f"Work Requirement '{work_summary.name}'")
|
|
256
256
|
list_task_groups(work_summary)
|
|
257
257
|
|
|
258
258
|
|
|
@@ -293,17 +293,17 @@ def list_object_paths():
|
|
|
293
293
|
namespace, tag = unpack_namespace_in_prefix(
|
|
294
294
|
CONFIG_COMMON.namespace, CONFIG_COMMON.name_tag
|
|
295
295
|
)
|
|
296
|
-
|
|
296
|
+
print_info(
|
|
297
297
|
f"Listing Object Paths in namespace '{namespace}' and "
|
|
298
298
|
f"names (prefixes) starting with '{tag}'"
|
|
299
299
|
)
|
|
300
300
|
if ARGS_PARSER.all and not ARGS_PARSER.details:
|
|
301
|
-
|
|
301
|
+
print_info("Listing all Objects")
|
|
302
302
|
|
|
303
303
|
object_paths = list_matching_object_paths(CLIENT, namespace, tag, ARGS_PARSER.all)
|
|
304
304
|
|
|
305
305
|
if len(object_paths) == 0:
|
|
306
|
-
|
|
306
|
+
print_info("No matching Object Paths")
|
|
307
307
|
return
|
|
308
308
|
|
|
309
309
|
if not ARGS_PARSER.details:
|
|
@@ -313,12 +313,12 @@ def list_object_paths():
|
|
|
313
313
|
# Print object details for selected objects
|
|
314
314
|
object_paths = select(CLIENT, object_paths, override_quiet=True)
|
|
315
315
|
if len(object_paths) != 0:
|
|
316
|
-
|
|
316
|
+
print_info(f"Showing Object details for {len(object_paths)} Object(s)")
|
|
317
317
|
|
|
318
318
|
object_detail_list = []
|
|
319
319
|
for object_path in object_paths:
|
|
320
320
|
if object_path.prefix:
|
|
321
|
-
|
|
321
|
+
print_info(f"Object Path '{object_path.name}' is a prefix not an object")
|
|
322
322
|
continue
|
|
323
323
|
object_detail: ObjectDetail = CLIENT.object_store_client.get_object_detail(
|
|
324
324
|
namespace=namespace, name=object_path.name
|
|
@@ -329,7 +329,7 @@ def list_object_paths():
|
|
|
329
329
|
|
|
330
330
|
|
|
331
331
|
def list_worker_pools():
|
|
332
|
-
|
|
332
|
+
print_info(
|
|
333
333
|
f"Displaying Worker Pools in namespace '{CONFIG_COMMON.namespace}' "
|
|
334
334
|
f"with '{CONFIG_COMMON.name_tag}' in name"
|
|
335
335
|
)
|
|
@@ -345,7 +345,7 @@ def list_worker_pools():
|
|
|
345
345
|
)
|
|
346
346
|
|
|
347
347
|
if ARGS_PARSER.active_only:
|
|
348
|
-
|
|
348
|
+
print_info("Displaying active Worker Pools only")
|
|
349
349
|
|
|
350
350
|
worker_pool_summaries = [
|
|
351
351
|
wp_summary
|
|
@@ -355,11 +355,11 @@ def list_worker_pools():
|
|
|
355
355
|
]
|
|
356
356
|
|
|
357
357
|
if len(worker_pool_summaries) == 0:
|
|
358
|
-
|
|
358
|
+
print_info("No Worker Pools to display")
|
|
359
359
|
return
|
|
360
360
|
|
|
361
361
|
if ARGS_PARSER.nodes or ARGS_PARSER.workers:
|
|
362
|
-
|
|
362
|
+
print_info(
|
|
363
363
|
"Please select the Worker Pool(s) for which to list "
|
|
364
364
|
f"{'Nodes' if ARGS_PARSER.nodes else 'Workers'}"
|
|
365
365
|
)
|
|
@@ -390,14 +390,14 @@ def list_worker_pools():
|
|
|
390
390
|
|
|
391
391
|
|
|
392
392
|
def list_compute_requirements():
|
|
393
|
-
|
|
393
|
+
print_info(
|
|
394
394
|
"Listing Compute Requirements in "
|
|
395
395
|
f"namespace '{CONFIG_COMMON.namespace}' with "
|
|
396
396
|
f" names containing '{CONFIG_COMMON.name_tag}'"
|
|
397
397
|
)
|
|
398
398
|
|
|
399
399
|
if ARGS_PARSER.active_only:
|
|
400
|
-
|
|
400
|
+
print_info("Listing active Compute Requirements only")
|
|
401
401
|
included_statuses = [
|
|
402
402
|
ComputeRequirementStatus.NEW,
|
|
403
403
|
ComputeRequirementStatus.STARTING,
|
|
@@ -416,7 +416,7 @@ def list_compute_requirements():
|
|
|
416
416
|
)
|
|
417
417
|
|
|
418
418
|
if len(compute_requirement_summaries) == 0:
|
|
419
|
-
|
|
419
|
+
print_info("No matching Compute Requirements")
|
|
420
420
|
return
|
|
421
421
|
|
|
422
422
|
compute_requirement_summaries = sorted_objects(compute_requirement_summaries)
|
|
@@ -452,11 +452,11 @@ def list_instances(compute_requirement_id: str):
|
|
|
452
452
|
)
|
|
453
453
|
instances: List[Instance] = search_client.list_all()
|
|
454
454
|
if len(instances) == 0:
|
|
455
|
-
|
|
455
|
+
print_info("No instances to list")
|
|
456
456
|
return
|
|
457
457
|
|
|
458
458
|
if ARGS_PARSER.public_ips_only:
|
|
459
|
-
|
|
459
|
+
print_info("Listing public IP addresses only:")
|
|
460
460
|
for instance in instances:
|
|
461
461
|
try:
|
|
462
462
|
if instance.publicIpAddress is not None:
|
|
@@ -493,7 +493,7 @@ def list_nodes(worker_pool_summaries: List[WorkerPoolSummary]):
|
|
|
493
493
|
nodes_all += nodes
|
|
494
494
|
|
|
495
495
|
if len(nodes_all) == 0:
|
|
496
|
-
|
|
496
|
+
print_info("No Nodes to display")
|
|
497
497
|
return
|
|
498
498
|
|
|
499
499
|
if ARGS_PARSER.workers:
|
|
@@ -532,7 +532,7 @@ def list_workers(nodes: List[Node]):
|
|
|
532
532
|
workers_all.append(worker)
|
|
533
533
|
|
|
534
534
|
if len(workers_all) == 0:
|
|
535
|
-
|
|
535
|
+
print_info("No Workers to display")
|
|
536
536
|
return
|
|
537
537
|
|
|
538
538
|
if not ARGS_PARSER.details:
|
|
@@ -553,7 +553,7 @@ def list_compute_requirement_templates():
|
|
|
553
553
|
Print the list of Compute Requirement Templates, filtered on Namespace
|
|
554
554
|
and Name. Set these both to empty strings to generate an unfiltered list.
|
|
555
555
|
"""
|
|
556
|
-
|
|
556
|
+
print_info(
|
|
557
557
|
"Listing Compute Requirement Templates in namespace "
|
|
558
558
|
f"'{CONFIG_COMMON.namespace}' with names including "
|
|
559
559
|
f"'{CONFIG_COMMON.name_tag}'"
|
|
@@ -566,7 +566,7 @@ def list_compute_requirement_templates():
|
|
|
566
566
|
)
|
|
567
567
|
|
|
568
568
|
if len(cr_templates) == 0:
|
|
569
|
-
|
|
569
|
+
print_info("No matching Compute Requirement Templates found")
|
|
570
570
|
return
|
|
571
571
|
|
|
572
572
|
if ARGS_PARSER.ids_only:
|
|
@@ -581,7 +581,7 @@ def list_compute_requirement_templates():
|
|
|
581
581
|
# Show details
|
|
582
582
|
cr_templates = select(CLIENT, cr_templates)
|
|
583
583
|
if len(cr_templates) > 0 and ARGS_PARSER.substitute_ids:
|
|
584
|
-
|
|
584
|
+
print_info(
|
|
585
585
|
"Substituting Compute Source Template IDs and Image Family IDs with names"
|
|
586
586
|
)
|
|
587
587
|
cr_template_details = [
|
|
@@ -605,7 +605,7 @@ def list_compute_source_templates():
|
|
|
605
605
|
and Name. Set these both to empty strings to generate an unfiltered list.
|
|
606
606
|
"""
|
|
607
607
|
|
|
608
|
-
|
|
608
|
+
print_info(
|
|
609
609
|
"Listing Compute Source Templates in namespace "
|
|
610
610
|
f"'{CONFIG_COMMON.namespace}' with names including "
|
|
611
611
|
f"'{CONFIG_COMMON.name_tag}'"
|
|
@@ -616,7 +616,7 @@ def list_compute_source_templates():
|
|
|
616
616
|
)
|
|
617
617
|
|
|
618
618
|
if len(cs_templates) == 0:
|
|
619
|
-
|
|
619
|
+
print_info("No matching Compute Source Templates found")
|
|
620
620
|
return
|
|
621
621
|
|
|
622
622
|
if ARGS_PARSER.ids_only:
|
|
@@ -651,7 +651,7 @@ def list_keyrings():
|
|
|
651
651
|
"""
|
|
652
652
|
keyrings: List[KeyringSummary] = CLIENT.keyring_client.find_all_keyrings()
|
|
653
653
|
if len(keyrings) == 0:
|
|
654
|
-
|
|
654
|
+
print_info("No Keyrings found")
|
|
655
655
|
return
|
|
656
656
|
|
|
657
657
|
if ARGS_PARSER.ids_only:
|
|
@@ -697,7 +697,7 @@ def list_image_families():
|
|
|
697
697
|
search_client: SearchClient = CLIENT.images_client.get_image_families(image_search)
|
|
698
698
|
image_family_summaries: List[MachineImageFamilySummary] = search_client.list_all()
|
|
699
699
|
if len(image_family_summaries) == 0:
|
|
700
|
-
|
|
700
|
+
print_info(
|
|
701
701
|
f"No matching Machine Image Families found in namespace "
|
|
702
702
|
f"'{CONFIG_COMMON.namespace}' with tag including '{CONFIG_COMMON.name_tag}'"
|
|
703
703
|
)
|
|
@@ -756,9 +756,9 @@ def list_namespace_storage_configurations():
|
|
|
756
756
|
namespace_list += namespaces_default
|
|
757
757
|
|
|
758
758
|
if len(namespace_list) == 0:
|
|
759
|
-
|
|
759
|
+
print_info("No Namespaces found")
|
|
760
760
|
return
|
|
761
|
-
|
|
761
|
+
print_info("Displaying all Object Store Namespaces")
|
|
762
762
|
|
|
763
763
|
# Accumulate all available headings; keep "namespace", "type"
|
|
764
764
|
# at the start
|
|
@@ -805,7 +805,7 @@ def list_allowances():
|
|
|
805
805
|
)
|
|
806
806
|
allowances: List[Allowance] = search_client.list_all()
|
|
807
807
|
if len(allowances) == 0:
|
|
808
|
-
|
|
808
|
+
print_info("No Allowances to display")
|
|
809
809
|
return
|
|
810
810
|
|
|
811
811
|
if ARGS_PARSER.ids_only:
|
|
@@ -819,7 +819,7 @@ def list_allowances():
|
|
|
819
819
|
|
|
820
820
|
# Show details
|
|
821
821
|
if len(allowances) > 0 and ARGS_PARSER.substitute_ids:
|
|
822
|
-
|
|
822
|
+
print_info(
|
|
823
823
|
"Substituting Compute Requirement Template IDs with names (if applicable)"
|
|
824
824
|
)
|
|
825
825
|
print_yd_object_list(
|
|
@@ -889,7 +889,7 @@ def list_namespaces():
|
|
|
889
889
|
).list_all()
|
|
890
890
|
|
|
891
891
|
if len(namespaces) == 0:
|
|
892
|
-
|
|
892
|
+
print_info("No Namespaces found")
|
|
893
893
|
return
|
|
894
894
|
|
|
895
895
|
if not ARGS_PARSER.details:
|
|
@@ -915,7 +915,7 @@ def list_namespace_policies():
|
|
|
915
915
|
)
|
|
916
916
|
namespace_policies: List[NamespacePolicy] = search_client.list_all()
|
|
917
917
|
if len(namespace_policies) == 0:
|
|
918
|
-
|
|
918
|
+
print_info("No Namespace Policies to display")
|
|
919
919
|
return
|
|
920
920
|
|
|
921
921
|
if not ARGS_PARSER.details:
|
|
@@ -942,7 +942,7 @@ def list_users():
|
|
|
942
942
|
users: List[User] = get_all_users(CLIENT)
|
|
943
943
|
|
|
944
944
|
if len(users) == 0:
|
|
945
|
-
|
|
945
|
+
print_info("No Users to display")
|
|
946
946
|
return
|
|
947
947
|
|
|
948
948
|
users.sort(key=lambda user: user.name)
|
|
@@ -975,7 +975,7 @@ def list_applications():
|
|
|
975
975
|
applications = get_all_applications(CLIENT)
|
|
976
976
|
|
|
977
977
|
if len(applications) == 0:
|
|
978
|
-
|
|
978
|
+
print_info("No Applications to display")
|
|
979
979
|
return
|
|
980
980
|
|
|
981
981
|
applications.sort(key=lambda app: app.name)
|
|
@@ -992,7 +992,9 @@ def list_applications():
|
|
|
992
992
|
{
|
|
993
993
|
PROP_GROUPS: [
|
|
994
994
|
group.name
|
|
995
|
-
for group in
|
|
995
|
+
for group in get_application_group_summaries(
|
|
996
|
+
CLIENT, application.id
|
|
997
|
+
)
|
|
996
998
|
],
|
|
997
999
|
PROP_RESOURCE: RN_APPLICATION,
|
|
998
1000
|
},
|
|
@@ -1009,7 +1011,7 @@ def list_groups():
|
|
|
1009
1011
|
group_summaries = get_all_groups(CLIENT)
|
|
1010
1012
|
|
|
1011
1013
|
if len(group_summaries) == 0:
|
|
1012
|
-
|
|
1014
|
+
print_info("No Groups to display")
|
|
1013
1015
|
return
|
|
1014
1016
|
|
|
1015
1017
|
group_summaries.sort(key=lambda group: group.name if group.name is not None else "")
|
|
@@ -1036,12 +1038,12 @@ def list_roles():
|
|
|
1036
1038
|
role_summaries = get_all_roles(CLIENT)
|
|
1037
1039
|
|
|
1038
1040
|
if len(role_summaries) == 0:
|
|
1039
|
-
|
|
1041
|
+
print_info("No Roles to display")
|
|
1040
1042
|
return
|
|
1041
1043
|
|
|
1042
1044
|
role_summaries.sort(key=lambda role: role.name if role.name is not None else "")
|
|
1043
1045
|
|
|
1044
|
-
|
|
1046
|
+
print_info("Obtaining permissions for each role ...")
|
|
1045
1047
|
roles: List[Role] = [CLIENT.account_client.get_role(x.id) for x in role_summaries]
|
|
1046
1048
|
|
|
1047
1049
|
# Sort permissions alphabetically (contorting the type)
|
yellowdog_cli/provision.py
CHANGED
|
@@ -30,7 +30,7 @@ from yellowdog_cli.utils.misc_utils import (
|
|
|
30
30
|
)
|
|
31
31
|
from yellowdog_cli.utils.printing import (
|
|
32
32
|
print_error,
|
|
33
|
-
|
|
33
|
+
print_info,
|
|
34
34
|
print_worker_pool,
|
|
35
35
|
print_yd_object,
|
|
36
36
|
)
|
|
@@ -96,7 +96,7 @@ def main():
|
|
|
96
96
|
|
|
97
97
|
if wp_json_file is not None:
|
|
98
98
|
wp_json_file = resolve_filename(files_directory, wp_json_file)
|
|
99
|
-
|
|
99
|
+
print_info(f"Loading Worker Pool data from: '{wp_json_file}'")
|
|
100
100
|
create_worker_pool_from_json(wp_json_file)
|
|
101
101
|
elif CONFIG_WP.template_id is None:
|
|
102
102
|
print_error("No template ID supplied")
|
|
@@ -149,7 +149,7 @@ def create_worker_pool_from_json(wp_json_file: str) -> None:
|
|
|
149
149
|
(INSTANCE_TAGS, CONFIG_WP.instance_tags),
|
|
150
150
|
]:
|
|
151
151
|
if reqt_template_usage.get(key) is None and value is not None:
|
|
152
|
-
|
|
152
|
+
print_info(f"Setting 'requirementTemplateUsage.{key}': '{value}'")
|
|
153
153
|
reqt_template_usage[key] = value
|
|
154
154
|
|
|
155
155
|
if (
|
|
@@ -157,7 +157,7 @@ def create_worker_pool_from_json(wp_json_file: str) -> None:
|
|
|
157
157
|
and CONFIG_WP.target_instance_count is not None
|
|
158
158
|
and CONFIG_WP.target_instance_count_set is True
|
|
159
159
|
):
|
|
160
|
-
|
|
160
|
+
print_info(
|
|
161
161
|
f"Setting 'requirementTemplateUsage.{TARGET_INSTANCE_COUNT}':"
|
|
162
162
|
f" '{CONFIG_WP.target_instance_count}'"
|
|
163
163
|
)
|
|
@@ -230,7 +230,7 @@ def create_worker_pool_from_json(wp_json_file: str) -> None:
|
|
|
230
230
|
("metricsEnabled", CONFIG_WP.metrics_enabled),
|
|
231
231
|
]:
|
|
232
232
|
if provisioned_properties.get(key) is None and value is not None:
|
|
233
|
-
|
|
233
|
+
print_info(f"Setting 'provisionedProperties.{key}': '{value}'")
|
|
234
234
|
provisioned_properties[key] = value
|
|
235
235
|
|
|
236
236
|
for key, value, is_set in [
|
|
@@ -242,16 +242,16 @@ def create_worker_pool_from_json(wp_json_file: str) -> None:
|
|
|
242
242
|
and value is not None
|
|
243
243
|
and is_set is True
|
|
244
244
|
):
|
|
245
|
-
|
|
245
|
+
print_info(f"Setting 'provisionedProperties.{key}': '{value}'")
|
|
246
246
|
provisioned_properties[key] = value
|
|
247
247
|
|
|
248
248
|
except KeyError as e:
|
|
249
249
|
raise Exception(f"Key error in JSON Worker Pool definition: {e}")
|
|
250
250
|
|
|
251
251
|
if ARGS_PARSER.dry_run:
|
|
252
|
-
|
|
252
|
+
print_info("Dry-run: Printing JSON Worker Pool specification")
|
|
253
253
|
print_yd_object(wp_data)
|
|
254
|
-
|
|
254
|
+
print_info("Dry-run: Complete")
|
|
255
255
|
return
|
|
256
256
|
|
|
257
257
|
response = requests.post(
|
|
@@ -262,13 +262,13 @@ def create_worker_pool_from_json(wp_json_file: str) -> None:
|
|
|
262
262
|
name = wp_data["requirementTemplateUsage"]["requirementName"]
|
|
263
263
|
if response.status_code == 200:
|
|
264
264
|
id = response.json()["id"]
|
|
265
|
-
|
|
265
|
+
print_info(
|
|
266
266
|
f"Provisioned Worker Pool '{reqt_template_usage['requirementNamespace']}/{name}' ({id})"
|
|
267
267
|
)
|
|
268
268
|
if ARGS_PARSER.quiet:
|
|
269
269
|
print(id)
|
|
270
270
|
if ARGS_PARSER.follow:
|
|
271
|
-
|
|
271
|
+
print_info("Following Worker Pool event stream")
|
|
272
272
|
follow_ids([id], auto_cr=ARGS_PARSER.auto_cr)
|
|
273
273
|
else:
|
|
274
274
|
print_error(f"Failed to provision Worker Pool '{name}'")
|
|
@@ -328,21 +328,21 @@ def create_worker_pool_from_toml():
|
|
|
328
328
|
node_workers = NodeWorkerTarget.per_node(CONFIG_WP.workers_per_node)
|
|
329
329
|
|
|
330
330
|
if CONFIG_WP.maintainInstanceCount is True:
|
|
331
|
-
|
|
331
|
+
print_info(
|
|
332
332
|
f"Warning: Property '{MAINTAIN_INSTANCE_COUNT}' will be set to "
|
|
333
333
|
"'false' when creating a Worker Pool"
|
|
334
334
|
)
|
|
335
335
|
|
|
336
336
|
# Create the Worker Pool
|
|
337
337
|
if node_workers.targetType == NodeWorkerTargetType.CUSTOM:
|
|
338
|
-
|
|
338
|
+
print_info(
|
|
339
339
|
f"Provisioning {CONFIG_WP.target_instance_count:,d} node(s) "
|
|
340
340
|
f"with a custom number of workers per node "
|
|
341
341
|
f"(minNodes: {CONFIG_WP.min_nodes:,d}, "
|
|
342
342
|
f"maxNodes: {CONFIG_WP.max_nodes:,d})"
|
|
343
343
|
)
|
|
344
344
|
else:
|
|
345
|
-
|
|
345
|
+
print_info(
|
|
346
346
|
f"Provisioning {CONFIG_WP.target_instance_count:,d} node(s) "
|
|
347
347
|
f"with {node_workers.targetCount} worker(s) "
|
|
348
348
|
f"{node_workers.targetType} "
|
|
@@ -359,7 +359,7 @@ def create_worker_pool_from_toml():
|
|
|
359
359
|
|
|
360
360
|
worker_pool_ids: List[str] = []
|
|
361
361
|
if num_batches > 1:
|
|
362
|
-
|
|
362
|
+
print_info(f"Batching into {num_batches} Compute Requirements")
|
|
363
363
|
|
|
364
364
|
for batch_number in range(num_batches):
|
|
365
365
|
id = add_batch_number_postfix(
|
|
@@ -368,14 +368,14 @@ def create_worker_pool_from_toml():
|
|
|
368
368
|
num_batches=num_batches,
|
|
369
369
|
)
|
|
370
370
|
if num_batches > 1:
|
|
371
|
-
|
|
371
|
+
print_info(
|
|
372
372
|
f"Provisioning Worker Pool {batch_number + 1} '{CONFIG_COMMON.namespace}/{id}' "
|
|
373
373
|
f"with {batches[batch_number].initial_nodes:,d} nodes(s) "
|
|
374
374
|
f"(minNodes: {batches[batch_number].min_nodes:,d}, "
|
|
375
375
|
f"maxNodes: {batches[batch_number].max_nodes:,d})"
|
|
376
376
|
)
|
|
377
377
|
else:
|
|
378
|
-
|
|
378
|
+
print_info(f"Provisioning Worker Pool '{CONFIG_COMMON.namespace}/{id}'")
|
|
379
379
|
try:
|
|
380
380
|
compute_requirement_template_usage = ComputeRequirementTemplateUsage(
|
|
381
381
|
templateId=CONFIG_WP.template_id,
|
|
@@ -407,8 +407,8 @@ def create_worker_pool_from_toml():
|
|
|
407
407
|
compute_requirement_template_usage,
|
|
408
408
|
provisioned_worker_pool_properties,
|
|
409
409
|
)
|
|
410
|
-
|
|
411
|
-
|
|
410
|
+
print_info(f"Created {link_entity(CONFIG_COMMON.url, worker_pool)}")
|
|
411
|
+
print_info(f"YellowDog ID is '{worker_pool.id}'")
|
|
412
412
|
worker_pool_ids.append(worker_pool.id)
|
|
413
413
|
if ARGS_PARSER.quiet:
|
|
414
414
|
print(worker_pool.id)
|
|
@@ -427,7 +427,7 @@ def create_worker_pool_from_toml():
|
|
|
427
427
|
else "is **disabled**"
|
|
428
428
|
)
|
|
429
429
|
|
|
430
|
-
|
|
430
|
+
print_info(
|
|
431
431
|
"Node boot time limit is "
|
|
432
432
|
f"{CONFIG_WP.node_boot_timeout} minute(s) | "
|
|
433
433
|
"Node idle shutdown "
|
|
@@ -442,17 +442,17 @@ def create_worker_pool_from_toml():
|
|
|
442
442
|
if CONFIG_WP.idle_pool_timeout != 0
|
|
443
443
|
else idle_pool_shutdown_msg
|
|
444
444
|
)
|
|
445
|
-
|
|
445
|
+
print_info(idle_pool_shutdown_msg)
|
|
446
446
|
|
|
447
447
|
if CONFIG_WP.metrics_enabled:
|
|
448
|
-
|
|
448
|
+
print_info("Node metrics are enabled")
|
|
449
449
|
|
|
450
450
|
if ARGS_PARSER.dry_run:
|
|
451
|
-
|
|
451
|
+
print_info("Dry-run: Complete")
|
|
452
452
|
return
|
|
453
453
|
|
|
454
454
|
if ARGS_PARSER.follow:
|
|
455
|
-
|
|
455
|
+
print_info("Following Worker Pool event stream(s)")
|
|
456
456
|
follow_ids(worker_pool_ids, auto_cr=ARGS_PARSER.auto_cr)
|
|
457
457
|
|
|
458
458
|
|
|
@@ -507,7 +507,7 @@ def _update_node_counts():
|
|
|
507
507
|
|
|
508
508
|
# Automatically increase targetInstanceCount if required
|
|
509
509
|
if CONFIG_WP.target_instance_count < 0:
|
|
510
|
-
|
|
510
|
+
print_info(
|
|
511
511
|
f"Increasing 'targetInstanceCount' from {CONFIG_WP.target_instance_count} "
|
|
512
512
|
"to 0 to satisfy minimum constraint"
|
|
513
513
|
)
|
|
@@ -515,7 +515,7 @@ def _update_node_counts():
|
|
|
515
515
|
|
|
516
516
|
# Automatically increase maxNodes if required
|
|
517
517
|
if CONFIG_WP.target_instance_count > CONFIG_WP.max_nodes:
|
|
518
|
-
|
|
518
|
+
print_info(
|
|
519
519
|
f"Increasing 'maxNodes' from {CONFIG_WP.max_nodes} to "
|
|
520
520
|
f"{CONFIG_WP.target_instance_count} to match 'targetInstanceCount'"
|
|
521
521
|
)
|
|
@@ -523,7 +523,7 @@ def _update_node_counts():
|
|
|
523
523
|
|
|
524
524
|
# Automatically set maxNodes to 1 if required
|
|
525
525
|
if CONFIG_WP.max_nodes < 1:
|
|
526
|
-
|
|
526
|
+
print_info(
|
|
527
527
|
f"Increasing 'maxNodes' from {CONFIG_WP.max_nodes} to 1 to satisfy "
|
|
528
528
|
"minimum constraint"
|
|
529
529
|
)
|
|
@@ -531,7 +531,7 @@ def _update_node_counts():
|
|
|
531
531
|
|
|
532
532
|
# Automatically reduce minNodes if required
|
|
533
533
|
if CONFIG_WP.target_instance_count < CONFIG_WP.min_nodes:
|
|
534
|
-
|
|
534
|
+
print_info(
|
|
535
535
|
f"Reducing 'minNodes' from {CONFIG_WP.min_nodes} to "
|
|
536
536
|
f"{CONFIG_WP.target_instance_count} to match 'targetInstanceCount'"
|
|
537
537
|
)
|
|
@@ -539,7 +539,7 @@ def _update_node_counts():
|
|
|
539
539
|
|
|
540
540
|
# Automatically set minNodes to 0 if required
|
|
541
541
|
if CONFIG_WP.min_nodes < 0:
|
|
542
|
-
|
|
542
|
+
print_info(
|
|
543
543
|
f"Increasing 'minNodes' from {CONFIG_WP.min_nodes} to 0 to satisfy "
|
|
544
544
|
"minimum constraint"
|
|
545
545
|
)
|