yellowdog-python-examples 7.17.1__tar.gz → 7.17.2__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 (79) hide show
  1. {yellowdog_python_examples-7.17.1/yellowdog_python_examples.egg-info → yellowdog_python_examples-7.17.2}/PKG-INFO +1 -1
  2. yellowdog_python_examples-7.17.2/yellowdog_cli/__init__.py +1 -0
  3. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/create.py +35 -13
  4. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/list.py +20 -1
  5. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/remove.py +4 -0
  6. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/args.py +11 -0
  7. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/entity_utils.py +31 -4
  8. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/items.py +2 -0
  9. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/load_resources.py +2 -0
  10. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/printing.py +27 -0
  11. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/settings.py +1 -1
  12. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2/yellowdog_python_examples.egg-info}/PKG-INFO +1 -1
  13. yellowdog_python_examples-7.17.1/yellowdog_cli/__init__.py +0 -1
  14. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/LICENSE +0 -0
  15. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/PYPI_README.md +0 -0
  16. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/README.md +0 -0
  17. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/pyproject.toml +0 -0
  18. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/requirements.txt +0 -0
  19. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/setup.cfg +0 -0
  20. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/tests/test_create_remove.py +0 -0
  21. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/tests/test_demos.py +0 -0
  22. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/tests/test_dryruns.py +0 -0
  23. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/tests/test_entrypoints.py +0 -0
  24. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/tests/test_gui.py +0 -0
  25. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/tests/test_list.py +0 -0
  26. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/tests/test_objects.py +0 -0
  27. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/tests/test_variable_processing.py +0 -0
  28. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/abort.py +0 -0
  29. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/admin.py +0 -0
  30. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/boost.py +0 -0
  31. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/cancel.py +0 -0
  32. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/cloudwizard.py +0 -0
  33. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/compare.py +0 -0
  34. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/delete.py +0 -0
  35. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/download.py +0 -0
  36. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/follow.py +0 -0
  37. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/format_json.py +0 -0
  38. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/hold.py +0 -0
  39. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/instantiate.py +0 -0
  40. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/jsonnet2json.py +0 -0
  41. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/provision.py +0 -0
  42. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/resize.py +0 -0
  43. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/show.py +0 -0
  44. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/shutdown.py +0 -0
  45. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/start.py +0 -0
  46. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/submit.py +0 -0
  47. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/terminate.py +0 -0
  48. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/upload.py +0 -0
  49. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/__init__.py +0 -0
  50. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/check_imports.py +0 -0
  51. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/cloudwizard_aws.py +0 -0
  52. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/cloudwizard_aws_types.py +0 -0
  53. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/cloudwizard_azure.py +0 -0
  54. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/cloudwizard_common.py +0 -0
  55. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/cloudwizard_gcp.py +0 -0
  56. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/compact_json.py +0 -0
  57. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/config_types.py +0 -0
  58. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/csv_data.py +0 -0
  59. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/follow_utils.py +0 -0
  60. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/interactive.py +0 -0
  61. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/load_config.py +0 -0
  62. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/misc_utils.py +0 -0
  63. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/property_names.py +0 -0
  64. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/provision_utils.py +0 -0
  65. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/rich_console_input_fixed.py +0 -0
  66. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/start_hold_common.py +0 -0
  67. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/submit_utils.py +0 -0
  68. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/type_check.py +0 -0
  69. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/upload_utils.py +0 -0
  70. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/validate_properties.py +0 -0
  71. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/variables.py +0 -0
  72. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/wrapper.py +0 -0
  73. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/utils/ydid_utils.py +0 -0
  74. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_cli/version.py +0 -0
  75. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_python_examples.egg-info/SOURCES.txt +0 -0
  76. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_python_examples.egg-info/dependency_links.txt +0 -0
  77. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_python_examples.egg-info/entry_points.txt +0 -0
  78. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_python_examples.egg-info/requires.txt +0 -0
  79. {yellowdog_python_examples-7.17.1 → yellowdog_python_examples-7.17.2}/yellowdog_python_examples.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yellowdog-python-examples
3
- Version: 7.17.1
3
+ Version: 7.17.2
4
4
  Summary: Python CLI commands using the YellowDog Python SDK
5
5
  Author-email: YellowDog Limited <support@yellowdog.co>
6
6
  Project-URL: Homepage, https://github.com/yellowdog/python-examples
@@ -0,0 +1 @@
1
+ __version__ = "7.17.2"
@@ -25,6 +25,7 @@ from yellowdog_client.model import (
25
25
  CloudProvider,
26
26
  Group,
27
27
  ImageOsType,
28
+ InternalUser,
28
29
  Keyring,
29
30
  MachineImage,
30
31
  MachineImageFamily,
@@ -39,7 +40,9 @@ from yellowdog_client.model import (
39
40
  from yellowdog_client.model.exceptions import InvalidRequestException
40
41
 
41
42
  from yellowdog_cli.utils.entity_utils import (
43
+ clear_application_caches,
42
44
  clear_compute_source_template_cache,
45
+ clear_group_caches,
43
46
  clear_image_family_search_cache,
44
47
  find_compute_requirement_template_id_by_name,
45
48
  find_compute_source_template_id_by_name,
@@ -831,7 +834,6 @@ def _get_model_object(class_name: str, resource: Dict, **kwargs):
831
834
  Return a populated YellowDog model object for the resource.
832
835
  Discard unexpected keywords.
833
836
  """
834
-
835
837
  def _patch_aws_fleet_enums():
836
838
  if isinstance(model_object, AwsFleetComputeSource):
837
839
  try:
@@ -1017,6 +1019,10 @@ def create_group(resource: Dict):
1017
1019
 
1018
1020
  current_role_ids = {role.role.id for role in group.roles}
1019
1021
 
1022
+ if current_role_ids == new_role_ids:
1023
+ print_log("No Role additions or deletions required")
1024
+ return
1025
+
1020
1026
  role_ids_to_remove = current_role_ids - new_role_ids
1021
1027
  for role_id in role_ids_to_remove:
1022
1028
  CLIENT.account_client.remove_role_from_group(group.id, role_id)
@@ -1041,6 +1047,7 @@ def create_group(resource: Dict):
1041
1047
  _get_model_object(RN_ADD_GROUP_REQUEST, resource)
1042
1048
  )
1043
1049
  print_log(f"Created Group '{group.name}' ({group.id})")
1050
+ clear_group_caches()
1044
1051
  update_roles(group)
1045
1052
 
1046
1053
  def update_group(group_id: str):
@@ -1095,6 +1102,10 @@ def create_application(resource: Dict):
1095
1102
  group.id for group in get_application_groups(CLIENT, app.id)
1096
1103
  }
1097
1104
 
1105
+ if current_group_ids == new_group_ids:
1106
+ print_log("No Group additions or deletions required")
1107
+ return
1108
+
1098
1109
  group_ids_to_remove = current_group_ids - new_group_ids
1099
1110
  for group_id in group_ids_to_remove:
1100
1111
  CLIENT.account_client.remove_application_from_group(group_id, app.id)
@@ -1128,6 +1139,7 @@ def create_application(resource: Dict):
1128
1139
  app = app_response.application
1129
1140
  print_log(f"Created Application '{app.name}' ({app.id})")
1130
1141
  show_key_and_secret(app_response.apiKey)
1142
+ clear_application_caches()
1131
1143
  update_groups(app)
1132
1144
 
1133
1145
  def update_application(app_id: str):
@@ -1159,10 +1171,9 @@ def create_application(resource: Dict):
1159
1171
 
1160
1172
  def update_user(resource: Dict):
1161
1173
  """
1162
- Update a user. Will also add or remove groups specified
1163
- by their names or IDs.
1174
+ Update a user (specified by name or ID). Will also add or remove
1175
+ groups specified by their names or IDs.
1164
1176
  """
1165
-
1166
1177
  name = resource.get(PROP_NAME)
1167
1178
  id = resource.get(PROP_ID)
1168
1179
 
@@ -1178,11 +1189,11 @@ def update_user(resource: Dict):
1178
1189
  # Convert group names to IDs
1179
1190
  new_group_ids = set()
1180
1191
  for group_name in groups:
1181
- app_id = get_group_id_by_name(CLIENT, group_name)
1182
- if app_id is None:
1192
+ group_id = get_group_id_by_name(CLIENT, group_name)
1193
+ if group_id is None:
1183
1194
  print_warning(f"Group name '{group_name}' not found ... ignoring")
1184
1195
  else:
1185
- new_group_ids.add(app_id)
1196
+ new_group_ids.add(group_id)
1186
1197
 
1187
1198
  def update_groups(user: User):
1188
1199
  """
@@ -1193,12 +1204,16 @@ def update_user(resource: Dict):
1193
1204
 
1194
1205
  current_group_ids = {group.id for group in get_user_groups(CLIENT, user.id)}
1195
1206
 
1207
+ if current_group_ids == new_group_ids:
1208
+ print_log("No Group additions or deletions required")
1209
+ return
1210
+
1196
1211
  group_ids_to_remove = current_group_ids - new_group_ids
1197
1212
  for group_id in group_ids_to_remove:
1198
1213
  CLIENT.account_client.remove_user_from_group(group_id, user.id)
1199
1214
  print_log(
1200
1215
  f"Removed Group '{get_group_name_by_id(CLIENT, group_id)}' "
1201
- f"from User ({group_id})"
1216
+ f"({group_id})"
1202
1217
  )
1203
1218
 
1204
1219
  group_ids_to_add = new_group_ids - current_group_ids
@@ -1206,13 +1221,16 @@ def update_user(resource: Dict):
1206
1221
  CLIENT.account_client.add_user_to_group(group_id, user.id)
1207
1222
  print_log(
1208
1223
  f"Added Group '{get_group_name_by_id(CLIENT, group_id)}' "
1209
- f"to User ({group_id})"
1224
+ f"({group_id})"
1210
1225
  )
1211
1226
 
1212
- # Main logic: try name then ID if present
1227
+ # Main logic: try name then ID if present; check for ID match
1213
1228
  user = None
1214
1229
  if name is not None:
1215
1230
  user = get_user_by_name_or_id(CLIENT, name)
1231
+ if user is not None and id is not None:
1232
+ if user.id != id:
1233
+ raise Exception(f"User name '{name}' and supplied ID do not match")
1216
1234
  if user is None and id is not None:
1217
1235
  user = get_user_by_name_or_id(CLIENT, id)
1218
1236
 
@@ -1221,11 +1239,15 @@ def update_user(resource: Dict):
1221
1239
  f"User '{name}' not found; Users cannot be created using "
1222
1240
  "the CLI, please use the YellowDog Portal"
1223
1241
  )
1224
- elif groups is not None:
1225
- print_log(f"Updating Groups for User '{name}' ({user.id})")
1242
+ return
1243
+
1244
+ username = user.username if isinstance(user, InternalUser) else user.name
1245
+
1246
+ if groups is not None:
1247
+ print_log(f"Updating Groups for User '{username}' ({user.id})")
1226
1248
  update_groups(user)
1227
1249
  else:
1228
- print_log(f"Nothing to do for User '{name}' ({user.id})")
1250
+ print_log(f"Nothing to do for User '{username}' ({user.id})")
1229
1251
 
1230
1252
 
1231
1253
  # Entry point
@@ -34,6 +34,7 @@ from yellowdog_client.model import (
34
34
  NodeSearch,
35
35
  NodeStatus,
36
36
  ObjectDetail,
37
+ PermissionDetail,
37
38
  Role,
38
39
  Task,
39
40
  TaskGroup,
@@ -131,6 +132,8 @@ def main():
131
132
  list_groups()
132
133
  elif ARGS_PARSER.roles:
133
134
  list_roles()
135
+ elif ARGS_PARSER.permissions:
136
+ list_permissions()
134
137
 
135
138
 
136
139
  def check_for_valid_option() -> bool:
@@ -151,8 +154,9 @@ def check_for_valid_option() -> bool:
151
154
  ARGS_PARSER.namespace_storage_configurations,
152
155
  ARGS_PARSER.nodes,
153
156
  ARGS_PARSER.object_paths,
154
- ARGS_PARSER.source_templates,
157
+ ARGS_PARSER.permissions,
155
158
  ARGS_PARSER.roles,
159
+ ARGS_PARSER.source_templates,
156
160
  ARGS_PARSER.task_groups,
157
161
  ARGS_PARSER.tasks,
158
162
  ARGS_PARSER.users,
@@ -964,6 +968,21 @@ def list_roles():
964
968
  print_yd_object(selected_users)
965
969
 
966
970
 
971
+ def list_permissions():
972
+ """
973
+ List all permissions in the account.
974
+ """
975
+ permissions: List[PermissionDetail] = CLIENT.account_client.list_permissions()
976
+ permissions.sort(key=lambda permission: permission.name)
977
+
978
+ if not ARGS_PARSER.details:
979
+ print_numbered_object_list(CLIENT, permissions, object_type_name="Permission")
980
+ return
981
+
982
+ for permission in select(CLIENT, permissions, object_type_name="Permission"):
983
+ print_yd_object(permission)
984
+
985
+
967
986
  def get_autoscaling_capacity(namespace: str) -> Dict:
968
987
  """
969
988
  Get the current autoscaling values for a namespace.
@@ -19,6 +19,8 @@ from yellowdog_client.model import (
19
19
  )
20
20
 
21
21
  from yellowdog_cli.utils.entity_utils import (
22
+ clear_application_caches,
23
+ clear_group_caches,
22
24
  find_compute_requirement_template_id_by_name,
23
25
  find_compute_source_template_id_by_name,
24
26
  get_application_id_by_name,
@@ -521,6 +523,7 @@ def remove_group(resource: Dict):
521
523
  try:
522
524
  CLIENT.account_client.delete_group(group_id)
523
525
  print_log(f"Removed Group '{group_name}' ({group_id})")
526
+ clear_group_caches()
524
527
  except Exception as e:
525
528
  print_error(f"Unable to delete Group '{group_name}' ({group_id}): {e}")
526
529
 
@@ -543,6 +546,7 @@ def remove_application(resource: Dict):
543
546
  try:
544
547
  CLIENT.account_client.delete_application(app_id)
545
548
  print_log(f"Removed Application '{app_name}' ({app_id})")
549
+ clear_application_caches()
546
550
  except Exception as e:
547
551
  print_error(f"Unable to delete Application '{app_name}' ({app_id}): {e}")
548
552
 
@@ -651,6 +651,12 @@ class CLIParser:
651
651
  required=False,
652
652
  help="list roles",
653
653
  )
654
+ parser.add_argument(
655
+ "--permissions",
656
+ action="store_true",
657
+ required=False,
658
+ help="list permissions",
659
+ )
654
660
  parser.add_argument(
655
661
  "--output-file",
656
662
  type=str,
@@ -1551,6 +1557,11 @@ class CLIParser:
1551
1557
  def roles(self) -> Optional[bool]:
1552
1558
  return self.args.roles
1553
1559
 
1560
+ @property
1561
+ @allow_missing_attribute
1562
+ def permissions(self) -> Optional[bool]:
1563
+ return self.args.permissions
1564
+
1554
1565
  @property
1555
1566
  @allow_missing_attribute
1556
1567
  def show_keyring_passwords(self) -> Optional[bool]:
@@ -574,8 +574,11 @@ def get_role_id_by_name(client: PlatformClient, role_name: str) -> Optional[str]
574
574
  if get_ydid_type(role_name) == YDIDType.ROLE:
575
575
  return role_name
576
576
 
577
- for role in get_all_roles(client):
578
- if role_name == role.name:
577
+ role_search = RoleSearch(name=role_name)
578
+ search_client: SearchClient = client.account_client.get_roles(role_search)
579
+
580
+ for role in search_client.list_all():
581
+ if role.name == role_name:
579
582
  return role.id
580
583
 
581
584
  return None
@@ -606,8 +609,11 @@ def get_all_roles(client: PlatformClient) -> List[RoleSummary]:
606
609
  @lru_cache
607
610
  def get_group_id_by_name(client: PlatformClient, group_name: str) -> Optional[str]:
608
611
  """
609
- Get a group's ID by its name.
612
+ Get a group's ID by its name. Accept IDs and return unchanged.
610
613
  """
614
+ if get_ydid_type(group_name) == YDIDType.GROUP:
615
+ return group_name
616
+
611
617
  group_search = GroupSearch(name=group_name)
612
618
  search_client: SearchClient = client.account_client.get_groups(group_search)
613
619
  group_summaries: List[GroupSummary] = search_client.list_all()
@@ -641,6 +647,15 @@ def get_all_groups(client: PlatformClient) -> List[GroupSummary]:
641
647
  return search_client.list_all()
642
648
 
643
649
 
650
+ def clear_group_caches():
651
+ """
652
+ Clear the group caches.
653
+ """
654
+ get_all_groups.cache_clear()
655
+ get_group_name_by_id.cache_clear()
656
+ get_group_id_by_name.cache_clear()
657
+
658
+
644
659
  @lru_cache
645
660
  def get_all_applications(client: PlatformClient) -> List[Application]:
646
661
  """
@@ -656,8 +671,11 @@ def get_all_applications(client: PlatformClient) -> List[Application]:
656
671
  @lru_cache
657
672
  def get_application_id_by_name(client: PlatformClient, app_name: str) -> Optional[str]:
658
673
  """
659
- Get an application ID by its name.
674
+ Get an application ID by its name. Accept IDs and return unchanged.
660
675
  """
676
+ if get_ydid_type(app_name) == YDIDType.APPLICATION:
677
+ return app_name
678
+
661
679
  for app in get_all_applications(client):
662
680
  if app.name == app_name:
663
681
  return app.id
@@ -665,6 +683,14 @@ def get_application_id_by_name(client: PlatformClient, app_name: str) -> Optiona
665
683
  return None
666
684
 
667
685
 
686
+ def clear_application_caches():
687
+ """
688
+ Clear the application caches.
689
+ """
690
+ get_all_applications.cache_clear()
691
+ get_application_id_by_name.cache_clear()
692
+
693
+
668
694
  def get_application_groups(client: PlatformClient, app_id: str) -> List[GroupSummary]:
669
695
  """
670
696
  Get the groups to which an application belongs.
@@ -679,6 +705,7 @@ def get_user_groups(client: PlatformClient, user_id: str) -> List[GroupSummary]:
679
705
  return client.account_client.get_user_groups(user_id).list_all()
680
706
 
681
707
 
708
+ @lru_cache
682
709
  def get_user_by_name_or_id(
683
710
  client: PlatformClient, user_name_or_id: str
684
711
  ) -> Optional[User]:
@@ -20,6 +20,7 @@ from yellowdog_client.model import (
20
20
  NamespaceStorageConfiguration,
21
21
  Node,
22
22
  ObjectPath,
23
+ PermissionDetail,
23
24
  ProvisionedWorkerPool,
24
25
  Role,
25
26
  Task,
@@ -50,6 +51,7 @@ Item = TypeVar(
50
51
  NamespaceStorageConfiguration,
51
52
  Node,
52
53
  ObjectPath,
54
+ PermissionDetail,
53
55
  ProvisionedWorkerPool,
54
56
  Role,
55
57
  Task,
@@ -21,6 +21,7 @@ from yellowdog_cli.utils.settings import (
21
21
  RN_SOURCE_TEMPLATE,
22
22
  RN_STORAGE_CONFIGURATION,
23
23
  RN_STRING_ATTRIBUTE_DEFINITION,
24
+ RN_USER,
24
25
  )
25
26
  from yellowdog_cli.utils.variables import (
26
27
  load_json_file_with_variable_substitutions,
@@ -113,6 +114,7 @@ def _resequence_resources(
113
114
  RN_CONFIGURED_POOL,
114
115
  RN_GROUP,
115
116
  RN_APPLICATION,
117
+ RN_USER,
116
118
  ]
117
119
 
118
120
  try:
@@ -41,6 +41,7 @@ from yellowdog_client.model import (
41
41
  Node,
42
42
  ObjectDetail,
43
43
  ObjectPath,
44
+ PermissionDetail,
44
45
  ProvisionedWorkerPool,
45
46
  ProvisionedWorkerPoolProperties,
46
47
  Role,
@@ -230,6 +231,7 @@ TYPE_MAP = {
230
231
  NamespacePolicy: "Namespace Policy",
231
232
  Node: "Node",
232
233
  ObjectPath: "Object Path",
234
+ PermissionDetail: "Permission",
233
235
  ProvisionedWorkerPool: "Provisioned Worker Pool",
234
236
  Task: "Task",
235
237
  TaskGroup: "Task Group",
@@ -831,6 +833,29 @@ def roles_table(
831
833
  return headers, table
832
834
 
833
835
 
836
+ def permissions_table(
837
+ permissions: List[PermissionDetail],
838
+ ) -> (List[str], List[List]):
839
+ headers = [
840
+ "#",
841
+ "Name",
842
+ "Description",
843
+ "Includes",
844
+ ]
845
+ table = []
846
+ for index, permission in enumerate(permissions):
847
+ includes = ", ".join(sorted([x for x in permission.includes]))
848
+ table.append(
849
+ [
850
+ index + 1,
851
+ permission.name,
852
+ permission.title,
853
+ includes,
854
+ ]
855
+ )
856
+ return headers, table
857
+
858
+
834
859
  def print_numbered_object_list(
835
860
  client: PlatformClient,
836
861
  objects: List[Union[Item, str, Dict]],
@@ -899,6 +924,8 @@ def print_numbered_object_list(
899
924
  headers, table = groups_table(objects)
900
925
  elif isinstance(objects[0], Role):
901
926
  headers, table = roles_table(objects)
927
+ elif isinstance(objects[0], PermissionDetail):
928
+ headers, table = permissions_table(objects)
902
929
  else:
903
930
  table = []
904
931
  for index, obj in enumerate(objects):
@@ -82,7 +82,7 @@ HIGHLIGHTED_STATES = [
82
82
  r"(?P<starved>STARVED)",
83
83
  r"(?P<transitioning>CONFIGURING)",
84
84
  r"(?P<transitioning>DOWNLOADING)",
85
- r"(?P<transitioning>LATE)",
85
+ # r"(?P<transitioning>LATE$)",
86
86
  r"(?P<transitioning>NEW)",
87
87
  r"(?P<transitioning>PROVISIONING)",
88
88
  r"(?P<transitioning>STOPPING)",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yellowdog-python-examples
3
- Version: 7.17.1
3
+ Version: 7.17.2
4
4
  Summary: Python CLI commands using the YellowDog Python SDK
5
5
  Author-email: YellowDog Limited <support@yellowdog.co>
6
6
  Project-URL: Homepage, https://github.com/yellowdog/python-examples
@@ -1 +0,0 @@
1
- __version__ = "7.17.1"