-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
113 lines (94 loc) · 3.63 KB
/
main.go
File metadata and controls
113 lines (94 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package main
import (
"fmt"
"os"
"sync"
"oc-scanner/scanner"
"github.com/texttheater/golang-levenshtein/levenshtein"
)
func suggestClosest(input string, options []string) string {
// Set minimum distance threshold - only suggest if difference is less than 3 characters
minDistance := 3
closest := ""
// Iterate through all valid options and calculate edit distance
for _, opt := range options {
// Calculate Levenshtein distance between input and current option
// Using runes to properly handle Unicode characters
dist := levenshtein.DistanceForStrings([]rune(input), []rune(opt), levenshtein.DefaultOptions)
// If this option is closer than our current best match, update it
if dist < minDistance {
minDistance = dist
closest = opt
}
}
return closest
}
func main() {
// Validate command line arguments - need at least 4 args: program name, command, namespace, and at least one resource type
if len(os.Args) < 4 {
fmt.Println("Usage: kube-scanner scan <namespace> <resource-type> [<resource-type>...]")
return
}
// Parse command line arguments
command := os.Args[1] // First argument should be the command (e.g., "scan")
namespace := os.Args[2] // Second argument is the Kubernetes namespace to scan
resources := os.Args[3:] // Remaining arguments are the resource types to scan
// Validate that the command is supported (currently only "scan" is implemented)
if command != "scan" {
fmt.Println("Error: supported command is 'scan'")
return
}
// Validate that the namespace is not empty
if namespace == "" {
fmt.Println("Error: namespace is empty")
return
}
// Resource type mapping - maps resource type names to factory functions that create appropriate scanners
// This design pattern allows easy addition of new resource types by just adding entries to this map
scannerMap := map[string]func(string) scanner.Scanner{
"pods": func(ns string) scanner.Scanner {
return scanner.PodScanner{Namespace: ns}
},
"deployments": func(ns string) scanner.Scanner {
return scanner.DeploymentScanner{Namespace: ns}
},
}
// Create a WaitGroup to coordinate concurrent scanning operations
var wg sync.WaitGroup
// Extract valid resource types from the scanner map for error suggestion purposes
validTypes := make([]string, 0, len(scannerMap))
for k := range scannerMap {
validTypes = append(validTypes, k)
}
// Process each requested resource type
for _, resource := range resources {
// Check if the requested resource type is supported
factory, ok := scannerMap[resource]
if !ok {
// Resource type not found - try to suggest a similar one
closest := suggestClosest(resource, validTypes)
if closest != "" {
fmt.Printf("Unknown resource type: %s\nDid you mean: %s ?\n", resource, closest)
} else {
fmt.Printf("Unknown resource type: %s\n", resource)
}
continue // Skip this resource and move to the next one
}
// Create scanner instance for this resource type
s := factory(namespace)
// Launch concurrent scan operation for this resource
wg.Add(1) // Increment wait group counter before starting goroutine
go func(r string, sc scanner.Scanner) {
defer wg.Done() // Ensure wait group is decremented when goroutine completes
// Execute the scan with user-friendly status messages
fmt.Printf("🔍 Scanning %s in namespace '%s'...\n", r, namespace)
if err := sc.Scan(); err != nil {
fmt.Printf("❌ Error scanning %s: %v\n", r, err)
}
}(resource, s) // Pass current values to avoid closure issues
}
// Wait for all concurrent scan operations to complete
fmt.Println("⏳ Waiting for scans to complete...")
wg.Wait()
fmt.Println("✅ All scans completed.")
}