Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v0.21] Merge pull request #2270 from FabianKramm/main #2271

Merged
merged 1 commit into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions chart/tests/clusterrole_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ tests:
customResources:
test.test-group:
enabled: true
scope: Cluster
release:
name: my-release
namespace: my-namespace
Expand Down
24 changes: 21 additions & 3 deletions chart/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3025,6 +3025,10 @@
"type": "boolean",
"description": "Enabled defines if this option should be enabled."
},
"scope": {
"type": "string",
"description": "Scope defines the scope of the resource"
},
"patches": {
"items": {
"$ref": "#/$defs/TranslatePatch"
Expand All @@ -3034,7 +3038,11 @@
}
},
"additionalProperties": false,
"type": "object"
"type": "object",
"required": [
"enabled",
"scope"
]
},
"SyncNodeSelector": {
"properties": {
Expand Down Expand Up @@ -3228,6 +3236,10 @@
"type": "boolean",
"description": "Enabled defines if this option should be enabled."
},
"scope": {
"type": "string",
"description": "Scope defines the scope of the resource. If undefined, will use Namespaced. Currently only Namespaced is supported."
},
"patches": {
"items": {
"$ref": "#/$defs/TranslatePatch"
Expand All @@ -3237,7 +3249,10 @@
}
},
"additionalProperties": false,
"type": "object"
"type": "object",
"required": [
"enabled"
]
},
"Telemetry": {
"properties": {
Expand Down Expand Up @@ -3285,7 +3300,10 @@
}
},
"additionalProperties": false,
"type": "object"
"type": "object",
"required": [
"path"
]
},
"TranslatePatchLabels": {
"properties": {},
Expand Down
27 changes: 16 additions & 11 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,15 +502,25 @@ type SyncFromHost struct {

type SyncToHostCustomResource struct {
// Enabled defines if this option should be enabled.
Enabled bool `json:"enabled,omitempty"`
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"`
Path string `json:"path,omitempty" jsonschema:"required"`

// Expression transforms the value according to the given JavaScript expression.
Expression string `json:"expression,omitempty"`
Expand Down Expand Up @@ -550,17 +560,12 @@ type TranslatePatchReference struct {
NamespacePath string `json:"namespacePath,omitempty"`
}

type TranslatePatchExpression struct {
// ToHost is the expression to apply when retrieving a change from virtual to host.
ToHost string `json:"toHost,omitempty"`

// FromHost is the patch to apply when retrieving a change from host to virtual.
FromHost string `json:"fromHost,omitempty"`
}

type SyncFromHostCustomResource struct {
// Enabled defines if this option should be enabled.
Enabled bool `json:"enabled,omitempty"`
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"`
Expand Down
75 changes: 46 additions & 29 deletions pkg/config/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,107 +22,124 @@ var allowedPodSecurityStandards = map[string]bool{

var verbs = []string{"get", "list", "create", "update", "patch", "watch", "delete", "deletecollection"}

func ValidateConfigAndSetDefaults(config *VirtualClusterConfig) error {
func ValidateConfigAndSetDefaults(vConfig *VirtualClusterConfig) error {
// check the value of pod security standard
if config.Policies.PodSecurityStandard != "" && !allowedPodSecurityStandards[config.Policies.PodSecurityStandard] {
return fmt.Errorf("invalid argument enforce-pod-security-standard=%s, must be one of: privileged, baseline, restricted", config.Policies.PodSecurityStandard)
if vConfig.Policies.PodSecurityStandard != "" && !allowedPodSecurityStandards[vConfig.Policies.PodSecurityStandard] {
return fmt.Errorf("invalid argument enforce-pod-security-standard=%s, must be one of: privileged, baseline, restricted", vConfig.Policies.PodSecurityStandard)
}

// parse tolerations
for _, t := range config.Sync.ToHost.Pods.EnforceTolerations {
for _, t := range vConfig.Sync.ToHost.Pods.EnforceTolerations {
_, err := toleration.ParseToleration(t)
if err != nil {
return err
}
}

// check if enable scheduler works correctly
if config.ControlPlane.Advanced.VirtualScheduler.Enabled && !config.Sync.FromHost.Nodes.Selector.All && len(config.Sync.FromHost.Nodes.Selector.Labels) == 0 {
config.Sync.FromHost.Nodes.Selector.All = true
if vConfig.ControlPlane.Advanced.VirtualScheduler.Enabled && !vConfig.Sync.FromHost.Nodes.Selector.All && len(vConfig.Sync.FromHost.Nodes.Selector.Labels) == 0 {
vConfig.Sync.FromHost.Nodes.Selector.All = true
}

// enable additional controllers required for scheduling with storage
if config.ControlPlane.Advanced.VirtualScheduler.Enabled && config.Sync.ToHost.PersistentVolumeClaims.Enabled {
if config.Sync.FromHost.CSINodes.Enabled == "auto" {
config.Sync.FromHost.CSINodes.Enabled = "true"
if vConfig.ControlPlane.Advanced.VirtualScheduler.Enabled && vConfig.Sync.ToHost.PersistentVolumeClaims.Enabled {
if vConfig.Sync.FromHost.CSINodes.Enabled == "auto" {
vConfig.Sync.FromHost.CSINodes.Enabled = "true"
}
if config.Sync.FromHost.CSIStorageCapacities.Enabled == "auto" {
config.Sync.FromHost.CSIStorageCapacities.Enabled = "true"
if vConfig.Sync.FromHost.CSIStorageCapacities.Enabled == "auto" {
vConfig.Sync.FromHost.CSIStorageCapacities.Enabled = "true"
}
if config.Sync.FromHost.CSIDrivers.Enabled == "auto" {
config.Sync.FromHost.CSIDrivers.Enabled = "true"
if vConfig.Sync.FromHost.CSIDrivers.Enabled == "auto" {
vConfig.Sync.FromHost.CSIDrivers.Enabled = "true"
}
if config.Sync.FromHost.StorageClasses.Enabled == "auto" && !config.Sync.ToHost.StorageClasses.Enabled {
config.Sync.FromHost.StorageClasses.Enabled = "true"
if vConfig.Sync.FromHost.StorageClasses.Enabled == "auto" && !vConfig.Sync.ToHost.StorageClasses.Enabled {
vConfig.Sync.FromHost.StorageClasses.Enabled = "true"
}
}

// check if embedded database and multiple replicas
if vConfig.Config.BackingStoreType() == config.StoreTypeEmbeddedDatabase && vConfig.ControlPlane.StatefulSet.HighAvailability.Replicas > 1 {
return fmt.Errorf("embedded database is not supported with multiple replicas")
}

// check if custom resources have correct scope
for key, customResource := range vConfig.Sync.ToHost.CustomResources {
if customResource.Scope != "" && customResource.Scope != config.ScopeNamespaced {
return fmt.Errorf("unsupported scope %s for sync.toHost.customResources['%s'].scope. Only 'Namespaced' is allowed", customResource.Scope, key)
}
}
for key, customResource := range vConfig.Sync.FromHost.CustomResources {
if customResource.Scope != "" && customResource.Scope != config.ScopeCluster {
return fmt.Errorf("unsupported scope %s for sync.fromHost.customResources['%s'].scope. Only 'Cluster' is allowed", customResource.Scope, key)
}
}

// check if nodes controller needs to be enabled
if config.ControlPlane.Advanced.VirtualScheduler.Enabled && !config.Sync.FromHost.Nodes.Enabled {
if vConfig.ControlPlane.Advanced.VirtualScheduler.Enabled && !vConfig.Sync.FromHost.Nodes.Enabled {
return errors.New("sync.fromHost.nodes.enabled is false, but required if using virtual scheduler")
}

// check if storage classes and host storage classes are enabled at the same time
if config.Sync.FromHost.StorageClasses.Enabled == "true" && config.Sync.ToHost.StorageClasses.Enabled {
if vConfig.Sync.FromHost.StorageClasses.Enabled == "true" && vConfig.Sync.ToHost.StorageClasses.Enabled {
return errors.New("you cannot enable both sync.fromHost.storageClasses.enabled and sync.toHost.storageClasses.enabled at the same time. Choose only one of them")
}

if config.Sync.FromHost.PriorityClasses.Enabled && config.Sync.ToHost.PriorityClasses.Enabled {
if vConfig.Sync.FromHost.PriorityClasses.Enabled && vConfig.Sync.ToHost.PriorityClasses.Enabled {
return errors.New("cannot sync priorityclasses to and from host at the same time")
}

// volumesnapshots and volumesnapshotcontents are dependant on each other
if config.Sync.ToHost.VolumeSnapshotContents.Enabled && !config.Sync.ToHost.VolumeSnapshots.Enabled {
if vConfig.Sync.ToHost.VolumeSnapshotContents.Enabled && !vConfig.Sync.ToHost.VolumeSnapshots.Enabled {
return errors.New("when syncing volume snapshots contents to the host, one must set sync.toHost.volumeSnapshots.enabled to true")
}
if config.Sync.ToHost.VolumeSnapshots.Enabled && !config.Sync.ToHost.VolumeSnapshotContents.Enabled {
if vConfig.Sync.ToHost.VolumeSnapshots.Enabled && !vConfig.Sync.ToHost.VolumeSnapshotContents.Enabled {
return errors.New("when syncing volume snapshots to the host, one must set sync.toHost.volumeSnapshotContents.enabled to true")
}

// validate central admission control
err := validateCentralAdmissionControl(config)
err := validateCentralAdmissionControl(vConfig)
if err != nil {
return err
}

// validate generic sync config
err = validateGenericSyncConfig(config.Experimental.GenericSync)
err = validateGenericSyncConfig(vConfig.Experimental.GenericSync)
if err != nil {
return fmt.Errorf("validate experimental.genericSync")
}

// validate distro
err = validateDistro(config)
err = validateDistro(vConfig)
if err != nil {
return err
}

err = validateK0sAndNoExperimentalKubeconfig(config)
err = validateK0sAndNoExperimentalKubeconfig(vConfig)
if err != nil {
return err
}

// check deny proxy requests
for _, c := range config.Experimental.DenyProxyRequests {
for _, c := range vConfig.Experimental.DenyProxyRequests {
err := validateCheck(c)
if err != nil {
return err
}
}

// check resolve dns
err = validateMappings(config.Networking.ResolveDNS)
err = validateMappings(vConfig.Networking.ResolveDNS)
if err != nil {
return err
}

// set service name
if config.ControlPlane.Advanced.WorkloadServiceAccount.Name == "" {
config.ControlPlane.Advanced.WorkloadServiceAccount.Name = "vc-workload-" + config.Name
if vConfig.ControlPlane.Advanced.WorkloadServiceAccount.Name == "" {
vConfig.ControlPlane.Advanced.WorkloadServiceAccount.Name = "vc-workload-" + vConfig.Name
}

// pro validate config
err = ProValidateConfig(config)
err = ProValidateConfig(vConfig)
if err != nil {
return err
}
Expand Down
Loading