-
Notifications
You must be signed in to change notification settings - Fork 423
/
config.go
2317 lines (1741 loc) · 93.7 KB
/
config.go
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package config
import (
_ "embed"
"errors"
"fmt"
"reflect"
"regexp"
"strings"
"github.com/invopop/jsonschema"
"sigs.k8s.io/yaml"
)
//go:embed values.yaml
var Values string
var ErrInvalidConfig = errors.New("invalid config")
// NewDefaultConfig creates a new config based on the values.yaml, including all default values.
func NewDefaultConfig() (*Config, error) {
retConfig := &Config{}
err := yaml.Unmarshal([]byte(Values), retConfig)
if err != nil {
return nil, err
}
return retConfig, nil
}
// Config is the vCluster config. This struct describes valid Helm values for vCluster as well as configuration used by the vCluster binary itself.
type Config struct {
// Global values shared across all (sub)charts
Global interface{} `json:"global,omitempty"`
// ExportKubeConfig describes how vCluster should export the vCluster kubeConfig file.
ExportKubeConfig ExportKubeConfig `json:"exportKubeConfig,omitempty"`
// Sync describes how to sync resources from the virtual cluster to host cluster and back.
Sync Sync `json:"sync,omitempty"`
// Integrations holds config for vCluster integrations with other operators or tools running on the host cluster
Integrations Integrations `json:"integrations,omitempty"`
// Networking options related to the virtual cluster.
Networking Networking `json:"networking,omitempty"`
// Policies to enforce for the virtual cluster deployment as well as within the virtual cluster.
Policies Policies `json:"policies,omitempty"`
// Configure vCluster's control plane components and deployment.
ControlPlane ControlPlane `json:"controlPlane,omitempty"`
// RBAC options for the virtual cluster.
RBAC RBAC `json:"rbac,omitempty"`
// Define which vCluster plugins to load.
Plugins map[string]Plugins `json:"plugins,omitempty"`
// Experimental features for vCluster. Configuration here might change, so be careful with this.
Experimental Experimental `json:"experimental,omitempty"`
// External holds configuration for tools that are external to the vCluster.
External map[string]ExternalConfig `json:"external,omitempty"`
// Configuration related to telemetry gathered about vCluster usage.
Telemetry Telemetry `json:"telemetry,omitempty"`
// ServiceCIDR holds the service cidr for the virtual cluster. Do not use this option anymore.
ServiceCIDR string `json:"serviceCIDR,omitempty"`
// Specifies whether to use vCluster Pro. This is automatically inferred in newer versions. Do not use that option anymore.
Pro bool `json:"pro,omitempty"`
// Plugin specifies which vCluster plugins to enable. Use "plugins" instead. Do not use this option anymore.
Plugin map[string]Plugin `json:"plugin,omitempty"`
}
// Integrations holds config for vCluster integrations with other operators or tools running on the host cluster
type Integrations struct {
// MetricsServer reuses the metrics server from the host cluster within the vCluster.
MetricsServer MetricsServer `json:"metricsServer,omitempty"`
// KubeVirt reuses a host kubevirt and makes certain CRDs from it available inside the vCluster
KubeVirt KubeVirt `json:"kubeVirt,omitempty"`
// ExternalSecrets reuses a host external secret operator and makes certain CRDs from it available inside the vCluster
ExternalSecrets ExternalSecrets `json:"externalSecrets,omitempty"`
}
// ExternalSecrets reuses a host external secret operator and makes certain CRDs from it available inside the vCluster
type ExternalSecrets struct {
// Enabled defines whether the external secret integration is enabled or not
Enabled bool `json:"enabled,omitempty"`
// Webhook defines whether the host webhooks are reused or not
Webhook EnableSwitch `json:"webhook,omitempty"`
// Sync defines the syncing behavior for the integration
Sync ExternalSecretsSync `json:"sync,omitempty"`
}
type ExternalSecretsSync struct {
// ExternalSecrets defines whether to sync external secrets or not
ExternalSecrets EnableSwitch `json:"externalSecrets,omitempty"`
// Stores defines whether to sync stores or not
Stores EnableSwitch `json:"stores,omitempty"`
// ClusterStores defines whether to sync cluster stores or not
ClusterStores ClusterStoresSyncConfig `json:"clusterStores,omitempty"`
}
type ClusterStoresSyncConfig struct {
EnableSwitch
// Selector defines what cluster stores should be synced
Selector LabelSelector `json:"selector,omitempty"`
}
type LabelSelector struct {
// Labels defines what labels should be looked for
Labels map[string]string `json:"labels,omitempty"`
}
// KubeVirt reuses a host kubevirt and makes certain CRDs from it available inside the vCluster
type KubeVirt struct {
// Enabled signals if the integration should be enabled
Enabled bool `json:"enabled,omitempty"`
// APIService holds information about where to find the virt-api service. Defaults to virt-api/kubevirt.
APIService APIService `json:"apiService,omitempty"`
// Webhook holds configuration for enabling the webhook within the vCluster
Webhook EnableSwitch `json:"webhook,omitempty"`
// Sync holds configuration on what resources to sync
Sync KubeVirtSync `json:"sync,omitempty"`
}
// KubeVirtSync are the crds that are supported by this integration
type KubeVirtSync struct {
// If DataVolumes should get synced
DataVolumes EnableSwitch `json:"dataVolumes,omitempty"`
// If VirtualMachineInstanceMigrations should get synced
VirtualMachineInstanceMigrations EnableSwitch `json:"virtualMachineInstanceMigrations,omitempty"`
// If VirtualMachineInstances should get synced
VirtualMachineInstances EnableSwitch `json:"virtualMachineInstances,omitempty"`
// If VirtualMachines should get synced
VirtualMachines EnableSwitch `json:"virtualMachines,omitempty"`
// If VirtualMachineClones should get synced
VirtualMachineClones EnableSwitch `json:"virtualMachineClones,omitempty"`
// If VirtualMachinePools should get synced
VirtualMachinePools EnableSwitch `json:"virtualMachinePools,omitempty"`
}
// MetricsServer reuses the metrics server from the host cluster within the vCluster.
type MetricsServer struct {
// Enabled signals the metrics server integration should be enabled.
Enabled bool `json:"enabled,omitempty"`
// APIService holds information about where to find the metrics-server service. Defaults to metrics-server/kube-system.
APIService APIService `json:"apiService,omitempty"`
// Nodes defines if metrics-server nodes api should get proxied from host to virtual cluster.
Nodes bool `json:"nodes,omitempty"`
// Pods defines if metrics-server pods api should get proxied from host to virtual cluster.
Pods bool `json:"pods,omitempty"`
}
// APIService holds configuration related to the api server
type APIService struct {
// Service is a reference to the service for the API server.
Service APIServiceService `json:"service,omitempty"`
}
// APIServiceService holds the service name and namespace of the host apiservice.
type APIServiceService struct {
// Name is the name of the host service of the apiservice.
Name string `json:"name,omitempty"`
// Namespace is the name of the host service of the apiservice.
Namespace string `json:"namespace,omitempty"`
// Port is the target port on the host service to connect to.
Port int `json:"port,omitempty"`
}
// ExternalConfig holds external tool configuration
type ExternalConfig map[string]interface{}
func (c *Config) UnmarshalYAMLStrict(data []byte) error {
return UnmarshalYAMLStrict(data, c)
}
func (c *Config) GetPlatformConfig() (*PlatformConfig, error) {
if c.External == nil {
return &PlatformConfig{}, nil
}
if c.External["platform"] == nil {
return &PlatformConfig{}, nil
}
yamlBytes, err := yaml.Marshal(c.External["platform"])
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrInvalidConfig, err)
}
retConfig := &PlatformConfig{}
if err := yaml.Unmarshal(yamlBytes, retConfig); err != nil {
return nil, fmt.Errorf("%w: %w", ErrInvalidConfig, err)
}
return retConfig, nil
}
func (c *Config) SetPlatformConfig(platformConfig *PlatformConfig) error {
yamlBytes, err := yaml.Marshal(platformConfig)
if err != nil {
return fmt.Errorf("%w: %w", ErrInvalidConfig, err)
}
setConfig := ExternalConfig{}
if err := yaml.Unmarshal(yamlBytes, &setConfig); err != nil {
return fmt.Errorf("%w: %w", ErrInvalidConfig, err)
}
if c.External == nil {
c.External = map[string]ExternalConfig{}
}
c.External["platform"] = setConfig
return nil
}
// BackingStoreType returns the backing store type of the vCluster.
// If no backing store is enabled, it returns StoreTypeUnknown.
func (c *Config) BackingStoreType() StoreType {
switch {
case c.ControlPlane.BackingStore.Etcd.Embedded.Enabled:
return StoreTypeEmbeddedEtcd
case c.ControlPlane.BackingStore.Etcd.Deploy.Enabled:
return StoreTypeExternalEtcd
case c.ControlPlane.BackingStore.Database.Embedded.Enabled:
return StoreTypeEmbeddedDatabase
case c.ControlPlane.BackingStore.Database.External.Enabled:
return StoreTypeExternalDatabase
default:
return StoreTypeEmbeddedDatabase
}
}
func (c *Config) EmbeddedDatabase() bool {
return !c.ControlPlane.BackingStore.Database.External.Enabled && !c.ControlPlane.BackingStore.Etcd.Embedded.Enabled && !c.ControlPlane.BackingStore.Etcd.Deploy.Enabled
}
func (c *Config) Distro() string {
if c.ControlPlane.Distro.K3S.Enabled {
return K3SDistro
} else if c.ControlPlane.Distro.K0S.Enabled {
return K0SDistro
} else if c.ControlPlane.Distro.K8S.Enabled {
return K8SDistro
}
return K8SDistro
}
func (c *Config) IsConfiguredForSleepMode() bool {
if c != nil && c.External != nil && c.External["platform"] == nil {
return false
}
return c.External["platform"]["autoSleep"] != nil || c.External["platform"]["autoDelete"] != nil
}
// ValidateChanges checks for disallowed config changes.
// Currently only certain backingstore changes are allowed but no distro change.
func ValidateChanges(oldCfg, newCfg *Config) error {
oldDistro, newDistro := oldCfg.Distro(), newCfg.Distro()
oldBackingStore, newBackingStore := oldCfg.BackingStoreType(), newCfg.BackingStoreType()
return ValidateStoreAndDistroChanges(newBackingStore, oldBackingStore, newDistro, oldDistro)
}
// ValidateStoreAndDistroChanges checks whether migrating from one store to the other is allowed.
func ValidateStoreAndDistroChanges(currentStoreType, previousStoreType StoreType, currentDistro, previousDistro string) error {
if currentDistro != previousDistro && !(previousDistro == "eks" && currentDistro == K8SDistro) {
return fmt.Errorf("seems like you were using %s as a distro before and now have switched to %s, please make sure to not switch between vCluster distros", previousDistro, currentDistro)
}
if currentStoreType != previousStoreType {
if currentStoreType != StoreTypeEmbeddedEtcd {
return fmt.Errorf("seems like you were using %s as a store before and now have switched to %s, please make sure to not switch between vCluster stores", previousStoreType, currentStoreType)
}
if previousStoreType != StoreTypeExternalEtcd && previousStoreType != StoreTypeEmbeddedDatabase {
return fmt.Errorf("seems like you were using %s as a store before and now have switched to %s, please make sure to not switch between vCluster stores", previousStoreType, currentStoreType)
}
}
return nil
}
func (c *Config) IsProFeatureEnabled() bool {
if len(c.Networking.ResolveDNS) > 0 {
return true
}
if c.ControlPlane.CoreDNS.Embedded {
return true
}
if c.Distro() == K8SDistro {
if c.ControlPlane.BackingStore.Database.External.Enabled {
return true
}
}
if c.ControlPlane.BackingStore.Etcd.Embedded.Enabled {
return true
}
if len(c.Policies.CentralAdmission.ValidatingWebhooks) > 0 || len(c.Policies.CentralAdmission.MutatingWebhooks) > 0 {
return true
}
if c.ControlPlane.HostPathMapper.Central {
return true
}
if c.Experimental.SyncSettings.DisableSync {
return true
}
if c.Experimental.SyncSettings.RewriteKubernetesService {
return true
}
if c.Experimental.IsolatedControlPlane.Enabled {
return true
}
if len(c.Experimental.DenyProxyRequests) > 0 {
return true
}
if len(c.External["platform"]) > 0 {
return true
}
if len(c.Sync.ToHost.CustomResources) > 0 || len(c.Sync.FromHost.CustomResources) > 0 {
return true
}
return false
}
func UnmarshalYAMLStrict(data []byte, i any) error {
if err := yaml.UnmarshalStrict(data, i); err != nil {
return fmt.Errorf("%w: %w", ErrInvalidConfig, err)
}
return nil
}
// ExportKubeConfig describes how vCluster should export the vCluster kubeconfig.
type ExportKubeConfig struct {
// Context is the name of the context within the generated kubeconfig to use.
Context string `json:"context,omitempty"`
// Override the default https://localhost:8443 and specify a custom hostname for the generated kubeconfig.
Server string `json:"server,omitempty"`
// If tls should get skipped for the server
Insecure bool `json:"insecure,omitempty"`
// ServiceAccount can be used to generate a service account token instead of the default certificates.
ServiceAccount ExportKubeConfigServiceAccount `json:"serviceAccount,omitempty"`
// Declare in which host cluster secret vCluster should store the generated virtual cluster kubeconfig.
// If this is not defined, vCluster will create it with `vc-NAME`. If you specify another name,
// vCluster creates the config in this other secret.
Secret ExportKubeConfigSecretReference `json:"secret,omitempty"`
}
type ExportKubeConfigServiceAccount struct {
// Name of the service account to be used to generate a service account token instead of the default certificates.
Name string `json:"name,omitempty"`
// Namespace of the service account to be used to generate a service account token instead of the default certificates.
// If omitted, will use the kube-system namespace.
Namespace string `json:"namespace,omitempty"`
// ClusterRole to assign to the service account.
ClusterRole string `json:"clusterRole,omitempty"`
}
// Declare in which host cluster secret vCluster should store the generated virtual cluster kubeconfig.
// If this is not defined, vCluster create it with `vc-NAME`. If you specify another name,
// vCluster creates the config in this other secret.
type ExportKubeConfigSecretReference struct {
// Name is the name of the secret where the kubeconfig should get stored.
Name string `json:"name,omitempty"`
// Namespace where vCluster should store the kubeconfig secret. If this is not equal to the namespace
// where you deployed vCluster, you need to make sure vCluster has access to this other namespace.
Namespace string `json:"namespace,omitempty"`
}
type Sync struct {
// Configure resources to sync from the virtual cluster to the host cluster.
ToHost SyncToHost `json:"toHost,omitempty"`
// Configure what resources vCluster should sync from the host cluster to the virtual cluster.
FromHost SyncFromHost `json:"fromHost,omitempty"`
}
type SyncToHost struct {
// Pods defines if pods created within the virtual cluster should get synced to the host cluster.
Pods SyncPods `json:"pods,omitempty"`
// Secrets defines if secrets created within the virtual cluster should get synced to the host cluster.
Secrets SyncAllResource `json:"secrets,omitempty"`
// ConfigMaps defines if config maps created within the virtual cluster should get synced to the host cluster.
ConfigMaps SyncAllResource `json:"configMaps,omitempty"`
// Ingresses defines if ingresses created within the virtual cluster should get synced to the host cluster.
Ingresses EnableSwitchWithPatches `json:"ingresses,omitempty"`
// Services defines if services created within the virtual cluster should get synced to the host cluster.
Services EnableSwitchWithPatches `json:"services,omitempty"`
// Endpoints defines if endpoints created within the virtual cluster should get synced to the host cluster.
Endpoints EnableSwitchWithPatches `json:"endpoints,omitempty"`
// NetworkPolicies defines if network policies created within the virtual cluster should get synced to the host cluster.
NetworkPolicies EnableSwitchWithPatches `json:"networkPolicies,omitempty"`
// PersistentVolumeClaims defines if persistent volume claims created within the virtual cluster should get synced to the host cluster.
PersistentVolumeClaims EnableSwitchWithPatches `json:"persistentVolumeClaims,omitempty"`
// PersistentVolumes defines if persistent volumes created within the virtual cluster should get synced to the host cluster.
PersistentVolumes EnableSwitchWithPatches `json:"persistentVolumes,omitempty"`
// VolumeSnapshots defines if volume snapshots created within the virtual cluster should get synced to the host cluster.
VolumeSnapshots EnableSwitchWithPatches `json:"volumeSnapshots,omitempty"`
// VolumeSnapshotContents defines if volume snapshot contents created within the virtual cluster should get synced to the host cluster.
VolumeSnapshotContents EnableSwitchWithPatches `json:"volumeSnapshotContents,omitempty"`
// StorageClasses defines if storage classes created within the virtual cluster should get synced to the host cluster.
StorageClasses EnableSwitchWithPatches `json:"storageClasses,omitempty"`
// ServiceAccounts defines if service accounts created within the virtual cluster should get synced to the host cluster.
ServiceAccounts EnableSwitchWithPatches `json:"serviceAccounts,omitempty"`
// PodDisruptionBudgets defines if pod disruption budgets created within the virtual cluster should get synced to the host cluster.
PodDisruptionBudgets EnableSwitchWithPatches `json:"podDisruptionBudgets,omitempty"`
// PriorityClasses defines if priority classes created within the virtual cluster should get synced to the host cluster.
PriorityClasses EnableSwitchWithPatches `json:"priorityClasses,omitempty"`
// CustomResources defines what custom resources should get synced from the virtual cluster to the host cluster. vCluster will copy the definition automatically from host cluster to virtual cluster on startup.
// vCluster will also automatically add any required RBAC permissions to the vCluster role for this to work.
CustomResources map[string]SyncToHostCustomResource `json:"customResources,omitempty"`
}
type EnableSwitchWithPatches struct {
// Enabled defines if this option should be enabled.
Enabled bool `json:"enabled,omitempty"`
// Patches patch the resource according to the provided specification.
Patches []TranslatePatch `json:"patches,omitempty"`
}
type SyncFromHost struct {
// Nodes defines if nodes should get synced from the host cluster to the virtual cluster, but not back.
Nodes SyncNodes `json:"nodes,omitempty"`
// Events defines if events should get synced from the host cluster to the virtual cluster, but not back.
Events EnableSwitchWithPatches `json:"events,omitempty"`
// IngressClasses defines if ingress classes should get synced from the host cluster to the virtual cluster, but not back.
IngressClasses EnableSwitchWithPatches `json:"ingressClasses,omitempty"`
// RuntimeClasses defines if runtime classes should get synced from the host cluster to the virtual cluster, but not back.
RuntimeClasses EnableSwitchWithPatches `json:"runtimeClasses,omitempty"`
// PriorityClasses defines if priority classes classes should get synced from the host cluster to the virtual cluster, but not back.
PriorityClasses EnableSwitchWithPatches `json:"priorityClasses,omitempty"`
// StorageClasses defines if storage classes should get synced from the host cluster to the virtual cluster, but not back. If auto, is automatically enabled when the virtual scheduler is enabled.
StorageClasses EnableAutoSwitchWithPatches `json:"storageClasses,omitempty"`
// CSINodes defines if csi nodes should get synced from the host cluster to the virtual cluster, but not back. If auto, is automatically enabled when the virtual scheduler is enabled.
CSINodes EnableAutoSwitchWithPatches `json:"csiNodes,omitempty"`
// CSIDrivers defines if csi drivers should get synced from the host cluster to the virtual cluster, but not back. If auto, is automatically enabled when the virtual scheduler is enabled.
CSIDrivers EnableAutoSwitchWithPatches `json:"csiDrivers,omitempty"`
// CSIStorageCapacities defines if csi storage capacities should get synced from the host cluster to the virtual cluster, but not back. If auto, is automatically enabled when the virtual scheduler is enabled.
CSIStorageCapacities EnableAutoSwitchWithPatches `json:"csiStorageCapacities,omitempty"`
// CustomResources defines what custom resources should get synced read-only to the virtual cluster from the host cluster. vCluster will automatically add any required RBAC to the vCluster cluster role.
CustomResources map[string]SyncFromHostCustomResource `json:"customResources,omitempty"`
// VolumeSnapshotClasses defines if volume snapshot classes created within the virtual cluster should get synced to the host cluster.
VolumeSnapshotClasses EnableSwitchWithPatches `json:"volumeSnapshotClasses,omitempty"`
}
type SyncToHostCustomResource struct {
// Enabled defines if this option should be enabled.
Enabled bool `json:"enabled,omitempty" jsonschema:"required"`
// Scope defines the scope of the resource. If undefined, will use Namespaced. Currently only Namespaced is supported.
Scope Scope `json:"scope,omitempty"`
// Patches patch the resource according to the provided specification.
Patches []TranslatePatch `json:"patches,omitempty"`
}
type Scope string
const (
ScopeNamespaced Scope = "Namespaced"
ScopeCluster Scope = "Cluster"
)
type TranslatePatch struct {
// Path is the path within the patch to target. If the path is not found within the patch, the patch is not applied.
Path string `json:"path,omitempty" jsonschema:"required"`
// Expression transforms the value according to the given JavaScript expression.
Expression string `json:"expression,omitempty"`
// ReverseExpression transforms the value according to the given JavaScript expression.
ReverseExpression string `json:"reverseExpression,omitempty"`
// Reference treats the path value as a reference to another object and will rewrite it based on the chosen mode
// automatically. In single-namespace mode this will translate the name to "vxxxxxxxxx" to avoid conflicts with
// other names, in multi-namespace mode this will not translate the name.
Reference *TranslatePatchReference `json:"reference,omitempty"`
// Labels treats the path value as a labels selector.
Labels *TranslatePatchLabels `json:"labels,omitempty"`
}
type TranslatePatchLabels struct{}
type TranslatePatchReference struct {
// APIVersion is the apiVersion of the referenced object.
APIVersion string `json:"apiVersion,omitempty" jsonschema:"required"`
// APIVersionPath is optional relative path to use to determine the kind. If APIVersionPath is not found, will fallback to apiVersion.
APIVersionPath string `json:"apiVersionPath,omitempty"`
// Kind is the kind of the referenced object.
Kind string `json:"kind,omitempty" jsonschema:"required"`
// KindPath is the optional relative path to use to determine the kind. If KindPath is not found, will fallback to kind.
KindPath string `json:"kindPath,omitempty"`
// NamePath is the optional relative path to the reference name within the object.
NamePath string `json:"namePath,omitempty"`
// NamespacePath is the optional relative path to the reference namespace within the object. If omitted or not found, namespacePath equals to the
// metadata.namespace path of the object.
NamespacePath string `json:"namespacePath,omitempty"`
}
type SyncFromHostCustomResource struct {
// Enabled defines if this option should be enabled.
Enabled bool `json:"enabled,omitempty" jsonschema:"required"`
// Scope defines the scope of the resource
Scope Scope `json:"scope,omitempty" jsonschema:"required"`
// Patches patch the resource according to the provided specification.
Patches []TranslatePatch `json:"patches,omitempty"`
}
type EnableAutoSwitch struct {
// Enabled defines if this option should be enabled.
Enabled StrBool `json:"enabled,omitempty" jsonschema:"oneof_type=string;boolean"`
}
type EnableAutoSwitchWithPatches struct {
// Enabled defines if this option should be enabled.
Enabled StrBool `json:"enabled,omitempty" jsonschema:"oneof_type=string;boolean"`
// Patches patch the resource according to the provided specification.
Patches []TranslatePatch `json:"patches,omitempty"`
}
type EnableSwitch struct {
// Enabled defines if this option should be enabled.
Enabled bool `json:"enabled,omitempty"`
}
type SyncAllResource struct {
// Enabled defines if this option should be enabled.
Enabled bool `json:"enabled,omitempty"`
// All defines if all resources of that type should get synced or only the necessary ones that are needed.
All bool `json:"all,omitempty"`
// Patches patch the resource according to the provided specification.
Patches []TranslatePatch `json:"patches,omitempty"`
}
type SyncPods struct {
// Enabled defines if pod syncing should be enabled.
Enabled bool `json:"enabled,omitempty"`
// TranslateImage maps an image to another image that should be used instead. For example this can be used to rewrite
// a certain image that is used within the virtual cluster to be another image on the host cluster
TranslateImage map[string]string `json:"translateImage,omitempty"`
// EnforceTolerations will add the specified tolerations to all pods synced by the virtual cluster.
EnforceTolerations []string `json:"enforceTolerations,omitempty"`
// UseSecretsForSATokens will use secrets to save the generated service account tokens by virtual cluster instead of using a
// pod annotation.
UseSecretsForSATokens bool `json:"useSecretsForSATokens,omitempty"`
// RewriteHosts is a special option needed to rewrite statefulset containers to allow the correct FQDN. virtual cluster will add
// a small container to each stateful set pod that will initially rewrite the /etc/hosts file to match the FQDN expected by
// the virtual cluster.
RewriteHosts SyncRewriteHosts `json:"rewriteHosts,omitempty"`
// Patches patch the resource according to the provided specification.
Patches []TranslatePatch `json:"patches,omitempty"`
}
type SyncRewriteHosts struct {
// Enabled specifies if rewriting stateful set pods should be enabled.
Enabled bool `json:"enabled,omitempty"`
// InitContainer holds extra options for the init container used by vCluster to rewrite the FQDN for stateful set pods.
InitContainer SyncRewriteHostsInitContainer `json:"initContainer,omitempty"`
}
type SyncRewriteHostsInitContainer struct {
// Image is the image virtual cluster should use to rewrite this FQDN.
Image string `json:"image,omitempty"`
// Resources are the resources that should be assigned to the init container for each stateful set init container.
Resources Resources `json:"resources,omitempty"`
}
type SyncNodes struct {
// Enabled specifies if syncing real nodes should be enabled. If this is disabled, vCluster will create fake nodes instead.
Enabled bool `json:"enabled,omitempty"`
// SyncBackChanges enables syncing labels and taints from the virtual cluster to the host cluster. If this is enabled someone within the virtual cluster will be able to change the labels and taints of the host cluster node.
SyncBackChanges bool `json:"syncBackChanges,omitempty"`
// ClearImageStatus will erase the image status when syncing a node. This allows to hide images that are pulled by the node.
ClearImageStatus bool `json:"clearImageStatus,omitempty"`
// Selector can be used to define more granular what nodes should get synced from the host cluster to the virtual cluster.
Selector SyncNodeSelector `json:"selector,omitempty"`
// Patches patch the resource according to the provided specification.
Patches []TranslatePatch `json:"patches,omitempty"`
}
type SyncNodeSelector struct {
// All specifies if all nodes should get synced by vCluster from the host to the virtual cluster or only the ones where pods are assigned to.
All bool `json:"all,omitempty"`
// Labels are the node labels used to sync nodes from host cluster to virtual cluster. This will also set the node selector when syncing a pod from virtual cluster to host cluster to the same value.
Labels map[string]string `json:"labels,omitempty"`
}
type ServiceMonitor struct {
// Enabled configures if Helm should create the service monitor.
Enabled bool `json:"enabled,omitempty"`
// Labels are the extra labels to add to the service monitor.
Labels map[string]string `json:"labels,omitempty"`
// Annotations are the extra annotations to add to the service monitor.
Annotations map[string]string `json:"annotations,omitempty"`
}
type Networking struct {
// ReplicateServices allows replicating services from the host within the virtual cluster or the other way around.
ReplicateServices ReplicateServices `json:"replicateServices,omitempty"`
// ResolveDNS allows to define extra DNS rules. This only works if embedded coredns is configured.
ResolveDNS []ResolveDNS `json:"resolveDNS,omitempty" product:"pro"`
// Advanced holds advanced network options.
Advanced NetworkingAdvanced `json:"advanced,omitempty"`
}
func (n Networking) JSONSchemaExtend(base *jsonschema.Schema) {
addProToJSONSchema(base, reflect.TypeOf(n))
}
type ReplicateServices struct {
// ToHost defines the services that should get synced from virtual cluster to the host cluster. If services are
// synced to a different namespace than the virtual cluster is in, additional permissions for the other namespace
// are required.
ToHost []ServiceMapping `json:"toHost,omitempty"`
// FromHost defines the services that should get synced from the host to the virtual cluster.
FromHost []ServiceMapping `json:"fromHost,omitempty"`
}
type ServiceMapping struct {
// From is the service that should get synced. Can be either in the form name or namespace/name.
From string `json:"from,omitempty"`
// To is the target service that it should get synced to. Can be either in the form name or namespace/name.
To string `json:"to,omitempty"`
}
type ResolveDNS struct {
// Hostname is the hostname within the vCluster that should be resolved from.
Hostname string `json:"hostname"`
// Service is the virtual cluster service that should be resolved from.
Service string `json:"service"`
// Namespace is the virtual cluster namespace that should be resolved from.
Namespace string `json:"namespace"`
// Target is the DNS target that should get mapped to
Target ResolveDNSTarget `json:"target,omitempty"`
}
type ResolveDNSTarget struct {
// Hostname to use as a DNS target
Hostname string `json:"hostname,omitempty"`
// IP to use as a DNS target
IP string `json:"ip,omitempty"`
// HostService to target, format is hostNamespace/hostService
HostService string `json:"hostService,omitempty"`
// HostNamespace to target
HostNamespace string `json:"hostNamespace,omitempty"`
// VClusterService format is hostNamespace/vClusterName/vClusterNamespace/vClusterService
VClusterService string `json:"vClusterService,omitempty"`
}
type NetworkingAdvanced struct {
// ClusterDomain is the Kubernetes cluster domain to use within the virtual cluster.
ClusterDomain string `json:"clusterDomain,omitempty"`
// FallbackHostCluster allows to fallback dns to the host cluster. This is useful if you want to reach host services without
// any other modification. You will need to provide a namespace for the service, e.g. my-other-service.my-other-namespace
FallbackHostCluster bool `json:"fallbackHostCluster,omitempty"`
// ProxyKubelets allows rewriting certain metrics and stats from the Kubelet to "fake" this for applications such as
// prometheus or other node exporters.
ProxyKubelets NetworkProxyKubelets `json:"proxyKubelets,omitempty"`
}
type NetworkProxyKubelets struct {
// ByHostname will add a special vCluster hostname to the nodes where the node can be reached at. This doesn't work
// for all applications, e.g. Prometheus requires a node IP.
ByHostname bool `json:"byHostname,omitempty"`
// ByIP will create a separate service in the host cluster for every node that will point to virtual cluster and will be used to
// route traffic.
ByIP bool `json:"byIP,omitempty"`
}
type Plugin struct {
Plugins `json:",inline"`
// Version is the plugin version, this is only needed for legacy plugins.
Version string `json:"version,omitempty"`
Env []interface{} `json:"env,omitempty"`
EnvFrom []interface{} `json:"envFrom,omitempty"`
Lifecycle map[string]interface{} `json:"lifecycle,omitempty"`
LivenessProbe map[string]interface{} `json:"livenessProbe,omitempty"`
ReadinessProbe map[string]interface{} `json:"readinessProbe,omitempty"`
StartupProbe map[string]interface{} `json:"startupProbe,omitempty"`
WorkingDir string `json:"workingDir,omitempty"`
Optional bool `json:"optional,omitempty"`
}
type Plugins struct {
// Name is the name of the init-container and NOT the plugin name
Name string `json:"name,omitempty"`
// Image is the container image that should be used for the plugin
Image string `json:"image,omitempty"`
// ImagePullPolicy is the pull policy to use for the container image
ImagePullPolicy string `json:"imagePullPolicy,omitempty"`
// Config is the plugin config to use. This can be arbitrary config used for the plugin.
Config map[string]interface{} `json:"config,omitempty"`
// RBAC holds additional rbac configuration for the plugin
RBAC PluginsRBAC `json:"rbac,omitempty"`
// Command is the command that should be used for the init container
Command []string `json:"command,omitempty"`
// Args are the arguments that should be used for the init container
Args []string `json:"args,omitempty"`
// SecurityContext is the container security context used for the init container
SecurityContext map[string]interface{} `json:"securityContext,omitempty"`
// Resources are the container resources used for the init container
Resources map[string]interface{} `json:"resources,omitempty"`
// VolumeMounts are extra volume mounts for the init container
VolumeMounts []interface{} `json:"volumeMounts,omitempty"`
}
type PluginsRBAC struct {
// Role holds extra virtual cluster role permissions for the plugin
Role PluginsExtraRules `json:"role,omitempty"`
// ClusterRole holds extra virtual cluster cluster role permissions required for the plugin
ClusterRole PluginsExtraRules `json:"clusterRole,omitempty"`
}
type PluginsExtraRules struct {
// ExtraRules are extra rbac permissions roles that will be added to role or cluster role
ExtraRules []RBACPolicyRule `json:"extraRules,omitempty"`
}
type RBACPolicyRule struct {
// Verbs is a list of Verbs that apply to ALL the ResourceKinds contained in this rule. '*' represents all verbs.
Verbs []string `json:"verbs"`
// APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of
// the enumerated resources in any API group will be allowed. "" represents the core API group and "*" represents all API groups.
APIGroups []string `json:"apiGroups,omitempty"`
// Resources is a list of resources this rule applies to. '*' represents all resources.
Resources []string `json:"resources,omitempty"`
// ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
ResourceNames []string `json:"resourceNames,omitempty"`
// NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path
// Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.
// Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both.
NonResourceURLs []string `json:"nonResourceURLs,omitempty"`
}
type ControlPlane struct {
// Distro holds virtual cluster related distro options. A distro cannot be changed after vCluster is deployed.
Distro Distro `json:"distro,omitempty"`
// BackingStore defines which backing store to use for virtual cluster. If not defined will use embedded database as a default backing store.
BackingStore BackingStore `json:"backingStore,omitempty"`
// CoreDNS defines everything related to the coredns that is deployed and used within the vCluster.
CoreDNS CoreDNS `json:"coredns,omitempty"`
// Proxy defines options for the virtual cluster control plane proxy that is used to do authentication and intercept requests.
Proxy ControlPlaneProxy `json:"proxy,omitempty"`
// HostPathMapper defines if vCluster should rewrite host paths.
HostPathMapper HostPathMapper `json:"hostPathMapper,omitempty" product:"pro"`
// Ingress defines options for vCluster ingress deployed by Helm.
Ingress ControlPlaneIngress `json:"ingress,omitempty"`
// Service defines options for vCluster service deployed by Helm.
Service ControlPlaneService `json:"service,omitempty"`
// StatefulSet defines options for vCluster statefulSet deployed by Helm.
StatefulSet ControlPlaneStatefulSet `json:"statefulSet,omitempty"`
// ServiceMonitor can be used to automatically create a service monitor for vCluster deployment itself.
ServiceMonitor ServiceMonitor `json:"serviceMonitor,omitempty"`
// Advanced holds additional configuration for the vCluster control plane.
Advanced ControlPlaneAdvanced `json:"advanced,omitempty"`
}
func (c ControlPlane) JSONSchemaExtend(base *jsonschema.Schema) {
addProToJSONSchema(base, reflect.TypeOf(c))
}
type ControlPlaneStatefulSet struct {
// HighAvailability holds options related to high availability.
HighAvailability ControlPlaneHighAvailability `json:"highAvailability,omitempty"`
// Resources are the resource requests and limits for the statefulSet container.
Resources Resources `json:"resources,omitempty"`
// Scheduling holds options related to scheduling.
Scheduling ControlPlaneScheduling `json:"scheduling,omitempty"`
// Security defines pod or container security context.
Security ControlPlaneSecurity `json:"security,omitempty"`
// Probes enables or disables the main container probes.
Probes ControlPlaneProbes `json:"probes,omitempty"`
// Persistence defines options around persistence for the statefulSet.
Persistence ControlPlanePersistence `json:"persistence,omitempty"`
// EnableServiceLinks for the StatefulSet pod
EnableServiceLinks *bool `json:"enableServiceLinks,omitempty"`
LabelsAndAnnotations `json:",inline"`
// Additional labels or annotations for the statefulSet pods.
Pods LabelsAndAnnotations `json:"pods,omitempty"`
// Image is the image for the controlPlane statefulSet container
Image StatefulSetImage `json:"image,omitempty"`
// ImagePullPolicy is the policy how to pull the image.
ImagePullPolicy string `json:"imagePullPolicy,omitempty"`
// WorkingDir specifies in what folder the main process should get started.
WorkingDir string `json:"workingDir,omitempty"`
// Command allows you to override the main command.
Command []string `json:"command,omitempty"`
// Args allows you to override the main arguments.
Args []string `json:"args,omitempty"`
// Env are additional environment variables for the statefulSet container.
Env []map[string]interface{} `json:"env,omitempty"`
// Set DNS policy for the pod.
DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty"`
// Specifies the DNS parameters of a pod.
DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty"`
}
type Distro struct {
// K8S holds K8s relevant configuration.
K8S DistroK8s `json:"k8s,omitempty"`
// K3S holds K3s relevant configuration.
K3S DistroK3s `json:"k3s,omitempty"`
// K0S holds k0s relevant configuration.
K0S DistroK0s `json:"k0s,omitempty"`
}
type DistroK3s struct {
// Enabled specifies if the K3s distro should be enabled. Only one distro can be enabled at the same time.
Enabled bool `json:"enabled,omitempty"`
// Token is the K3s token to use. If empty, vCluster will choose one.
Token string `json:"token,omitempty"`
DistroCommon `json:",inline"`
DistroContainer `json:",inline"`
}
type DistroK8s struct {
// Enabled specifies if the K8s distro should be enabled. Only one distro can be enabled at the same time.
Enabled bool `json:"enabled,omitempty"`
// Version specifies k8s components (scheduler, kube-controller-manager & apiserver) version.
// It is a shortcut for controlPlane.distro.k8s.apiServer.image.tag,
// controlPlane.distro.k8s.controllerManager.image.tag and
// controlPlane.distro.k8s.scheduler.image.tag
// If e.g. controlPlane.distro.k8s.version is set to v1.30.1 and
// controlPlane.distro.k8s.scheduler.image.tag
//(or controlPlane.distro.k8s.controllerManager.image.tag or controlPlane.distro.k8s.apiServer.image.tag)
// is set to v1.31.0,
// value from controlPlane.distro.k8s.<controlPlane-component>.image.tag will be used
// (where <controlPlane-component is apiServer, controllerManager and scheduler).
Version string `json:"version,omitempty"`
// APIServer holds configuration specific to starting the api server.
APIServer DistroContainerEnabled `json:"apiServer,omitempty"`
// ControllerManager holds configuration specific to starting the controller manager.
ControllerManager DistroContainerEnabled `json:"controllerManager,omitempty"`
// Scheduler holds configuration specific to starting the scheduler. Enable this via controlPlane.advanced.virtualScheduler.enabled
Scheduler DistroContainer `json:"scheduler,omitempty"`
DistroCommon `json:",inline"`
}
type DistroK0s struct {
// Enabled specifies if the k0s distro should be enabled. Only one distro can be enabled at the same time.
Enabled bool `json:"enabled,omitempty"`
// Config allows you to override the k0s config passed to the k0s binary.
Config string `json:"config,omitempty"`
DistroCommon `json:",inline"`
DistroContainer `json:",inline"`
}
type DistroCommon struct {
// Env are extra environment variables to use for the main container and NOT the init container.
Env []map[string]interface{} `json:"env,omitempty"`
// Resources for the distro init container
Resources map[string]interface{} `json:"resources,omitempty"`