diff --git a/charts/k3k/crds/k3k.io_virtualclusterpolicies.yaml b/charts/k3k/crds/k3k.io_virtualclusterpolicies.yaml
index 67c1a731..9d050f8d 100644
--- a/charts/k3k/crds/k3k.io_virtualclusterpolicies.yaml
+++ b/charts/k3k/crds/k3k.io_virtualclusterpolicies.yaml
@@ -11,10 +11,15 @@ spec:
kind: VirtualClusterPolicy
listKind: VirtualClusterPolicyList
plural: virtualclusterpolicies
+ shortNames:
+ - vcp
singular: virtualclusterpolicy
scope: Cluster
versions:
- additionalPrinterColumns:
+ - jsonPath: .spec.allowedMode
+ name: Mode
+ type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
@@ -46,20 +51,14 @@ spec:
default: {}
description: Spec defines the desired state of the VirtualClusterPolicy.
properties:
- allowedModeTypes:
- default:
+ allowedMode:
+ default: shared
+ description: AllowedMode specifies the allowed cluster provisioning
+ mode. Defaults to "shared".
+ enum:
- shared
- description: AllowedModeTypes specifies the allowed cluster provisioning
- modes. Defaults to [shared].
- items:
- description: ClusterMode is the possible provisioning mode of a
- Cluster.
- enum:
- - shared
- - virtual
- type: string
- minItems: 1
- type: array
+ - virtual
+ type: string
x-kubernetes-validations:
- message: mode is immutable
rule: self == oldSelf
diff --git a/cli/cmds/policy_create.go b/cli/cmds/policy_create.go
index 67206946..70fb9a0a 100644
--- a/cli/cmds/policy_create.go
+++ b/cli/cmds/policy_create.go
@@ -102,7 +102,7 @@ func createPolicy(ctx context.Context, client client.Client, mode v1alpha1.Clust
APIVersion: "k3k.io/v1alpha1",
},
Spec: v1alpha1.VirtualClusterPolicySpec{
- AllowedModeTypes: []v1alpha1.ClusterMode{mode},
+ AllowedMode: mode,
},
}
diff --git a/docs/crds/crd-docs.md b/docs/crds/crd-docs.md
index 3de0e9ad..7c08bfa4 100644
--- a/docs/crds/crd-docs.md
+++ b/docs/crds/crd-docs.md
@@ -293,7 +293,7 @@ _Appears in:_
| `limit` _[LimitRangeSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#limitrangespec-v1-core)_ | Limit specifies the LimitRange that will be applied to all pods within the VirtualClusterPolicy
to set defaults and constraints (min/max) | | |
| `defaultNodeSelector` _object (keys:string, values:string)_ | DefaultNodeSelector specifies the node selector that applies to all clusters (server + agent) in the target Namespace. | | |
| `defaultPriorityClass` _string_ | DefaultPriorityClass specifies the priorityClassName applied to all pods of all clusters in the target Namespace. | | |
-| `allowedModeTypes` _[ClusterMode](#clustermode) array_ | AllowedModeTypes specifies the allowed cluster provisioning modes. Defaults to [shared]. | [shared] | Enum: [shared virtual]
MinItems: 1
|
+| `allowedMode` _[ClusterMode](#clustermode)_ | AllowedMode specifies the allowed cluster provisioning mode. Defaults to "shared". | shared | Enum: [shared virtual]
|
| `disableNetworkPolicy` _boolean_ | DisableNetworkPolicy indicates whether to disable the creation of a default network policy for cluster isolation. | | |
| `podSecurityAdmissionLevel` _[PodSecurityAdmissionLevel](#podsecurityadmissionlevel)_ | PodSecurityAdmissionLevel specifies the pod security admission level applied to the pods in the namespace. | | Enum: [privileged baseline restricted]
|
diff --git a/docs/virtualclusterpolicy.md b/docs/virtualclusterpolicy.md
index d9a933ea..39126b24 100644
--- a/docs/virtualclusterpolicy.md
+++ b/docs/virtualclusterpolicy.md
@@ -33,7 +33,7 @@ It's also important to note what happens when a Namespace's policy binding chang
### Default Policy Values
-If you create a `VirtualClusterPolicy` without specifying any `spec` fields (e.g., using `k3kcli policy create my-default-policy`), it will be created with default settings. Currently, this includes `spec.allowedModeTypes` being set to `["shared"]`.
+If you create a `VirtualClusterPolicy` without specifying any `spec` fields (e.g., using `k3kcli policy create my-default-policy`), it will be created with default settings. Currently, this includes `spec.allowedMode` being set to `"shared"`.
```yaml
# Example of a minimal VCP (after creation with defaults)
@@ -42,17 +42,16 @@ kind: VirtualClusterPolicy
metadata:
name: my-default-policy
spec:
- allowedModeTypes:
- - shared
+ allowedMode: shared
```
## Key Capabilities & Examples
A `VirtualClusterPolicy` can configure several aspects of the Namespaces it's bound to and the virtual clusters operating within them.
-### 1. Restricting Allowed Virtual Cluster Modes (`allowedModeTypes`)
+### 1. Restricting Allowed Virtual Cluster Modes (`AllowedMode`)
-You can restrict the `mode` (e.g., "shared" or "virtual") in which K3k `Cluster` resources can be provisioned within bound Namespaces. If a `Cluster` is created in a bound Namespace with a mode not listed in `allowedModeTypes`, its creation might proceed but an error should be reported in the `Cluster` resource's status.
+You can restrict the `mode` (e.g., "shared" or "virtual") in which K3k `Cluster` resources can be provisioned within bound Namespaces. If a `Cluster` is created in a bound Namespace with a mode not allowed in `allowedMode`, its creation might proceed but an error should be reported in the `Cluster` resource's status.
**Example:** Allow only "shared" mode clusters.
diff --git a/examples/clusterset.yaml b/examples/clusterset.yaml
index 19a28a0a..c4b81c66 100644
--- a/examples/clusterset.yaml
+++ b/examples/clusterset.yaml
@@ -4,8 +4,6 @@ metadata:
name: policy-example
# spec:
# disableNetworkPolicy: false
- # allowedModeTypes:
- # - "shared"
- # - "virtual"
+ # allowedMode: "shared"
# podSecurityAdmissionLevel: "baseline"
# defaultPriorityClass: "lowpriority"
diff --git a/pkg/apis/k3k.io/v1alpha1/types.go b/pkg/apis/k3k.io/v1alpha1/types.go
index 15f1760b..abcd347b 100644
--- a/pkg/apis/k3k.io/v1alpha1/types.go
+++ b/pkg/apis/k3k.io/v1alpha1/types.go
@@ -333,8 +333,9 @@ type ClusterList struct {
// +kubebuilder:storageversion
// +kubebuilder:subresource:status
// +kubebuilder:object:root=true
+// +kubebuilder:printcolumn:JSONPath=".spec.allowedMode",name=Mode,type=string
// +kubebuilder:printcolumn:JSONPath=".metadata.creationTimestamp",name=Age,type=date
-// +kubebuilder:resource:scope=Cluster
+// +kubebuilder:resource:scope=Cluster,shortName=vcp
// VirtualClusterPolicy allows defining common configurations and constraints
// for clusters within a clusterpolicy.
@@ -377,13 +378,12 @@ type VirtualClusterPolicySpec struct {
// +optional
DefaultPriorityClass string `json:"defaultPriorityClass,omitempty"`
- // AllowedModeTypes specifies the allowed cluster provisioning modes. Defaults to [shared].
+ // AllowedMode specifies the allowed cluster provisioning mode. Defaults to "shared".
//
- // +kubebuilder:default={shared}
+ // +kubebuilder:default=shared
// +kubebuilder:validation:XValidation:message="mode is immutable",rule="self == oldSelf"
- // +kubebuilder:validation:MinItems=1
// +optional
- AllowedModeTypes []ClusterMode `json:"allowedModeTypes,omitempty"`
+ AllowedMode ClusterMode `json:"allowedMode,omitempty"`
// DisableNetworkPolicy indicates whether to disable the creation of a default network policy for cluster isolation.
//
diff --git a/pkg/apis/k3k.io/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/k3k.io/v1alpha1/zz_generated.deepcopy.go
index 448f301b..5c412243 100644
--- a/pkg/apis/k3k.io/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/k3k.io/v1alpha1/zz_generated.deepcopy.go
@@ -397,11 +397,6 @@ func (in *VirtualClusterPolicySpec) DeepCopyInto(out *VirtualClusterPolicySpec)
(*out)[key] = val
}
}
- if in.AllowedModeTypes != nil {
- in, out := &in.AllowedModeTypes, &out.AllowedModeTypes
- *out = make([]ClusterMode, len(*in))
- copy(*out, *in)
- }
if in.PodSecurityAdmissionLevel != nil {
in, out := &in.PodSecurityAdmissionLevel, &out.PodSecurityAdmissionLevel
*out = new(PodSecurityAdmissionLevel)
diff --git a/pkg/controller/policy/policy_test.go b/pkg/controller/policy/policy_test.go
index 4b40a5aa..d82b9912 100644
--- a/pkg/controller/policy/policy_test.go
+++ b/pkg/controller/policy/policy_test.go
@@ -26,40 +26,17 @@ var _ = Describe("VirtualClusterPolicy Controller", Label("controller"), Label("
Context("creating a VirtualClusterPolicy", func() {
- It("should have only the 'shared' allowedModeTypes", func() {
+ It("should have the 'shared' allowedMode", func() {
policy := newPolicy(v1alpha1.VirtualClusterPolicySpec{})
-
- allowedModeTypes := policy.Spec.AllowedModeTypes
- Expect(allowedModeTypes).To(HaveLen(1))
- Expect(allowedModeTypes).To(ContainElement(v1alpha1.SharedClusterMode))
+ Expect(policy.Spec.AllowedMode).To(Equal(v1alpha1.SharedClusterMode))
})
It("should have the 'virtual' mode if specified", func() {
policy := newPolicy(v1alpha1.VirtualClusterPolicySpec{
- AllowedModeTypes: []v1alpha1.ClusterMode{
- v1alpha1.VirtualClusterMode,
- },
+ AllowedMode: v1alpha1.VirtualClusterMode,
})
- allowedModeTypes := policy.Spec.AllowedModeTypes
- Expect(allowedModeTypes).To(HaveLen(1))
- Expect(allowedModeTypes).To(ContainElement(v1alpha1.VirtualClusterMode))
- })
-
- It("should have both modes if specified", func() {
- policy := newPolicy(v1alpha1.VirtualClusterPolicySpec{
- AllowedModeTypes: []v1alpha1.ClusterMode{
- v1alpha1.SharedClusterMode,
- v1alpha1.VirtualClusterMode,
- },
- })
-
- allowedModeTypes := policy.Spec.AllowedModeTypes
- Expect(allowedModeTypes).To(HaveLen(2))
- Expect(allowedModeTypes).To(ContainElements(
- v1alpha1.SharedClusterMode,
- v1alpha1.VirtualClusterMode,
- ))
+ Expect(policy.Spec.AllowedMode).To(Equal(v1alpha1.VirtualClusterMode))
})
It("should fail for a non-existing mode", func() {
@@ -68,11 +45,7 @@ var _ = Describe("VirtualClusterPolicy Controller", Label("controller"), Label("
GenerateName: "policy-",
},
Spec: v1alpha1.VirtualClusterPolicySpec{
- AllowedModeTypes: []v1alpha1.ClusterMode{
- v1alpha1.SharedClusterMode,
- v1alpha1.VirtualClusterMode,
- v1alpha1.ClusterMode("non-existing"),
- },
+ AllowedMode: v1alpha1.ClusterMode("non-existing"),
},
}