@@ -14,6 +14,7 @@ import (
1414 "go.goms.io/aks/AKSFlexNode/pkg/bootstrapper"
1515 "go.goms.io/aks/AKSFlexNode/pkg/config"
1616 "go.goms.io/aks/AKSFlexNode/pkg/logger"
17+ "go.goms.io/aks/AKSFlexNode/pkg/privatecluster"
1718 "go.goms.io/aks/AKSFlexNode/pkg/status"
1819)
1920
@@ -118,6 +119,107 @@ func runVersion() {
118119 fmt .Printf ("Build Time: %s\n " , BuildTime )
119120}
120121
122+ // Private cluster command variables
123+ var (
124+ aksResourceID string
125+ cleanupModeFlag string
126+ )
127+
128+ // NewPrivateJoinCommand creates a new private-join command
129+ func NewPrivateJoinCommand () * cobra.Command {
130+ cmd := & cobra.Command {
131+ Use : "private-join" ,
132+ Short : "Join a Private AKS cluster (requires sudo)" ,
133+ Long : `Join a Private AKS cluster.
134+
135+ Prerequisites:
136+ 1. A Private AKS cluster must exist with AAD and Azure RBAC enabled
137+ See: pkg/privatecluster/create_private_cluster.md
138+
139+ 2. Current user must have the following roles on the cluster:
140+ - Azure Kubernetes Service Cluster Admin Role
141+ - Azure Kubernetes Service RBAC Cluster Admin
142+
143+ 3. Current user must be logged in via 'sudo az login'
144+
145+ The full resource ID of the Private AKS cluster is required as the --aks-resource-id parameter.
146+ This same resource ID can be used later with the private-leave command.` ,
147+ RunE : func (cmd * cobra.Command , args []string ) error {
148+ return runPrivateJoin (cmd .Context ())
149+ },
150+ }
151+
152+ cmd .Flags ().StringVar (& aksResourceID , "aks-resource-id" , "" , "AKS cluster resource ID (required)" )
153+ cmd .MarkFlagRequired ("aks-resource-id" )
154+
155+ return cmd
156+ }
157+
158+ // NewPrivateLeaveCommand creates a new private-leave command
159+ func NewPrivateLeaveCommand () * cobra.Command {
160+ cmd := & cobra.Command {
161+ Use : "private-leave" ,
162+ Short : "Leave a Private AKS cluster (--mode=local|full, requires sudo)" ,
163+ Long : `Remove this edge node from a Private AKS cluster.
164+
165+ Cleanup modes:
166+ --local Local cleanup only (default):
167+ - Remove node from AKS cluster
168+ - Run aks-flex-node unbootstrap
169+ - Remove Arc Agent
170+ - Stop VPN and remove client config
171+ - Keep Gateway for other nodes
172+
173+ --full Full cleanup (requires --aks-resource-id):
174+ - All local cleanup steps
175+ - Delete Gateway VM
176+ - Delete Gateway subnet, NSG, Public IP
177+ - Delete SSH keys
178+
179+ This command requires the current user to be logged in via 'sudo az login'.` ,
180+ RunE : func (cmd * cobra.Command , args []string ) error {
181+ return runPrivateLeave (cmd .Context ())
182+ },
183+ }
184+
185+ cmd .Flags ().StringVar (& cleanupModeFlag , "mode" , "local" , "Cleanup mode: 'local' (keep Gateway) or 'full' (remove all Azure resources)" )
186+ cmd .Flags ().StringVar (& aksResourceID , "aks-resource-id" , "" , "AKS cluster resource ID (required for --mode=full)" )
187+
188+ return cmd
189+ }
190+
191+ // runPrivateJoin executes the private cluster join process
192+ func runPrivateJoin (ctx context.Context ) error {
193+ if os .Getuid () != 0 {
194+ return fmt .Errorf ("this command requires root privileges, please run with 'sudo'" )
195+ }
196+ runner := privatecluster .NewScriptRunner ("" )
197+ return runner .RunPrivateInstall (ctx , aksResourceID )
198+ }
199+
200+ // runPrivateLeave executes the private cluster leave process
201+ func runPrivateLeave (ctx context.Context ) error {
202+ if os .Getuid () != 0 {
203+ return fmt .Errorf ("this command requires root privileges, please run with 'sudo'" )
204+ }
205+ // Validate cleanup mode
206+ var mode privatecluster.CleanupMode
207+ switch cleanupModeFlag {
208+ case "local" :
209+ mode = privatecluster .CleanupModeLocal
210+ case "full" :
211+ mode = privatecluster .CleanupModeFull
212+ if aksResourceID == "" {
213+ return fmt .Errorf ("--aks-resource-id is required for full cleanup mode" )
214+ }
215+ default :
216+ return fmt .Errorf ("invalid cleanup mode: %s (use 'local' or 'full')" , cleanupModeFlag )
217+ }
218+
219+ runner := privatecluster .NewScriptRunner ("" )
220+ return runner .RunPrivateUninstall (ctx , mode , aksResourceID )
221+ }
222+
121223// runDaemonLoop runs the periodic status collection and bootstrap monitoring daemon
122224func runDaemonLoop (ctx context.Context , cfg * config.Config ) error {
123225 logger := logger .GetLoggerFromContext (ctx )
0 commit comments