1+ package azcli
2+
3+ import (
4+ "fmt"
5+ "strings"
6+
7+ "github.com/Azure/aks-mcp/internal/config"
8+ )
9+
10+ // FleetExecutor handles structured fleet command execution
11+ type FleetExecutor struct {
12+ * AzExecutor
13+ }
14+
15+ // NewFleetExecutor creates a new fleet command executor
16+ func NewFleetExecutor () * FleetExecutor {
17+ return & FleetExecutor {
18+ AzExecutor : NewExecutor (),
19+ }
20+ }
21+
22+ // Execute processes structured fleet commands
23+ func (e * FleetExecutor ) Execute (params map [string ]interface {}, cfg * config.ConfigData ) (string , error ) {
24+ // Extract structured parameters
25+ operation , ok := params ["operation" ].(string )
26+ if ! ok {
27+ return "" , fmt .Errorf ("operation parameter is required and must be a string" )
28+ }
29+
30+ resource , ok := params ["resource" ].(string )
31+ if ! ok {
32+ return "" , fmt .Errorf ("resource parameter is required and must be a string" )
33+ }
34+
35+ args , ok := params ["args" ].(string )
36+ if ! ok {
37+ return "" , fmt .Errorf ("args parameter is required and must be a string" )
38+ }
39+
40+ // Validate operation/resource combination
41+ if err := e .validateCombination (operation , resource ); err != nil {
42+ return "" , err
43+ }
44+
45+ // Construct the full command
46+ command := fmt .Sprintf ("az fleet %s %s" , resource , operation )
47+ if operation == "list" && resource == "fleet" {
48+ // Special case: "az fleet list" without resource in between
49+ command = "az fleet list"
50+ }
51+
52+ // Check access level
53+ if err := e .checkAccessLevel (operation , resource , cfg .AccessLevel ); err != nil {
54+ return "" , err
55+ }
56+
57+ // Build full command with args
58+ fullCommand := command
59+ if args != "" {
60+ fullCommand = fmt .Sprintf ("%s %s" , command , args )
61+ }
62+
63+ // Create params for the base executor
64+ execParams := map [string ]interface {}{
65+ "command" : fullCommand ,
66+ }
67+
68+ // Execute using the base executor
69+ return e .AzExecutor .Execute (execParams , cfg )
70+ }
71+
72+ // validateCombination validates if the operation/resource combination is valid
73+ func (e * FleetExecutor ) validateCombination (operation , resource string ) error {
74+ validCombinations := map [string ][]string {
75+ "fleet" : {"list" , "show" , "create" , "update" , "delete" },
76+ "member" : {"list" , "show" , "create" , "update" , "delete" },
77+ "updaterun" : {"list" , "show" , "create" , "start" , "stop" , "delete" },
78+ "updatestrategy" : {"list" , "show" , "create" , "delete" },
79+ }
80+
81+ validOps , exists := validCombinations [resource ]
82+ if ! exists {
83+ return fmt .Errorf ("invalid resource type: %s" , resource )
84+ }
85+
86+ for _ , validOp := range validOps {
87+ if operation == validOp {
88+ return nil
89+ }
90+ }
91+
92+ return fmt .Errorf ("invalid operation '%s' for resource '%s'. Valid operations: %s" ,
93+ operation , resource , strings .Join (validOps , ", " ))
94+ }
95+
96+ // checkAccessLevel ensures the operation is allowed for the current access level
97+ func (e * FleetExecutor ) checkAccessLevel (operation , resource string , accessLevel string ) error {
98+ // Read-only operations are allowed for all access levels
99+ readOnlyOps := []string {"list" , "show" }
100+ for _ , op := range readOnlyOps {
101+ if operation == op {
102+ return nil
103+ }
104+ }
105+
106+ // Write operations require readwrite or admin access
107+ if accessLevel == "readonly" {
108+ return fmt .Errorf ("operation '%s' requires readwrite or admin access level, current level is readonly" , operation )
109+ }
110+
111+ // All operations are allowed for readwrite and admin
112+ return nil
113+ }
114+
115+ // GetCommandForValidation returns the constructed command for security validation
116+ func (e * FleetExecutor ) GetCommandForValidation (operation , resource , args string ) string {
117+ command := fmt .Sprintf ("az fleet %s %s" , resource , operation )
118+ if operation == "list" && resource == "fleet" {
119+ command = "az fleet list"
120+ }
121+
122+ if args != "" {
123+ command = fmt .Sprintf ("%s %s" , command , args )
124+ }
125+
126+ return command
127+ }
0 commit comments