1
1
package main
2
2
3
3
import (
4
+ "context"
4
5
"flag"
5
6
"fmt"
6
7
"os"
@@ -10,6 +11,8 @@ import (
10
11
"github.com/rogosprojects/kbak/pkg/backup"
11
12
"github.com/rogosprojects/kbak/pkg/client"
12
13
"github.com/rogosprojects/kbak/pkg/utils"
14
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15
+ "k8s.io/client-go/tools/clientcmd"
13
16
"k8s.io/client-go/util/homedir"
14
17
)
15
18
@@ -48,7 +51,7 @@ func main() {
48
51
var resFlags resourceFlags
49
52
50
53
// Basic flags
51
- flag .StringVar (& namespace , "namespace" , "" , "Namespace to backup (required unless --all-namespaces is used )" )
54
+ flag .StringVar (& namespace , "namespace" , "" , "Namespace to backup (uses current namespace from kubeconfig if not specified )" )
52
55
flag .StringVar (& outputDir , "output" , "backups" , "Output directory for backup files" )
53
56
flag .BoolVar (& verbose , "verbose" , false , "Show verbose output" )
54
57
flag .BoolVar (& showVersion , "version" , false , "Show version information and exit" )
@@ -80,19 +83,11 @@ func main() {
80
83
flag .Parse ()
81
84
82
85
if showVersion {
83
- fmt .Printf ("%s %skbak%s version %s %s%s\n " ,
86
+ fmt .Printf ("%s %skbak%s version %s%s%s\n " ,
84
87
utils .K8sEmoji , utils .Bold , utils .Reset , utils .Cyan , Version , utils .Reset )
85
88
os .Exit (0 )
86
89
}
87
90
88
- // Validate namespace requirements
89
- if namespace == "" && ! allNamespaces {
90
- fmt .Printf ("%s %s%sError: either --namespace or --all-namespaces flag is required%s\n " ,
91
- utils .ErrorEmoji , utils .Red , utils .Bold , utils .Reset )
92
- flag .Usage ()
93
- os .Exit (1 )
94
- }
95
-
96
91
if allNamespaces && namespace != "" {
97
92
fmt .Printf ("%s %s%sWarning: --namespace flag is ignored when --all-namespaces is used%s\n " ,
98
93
utils .WarningEmoji , utils .Yellow , utils .Bold , utils .Reset )
@@ -107,13 +102,92 @@ func main() {
107
102
os .Exit (1 )
108
103
}
109
104
110
- // Handle all-namespaces case (not implemented yet, just a placeholder)
105
+ // If namespace is not specified and not using all-namespaces, get the current namespace from kubeconfig
106
+ if namespace == "" && ! allNamespaces {
107
+ loadingRules := clientcmd .NewDefaultClientConfigLoadingRules ()
108
+ loadingRules .ExplicitPath = kubeconfig
109
+ configOverrides := & clientcmd.ConfigOverrides {}
110
+ kubeConfig := clientcmd .NewNonInteractiveDeferredLoadingClientConfig (loadingRules , configOverrides )
111
+ currentNamespace , _ , err := kubeConfig .Namespace ()
112
+ if err != nil {
113
+ fmt .Printf ("%s %s%sError getting current namespace: %v%s\n " ,
114
+ utils .ErrorEmoji , utils .Red , utils .Bold , err , utils .Reset )
115
+ os .Exit (1 )
116
+ }
117
+ namespace = currentNamespace
118
+ if verbose {
119
+ fmt .Printf (" %sUsing current namespace: %s%s\n " ,
120
+ utils .Cyan , namespace , utils .Reset )
121
+ }
122
+ }
123
+
124
+ // Handle all-namespaces case
111
125
if allNamespaces {
112
- fmt .Printf ("%s %s%sError: --all-namespaces is not implemented yet%s\n " ,
113
- utils .ErrorEmoji , utils .Red , utils .Bold , utils .Reset )
114
- os .Exit (1 )
115
- // Here we would get a list of all namespaces and iterate through them
116
- // This feature is left for future implementation
126
+ // Get all namespaces
127
+ namespaces , err := k8sClient .Clientset .CoreV1 ().Namespaces ().List (context .TODO (), metav1.ListOptions {})
128
+ if err != nil {
129
+ fmt .Printf ("%s %s%sError listing namespaces: %v%s\n " ,
130
+ utils .ErrorEmoji , utils .Red , utils .Bold , err , utils .Reset )
131
+ os .Exit (1 )
132
+ }
133
+
134
+ // Create parent backup directory
135
+ timestamp := time .Now ().Format ("02Jan2006-15:04" )
136
+ parentBackupDir := filepath .Join (outputDir , timestamp , "all-namespaces" )
137
+
138
+ if err := os .MkdirAll (parentBackupDir , 0755 ); err != nil {
139
+ fmt .Printf ("%s %s%sError creating output directory: %v%s\n " ,
140
+ utils .ErrorEmoji , utils .Red , utils .Bold , err , utils .Reset )
141
+ os .Exit (1 )
142
+ }
143
+
144
+ fmt .Printf ("%s %s%sStarting backup of all namespaces to '%s'%s\n \n " ,
145
+ utils .StartEmoji , utils .Blue , utils .Bold , parentBackupDir , utils .Reset )
146
+
147
+ totalResourceCount := 0
148
+ totalErrorCount := 0
149
+
150
+ // Process each namespace
151
+ for _ , ns := range namespaces .Items {
152
+ nsName := ns .Name
153
+ nsBackupDir := filepath .Join (parentBackupDir , nsName )
154
+
155
+ if err := os .MkdirAll (nsBackupDir , 0755 ); err != nil {
156
+ fmt .Printf ("%s %s%sError creating directory for namespace %s: %v%s\n " ,
157
+ utils .ErrorEmoji , utils .Red , utils .Bold , nsName , err , utils .Reset )
158
+ totalErrorCount ++
159
+ continue
160
+ }
161
+
162
+ // Prepare resource type filter
163
+ selectedTypes := buildResourceTypeMap (resFlags )
164
+
165
+ fmt .Printf ("%sProcessing namespace: %s%s\n " ,
166
+ utils .Blue , nsName , utils .Reset )
167
+
168
+ // Perform backup for this namespace
169
+ resourceCount , errorCount := backup .PerformBackup (k8sClient , nsName , nsBackupDir , selectedTypes , verbose )
170
+
171
+ totalResourceCount += resourceCount
172
+ totalErrorCount += errorCount
173
+ }
174
+
175
+ if totalResourceCount > 0 {
176
+ fmt .Printf ("\n %s %s%sBackup completed successfully to %s (%d resources total across all namespaces)%s\n " ,
177
+ utils .SuccessEmoji , utils .Green , utils .Bold , parentBackupDir , totalResourceCount , utils .Reset )
178
+ } else {
179
+ fmt .Printf ("\n %s %s%sNo resources found to backup in any namespace%s\n " ,
180
+ utils .WarningEmoji , utils .Yellow , utils .Bold , utils .Reset )
181
+ }
182
+
183
+ // Exit with error code if there were errors
184
+ if totalErrorCount > 0 {
185
+ fmt .Printf ("%s %s%sCompleted with %d errors%s\n " ,
186
+ utils .ErrorEmoji , utils .Red , utils .Bold , totalErrorCount , utils .Reset )
187
+ os .Exit (1 )
188
+ }
189
+
190
+ os .Exit (0 )
117
191
}
118
192
119
193
// Create output directory with timestamp
@@ -145,7 +219,7 @@ func main() {
145
219
utils .SuccessEmoji , utils .Green , utils .Bold , backupDir , resourceCount , utils .Reset )
146
220
} else {
147
221
fmt .Printf ("\n %s %s%sNo resources found to backup in namespace '%s'%s\n " ,
148
- utils .InfoEmoji , utils .Yellow , utils .Bold , namespace , utils .Reset )
222
+ utils .WarningEmoji , utils .Yellow , utils .Bold , namespace , utils .Reset )
149
223
}
150
224
151
225
// Exit with error code if there were errors
0 commit comments