44
55import click
66
7+ from orca_cli .core .aliases import add_command_with_alias
78from orca_cli .core .context import OrcaContext
89from orca_cli .core .output import console , output_options , print_detail , print_list
910from orca_cli .core .validators import validate_id
@@ -21,7 +22,12 @@ def placement(ctx: click.Context) -> None:
2122# Resource Providers
2223# ══════════════════════════════════════════════════════════════════════════════
2324
24- @placement .command ("resource-provider-list" )
25+ @placement .group ("resource-provider" )
26+ def placement_resource_provider () -> None :
27+ """Manage Placement resource providers (compound noun)."""
28+
29+
30+ @placement_resource_provider .command ("list" )
2531@click .option ("--name" , default = None , help = "Filter by name." )
2632@click .option ("--uuid" , default = None , help = "Filter by UUID." )
2733@click .option ("--in-tree" , default = None , metavar = "UUID" , help = "Limit to providers in this tree." )
@@ -53,7 +59,7 @@ def rp_list(ctx, name, uuid, in_tree, output_format, columns, fit_width, max_wid
5359 fit_width = fit_width , max_width = max_width , noindent = noindent )
5460
5561
56- @placement .command ("resource-provider- show" )
62+ @placement_resource_provider .command ("show" )
5763@click .argument ("uuid" , callback = validate_id )
5864@output_options
5965@click .pass_context
@@ -74,7 +80,7 @@ def rp_show(ctx, uuid, output_format, columns, fit_width, max_width, noindent):
7480 fit_width = fit_width , max_width = max_width , noindent = noindent )
7581
7682
77- @placement .command ("resource-provider- create" )
83+ @placement_resource_provider .command ("create" )
7884@click .argument ("name" )
7985@click .option ("--uuid" , default = None , help = "Explicit UUID for the new provider." )
8086@click .option ("--parent-uuid" , default = None ,
@@ -101,7 +107,7 @@ def rp_create(ctx, name, uuid, parent_uuid, output_format, columns, fit_width, m
101107 fit_width = fit_width , max_width = max_width , noindent = noindent )
102108
103109
104- @placement .command ("resource-provider- set" )
110+ @placement_resource_provider .command ("set" )
105111@click .argument ("uuid" , callback = validate_id )
106112@click .option ("--name" , default = None , help = "New name." )
107113@click .option ("--parent-uuid" , default = None , help = "New parent provider UUID." )
@@ -122,7 +128,7 @@ def rp_set(ctx, uuid, name, parent_uuid):
122128 console .print (f"Resource provider [bold]{ uuid } [/bold] updated." )
123129
124130
125- @placement .command ("resource-provider- delete" )
131+ @placement_resource_provider .command ("delete" )
126132@click .argument ("uuid" , callback = validate_id )
127133@click .option ("--yes" , "-y" , is_flag = True , help = "Skip confirmation." )
128134@click .pass_context
@@ -140,7 +146,7 @@ def rp_delete(ctx, uuid, yes):
140146# Inventories
141147# ══════════════════════════════════════════════════════════════════════════════
142148
143- @placement .command ("resource-provider- inventory-list" )
149+ @placement_resource_provider .command ("inventory-list" )
144150@click .argument ("uuid" , callback = validate_id )
145151@output_options
146152@click .pass_context
@@ -168,7 +174,7 @@ def rp_inventory_list(ctx, uuid, output_format, columns, fit_width, max_width, n
168174 fit_width = fit_width , max_width = max_width , noindent = noindent )
169175
170176
171- @placement .command ("resource-provider- inventory-set" )
177+ @placement_resource_provider .command ("inventory-set" )
172178@click .argument ("uuid" , callback = validate_id )
173179@click .argument ("resource_class" )
174180@click .option ("--total" , type = int , required = True , help = "Total inventory units." )
@@ -198,7 +204,7 @@ def rp_inventory_set(ctx, uuid, resource_class, total, reserved,
198204 console .print (f"Inventory [bold]{ resource_class } [/bold] set for provider [bold]{ uuid } [/bold]." )
199205
200206
201- @placement .command ("resource-provider- inventory-delete" )
207+ @placement_resource_provider .command ("inventory-delete" )
202208@click .argument ("uuid" , callback = validate_id )
203209@click .argument ("resource_class" )
204210@click .option ("--yes" , "-y" , is_flag = True , help = "Skip confirmation." )
@@ -217,7 +223,7 @@ def rp_inventory_delete(ctx, uuid, resource_class, yes):
217223# Usages
218224# ══════════════════════════════════════════════════════════════════════════════
219225
220- @placement .command ("resource-provider- usage" )
226+ @placement_resource_provider .command ("usage" )
221227@click .argument ("uuid" , callback = validate_id )
222228@output_options
223229@click .pass_context
@@ -237,7 +243,12 @@ def rp_usage(ctx, uuid, output_format, columns, fit_width, max_width, noindent):
237243 fit_width = fit_width , max_width = max_width , noindent = noindent )
238244
239245
240- @placement .command ("usage-list" )
246+ @placement .group ("usage" )
247+ def placement_usage () -> None :
248+ """Inspect Placement usage."""
249+
250+
251+ @placement_usage .command ("list" )
241252@click .option ("--project-id" , default = None , help = "Filter by project UUID." )
242253@click .option ("--user-id" , default = None , help = "Filter by user UUID." )
243254@output_options
@@ -267,7 +278,12 @@ def usage_list(ctx, project_id, user_id, output_format, columns, fit_width, max_
267278# Resource Classes
268279# ══════════════════════════════════════════════════════════════════════════════
269280
270- @placement .command ("resource-class-list" )
281+ @placement .group ("resource-class" )
282+ def placement_resource_class () -> None :
283+ """Manage Placement resource classes (compound noun)."""
284+
285+
286+ @placement_resource_class .command ("list" )
271287@output_options
272288@click .pass_context
273289def rc_list (ctx , output_format , columns , fit_width , max_width , noindent ):
@@ -284,7 +300,7 @@ def rc_list(ctx, output_format, columns, fit_width, max_width, noindent):
284300 fit_width = fit_width , max_width = max_width , noindent = noindent )
285301
286302
287- @placement .command ("resource-class- show" )
303+ @placement_resource_class .command ("show" )
288304@click .argument ("name" )
289305@click .pass_context
290306def rc_show (ctx , name ):
@@ -297,7 +313,7 @@ def rc_show(ctx, name):
297313 console .print (f"Resource class [bold]{ name } [/bold] exists." )
298314
299315
300- @placement .command ("resource-class- create" )
316+ @placement_resource_class .command ("create" )
301317@click .argument ("name" )
302318@click .pass_context
303319def rc_create (ctx , name ):
@@ -308,7 +324,7 @@ def rc_create(ctx, name):
308324 console .print (f"Resource class [bold]{ name } [/bold] created." )
309325
310326
311- @placement .command ("resource-class- delete" )
327+ @placement_resource_class .command ("delete" )
312328@click .argument ("name" )
313329@click .option ("--yes" , "-y" , is_flag = True , help = "Skip confirmation." )
314330@click .pass_context
@@ -326,7 +342,12 @@ def rc_delete(ctx, name, yes):
326342# Traits
327343# ══════════════════════════════════════════════════════════════════════════════
328344
329- @placement .command ("trait-list" )
345+ @placement .group ("trait" )
346+ def placement_trait () -> None :
347+ """Manage Placement traits."""
348+
349+
350+ @placement_trait .command ("list" )
330351@click .option ("--name" , default = None , help = "Filter traits by name prefix." )
331352@click .option ("--associated" , is_flag = True , default = False ,
332353 help = "Only traits associated with a resource provider." )
@@ -352,7 +373,7 @@ def trait_list(ctx, name, associated, output_format, columns, fit_width, max_wid
352373 fit_width = fit_width , max_width = max_width , noindent = noindent )
353374
354375
355- @placement .command ("trait- create" )
376+ @placement_trait .command ("create" )
356377@click .argument ("name" )
357378@click .pass_context
358379def trait_create (ctx , name ):
@@ -363,7 +384,7 @@ def trait_create(ctx, name):
363384 console .print (f"Trait [bold]{ name } [/bold] created." )
364385
365386
366- @placement .command ("trait- delete" )
387+ @placement_trait .command ("delete" )
367388@click .argument ("name" )
368389@click .option ("--yes" , "-y" , is_flag = True , help = "Skip confirmation." )
369390@click .pass_context
@@ -377,7 +398,7 @@ def trait_delete(ctx, name, yes):
377398 console .print (f"Trait [bold]{ name } [/bold] deleted." )
378399
379400
380- @placement .command ("resource-provider- trait-list" )
401+ @placement_resource_provider .command ("trait-list" )
381402@click .argument ("uuid" , callback = validate_id )
382403@output_options
383404@click .pass_context
@@ -397,7 +418,7 @@ def rp_trait_list(ctx, uuid, output_format, columns, fit_width, max_width, noind
397418 fit_width = fit_width , max_width = max_width , noindent = noindent )
398419
399420
400- @placement .command ("resource-provider- trait-set" )
421+ @placement_resource_provider .command ("trait-set" )
401422@click .argument ("uuid" , callback = validate_id )
402423@click .argument ("traits" , nargs = - 1 , required = True )
403424@click .pass_context
@@ -414,7 +435,7 @@ def rp_trait_set(ctx, uuid, traits):
414435 console .print (f"Traits set on [bold]{ uuid } [/bold]." )
415436
416437
417- @placement .command ("resource-provider- trait-delete" )
438+ @placement_resource_provider .command ("trait-delete" )
418439@click .argument ("uuid" , callback = validate_id )
419440@click .option ("--yes" , "-y" , is_flag = True , help = "Skip confirmation." )
420441@click .pass_context
@@ -432,7 +453,12 @@ def rp_trait_delete(ctx, uuid, yes):
432453# Allocations
433454# ══════════════════════════════════════════════════════════════════════════════
434455
435- @placement .command ("allocation-show" )
456+ @placement .group ("allocation" )
457+ def placement_allocation () -> None :
458+ """Manage Placement allocations."""
459+
460+
461+ @placement_allocation .command ("show" )
436462@click .argument ("consumer_uuid" , callback = validate_id )
437463@output_options
438464@click .pass_context
@@ -459,7 +485,7 @@ def allocation_show(ctx, consumer_uuid, output_format, columns, fit_width, max_w
459485 fit_width = fit_width , max_width = max_width , noindent = noindent )
460486
461487
462- @placement .command ("allocation- delete" )
488+ @placement_allocation .command ("delete" )
463489@click .argument ("consumer_uuid" , callback = validate_id )
464490@click .option ("--yes" , "-y" , is_flag = True , help = "Skip confirmation." )
465491@click .pass_context
@@ -473,7 +499,7 @@ def allocation_delete(ctx, consumer_uuid, yes):
473499 console .print (f"Allocations for [bold]{ consumer_uuid } [/bold] deleted." )
474500
475501
476- @placement .command ("allocation- set" )
502+ @placement_allocation .command ("set" )
477503@click .argument ("consumer_uuid" , callback = validate_id )
478504@click .option ("--resource-provider" , "rp_uuid" , required = True , callback = validate_id ,
479505 help = "Resource provider UUID." )
@@ -510,7 +536,7 @@ def allocation_set(ctx, consumer_uuid, rp_uuid, resources, project_id, user_id):
510536# Allocation Candidates
511537# ══════════════════════════════════════════════════════════════════════════════
512538
513- @placement .command ("allocation- candidate-list" )
539+ @placement_allocation .command ("candidate-list" )
514540@click .option ("--resource" , "resources" , multiple = True , metavar = "CLASS=AMOUNT" ,
515541 required = True , help = "Requested resource, e.g. VCPU=4. Repeatable." )
516542@click .option ("--required" , "required_traits" , multiple = True , metavar = "TRAIT" ,
@@ -570,7 +596,7 @@ def allocation_candidate_list(ctx, resources, required_traits, forbidden_traits,
570596# Resource Provider Aggregates
571597# ══════════════════════════════════════════════════════════════════════════════
572598
573- @placement .command ("resource-provider- aggregate-list" )
599+ @placement_resource_provider .command ("aggregate-list" )
574600@click .argument ("uuid" , callback = validate_id )
575601@output_options
576602@click .pass_context
@@ -590,7 +616,7 @@ def rp_aggregate_list(ctx, uuid, output_format, columns, fit_width, max_width, n
590616 fit_width = fit_width , max_width = max_width , noindent = noindent )
591617
592618
593- @placement .command ("resource-provider- aggregate-set" )
619+ @placement_resource_provider .command ("aggregate-set" )
594620@click .argument ("uuid" , callback = validate_id )
595621@click .argument ("aggregates" , nargs = - 1 , required = True )
596622@click .pass_context
@@ -607,7 +633,7 @@ def rp_aggregate_set(ctx, uuid, aggregates):
607633 console .print (f"Aggregates set on [bold]{ uuid } [/bold]." )
608634
609635
610- @placement .command ("resource-provider- aggregate-delete" )
636+ @placement_resource_provider .command ("aggregate-delete" )
611637@click .argument ("uuid" , callback = validate_id )
612638@click .option ("--yes" , "-y" , is_flag = True , help = "Skip confirmation." )
613639@click .pass_context
@@ -630,7 +656,7 @@ def rp_aggregate_delete(ctx, uuid, yes):
630656# Inventory — show single / bulk set / bulk delete
631657# ══════════════════════════════════════════════════════════════════════════════
632658
633- @placement .command ("resource-provider- inventory-show" )
659+ @placement_resource_provider .command ("inventory-show" )
634660@click .argument ("uuid" , callback = validate_id )
635661@click .argument ("resource_class" )
636662@output_options
@@ -653,7 +679,7 @@ def rp_inventory_show(ctx, uuid, resource_class, output_format, columns, fit_wid
653679 fit_width = fit_width , max_width = max_width , noindent = noindent )
654680
655681
656- @placement .command ("resource-provider- inventory-delete-all" )
682+ @placement_resource_provider .command ("inventory-delete-all" )
657683@click .argument ("uuid" , callback = validate_id )
658684@click .option ("--yes" , "-y" , is_flag = True , help = "Skip confirmation." )
659685@click .pass_context
@@ -664,3 +690,94 @@ def rp_inventory_delete_all(ctx, uuid, yes):
664690 click .confirm (f"Delete all inventories for { uuid } ?" , abort = True )
665691 PlacementService (client ).delete_all_inventories (uuid )
666692 console .print (f"All inventories deleted for [bold]{ uuid } [/bold]." )
693+
694+
695+ # ── ADR-0008 deprecated aliases (backward compatibility) ──
696+
697+ add_command_with_alias (placement , rp_list ,
698+ legacy_name = "resource-provider-list" ,
699+ primary_path = "placement resource-provider list" )
700+ add_command_with_alias (placement , rp_show ,
701+ legacy_name = "resource-provider-show" ,
702+ primary_path = "placement resource-provider show" )
703+ add_command_with_alias (placement , rp_create ,
704+ legacy_name = "resource-provider-create" ,
705+ primary_path = "placement resource-provider create" )
706+ add_command_with_alias (placement , rp_set ,
707+ legacy_name = "resource-provider-set" ,
708+ primary_path = "placement resource-provider set" )
709+ add_command_with_alias (placement , rp_delete ,
710+ legacy_name = "resource-provider-delete" ,
711+ primary_path = "placement resource-provider delete" )
712+ add_command_with_alias (placement , rp_inventory_list ,
713+ legacy_name = "resource-provider-inventory-list" ,
714+ primary_path = "placement resource-provider inventory-list" )
715+ add_command_with_alias (placement , rp_inventory_set ,
716+ legacy_name = "resource-provider-inventory-set" ,
717+ primary_path = "placement resource-provider inventory-set" )
718+ add_command_with_alias (placement , rp_inventory_delete ,
719+ legacy_name = "resource-provider-inventory-delete" ,
720+ primary_path = "placement resource-provider inventory-delete" )
721+ add_command_with_alias (placement , rp_inventory_show ,
722+ legacy_name = "resource-provider-inventory-show" ,
723+ primary_path = "placement resource-provider inventory-show" )
724+ add_command_with_alias (placement , rp_inventory_delete_all ,
725+ legacy_name = "resource-provider-inventory-delete-all" ,
726+ primary_path = "placement resource-provider inventory-delete-all" )
727+ add_command_with_alias (placement , rp_usage ,
728+ legacy_name = "resource-provider-usage" ,
729+ primary_path = "placement resource-provider usage" )
730+ add_command_with_alias (placement , rp_trait_list ,
731+ legacy_name = "resource-provider-trait-list" ,
732+ primary_path = "placement resource-provider trait-list" )
733+ add_command_with_alias (placement , rp_trait_set ,
734+ legacy_name = "resource-provider-trait-set" ,
735+ primary_path = "placement resource-provider trait-set" )
736+ add_command_with_alias (placement , rp_trait_delete ,
737+ legacy_name = "resource-provider-trait-delete" ,
738+ primary_path = "placement resource-provider trait-delete" )
739+ add_command_with_alias (placement , rp_aggregate_list ,
740+ legacy_name = "resource-provider-aggregate-list" ,
741+ primary_path = "placement resource-provider aggregate-list" )
742+ add_command_with_alias (placement , rp_aggregate_set ,
743+ legacy_name = "resource-provider-aggregate-set" ,
744+ primary_path = "placement resource-provider aggregate-set" )
745+ add_command_with_alias (placement , rp_aggregate_delete ,
746+ legacy_name = "resource-provider-aggregate-delete" ,
747+ primary_path = "placement resource-provider aggregate-delete" )
748+ add_command_with_alias (placement , usage_list ,
749+ legacy_name = "usage-list" ,
750+ primary_path = "placement usage list" )
751+ add_command_with_alias (placement , rc_list ,
752+ legacy_name = "resource-class-list" ,
753+ primary_path = "placement resource-class list" )
754+ add_command_with_alias (placement , rc_show ,
755+ legacy_name = "resource-class-show" ,
756+ primary_path = "placement resource-class show" )
757+ add_command_with_alias (placement , rc_create ,
758+ legacy_name = "resource-class-create" ,
759+ primary_path = "placement resource-class create" )
760+ add_command_with_alias (placement , rc_delete ,
761+ legacy_name = "resource-class-delete" ,
762+ primary_path = "placement resource-class delete" )
763+ add_command_with_alias (placement , trait_list ,
764+ legacy_name = "trait-list" ,
765+ primary_path = "placement trait list" )
766+ add_command_with_alias (placement , trait_create ,
767+ legacy_name = "trait-create" ,
768+ primary_path = "placement trait create" )
769+ add_command_with_alias (placement , trait_delete ,
770+ legacy_name = "trait-delete" ,
771+ primary_path = "placement trait delete" )
772+ add_command_with_alias (placement , allocation_show ,
773+ legacy_name = "allocation-show" ,
774+ primary_path = "placement allocation show" )
775+ add_command_with_alias (placement , allocation_delete ,
776+ legacy_name = "allocation-delete" ,
777+ primary_path = "placement allocation delete" )
778+ add_command_with_alias (placement , allocation_set ,
779+ legacy_name = "allocation-set" ,
780+ primary_path = "placement allocation set" )
781+ add_command_with_alias (placement , allocation_candidate_list ,
782+ legacy_name = "allocation-candidate-list" ,
783+ primary_path = "placement allocation candidate-list" )
0 commit comments