Skip to content

Commit

Permalink
refactor: add customResources.scope & require scope for fromHost cust…
Browse files Browse the repository at this point in the history
…omResources

(cherry picked from commit 50239c0)
  • Loading branch information
FabianKramm committed Nov 9, 2024
1 parent c3115af commit 8ac51c8
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 43 deletions.
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

0 comments on commit 8ac51c8

Please sign in to comment.