@@ -55,6 +55,7 @@ import (
55
55
"github.com/heptio/ark/pkg/client"
56
56
"github.com/heptio/ark/pkg/cloudprovider"
57
57
"github.com/heptio/ark/pkg/cmd"
58
+ "github.com/heptio/ark/pkg/cmd/util/flag"
58
59
"github.com/heptio/ark/pkg/cmd/util/signals"
59
60
"github.com/heptio/ark/pkg/controller"
60
61
arkdiscovery "github.com/heptio/ark/pkg/discovery"
@@ -80,19 +81,21 @@ type serverConfig struct {
80
81
pluginDir , metricsAddress , defaultBackupLocation string
81
82
backupSyncPeriod , podVolumeOperationTimeout time.Duration
82
83
restoreResourcePriorities []string
84
+ defaultVolumeSnapshotLocations map [string ]string
83
85
restoreOnly bool
84
86
}
85
87
86
88
func NewCommand () * cobra.Command {
87
89
var (
88
90
logLevelFlag = logging .LogLevelFlag (logrus .InfoLevel )
89
91
config = serverConfig {
90
- pluginDir : "/plugins" ,
91
- metricsAddress : defaultMetricsAddress ,
92
- defaultBackupLocation : "default" ,
93
- backupSyncPeriod : defaultBackupSyncPeriod ,
94
- podVolumeOperationTimeout : defaultPodVolumeOperationTimeout ,
95
- restoreResourcePriorities : defaultRestorePriorities ,
92
+ pluginDir : "/plugins" ,
93
+ metricsAddress : defaultMetricsAddress ,
94
+ defaultBackupLocation : "default" ,
95
+ defaultVolumeSnapshotLocations : make (map [string ]string ),
96
+ backupSyncPeriod : defaultBackupSyncPeriod ,
97
+ podVolumeOperationTimeout : defaultPodVolumeOperationTimeout ,
98
+ restoreResourcePriorities : defaultRestorePriorities ,
96
99
}
97
100
)
98
101
@@ -144,6 +147,12 @@ func NewCommand() *cobra.Command {
144
147
command .Flags ().StringSliceVar (& config .restoreResourcePriorities , "restore-resource-priorities" , config .restoreResourcePriorities , "desired order of resource restores; any resource not in the list will be restored alphabetically after the prioritized resources" )
145
148
command .Flags ().StringVar (& config .defaultBackupLocation , "default-backup-storage-location" , config .defaultBackupLocation , "name of the default backup storage location" )
146
149
150
+ volumeSnapshotLocations := flag .NewMap ().WithKeyValueDelimiter (":" )
151
+ command .Flags ().Var (& volumeSnapshotLocations , "default-volume-snapshot-locations" , "list of unique volume providers and default volume snapshot location (provider1:location-01, provider2:location-02, ...)" )
152
+ if volumeSnapshotLocations .Data () != nil {
153
+ config .defaultVolumeSnapshotLocations = volumeSnapshotLocations .Data ()
154
+ }
155
+
147
156
return command
148
157
}
149
158
@@ -277,6 +286,11 @@ func (s *server) run() error {
277
286
Warnf ("Default backup storage location %q not found; backups must explicitly specify a location" , s .config .defaultBackupLocation )
278
287
}
279
288
289
+ defaultVolumeSnapshotLocations , err := s .getDefaultVolumeSnapshotLocations ()
290
+ if err != nil {
291
+ return err
292
+ }
293
+
280
294
if config .PersistentVolumeProvider == nil {
281
295
s .logger .Info ("PersistentVolumeProvider config not provided, volume snapshots and restores are disabled" )
282
296
} else {
@@ -292,13 +306,50 @@ func (s *server) run() error {
292
306
return err
293
307
}
294
308
295
- if err := s .runControllers (config ); err != nil {
309
+ if err := s .runControllers (config , defaultVolumeSnapshotLocations ); err != nil {
296
310
return err
297
311
}
298
312
299
313
return nil
300
314
}
301
315
316
+ func (s * server ) getDefaultVolumeSnapshotLocations () (map [string ]* api.VolumeSnapshotLocation , error ) {
317
+ providerDefaults := make (map [string ]* api.VolumeSnapshotLocation )
318
+ if len (s .config .defaultVolumeSnapshotLocations ) == 0 {
319
+ return providerDefaults , nil
320
+ }
321
+
322
+ volumeSnapshotLocations , err := s .arkClient .ArkV1 ().VolumeSnapshotLocations (s .namespace ).List (metav1.ListOptions {})
323
+ if err != nil {
324
+ return providerDefaults , errors .WithStack (err )
325
+ }
326
+
327
+ providerLocations := make (map [string ][]* api.VolumeSnapshotLocation )
328
+ for _ , vsl := range volumeSnapshotLocations .Items {
329
+ providerLocations [vsl .Spec .Provider ] = append (providerLocations [vsl .Spec .Provider ], & vsl )
330
+ }
331
+
332
+ for provider , locations := range providerLocations {
333
+ defaultLocation , ok := s .config .defaultVolumeSnapshotLocations [provider ]
334
+ if ! ok {
335
+ return providerDefaults , errors .Errorf ("missing provider %s. When using default volume snapshot locations, one must exist for every known provider." , provider )
336
+ }
337
+
338
+ for _ , location := range locations {
339
+ if location .ObjectMeta .Name == defaultLocation {
340
+ providerDefaults [provider ] = location
341
+ break
342
+ }
343
+ }
344
+
345
+ if _ , ok := providerDefaults [provider ]; ! ok {
346
+ return providerDefaults , errors .Errorf ("%s is not a valid volume snapshot location for %s" , defaultLocation , provider )
347
+ }
348
+ }
349
+
350
+ return providerDefaults , nil
351
+ }
352
+
302
353
func (s * server ) applyConfigDefaults (c * api.Config ) {
303
354
if s .config .backupSyncPeriod == 0 {
304
355
s .config .backupSyncPeriod = defaultBackupSyncPeriod
@@ -572,7 +623,7 @@ func (s *server) initRestic() error {
572
623
return nil
573
624
}
574
625
575
- func (s * server ) runControllers (config * api.Config ) error {
626
+ func (s * server ) runControllers (config * api.Config , defaultVolumeSnapshotLocations map [ string ] * api. VolumeSnapshotLocation ) error {
576
627
s .logger .Info ("Starting controllers" )
577
628
578
629
ctx := s .ctx
@@ -637,7 +688,7 @@ func (s *server) runControllers(config *api.Config) error {
637
688
s .sharedInformerFactory .Ark ().V1 ().BackupStorageLocations (),
638
689
s .config .defaultBackupLocation ,
639
690
s .sharedInformerFactory .Ark ().V1 ().VolumeSnapshotLocations (),
640
- nil ,
691
+ s . config . defaultVolumeSnapshotLocations ,
641
692
s .metrics ,
642
693
)
643
694
wg .Add (1 )
0 commit comments