Skip to content

Commit 377ea2f

Browse files
committed
chore: sync config/*.go and values.schema.json to vCluster version v0.27.0-beta.1
1 parent 7ef1d69 commit 377ea2f

File tree

7 files changed

+306
-89
lines changed

7 files changed

+306
-89
lines changed

config/config.go

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ type Standalone struct {
173173
// Enabled defines if standalone mode should be enabled.
174174
Enabled bool `json:"enabled,omitempty"`
175175

176+
// SyncConfig allows controlling the vCluster config through a secret "vcluster-config" in the namespace "kube-system". vCluster will watch for changes in this secret and
177+
// update the local config accordingly and restart vCluster if needed.
178+
SyncConfig StandaloneSyncConfig `json:"syncConfig,omitempty"`
179+
176180
// DataDir defines the data directory for the standalone mode.
177181
DataDir string `json:"dataDir,omitempty"`
178182

@@ -186,13 +190,15 @@ type Standalone struct {
186190
JoinNode StandaloneJoinNode `json:"joinNode,omitempty"`
187191
}
188192

193+
type StandaloneSyncConfig struct {
194+
// Enabled defines if config syncing should be enabled.
195+
Enabled bool `json:"enabled,omitempty"`
196+
}
197+
189198
type StandaloneJoinNode struct {
190199
// Enabled defines if the standalone node should be joined into the cluster. If false, only the control plane binaries will be executed and no node will show up in the actual cluster.
191200
Enabled bool `json:"enabled,omitempty"`
192201

193-
// Name defines the name of the standalone node. If empty the node will get the hostname as name.
194-
Name string `json:"name,omitempty"`
195-
196202
JoinConfiguration `json:",inline"`
197203
}
198204

@@ -534,11 +540,17 @@ type ExternalSecrets struct {
534540
}
535541

536542
type ExternalSecretsSync struct {
543+
// ToHost defines what resources are synced from the virtual cluster to the host
544+
ToHost ExternalSecretsSyncToHostConfig `json:"toHost,omitempty"`
545+
// FromHost defines what resources are synced from the host cluster to the virtual cluster
546+
FromHost ExternalSecretsSyncFromHostConfig `json:"fromHost,omitempty"`
537547
// ExternalSecrets defines if external secrets should get synced from the virtual cluster to the host cluster.
538548
ExternalSecrets EnableSwitch `json:"externalSecrets,omitempty"`
539549
// Stores defines if secret stores should get synced from the virtual cluster to the host cluster and then bi-directionally.
550+
// Deprecated: Use Integrations.ExternalSecrets.Sync.ToHost.Stores instead.
540551
Stores EnableSwitch `json:"stores,omitempty"`
541552
// ClusterStores defines if cluster secrets stores should get synced from the host cluster to the virtual cluster.
553+
// Deprecated: Use Integrations.ExternalSecrets.Sync.FromHost.ClusterStores instead.
542554
ClusterStores ClusterStoresSyncConfig `json:"clusterStores,omitempty"`
543555
}
544556

@@ -548,6 +560,27 @@ type ClusterStoresSyncConfig struct {
548560
Selector LabelSelector `json:"selector,omitempty"`
549561
}
550562

563+
type ExternalSecretsSyncToHostConfig struct {
564+
// ExternalSecrets allows to configure if only a subset of ExternalSecrets matching a label selector should get synced from the virtual cluster to the host cluster.
565+
ExternalSecrets SelectorConfig `json:"externalSecrets,omitempty"`
566+
// Stores defines if secret stores should get synced from the virtual cluster to the host cluster and then bi-directionally.
567+
Stores EnableSwitchSelector `json:"stores,omitempty"`
568+
}
569+
570+
type ExternalSecretsSyncFromHostConfig struct {
571+
// ClusterStores defines if cluster secrets stores should get synced from the host cluster to the virtual cluster.
572+
ClusterStores EnableSwitchSelector `json:"clusterStores,omitempty"`
573+
}
574+
575+
type SelectorConfig struct {
576+
Selector StandardLabelSelector `json:"selector,omitempty"`
577+
}
578+
579+
type EnableSwitchSelector struct {
580+
SelectorConfig
581+
EnableSwitch
582+
}
583+
551584
type LabelSelector struct {
552585
// Labels defines what labels should be looked for
553586
Labels map[string]string `json:"labels,omitempty"`
@@ -835,6 +868,10 @@ func (c *Config) IsProFeatureEnabled() bool {
835868
return true
836869
}
837870

871+
if c.PrivateNodes.Enabled {
872+
return true
873+
}
874+
838875
return false
839876
}
840877

@@ -1278,7 +1315,7 @@ type SyncRewriteHosts struct {
12781315

12791316
type SyncRewriteHostsInitContainer struct {
12801317
// Image is the image virtual cluster should use to rewrite this FQDN.
1281-
Image string `json:"image,omitempty"`
1318+
Image Image `json:"image,omitempty"`
12821319

12831320
// Resources are the resources that should be assigned to the init container for each stateful set init container.
12841321
Resources Resources `json:"resources,omitempty"`
@@ -1572,7 +1609,9 @@ type ControlPlaneStatefulSet struct {
15721609
Pods LabelsAndAnnotations `json:"pods,omitempty"`
15731610

15741611
// Image is the image for the controlPlane statefulSet container
1575-
Image StatefulSetImage `json:"image,omitempty"`
1612+
// It defaults to the vCluster pro repository that includes the optional pro modules that are turned off by default.
1613+
// If you still want to use the pure OSS build, set the repository to 'loft-sh/vcluster-oss'.
1614+
Image Image `json:"image,omitempty"`
15761615

15771616
// ImagePullPolicy is the policy how to pull the image.
15781617
ImagePullPolicy string `json:"imagePullPolicy,omitempty"`
@@ -1670,20 +1709,6 @@ type DistroContainerEnabled struct {
16701709
ExtraArgs []string `json:"extraArgs,omitempty"`
16711710
}
16721711

1673-
type StatefulSetImage struct {
1674-
// Configure the registry of the container image, e.g. my-registry.com or ghcr.io
1675-
// It defaults to ghcr.io and can be overriding either by using this field or controlPlane.advanced.defaultImageRegistry
1676-
Registry string `json:"registry,omitempty"`
1677-
1678-
// Configure the repository of the container image, e.g. my-repo/my-image.
1679-
// It defaults to the vCluster pro repository that includes the optional pro modules that are turned off by default.
1680-
// If you still want to use the pure OSS build, use 'loft-sh/vcluster-oss' instead.
1681-
Repository string `json:"repository,omitempty"`
1682-
1683-
// Tag is the tag of the container image, e.g. latest
1684-
Tag string `json:"tag,omitempty"`
1685-
}
1686-
16871712
type Image struct {
16881713
// Registry is the registry of the container image, e.g. my-registry.com or ghcr.io. This setting can be globally
16891714
// overridden via the controlPlane.advanced.defaultImageRegistry option. Empty means docker hub.
@@ -1692,10 +1717,27 @@ type Image struct {
16921717
// Repository is the repository of the container image, e.g. my-repo/my-image
16931718
Repository string `json:"repository,omitempty"`
16941719

1695-
// Tag is the tag of the container image, e.g. latest. If set to the default, it will use the host Kubernetes version.
1720+
// Tag is the tag of the container image, and is the default version.
16961721
Tag string `json:"tag,omitempty"`
16971722
}
16981723

1724+
func (i Image) String() (ref string) {
1725+
if i.Registry != "" {
1726+
ref = i.Registry + "/"
1727+
}
1728+
1729+
if i.Registry != "" && i.Repository != "" && !strings.ContainsRune(i.Repository, '/') {
1730+
ref += "library/"
1731+
}
1732+
ref += i.Repository
1733+
1734+
if i.Tag != "" {
1735+
ref += ":" + i.Tag
1736+
}
1737+
1738+
return ref
1739+
}
1740+
16991741
type ImagePullSecretName struct {
17001742
// Name of the image pull secret to use.
17011743
Name string `json:"name,omitempty"`

config/config_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"testing"
77

88
"gotest.tools/assert"
9+
"gotest.tools/assert/cmp"
910
)
1011

1112
func TestConfig_Diff(t *testing.T) {
@@ -385,3 +386,89 @@ func TestConfig_IsProFeatureEnabled(t *testing.T) {
385386
})
386387
}
387388
}
389+
390+
func TestImage_String(t *testing.T) {
391+
testCases := []struct {
392+
name string
393+
image Image
394+
expected string
395+
}{
396+
{
397+
name: "complete image reference",
398+
image: Image{
399+
Registry: "registry.k8s.io",
400+
Repository: "coredns/coredns",
401+
Tag: "1.11.3",
402+
},
403+
expected: "registry.k8s.io/coredns/coredns:1.11.3",
404+
},
405+
{
406+
name: "may omit registry",
407+
image: Image{
408+
Repository: "coredns/coredns",
409+
Tag: "1.11.3",
410+
},
411+
expected: "coredns/coredns:1.11.3",
412+
},
413+
{
414+
name: "may omit registry and repo",
415+
image: Image{
416+
Repository: "alpine",
417+
Tag: "3.20",
418+
},
419+
expected: "alpine:3.20",
420+
},
421+
{
422+
name: "may omit tag",
423+
image: Image{
424+
Repository: "alpine",
425+
},
426+
expected: "alpine",
427+
},
428+
{
429+
name: "omit repo but not registry is library",
430+
image: Image{
431+
Registry: "ghcr.io",
432+
Repository: "alpine",
433+
Tag: "3.20",
434+
},
435+
expected: "ghcr.io/library/alpine:3.20",
436+
},
437+
{
438+
name: "registry may have port",
439+
image: Image{
440+
Registry: "host.docker.internal:5000",
441+
Repository: "coredns/coredns",
442+
Tag: "1.11.3",
443+
},
444+
expected: "host.docker.internal:5000/coredns/coredns:1.11.3",
445+
},
446+
{
447+
name: "registry with port and omit tag",
448+
image: Image{
449+
Registry: "localhost:5000",
450+
Repository: "coredns/coredns",
451+
},
452+
expected: "localhost:5000/coredns/coredns",
453+
},
454+
{
455+
name: "empty image is nil value",
456+
image: Image{},
457+
expected: "",
458+
},
459+
}
460+
461+
for _, tt := range testCases {
462+
t.Run("String(): "+tt.name, func(t *testing.T) {
463+
if actual := tt.image.String(); actual != tt.expected {
464+
t.Errorf("Expected %s, got %s", tt.expected, actual)
465+
}
466+
})
467+
468+
t.Run("ParseImageRef(): "+tt.name, func(t *testing.T) {
469+
var image Image
470+
ParseImageRef(tt.expected, &image)
471+
assert.Check(t, cmp.DeepEqual(tt.image, image))
472+
})
473+
}
474+
}

config/default_extra_values.go

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,23 @@ const (
2323

2424
// K3SVersionMap holds the supported k3s versions
2525
var K3SVersionMap = map[string]string{
26+
"1.33": "rancher/k3s:v1.33.1-k3s1",
2627
"1.32": "rancher/k3s:v1.32.1-k3s1",
2728
"1.31": "rancher/k3s:v1.31.1-k3s1",
2829
"1.30": "rancher/k3s:v1.30.2-k3s1",
2930
}
3031

3132
// K8SVersionMap holds the supported k8s api servers
3233
var K8SVersionMap = map[string]string{
34+
"1.33": "ghcr.io/loft-sh/kubernetes:v1.33.1",
3335
"1.32": "ghcr.io/loft-sh/kubernetes:v1.32.1",
3436
"1.31": "ghcr.io/loft-sh/kubernetes:v1.31.1",
3537
"1.30": "ghcr.io/loft-sh/kubernetes:v1.30.2",
3638
}
3739

3840
// K8SEtcdVersionMap holds the supported etcd
3941
var K8SEtcdVersionMap = map[string]string{
42+
"1.33": "registry.k8s.io/etcd:3.5.21-0",
4043
"1.32": "registry.k8s.io/etcd:3.5.21-0",
4144
"1.31": "registry.k8s.io/etcd:3.5.15-0",
4245
"1.30": "registry.k8s.io/etcd:3.5.13-0",
@@ -87,26 +90,31 @@ func getExtraValues(options *ExtraValuesOptions) (*Config, error) {
8790
return vConfig, nil
8891
}
8992

90-
func SplitImage(image string) (string, string, string) {
91-
imageSplitted := strings.Split(image, ":")
92-
if len(imageSplitted) == 1 {
93-
return "", "", ""
93+
func ParseImageRef(ref string, image *Image) {
94+
*image = Image{}
95+
96+
splitRepoAndTag := func(s string) {
97+
split := strings.SplitN(s, ":", 2)
98+
switch len(split) {
99+
case 1:
100+
image.Repository = s
101+
case 2:
102+
image.Repository = split[0]
103+
image.Tag = split[1]
104+
}
105+
image.Repository = strings.TrimPrefix(image.Repository, "library/")
94106
}
95107

96-
// check if registry needs to be filled
97-
registryAndRepository := strings.Join(imageSplitted[:len(imageSplitted)-1], ":")
98-
parts := strings.Split(registryAndRepository, "/")
99-
registry := ""
100-
repository := strings.Join(parts, "/")
101-
if len(parts) >= 2 && (strings.ContainsRune(parts[0], '.') || strings.ContainsRune(parts[0], ':')) {
102-
// The first part of the repository is treated as the registry domain
103-
// iff it contains a '.' or ':' character, otherwise it is all repository
104-
// and the domain defaults to Docker Hub.
105-
registry = parts[0]
106-
repository = strings.Join(parts[1:], "/")
108+
parts := strings.SplitN(ref, "/", 2)
109+
switch {
110+
case len(parts) == 1: // <repo>[:<tag>]
111+
splitRepoAndTag(parts[0])
112+
case strings.ContainsAny(parts[0], ".:"): // <registry>/<repo>[:<tag>]
113+
image.Registry = parts[0]
114+
splitRepoAndTag(parts[1])
115+
default: // <repo/repo>[:<tag]
116+
splitRepoAndTag(ref)
107117
}
108-
109-
return registry, repository, imageSplitted[len(imageSplitted)-1]
110118
}
111119

112120
func addCommonReleaseValues(config *Config, options *ExtraValuesOptions) {

config/legacyconfig/migrate.go

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func migrateK8sAndEKS(oldValues string, newConfig *config.Config) error {
6363
if oldConfig.API.ImagePullPolicy != "" {
6464
newConfig.ControlPlane.Distro.K8S.ImagePullPolicy = oldConfig.API.ImagePullPolicy
6565
}
66-
convertImage(oldConfig.API.Image, &newConfig.ControlPlane.Distro.K8S.Image)
66+
config.ParseImageRef(oldConfig.API.Image, &newConfig.ControlPlane.Distro.K8S.Image)
6767
}
6868
convertAPIValues(oldConfig.API, &newConfig.ControlPlane.Distro.K8S.APIServer)
6969
convertControllerValues(oldConfig.Controller, &newConfig.ControlPlane.Distro.K8S.ControllerManager)
@@ -170,7 +170,7 @@ func convertEtcd(oldConfig EtcdValues, newConfig *config.Config) error {
170170
newConfig.ControlPlane.BackingStore.Etcd.Deploy.StatefulSet.ImagePullPolicy = oldConfig.ImagePullPolicy
171171
}
172172
if oldConfig.Image != "" {
173-
convertImage(oldConfig.Image, &newConfig.ControlPlane.BackingStore.Etcd.Deploy.StatefulSet.Image)
173+
config.ParseImageRef(oldConfig.Image, &newConfig.ControlPlane.BackingStore.Etcd.Deploy.StatefulSet.Image)
174174
}
175175
newConfig.ControlPlane.BackingStore.Etcd.Deploy.StatefulSet.ExtraArgs = oldConfig.ExtraArgs
176176
if oldConfig.Resources != nil {
@@ -668,7 +668,9 @@ func convertK8sSyncerConfig(distro string, oldConfig K8sSyncerValues, newConfig
668668
}
669669

670670
func convertSyncerConfig(distro string, oldConfig SyncerValues, newConfig *config.Config) error {
671-
convertStatefulSetImage(oldConfig.Image, &newConfig.ControlPlane.StatefulSet.Image)
671+
if oldConfig.Image != "" {
672+
config.ParseImageRef(oldConfig.Image, &newConfig.ControlPlane.StatefulSet.Image)
673+
}
672674
if oldConfig.ImagePullPolicy != "" {
673675
newConfig.ControlPlane.StatefulSet.ImagePullPolicy = oldConfig.ImagePullPolicy
674676
}
@@ -927,7 +929,7 @@ func migrateFlag(distro, key, value string, newConfig *config.Config) error {
927929
return fmt.Errorf("value is missing")
928930
}
929931

930-
newConfig.Sync.ToHost.Pods.RewriteHosts.InitContainer.Image = value
932+
config.ParseImageRef(value, &newConfig.Sync.ToHost.Pods.RewriteHosts.InitContainer.Image)
931933
case "cluster-domain":
932934
if value == "" {
933935
return fmt.Errorf("value is missing")
@@ -1109,7 +1111,9 @@ func applyStorage(oldConfig Storage, newConfig *config.Config) {
11091111

11101112
func convertVClusterConfig(oldConfig VClusterValues, retDistroCommon *config.DistroCommon, retDistroContainer *config.DistroContainer, newConfig *config.Config) error {
11111113
retDistroCommon.Env = oldConfig.Env
1112-
convertImage(oldConfig.Image, &retDistroCommon.Image)
1114+
if oldConfig.Image != "" {
1115+
config.ParseImageRef(oldConfig.Image, &retDistroCommon.Image)
1116+
}
11131117
if len(oldConfig.Resources) > 0 {
11141118
retDistroCommon.Resources = mergeMaps(retDistroCommon.Resources, oldConfig.Resources)
11151119
}
@@ -1133,22 +1137,6 @@ func convertVClusterConfig(oldConfig VClusterValues, retDistroCommon *config.Dis
11331137
return nil
11341138
}
11351139

1136-
func convertStatefulSetImage(image string, into *config.StatefulSetImage) {
1137-
if image == "" {
1138-
return
1139-
}
1140-
1141-
into.Registry, into.Repository, into.Tag = config.SplitImage(image)
1142-
}
1143-
1144-
func convertImage(image string, into *config.Image) {
1145-
if image == "" {
1146-
return
1147-
}
1148-
1149-
into.Registry, into.Repository, into.Tag = config.SplitImage(image)
1150-
}
1151-
11521140
func mergeIntoMap(retMap map[string]string, arr []string) map[string]string {
11531141
if retMap == nil {
11541142
retMap = map[string]string{}

0 commit comments

Comments
 (0)