diff --git a/workspaces/backend/api/suite_test.go b/workspaces/backend/api/suite_test.go index 498c4155..0f23ecdd 100644 --- a/workspaces/backend/api/suite_test.go +++ b/workspaces/backend/api/suite_test.go @@ -65,6 +65,8 @@ func TestAPI(t *testing.T) { RunSpecs(t, "API Suite") } +const namespaceName = "default" + var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) ctx, cancel = context.WithCancel(context.Background()) @@ -177,8 +179,9 @@ func NewExampleWorkspaceKind(name string) *kubefloworgv1beta1.WorkspaceKind { }, Logo: kubefloworgv1beta1.WorkspaceKindIcon{ ConfigMap: &kubefloworgv1beta1.WorkspaceKindConfigMap{ - Name: "my-logos", - Key: "apple-touch-icon-152x152.png", + Name: "my-logos", + Namespace: namespaceName, + Key: "apple-touch-icon-152x152.png", }, }, }, diff --git a/workspaces/controller/api/v1beta1/workspace_types.go b/workspaces/controller/api/v1beta1/workspace_types.go index ee5ba99a..5b513902 100644 --- a/workspaces/controller/api/v1beta1/workspace_types.go +++ b/workspaces/controller/api/v1beta1/workspace_types.go @@ -45,7 +45,7 @@ type WorkspaceSpec struct { // the WorkspaceKind to use //+kubebuilder:validation:MinLength:=2 //+kubebuilder:validation:MaxLength:=63 - //+kubebuilder:validation:Pattern:=^[a-z0-9][-a-z0-9]*[a-z0-9]$ + //+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ //+kubebuilder:validation:XValidation:rule="self == oldSelf",message="Workspace 'kind' is immutable" //+kubebuilder:example="jupyterlab" Kind string `json:"kind"` @@ -85,7 +85,7 @@ type WorkspacePodVolumes struct { //+kubebuilder:validation:Optional //+kubebuilder:validation:MinLength:=2 //+kubebuilder:validation:MaxLength:=63 - //+kubebuilder:validation:Pattern:=^[a-z0-9][-a-z0-9]*[a-z0-9]$ + //+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ //+kubebuilder:example="my-home-pvc" Home *string `json:"home,omitempty"` @@ -104,7 +104,7 @@ type PodVolumeMount struct { // the name of the PVC to mount //+kubebuilder:validation:MinLength:=2 //+kubebuilder:validation:MaxLength:=63 - //+kubebuilder:validation:Pattern:=^[a-z0-9][-a-z0-9]*[a-z0-9]$ + //+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ //+kubebuilder:example="my-data-pvc" PVCName string `json:"pvcName"` diff --git a/workspaces/controller/api/v1beta1/workspacekind_types.go b/workspaces/controller/api/v1beta1/workspacekind_types.go index e1bf0d26..f2fa3829 100644 --- a/workspaces/controller/api/v1beta1/workspacekind_types.go +++ b/workspaces/controller/api/v1beta1/workspacekind_types.go @@ -89,9 +89,21 @@ type WorkspaceKindIcon struct { } type WorkspaceKindConfigMap struct { + + //+kubebuilder:validation:MinLength:=1 + //+kubebuilder:validation:MaxLength:=253 + //+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ //+kubebuilder:example="my-logos" Name string `json:"name"` + //+kubebuilder:validation:MinLength:=1 + //+kubebuilder:validation:MaxLength:=63 + //+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + Namespace string `json:"namespace"` + + //+kubebuilder:validation:MinLength:=1 + //+kubebuilder:validation:MaxLength:=253 + //+kubebuilder:validation:Pattern:=^[-._a-zA-Z0-9]+$ //+kubebuilder:example="apple-touch-icon-152x152.png" Key string `json:"key"` } diff --git a/workspaces/controller/config/crd/bases/kubeflow.org_workspacekinds.yaml b/workspaces/controller/config/crd/bases/kubeflow.org_workspacekinds.yaml index c1275a13..09360ce9 100644 --- a/workspaces/controller/config/crd/bases/kubeflow.org_workspacekinds.yaml +++ b/workspaces/controller/config/crd/bases/kubeflow.org_workspacekinds.yaml @@ -4273,13 +4273,25 @@ spec: properties: key: example: apple-touch-icon-152x152.png + maxLength: 253 + minLength: 1 + pattern: ^[-._a-zA-Z0-9]+$ type: string name: example: my-logos + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + namespace: + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string required: - key - name + - namespace type: object url: example: https://jupyter.org/assets/favicons/apple-touch-icon-152x152.png @@ -4298,13 +4310,25 @@ spec: properties: key: example: apple-touch-icon-152x152.png + maxLength: 253 + minLength: 1 + pattern: ^[-._a-zA-Z0-9]+$ type: string name: example: my-logos + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + namespace: + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ type: string required: - key - name + - namespace type: object url: example: https://jupyter.org/assets/favicons/apple-touch-icon-152x152.png diff --git a/workspaces/controller/config/crd/bases/kubeflow.org_workspaces.yaml b/workspaces/controller/config/crd/bases/kubeflow.org_workspaces.yaml index 201d595b..38f6fc89 100644 --- a/workspaces/controller/config/crd/bases/kubeflow.org_workspaces.yaml +++ b/workspaces/controller/config/crd/bases/kubeflow.org_workspaces.yaml @@ -55,7 +55,7 @@ spec: example: jupyterlab maxLength: 63 minLength: 2 - pattern: ^[a-z0-9][-a-z0-9]*[a-z0-9]$ + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string x-kubernetes-validations: - message: Workspace 'kind' is immutable @@ -130,7 +130,7 @@ spec: example: my-data-pvc maxLength: 63 minLength: 2 - pattern: ^[a-z0-9][-a-z0-9]*[a-z0-9]$ + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string readOnly: default: false @@ -154,7 +154,7 @@ spec: example: my-home-pvc maxLength: 63 minLength: 2 - pattern: ^[a-z0-9][-a-z0-9]*[a-z0-9]$ + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ type: string type: object required: diff --git a/workspaces/controller/internal/controller/suite_test.go b/workspaces/controller/internal/controller/suite_test.go index 7d6a6b90..4a362df2 100644 --- a/workspaces/controller/internal/controller/suite_test.go +++ b/workspaces/controller/internal/controller/suite_test.go @@ -58,6 +58,8 @@ var ( cancel context.CancelFunc ) +const namespaceName = "default" + func TestControllers(t *testing.T) { RegisterFailHandler(Fail) @@ -192,8 +194,9 @@ func NewExampleWorkspaceKind1(name string) *kubefloworgv1beta1.WorkspaceKind { }, Logo: kubefloworgv1beta1.WorkspaceKindIcon{ ConfigMap: &kubefloworgv1beta1.WorkspaceKindConfigMap{ - Name: "my-logos", - Key: "apple-touch-icon-152x152.png", + Name: "my-logos", + Namespace: namespaceName, + Key: "apple-touch-icon-152x152.png", }, }, }, diff --git a/workspaces/controller/internal/controller/workspacekind_controller_test.go b/workspaces/controller/internal/controller/workspacekind_controller_test.go index 505a9dc8..d2baf819 100644 --- a/workspaces/controller/internal/controller/workspacekind_controller_test.go +++ b/workspaces/controller/internal/controller/workspacekind_controller_test.go @@ -118,8 +118,9 @@ var _ = Describe("WorkspaceKind Controller", func() { newWorkspaceKind.Spec.Spawner.Icon = kubefloworgv1beta1.WorkspaceKindIcon{ Url: ptr.To("https://example.com/icon.png"), ConfigMap: &kubefloworgv1beta1.WorkspaceKindConfigMap{ - Name: "my-logos", - Key: "icon.png", + Name: "my-logos", + Namespace: namespaceName, + Key: "icon.png", }, } Expect(k8sClient.Patch(ctx, newWorkspaceKind, patch)).NotTo(Succeed()) diff --git a/workspaces/controller/internal/webhook/suite_test.go b/workspaces/controller/internal/webhook/suite_test.go index a4e9e077..9ff60e24 100644 --- a/workspaces/controller/internal/webhook/suite_test.go +++ b/workspaces/controller/internal/webhook/suite_test.go @@ -63,6 +63,8 @@ var ( cancel context.CancelFunc ) +const namespaceName = "default" + func TestAPIs(t *testing.T) { RegisterFailHandler(Fail) @@ -186,8 +188,9 @@ func NewExampleWorkspaceKind(name string) *kubefloworgv1beta1.WorkspaceKind { }, Logo: kubefloworgv1beta1.WorkspaceKindIcon{ ConfigMap: &kubefloworgv1beta1.WorkspaceKindConfigMap{ - Name: "my-logos", - Key: "apple-touch-icon-152x152.png", + Name: "my-logos", + Namespace: namespaceName, + Key: "apple-touch-icon-152x152.png", }, }, },