Skip to content

Commit ad84d14

Browse files
author
weiliu2
committed
change to go and remove bash file
1 parent 69604af commit ad84d14

File tree

15 files changed

+2244
-1442
lines changed

15 files changed

+2244
-1442
lines changed

.gitignore

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,41 @@
11
# Binaries for programs and plugins
2-
*.exe
3-
*.exe~
2+
# Build artifacts
3+
# Config files with sensitive data (keep sample config)
4+
# Go workspace file
5+
# IDE and editor files
6+
# Log files
7+
# OS generated files
8+
# Output of the go coverage tool, specifically when used with LiteIDE
9+
# Test binary, built with `go test -c`
10+
# Test coverage reports
411
*.dll
5-
*.so
612
*.dylib
7-
aks-flex-node
8-
9-
# Test binary, built with `go test -c`
10-
*.test
11-
12-
# Output of the go coverage tool, specifically when used with LiteIDE
13+
*.exe
14+
*.exe~
15+
*.log
1316
*.out
14-
15-
# Test coverage reports
16-
coverage.out
17-
coverage.html
18-
coverage.xml
19-
20-
# Go workspace file
21-
go.work
22-
23-
# IDE and editor files
24-
.vscode/
25-
.idea/
26-
*.swp
17+
*.so
2718
*.swo
19+
*.swp
20+
*.test
2821
*~
29-
30-
# OS generated files
3122
.DS_Store
3223
.DS_Store?
33-
._*
3424
.Spotlight-V100
3525
.Trashes
36-
ehthumbs.db
37-
Thumbs.db
38-
39-
# Log files
40-
*.log
26+
._*
27+
.idea/
28+
.vscode/
29+
/build/
30+
/dist/AKSFlexNode
4131
/var/log/
42-
43-
# Config files with sensitive data (keep sample config)
32+
AKSFlexNode
33+
Standard_D8pds_v6_sku.json
34+
Thumbs.db
35+
aks-flex-node
4436
config.json
45-
46-
# Build artifacts
47-
/build/
48-
/dist/
37+
coverage.html
38+
coverage.out
39+
coverage.xml
40+
ehthumbs.db
41+
go.work

commands.go

Lines changed: 66 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ var (
2525
BuildTime = "unknown"
2626
)
2727

28+
// Unbootstrap command flags
29+
var cleanupMode string
30+
2831
// NewAgentCommand creates a new agent command
2932
func NewAgentCommand() *cobra.Command {
3033
cmd := &cobra.Command{
@@ -44,12 +47,19 @@ func NewUnbootstrapCommand() *cobra.Command {
4447
cmd := &cobra.Command{
4548
Use: "unbootstrap",
4649
Short: "Remove AKS node configuration and Arc connection",
47-
Long: "Clean up and remove all AKS node components and Arc registration from this machine",
50+
Long: `Clean up and remove all AKS node components and Arc registration from this machine.
51+
52+
For private clusters (config has private: true), this also handles VPN cleanup:
53+
--cleanup-mode=local Remove node and local VPN config, keep Gateway (default)
54+
--cleanup-mode=full Remove everything including Gateway VM and Azure resources`,
4855
RunE: func(cmd *cobra.Command, args []string) error {
4956
return runUnbootstrap(cmd.Context())
5057
},
5158
}
5259

60+
cmd.Flags().StringVar(&cleanupMode, "cleanup-mode", "local",
61+
"Private cluster cleanup mode: 'local' (keep Gateway) or 'full' (remove all Azure resources)")
62+
5363
return cmd
5464
}
5565

@@ -76,6 +86,19 @@ func runAgent(ctx context.Context) error {
7686
return fmt.Errorf("failed to load config from %s: %w", configPath, err)
7787
}
7888

89+
// For private clusters, run Gateway/VPN setup before bootstrap
90+
if cfg.Azure.TargetCluster != nil && cfg.Azure.TargetCluster.Private {
91+
logger.Info("Private cluster detected, running Gateway/VPN setup...")
92+
if os.Getuid() != 0 {
93+
return fmt.Errorf("private cluster setup requires root privileges, please run with 'sudo'")
94+
}
95+
runner := privatecluster.NewScriptRunner("")
96+
if err := runner.RunPrivateInstall(ctx, cfg.Azure.TargetCluster.ResourceID); err != nil {
97+
return fmt.Errorf("private cluster setup failed: %w", err)
98+
}
99+
logger.Info("Private cluster setup completed")
100+
}
101+
79102
bootstrapExecutor := bootstrapper.New(cfg, logger)
80103
result, err := bootstrapExecutor.Bootstrap(ctx)
81104
if err != nil {
@@ -101,14 +124,55 @@ func runUnbootstrap(ctx context.Context) error {
101124
return fmt.Errorf("failed to load config from %s: %w", configPath, err)
102125
}
103126

127+
// For private clusters, run VPN/Gateway cleanup first
128+
if cfg.Azure.TargetCluster != nil && cfg.Azure.TargetCluster.Private {
129+
logger.Info("Private cluster detected, running VPN/Gateway cleanup...")
130+
131+
// Validate cleanup mode
132+
var mode privatecluster.CleanupMode
133+
switch cleanupMode {
134+
case "local":
135+
mode = privatecluster.CleanupModeLocal
136+
case "full":
137+
mode = privatecluster.CleanupModeFull
138+
default:
139+
return fmt.Errorf("invalid cleanup mode: %s (use 'local' or 'full')", cleanupMode)
140+
}
141+
142+
// Check root privileges for private cluster cleanup
143+
if os.Getuid() != 0 {
144+
return fmt.Errorf("private cluster cleanup requires root privileges, please run with 'sudo'")
145+
}
146+
147+
options := privatecluster.UninstallOptions{
148+
Mode: mode,
149+
AKSResourceID: cfg.Azure.TargetCluster.ResourceID,
150+
}
151+
uninstaller := privatecluster.NewUninstaller(options)
152+
if err := uninstaller.Uninstall(ctx); err != nil {
153+
logger.Warnf("Private cluster cleanup had errors: %v", err)
154+
// Continue with normal unbootstrap even if private cleanup has issues
155+
}
156+
logger.Info("Private cluster cleanup completed")
157+
}
158+
159+
// Run normal unbootstrap
104160
bootstrapExecutor := bootstrapper.New(cfg, logger)
105161
result, err := bootstrapExecutor.Unbootstrap(ctx)
106162
if err != nil {
107163
return err
108164
}
109165

110166
// Handle and log the result (unbootstrap is more lenient with failures)
111-
return handleExecutionResult(result, "unbootstrap", logger)
167+
if err := handleExecutionResult(result, "unbootstrap", logger); err != nil {
168+
return err
169+
}
170+
171+
// Print final success message
172+
fmt.Println()
173+
fmt.Println("\033[0;32mSUCCESS:\033[0m Unbootstrap completed successfully!")
174+
175+
return nil
112176
}
113177

114178
// runVersion displays version information
@@ -119,106 +183,6 @@ func runVersion() {
119183
fmt.Printf("Build Time: %s\n", BuildTime)
120184
}
121185

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-
}
222186

223187
// runDaemonLoop runs the periodic status collection and bootstrap monitoring daemon
224188
func runDaemonLoop(ctx context.Context, cfg *config.Config) error {

main.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,13 @@ func main() {
2626

2727
// Add global flags for configuration
2828
rootCmd.PersistentFlags().StringVar(&configPath, "config", "", "Path to configuration JSON file (required for agent/unbootstrap)")
29-
rootCmd.PersistentFlags().MarkHidden("config") // Hide from global help, shown in agent/unbootstrap help
29+
_ = rootCmd.PersistentFlags().MarkHidden("config")
3030
// Don't mark as required globally - we'll check in PersistentPreRunE for commands that need it
3131

3232
// Add commands
3333
rootCmd.AddCommand(NewAgentCommand())
3434
rootCmd.AddCommand(NewUnbootstrapCommand())
3535
rootCmd.AddCommand(NewVersionCommand())
36-
rootCmd.AddCommand(NewPrivateJoinCommand())
37-
rootCmd.AddCommand(NewPrivateLeaveCommand())
3836

3937
// Set up context with signal handling
4038
ctx, cancel := context.WithCancel(context.Background())
@@ -54,7 +52,7 @@ func main() {
5452
rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
5553
// Skip config loading for commands that don't need it
5654
switch cmd.Name() {
57-
case "version", "private-join", "private-leave":
55+
case "version":
5856
return nil
5957
}
6058

pkg/config/structs.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type ServicePrincipalConfig struct {
3939
type TargetClusterConfig struct {
4040
ResourceID string `json:"resourceId"` // Full resource ID of the target AKS cluster
4141
Location string `json:"location"` // Azure region of the cluster (e.g., "eastus", "westus2")
42+
Private bool `json:"private"` // Whether this is a private AKS cluster (requires Gateway/VPN setup)
4243
Name string // will be populated from ResourceID
4344
ResourceGroup string // will be populated from ResourceID
4445
SubscriptionID string // will be populated from ResourceID

0 commit comments

Comments
 (0)