From 2913dff33eba32f85facb0cf55742fad7ee62b66 Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Sat, 16 Dec 2023 13:27:03 +0200 Subject: [PATCH] Refactor redis module using latest schemas Signed-off-by: Stefan Prodan --- .../pkg/timoni.sh/core/v1alpha1/image.cue | 59 +++++++++++- .../pkg/timoni.sh/core/v1alpha1/instance.cue | 27 ++++++ .../pkg/timoni.sh/core/v1alpha1/metadata.cue | 93 +++++++++++++++++-- .../timoni.sh/core/v1alpha1/requirements.cue | 40 ++++++++ .../pkg/timoni.sh/core/v1alpha1/selector.cue | 9 +- .../pkg/timoni.sh/core/v1alpha1/semver.cue | 29 ++++++ examples/redis/debug_tool.cue | 4 +- examples/redis/debug_values.cue | 3 +- examples/redis/templates/config.cue | 59 ++++++++---- .../redis/templates/master.deployment.cue | 24 ++--- examples/redis/templates/master.pvc.cue | 11 +-- examples/redis/templates/master.service.cue | 15 +-- .../redis/templates/replica.deployment.cue | 21 ++--- examples/redis/templates/replica.service.cue | 16 ++-- examples/redis/templates/test.job.cue | 15 ++- examples/redis/timoni.cue | 2 +- examples/redis/values.cue | 4 +- 17 files changed, 332 insertions(+), 99 deletions(-) create mode 100644 examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/instance.cue create mode 100644 examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/requirements.cue create mode 100644 examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/semver.cue diff --git a/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/image.cue b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/image.cue index 3c6b93c5..ec500aa1 100644 --- a/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/image.cue +++ b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/image.cue @@ -3,7 +3,10 @@ package v1alpha1 -import "strings" +import ( + "encoding/base64" + "strings" +) // Image defines the schema for OCI image reference used in Kubernetes PodSpec container image. #Image: { @@ -22,6 +25,10 @@ import "strings" // Spec: https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests. digest!: string + // PullPolicy defines the pull policy for the image. + // By default, it is set to IfNotPresent. + pullPolicy: *"IfNotPresent" | "Always" | "Never" + // Reference is the image address computed from repository, tag and digest // in the format [REPOSITORY]:[TAG]@[DIGEST]. reference: string @@ -42,3 +49,53 @@ import "strings" reference: "\(repository):latest" } } + +// ImagePullSecret is a generator for Kubernetes Secrets of type kubernetes.io/dockerconfigjson. +// Spec: https://kubernetes.io/docs/concepts/configuration/secret/#docker-config-secrets. +#ImagePullSecret: { + // Metadata is the Kubernetes object's metadata generated by Timoni. + meta=metadata: #Metadata + + // Registry is the hostname of the container registry in the format [HOST[:PORT_NUMBER]]. + registry!: string + + // Username is the username used to authenticate to the container registry. + username!: string + + // Password is the password used to authenticate to the container registry. + password!: string + + // Optional suffix used to generate the Secret name. + suffix: *"" | string + + let auth = base64.Encode(null, username+":"+password) + + // The object is a read-only struct that contains the generated + // Kubernetes Secret of type kubernetes.io/dockerconfigjson. + object: { + apiVersion: "v1" + kind: "Secret" + type: "kubernetes.io/dockerconfigjson" + metadata: { + name: meta.name + suffix + namespace: meta.namespace + labels: meta.labels + if meta.annotations != _|_ { + annotations: meta.annotations + } + } + stringData: { + ".dockerconfigjson": #""" + { + "auths": { + "\#(registry)": { + "username": "\#(username)", + "password": "\#(password)", + "auth": "\#(auth)" + } + } + } + """# + } + } +} diff --git a/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/instance.cue b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/instance.cue new file mode 100644 index 00000000..ad96b062 --- /dev/null +++ b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/instance.cue @@ -0,0 +1,27 @@ +// Copyright 2023 Stefan Prodan +// SPDX-License-Identifier: Apache-2.0 + +package v1alpha1 + +import "strings" + +// InstanceName defines the schema for the name of a Timoni instance. +// The instance name is used as a Kubernetes label value and must be 63 characters or less. +#InstanceName: string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" & strings.MinRunes(1) & strings.MaxRunes(63) + +// InstanceNamespace defines the schema for the namespace of a Timoni instance. +// The instance namespace is used as a Kubernetes label value and must be 63 characters or less. +#InstanceNamespace: string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" & strings.MinRunes(1) & strings.MaxRunes(63) + +// InstanceOwnerReference defines the schema for Kubernetes labels used to denote ownership. +#InstanceOwnerReference: { + #Name: "instance.timoni.sh/name" + #Namespace: "instance.timoni.sh/namespace" +} + +// InstanceModule defines the schema for the Module of a Timoni instance. +#InstanceModule: { + url: string & =~"^((oci|file)://.*)$" + version: *"latest" | string + digest?: string +} diff --git a/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/metadata.cue b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/metadata.cue index 2b6cfe88..ae7bb7c2 100644 --- a/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/metadata.cue +++ b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/metadata.cue @@ -5,6 +5,19 @@ package v1alpha1 import "strings" +// Annotations defines the schema for Kubernetes object metadata annotations. +#Annotations: {[string & strings.MaxRunes(253)]: string} + +// Labels defines the schema for Kubernetes object metadata labels. +#Labels: {[string & strings.MaxRunes(253)]: string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" & strings.MaxRunes(63)} + +#StdLabelName: "app.kubernetes.io/name" +#StdLabelVersion: "app.kubernetes.io/version" +#StdLabelPartOf: "app.kubernetes.io/part-of" +#StdLabelManagedBy: "app.kubernetes.io/managed-by" +#StdLabelComponent: "app.kubernetes.io/component" +#StdLabelInstance: "app.kubernetes.io/instance" + // Metadata defines the schema for Kubernetes object metadata. #Metadata: { // Version should be in the strict semver format. Is required when creating resources. @@ -13,24 +26,90 @@ import "strings" // Name must be unique within a namespace. Is required when creating resources. // Name is primarily intended for creation idempotence and configuration definition. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names - name!: string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" & strings.MaxRunes(63) + name!: #InstanceName // Namespace defines the space within which each name must be unique. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces - namespace!: string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" & strings.MaxRunes(63) + namespace!: #InstanceNamespace // Annotations is an unstructured key value map stored with a resource that may be // set to store and retrieve arbitrary metadata. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations - annotations?: {[string & =~"^(([A-Za-z0-9][-A-Za-z0-9_./]*)?[A-Za-z0-9])?$" & strings.MaxRunes(63)]: string} + annotations?: #Annotations // Map of string keys and values that can be used to organize and categorize (scope and select) objects. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels - labels: {[string & =~"^(([A-Za-z0-9][-A-Za-z0-9_./]*)?[A-Za-z0-9])?$" & strings.MaxRunes(63)]: string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" & strings.MaxRunes(63)} + labels: #Labels - // Standard Kubernetes labels: app name and version. + // Standard Kubernetes labels: app name, version and managed-by. labels: { - "app.kubernetes.io/name": name - "app.kubernetes.io/version": #Version + "\(#StdLabelName)": name + "\(#StdLabelVersion)": #Version + "\(#StdLabelManagedBy)": "Timoni" + } + + // LabelSelector selects Pods based on the app.kubernetes.io/name label. + #LabelSelector: #Labels & { + "\(#StdLabelName)": name + } +} + +// MetaComponent generates the Kubernetes object metadata for a module namespaced component. +// The metadata.name is composed of the instance name and the component name. +// The metadata.labels contain the app.kubernetes.io/component label. +#MetaComponent: { + // Meta is the Kubernetes object's metadata generated by Timoni. + #Meta!: #Metadata + + // Component is the name of the component used + // as a suffix for the generate object name. + #Component!: string & strings.MaxRunes(30) + + name: #Meta.name + "-" + #Component + namespace: #Meta.namespace + + labels: #Meta.labels + labels: "\(#StdLabelComponent)": #Component + + annotations?: #Annotations + if #Meta.annotations != _|_ { + annotations: #Meta.annotations + } + + // LabelSelector selects Pods based on the app.kubernetes.io/name + // and app.kubernetes.io/component labels. + #LabelSelector: #Labels & { + "\(#StdLabelComponent)": #Component + "\(#StdLabelName)": #Meta.name + } +} + +// MetaClusterComponent generates the Kubernetes object metadata for a module non-namespaced component. +// The metadata.name is composed of the instance name and the component name. +// The metadata.namespace is unset. +// The metadata.labels contain the app.kubernetes.io/component label. +#MetaClusterComponent: { + // Meta is the Kubernetes object's metadata generated by Timoni. + #Meta!: #Metadata + + // Component is the name of the component used + // as a suffix for the generate object name. + #Component!: string & strings.MaxRunes(30) + + name: #Meta.name + "-" + #Component + + labels: #Meta.labels + labels: "\(#StdLabelComponent)": #Component + + annotations?: #Annotations + if #Meta.annotations != _|_ { + annotations: #Meta.annotations + } + + // LabelSelector selects Pods based on the app.kubernetes.io/name + // and app.kubernetes.io/component labels. + #LabelSelector: #Labels & { + "\(#StdLabelComponent)": #Component + "\(#StdLabelName)": #Meta.name } } diff --git a/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/requirements.cue b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/requirements.cue new file mode 100644 index 00000000..d3b5573a --- /dev/null +++ b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/requirements.cue @@ -0,0 +1,40 @@ +// Copyright 2023 Stefan Prodan +// SPDX-License-Identifier: Apache-2.0 + +package v1alpha1 + +import ( + "strconv" + "strings" +) + +// CPUQuantity is a string that is validated as a quantity of CPU, such as 100m or 2000m. +#CPUQuantity: string & =~"^[1-9]\\d*m$" + +// MemoryQuantity is a string that is validated as a quantity of memory, such as 128Mi or 2Gi. +#MemoryQuantity: string & =~"^[1-9]\\d*(Mi|Gi)$" + +// ResourceRequirement defines the schema for the CPU and Memory resource requirements. +#ResourceRequirement: { + cpu?: #CPUQuantity + memory?: #MemoryQuantity +} + +// ResourceRequirements defines the schema for the compute resource requirements of a container. +// More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/. +#ResourceRequirements: { + // Limits describes the maximum amount of compute resources allowed. + limits?: #ResourceRequirement + + // Requests describes the minimum amount of compute resources required. + // Requests cannot exceed Limits. + requests?: #ResourceRequirement & { + if limits != _|_ { + if limits.cpu != _|_ { + _lc: strconv.Atoi(strings.Split(limits.cpu, "m")[0]) + _rc: strconv.Atoi(strings.Split(requests.cpu, "m")[0]) + #cpu: int & >=_rc & _lc + } + } + } +} diff --git a/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/selector.cue b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/selector.cue index 3e8306b1..207984e1 100644 --- a/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/selector.cue +++ b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/selector.cue @@ -3,19 +3,18 @@ package v1alpha1 -import "strings" - // Selector defines the schema for Kubernetes Pod label selector used in Deployments, Services, Jobs, etc. +// Depreacted in favor of #Metadata.#LabelSelector #Selector: { // Name must be unique within a namespace. Is required when creating resources. // Name is primarily intended for creation idempotence and configuration definition. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names - #Name!: string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" & strings.MinRunes(1) & strings.MaxRunes(63) + #Name!: #InstanceName // Map of string keys and values that can be used to organize and categorize (scope and select) objects. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels - labels: {[string & =~"^(([A-Za-z0-9][-A-Za-z0-9_./]*)?[A-Za-z0-9])?$" & strings.MaxRunes(63)]: string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" & strings.MaxRunes(63)} + labels: #Labels // Standard Kubernetes label: app name. - labels: "app.kubernetes.io/name": #Name + labels: "\(#StdLabelName)": #Name } diff --git a/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/semver.cue b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/semver.cue new file mode 100644 index 00000000..ecd1e397 --- /dev/null +++ b/examples/redis/cue.mod/pkg/timoni.sh/core/v1alpha1/semver.cue @@ -0,0 +1,29 @@ +// Copyright 2023 Stefan Prodan +// SPDX-License-Identifier: Apache-2.0 + +package v1alpha1 + +import ( + "strconv" + "strings" +) + +// SemVer validates the input version string and extracts the major and minor version numbers. +// When Minimum is set, the major and minor parts must be greater or equal to the minimum +// or a validation error is returned. +#SemVer: { + // Input version string in strict semver format. + #Version!: string & =~"^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" + + // Minimum is the minimum allowed MAJOR.MINOR version. + #Minimum: *"0.0.0" | string & =~"^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" + + let minMajor = strconv.Atoi(strings.Split(#Minimum, ".")[0]) + let minMinor = strconv.Atoi(strings.Split(#Minimum, ".")[1]) + + major: int & >=minMajor + major: strconv.Atoi(strings.Split(#Version, ".")[0]) + + minor: int & >=minMinor + minor: strconv.Atoi(strings.Split(#Version, ".")[1]) +} diff --git a/examples/redis/debug_tool.cue b/examples/redis/debug_tool.cue index cdf74861..5181ff46 100644 --- a/examples/redis/debug_tool.cue +++ b/examples/redis/debug_tool.cue @@ -9,7 +9,7 @@ import ( _resources: timoni.apply.master + timoni.apply.replica + timoni.apply.test // The build command generates the Kubernetes manifests and prints the multi-docs YAML to stdout. -// Example 'cue cmd -t debug -t name=test -t namespace=test -t mv=1.0.0 -t kv=1.28.0 build'. +// Example 'cue cmd -t debug -t name=redis -t namespace=test -t mv=1.0.0 -t kv=1.28.0 build'. command: build: { task: print: cli.Print & { text: yaml.MarshalStream(_resources) @@ -17,7 +17,7 @@ command: build: { } // The ls command prints a table with the Kubernetes resources kind, namespace, name and version. -// Example 'cue cmd -t debug -t name=test -t namespace=test -t mv=1.0.0 -t kv=1.28.0 ls'. +// Example 'cue cmd -t debug -t name=redis -t namespace=test -t mv=1.0.0 -t kv=1.28.0 ls'. command: ls: { task: print: cli.Print & { text: tabwriter.Write([ diff --git a/examples/redis/debug_values.cue b/examples/redis/debug_values.cue index ed68106f..72a656c6 100644 --- a/examples/redis/debug_values.cue +++ b/examples/redis/debug_values.cue @@ -3,7 +3,7 @@ package main // Values used by debug_tool.cue. -// Debug example 'cue cmd -t debug -t name=test -t namespace=test -t mv=1.0.0 -t kv=1.28.0 build'. +// Debug example 'cue cmd -t debug -t name=redis -t namespace=test -t mv=1.0.0 -t kv=1.28.0 build'. values: { podAnnotations: "cluster-autoscaler.kubernetes.io/safe-to-evict": "true" image: { @@ -11,4 +11,5 @@ values: { tag: "7-alpine" digest: "" } + test: enabled: true } diff --git a/examples/redis/templates/config.cue b/examples/redis/templates/config.cue index 5e74057a..72783b9f 100644 --- a/examples/redis/templates/config.cue +++ b/examples/redis/templates/config.cue @@ -1,18 +1,35 @@ package templates import ( - "strings" - timoniv1 "timoni.sh/core/v1alpha1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" corev1 "k8s.io/api/core/v1" ) // Config defines the schema and defaults for the Instance values. #Config: { - // Runtime version info + // The kubeVersion is a required field, set at apply-time + // via timoni.cue by querying the user's Kubernetes API. + kubeVersion!: string + // Using the kubeVersion you can enforce a minimum Kubernetes minor version. + // By default, the minimum Kubernetes version is set to 1.20. + clusterVersion: timoniv1.#SemVer & {#Version: kubeVersion, #Minimum: "1.20.0"} + + // The moduleVersion is set from the user-supplied module version. + // This field is used for the `app.kubernetes.io/version` label. moduleVersion!: string - kubeVersion!: string + + // The Kubernetes metadata common to all resources. + // The `metadata.name` and `metadata.namespace` fields are + // set from the user-supplied instance name and namespace. + metadata: timoniv1.#Metadata & {#Version: moduleVersion} + + // The labels allows adding `metadata.labels` to all resources. + // The `app.kubernetes.io/name` and `app.kubernetes.io/version` labels + // are automatically generated and can't be overwritten. + metadata: labels: timoniv1.#Labels + + // The annotations allows adding `metadata.annotations` to all resources. + metadata: annotations?: timoniv1.#Annotations // Redis config maxmemory: *512 | int & >=64 @@ -24,20 +41,8 @@ import ( } password?: string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" - // Metadata (common to all resources) - metadata: metav1.#ObjectMeta - metadata: name: *"redis" | string & =~"^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$" & strings.MaxRunes(63) - metadata: namespace: *"default" | string & strings.MaxRunes(63) - metadata: labels: { - "app.kubernetes.io/version": image.tag - "app.kubernetes.io/part-of": metadata.name - } - metadata: annotations?: {[string]: string} - // Container image - image: timoniv1.#Image - imagePullPolicy: *"IfNotPresent" | string - + image: timoniv1.#Image imagePullSecrets?: [...corev1.LocalObjectReference] // Resource requirements @@ -45,6 +50,18 @@ import ( resources: requests: memory: *"64Mi" | string resources: limits: memory: *"\(maxmemory+32)Mi" | string + // The resources allows setting the container resource requirements. + // By default, each Redis container requests 100m CPU and 64Mi memory. + resources: timoniv1.#ResourceRequirements & { + requests: { + cpu: *"100m" | timoniv1.#CPUQuantity + memory: *"64Mi" | timoniv1.#MemoryQuantity + } + limits: { + memory: *"\(maxmemory+32)Mi" | timoniv1.#MemoryQuantity + } + } + // Security (common to all deployments) podSecurityContext: *{ fsGroup: 1001 @@ -78,8 +95,10 @@ import ( service: port: *6379 | int & >0 & <=65535 clusterDomain: "cluster.local" - // Test connection - test: *true | bool + // Test Job disabled by default. + test: { + enabled: *false | bool + } } // Instance takes the config values and outputs the Kubernetes objects. diff --git a/examples/redis/templates/master.deployment.cue b/examples/redis/templates/master.deployment.cue index 8f7a4544..8e0508ea 100644 --- a/examples/redis/templates/master.deployment.cue +++ b/examples/redis/templates/master.deployment.cue @@ -3,22 +3,19 @@ package templates import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + timoniv1 "timoni.sh/core/v1alpha1" ) #MasterDeployment: appsv1.#Deployment & { _config: #Config - _name: "\(_config.metadata.name)-master" - _selectorLabel: "app.kubernetes.io/name": _name + _selectorLabel: { + "\(timoniv1.#StdLabelName)": "\(_config.metadata.name)-master" + } apiVersion: "apps/v1" kind: "Deployment" - metadata: { - name: _name - namespace: _config.metadata.namespace - labels: _selectorLabel - labels: _config.metadata.labels - if _config.metadata.annotations != _|_ { - annotations: _config.metadata.annotations - } + metadata: timoniv1.#MetaComponent & { + #Meta: _config.metadata + #Component: "master" } spec: appsv1.#DeploymentSpec & { strategy: type: "Recreate" @@ -34,9 +31,9 @@ import ( serviceAccountName: _config.metadata.name containers: [ { - name: _config.metadata.name + name: "redis" image: _config.image.reference - imagePullPolicy: _config.imagePullPolicy + imagePullPolicy: _config.image.pullPolicy ports: [{ name: "redis" containerPort: 6379 @@ -84,10 +81,9 @@ import ( emptyDir: {} } if _config.persistence.enabled { - persistentVolumeClaim: claimName: _name + persistentVolumeClaim: claimName: "\(_config.metadata.name)-master" } }, - { name: "config" configMap: { diff --git a/examples/redis/templates/master.pvc.cue b/examples/redis/templates/master.pvc.cue index a9438dee..471f4635 100644 --- a/examples/redis/templates/master.pvc.cue +++ b/examples/redis/templates/master.pvc.cue @@ -2,19 +2,16 @@ package templates import ( corev1 "k8s.io/api/core/v1" + timoniv1 "timoni.sh/core/v1alpha1" ) #MasterPVC: corev1.#PersistentVolumeClaim & { _config: #Config apiVersion: "v1" kind: "PersistentVolumeClaim" - metadata: { - name: "\(_config.metadata.name)-master" - namespace: _config.metadata.namespace - labels: _config.metadata.labels - if _config.metadata.annotations != _|_ { - annotations: _config.metadata.annotations - } + metadata: timoniv1.#MetaComponent & { + #Meta: _config.metadata + #Component: "master" } spec: corev1.#PersistentVolumeClaimSpec & { storageClassName: _config.persistence.storageClass diff --git a/examples/redis/templates/master.service.cue b/examples/redis/templates/master.service.cue index e5ac7ee2..16064d61 100644 --- a/examples/redis/templates/master.service.cue +++ b/examples/redis/templates/master.service.cue @@ -2,22 +2,17 @@ package templates import ( corev1 "k8s.io/api/core/v1" + timoniv1 "timoni.sh/core/v1alpha1" ) #MasterService: corev1.#Service & { _config: #Config - _selectorLabel: "app.kubernetes.io/name": "\(_config.metadata.name)-master" + _selectorLabel: { + "\(timoniv1.#StdLabelName)": "\(_config.metadata.name)-master" + } apiVersion: "v1" kind: "Service" - metadata: { - name: _config.metadata.name - namespace: _config.metadata.namespace - labels: _selectorLabel - labels: _config.metadata.labels - if _config.metadata.annotations != _|_ { - annotations: _config.metadata.annotations - } - } + metadata: _config.metadata spec: corev1.#ServiceSpec & { type: corev1.#ServiceTypeClusterIP selector: _selectorLabel diff --git a/examples/redis/templates/replica.deployment.cue b/examples/redis/templates/replica.deployment.cue index 0ad728ff..123b4492 100644 --- a/examples/redis/templates/replica.deployment.cue +++ b/examples/redis/templates/replica.deployment.cue @@ -3,22 +3,19 @@ package templates import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + timoniv1 "timoni.sh/core/v1alpha1" ) #ReplicaDeployment: appsv1.#Deployment & { _config: #Config - _name: "\(_config.metadata.name)-replica" - _selectorLabel: "app.kubernetes.io/name": _name + _selectorLabel: { + "\(timoniv1.#StdLabelName)": "\(_config.metadata.name)-replica" + } apiVersion: "apps/v1" kind: "Deployment" - metadata: { - name: _name - namespace: _config.metadata.namespace - labels: _selectorLabel - labels: _config.metadata.labels - if _config.metadata.annotations != _|_ { - annotations: _config.metadata.annotations - } + metadata: timoniv1.#MetaComponent & { + #Meta: _config.metadata + #Component: "replica" } spec: appsv1.#DeploymentSpec & { strategy: type: "RollingUpdate" @@ -35,9 +32,9 @@ import ( serviceAccountName: _config.metadata.name containers: [ { - name: _config.metadata.name + name: "redis" image: _config.image.reference - imagePullPolicy: _config.imagePullPolicy + imagePullPolicy: _config.image.pullPolicy ports: [{ name: "redis" containerPort: 6379 diff --git a/examples/redis/templates/replica.service.cue b/examples/redis/templates/replica.service.cue index 8ee93c3d..4e4d53cf 100644 --- a/examples/redis/templates/replica.service.cue +++ b/examples/redis/templates/replica.service.cue @@ -2,21 +2,19 @@ package templates import ( corev1 "k8s.io/api/core/v1" + timoniv1 "timoni.sh/core/v1alpha1" ) #ReplicaService: corev1.#Service & { _config: #Config - _selectorLabel: "app.kubernetes.io/name": "\(_config.metadata.name)-replica" + _selectorLabel: { + "\(timoniv1.#StdLabelName)": "\(_config.metadata.name)-replica" + } apiVersion: "v1" kind: "Service" - metadata: { - name: "\(_config.metadata.name)-readonly" - namespace: _config.metadata.namespace - labels: _selectorLabel - labels: _config.metadata.labels - if _config.metadata.annotations != _|_ { - annotations: _config.metadata.annotations - } + metadata: timoniv1.#MetaComponent & { + #Meta: _config.metadata + #Component: "readonly" } spec: corev1.#ServiceSpec & { type: corev1.#ServiceTypeClusterIP diff --git a/examples/redis/templates/test.job.cue b/examples/redis/templates/test.job.cue index df467ba3..ce6861f8 100644 --- a/examples/redis/templates/test.job.cue +++ b/examples/redis/templates/test.job.cue @@ -13,21 +13,20 @@ import ( _config: #Config apiVersion: "batch/v1" kind: "Job" - metadata: { - name: "\(_config.metadata.name)-test" - namespace: _config.metadata.namespace - labels: _config.metadata.labels - annotations: timoniv1.Action.Force + metadata: timoniv1.#MetaComponent & { + #Meta: _config.metadata + #Component: "test" } + metadata: annotations: timoniv1.Action.Force spec: batchv1.#JobSpec & { template: corev1.#PodTemplateSpec & { - metadata: labels: _config.metadata.labels let _checksum = uuid.SHA1(uuid.ns.DNS, yaml.Marshal(_config)) metadata: annotations: "timoni.sh/checksum": "\(_checksum)" spec: { containers: [{ - name: "redis-cli" - image: _config.image.reference + name: "redis-cli" + image: _config.image.reference + imagePullPolicy: _config.image.pullPolicy command: [ "redis-cli", if _config.password != _|_ { diff --git a/examples/redis/timoni.cue b/examples/redis/timoni.cue index bd07e11e..9bf49fd9 100644 --- a/examples/redis/timoni.cue +++ b/examples/redis/timoni.cue @@ -45,7 +45,7 @@ timoni: { apply: replica: [for obj in instance.replica.objects {obj}] // Conditionally run tests after an install or upgrade. - if instance.config.test { + if instance.config.test.enabled { apply: test: [for obj in instance.test.objects {obj}] } } diff --git a/examples/redis/values.cue b/examples/redis/values.cue index a7469304..aa6eac4e 100644 --- a/examples/redis/values.cue +++ b/examples/redis/values.cue @@ -5,7 +5,7 @@ package main values: { image: { repository: "cgr.dev/chainguard/redis" - tag: "7.2.2" - digest: "sha256:44fb8de1c26cd2cd84fe6932075bdb47f11ad59d28ca14966d6228a0d5872d50" + tag: "7.2.3" + digest: "sha256:b7b6cb0fc4df5826ca1952faf55748fbd71aff1bd3150c54f24dd32ccc923fcd" } }