From 4e766ed82e5772fda14a5112a6ded6f41e73eedb Mon Sep 17 00:00:00 2001 From: Timofei Larkin Date: Wed, 8 Oct 2025 16:18:44 +0300 Subject: [PATCH] [api,platform] Decouple CozyRDs from API HR This commit patches the Cozystack API server to tolerate an absence of Cozystack Resource Definitions either registered as CRDs on the k8s API or simply as an absence of CozyRDs persisted to etcd. This decouples the upgrade of the CozyRD CRD from the upgrade of the Cozystack API. ```release-note [api,platform] Decouple the Cozystack API from the Cozystack Resource Definitions, allowing independent upgrades of either one and a more reliable migration from 0.36 to 0.37. ``` Signed-off-by: Timofei Larkin --- hack/update-crd.sh | 2 +- packages/core/platform/bundles/paas-full.yaml | 12 + .../core/platform/bundles/paas-hosted.yaml | 12 + .../Chart.yaml | 3 + .../Makefile | 4 + ...stack.io_cozystackresourcedefinitions.yaml | 680 ++++++++++++++++++ .../templates/crd.yaml | 2 + .../values.yaml | 1 + .../cozystack-resource-definitions/Chart.yaml | 3 + .../cozystack-resource-definitions/Makefile | 4 + .../cozyrds/bootbox.yaml | 0 .../cozyrds/bucket.yaml | 0 .../cozyrds/clickhouse.yaml | 0 .../cozyrds/etcd.yaml | 0 .../cozyrds/ferretdb.yaml | 0 .../cozyrds/http-cache.yaml | 0 .../cozyrds/info.yaml | 0 .../cozyrds/ingress.yaml | 0 .../cozyrds/kafka.yaml | 0 .../cozyrds/kubernetes.yaml | 0 .../cozyrds/monitoring.yaml | 0 .../cozyrds/mysql.yaml | 0 .../cozyrds/nats.yaml | 0 .../cozyrds/postgres.yaml | 0 .../cozyrds/rabbitmq.yaml | 0 .../cozyrds/redis.yaml | 0 .../cozyrds/seaweedfs.yaml | 0 .../cozyrds/tcp-balancer.yaml | 0 .../cozyrds/tenant.yaml | 0 .../cozyrds/virtual-machine.yaml | 0 .../cozyrds/vm-disk.yaml | 0 .../cozyrds/vm-instance.yaml | 0 .../cozyrds/vpn.yaml | 0 .../templates}/cozyrds.yaml | 0 .../values.yaml | 1 + pkg/cmd/server/openapi.go | 4 +- pkg/cmd/server/start.go | 30 +- 37 files changed, 753 insertions(+), 5 deletions(-) create mode 100644 packages/system/cozystack-resource-definition-crd/Chart.yaml create mode 100644 packages/system/cozystack-resource-definition-crd/Makefile create mode 100644 packages/system/cozystack-resource-definition-crd/definition/cozystack.io_cozystackresourcedefinitions.yaml create mode 100644 packages/system/cozystack-resource-definition-crd/templates/crd.yaml create mode 100644 packages/system/cozystack-resource-definition-crd/values.yaml create mode 100644 packages/system/cozystack-resource-definitions/Chart.yaml create mode 100644 packages/system/cozystack-resource-definitions/Makefile rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/bootbox.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/bucket.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/clickhouse.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/etcd.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/ferretdb.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/http-cache.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/info.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/ingress.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/kafka.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/kubernetes.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/monitoring.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/mysql.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/nats.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/postgres.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/rabbitmq.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/redis.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/seaweedfs.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/tcp-balancer.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/tenant.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/virtual-machine.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/vm-disk.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/vm-instance.yaml (100%) rename packages/system/{cozystack-api => cozystack-resource-definitions}/cozyrds/vpn.yaml (100%) rename packages/system/{cozystack-api/templates/cozystack-resource-definitions => cozystack-resource-definitions/templates}/cozyrds.yaml (100%) create mode 100644 packages/system/cozystack-resource-definitions/values.yaml diff --git a/hack/update-crd.sh b/hack/update-crd.sh index ab9a59b7..456bf842 100755 --- a/hack/update-crd.sh +++ b/hack/update-crd.sh @@ -8,7 +8,7 @@ need yq; need jq; need base64 CHART_YAML="${CHART_YAML:-Chart.yaml}" VALUES_YAML="${VALUES_YAML:-values.yaml}" SCHEMA_JSON="${SCHEMA_JSON:-values.schema.json}" -CRD_DIR="../../system/cozystack-api/cozyrds" +CRD_DIR="../../system/cozystack-resource-definitions/cozyrds" [[ -f "$CHART_YAML" ]] || { echo "No $CHART_YAML found"; exit 1; } [[ -f "$SCHEMA_JSON" ]] || { echo "No $SCHEMA_JSON found"; exit 1; } diff --git a/packages/core/platform/bundles/paas-full.yaml b/packages/core/platform/bundles/paas-full.yaml index 2343e97e..f4274eda 100644 --- a/packages/core/platform/bundles/paas-full.yaml +++ b/packages/core/platform/bundles/paas-full.yaml @@ -105,6 +105,18 @@ releases: disableTelemetry: true {{- end }} +- name: cozystack-resource-definition-crd + releaseName: cozystack-resource-definition-crd + chart: cozystack-resource-definition-crd + namespace: cozy-system + dependsOn: [cilium,kubeovn,cozystack-api,cozystack-controller] + +- name: cozystack-resource-definitions + releaseName: cozystack-resource-definitions + chart: cozystack-resource-definitions + namespace: cozy-system + dependsOn: [cilium,kubeovn,cozystack-api,cozystack-controller,cozystack-resource-definition-crd] + - name: cert-manager releaseName: cert-manager chart: cozy-cert-manager diff --git a/packages/core/platform/bundles/paas-hosted.yaml b/packages/core/platform/bundles/paas-hosted.yaml index 710dd439..5526d2a7 100644 --- a/packages/core/platform/bundles/paas-hosted.yaml +++ b/packages/core/platform/bundles/paas-hosted.yaml @@ -52,6 +52,18 @@ releases: disableTelemetry: true {{- end }} +- name: cozystack-resource-definition-crd + releaseName: cozystack-resource-definition-crd + chart: cozystack-resource-definition-crd + namespace: cozy-system + dependsOn: [cozystack-api,cozystack-controller] + +- name: cozystack-resource-definitions + releaseName: cozystack-resource-definitions + chart: cozystack-resource-definitions + namespace: cozy-system + dependsOn: [cozystack-api,cozystack-controller,cozystack-resource-definition-crd] + - name: cert-manager releaseName: cert-manager chart: cozy-cert-manager diff --git a/packages/system/cozystack-resource-definition-crd/Chart.yaml b/packages/system/cozystack-resource-definition-crd/Chart.yaml new file mode 100644 index 00000000..9924c7fa --- /dev/null +++ b/packages/system/cozystack-resource-definition-crd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: cozystack-resource-definition-crd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/cozystack-resource-definition-crd/Makefile b/packages/system/cozystack-resource-definition-crd/Makefile new file mode 100644 index 00000000..ddb24aef --- /dev/null +++ b/packages/system/cozystack-resource-definition-crd/Makefile @@ -0,0 +1,4 @@ +export NAME=cozystack-resource-definition-crd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/cozystack-resource-definition-crd/definition/cozystack.io_cozystackresourcedefinitions.yaml b/packages/system/cozystack-resource-definition-crd/definition/cozystack.io_cozystackresourcedefinitions.yaml new file mode 100644 index 00000000..685d4ac5 --- /dev/null +++ b/packages/system/cozystack-resource-definition-crd/definition/cozystack.io_cozystackresourcedefinitions.yaml @@ -0,0 +1,680 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: cozystackresourcedefinitions.cozystack.io +spec: + group: cozystack.io + names: + kind: CozystackResourceDefinition + listKind: CozystackResourceDefinitionList + plural: cozystackresourcedefinitions + singular: cozystackresourcedefinition + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: CozystackResourceDefinition is the Schema for the cozystackresourcedefinitions + API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + application: + description: Application configuration + properties: + kind: + description: Kind of the application, used for UI and API + type: string + openAPISchema: + description: OpenAPI schema for the application, used for API + validation + type: string + plural: + description: Plural name of the application, used for UI and API + type: string + singular: + description: Singular name of the application, used for UI and + API + type: string + required: + - kind + - openAPISchema + - plural + - singular + type: object + dashboard: + description: Dashboard configuration for this resource + properties: + category: + description: Category used to group resources in the UI (e.g., + "Storage", "Networking") + type: string + description: + description: Short description shown in catalogs or headers (e.g., + "S3 compatible storage") + type: string + icon: + description: Icon encoded as a string (e.g., inline SVG, base64, + or data URI) + type: string + keysOrder: + description: Order of keys in the YAML view + items: + items: + type: string + type: array + type: array + module: + description: Whether this resource is a module (tenant module) + type: boolean + name: + description: Hard-coded name used in the UI (e.g., "bucket") + type: string + plural: + description: Plural human-readable name (e.g., "Buckets") + type: string + singular: + description: Human-readable name shown in the UI (e.g., "Bucket") + type: string + singularResource: + description: Whether this resource is singular (not a collection) + in the UI + type: boolean + tabs: + description: Which tabs to show for this resource + items: + description: DashboardTab enumerates allowed UI tabs. + enum: + - workloads + - ingresses + - services + - secrets + - yaml + type: string + type: array + tags: + description: Free-form tags for search and filtering + items: + type: string + type: array + weight: + description: Order weight for sorting resources in the UI (lower + first) + type: integer + required: + - category + - plural + - singular + type: object + ingresses: + description: Ingress selectors + properties: + exclude: + description: |- + Exclude contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, it is + hidden from the user, regardless of the matches in the include array. + items: + description: |- + CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. + A resource matches this selector only if it satisfies ALL criteria: + - Label selector conditions (matchExpressions and matchLabels) + - AND has a name that matches one of the names in resourceNames (if specified) + + The resourceNames field supports Go templates with the following variables available: + - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) + - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) + - {{ .namespace }}: The namespace of the resource being processed + + Example YAML: + secrets: + include: + - matchExpressions: + - key: badlabel + operator: DoesNotExist + matchLabels: + goodlabel: goodvalue + resourceNames: + - "{{ .name }}-secret" + - "{{ .kind }}-{{ .name }}-tls" + - "specificname" + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + include: + description: |- + Include contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, and + matches none of the selectors in the exclude array that resource is marked + as a tenant resource and is visible to users. + items: + description: |- + CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. + A resource matches this selector only if it satisfies ALL criteria: + - Label selector conditions (matchExpressions and matchLabels) + - AND has a name that matches one of the names in resourceNames (if specified) + + The resourceNames field supports Go templates with the following variables available: + - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) + - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) + - {{ .namespace }}: The namespace of the resource being processed + + Example YAML: + secrets: + include: + - matchExpressions: + - key: badlabel + operator: DoesNotExist + matchLabels: + goodlabel: goodvalue + resourceNames: + - "{{ .name }}-secret" + - "{{ .kind }}-{{ .name }}-tls" + - "specificname" + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + type: object + release: + description: Release configuration + properties: + chart: + description: Helm chart configuration + properties: + name: + description: Name of the Helm chart + type: string + sourceRef: + description: Source reference for the Helm chart + properties: + kind: + default: HelmRepository + description: Kind of the source reference + type: string + name: + description: Name of the source reference + type: string + namespace: + default: cozy-public + description: Namespace of the source reference + type: string + required: + - kind + - name + - namespace + type: object + required: + - name + - sourceRef + type: object + labels: + additionalProperties: + type: string + description: Labels for the release + type: object + prefix: + description: Prefix for the release name + type: string + required: + - chart + - prefix + type: object + secrets: + description: Secret selectors + properties: + exclude: + description: |- + Exclude contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, it is + hidden from the user, regardless of the matches in the include array. + items: + description: |- + CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. + A resource matches this selector only if it satisfies ALL criteria: + - Label selector conditions (matchExpressions and matchLabels) + - AND has a name that matches one of the names in resourceNames (if specified) + + The resourceNames field supports Go templates with the following variables available: + - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) + - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) + - {{ .namespace }}: The namespace of the resource being processed + + Example YAML: + secrets: + include: + - matchExpressions: + - key: badlabel + operator: DoesNotExist + matchLabels: + goodlabel: goodvalue + resourceNames: + - "{{ .name }}-secret" + - "{{ .kind }}-{{ .name }}-tls" + - "specificname" + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + include: + description: |- + Include contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, and + matches none of the selectors in the exclude array that resource is marked + as a tenant resource and is visible to users. + items: + description: |- + CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. + A resource matches this selector only if it satisfies ALL criteria: + - Label selector conditions (matchExpressions and matchLabels) + - AND has a name that matches one of the names in resourceNames (if specified) + + The resourceNames field supports Go templates with the following variables available: + - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) + - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) + - {{ .namespace }}: The namespace of the resource being processed + + Example YAML: + secrets: + include: + - matchExpressions: + - key: badlabel + operator: DoesNotExist + matchLabels: + goodlabel: goodvalue + resourceNames: + - "{{ .name }}-secret" + - "{{ .kind }}-{{ .name }}-tls" + - "specificname" + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + type: object + services: + description: Service selectors + properties: + exclude: + description: |- + Exclude contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, it is + hidden from the user, regardless of the matches in the include array. + items: + description: |- + CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. + A resource matches this selector only if it satisfies ALL criteria: + - Label selector conditions (matchExpressions and matchLabels) + - AND has a name that matches one of the names in resourceNames (if specified) + + The resourceNames field supports Go templates with the following variables available: + - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) + - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) + - {{ .namespace }}: The namespace of the resource being processed + + Example YAML: + secrets: + include: + - matchExpressions: + - key: badlabel + operator: DoesNotExist + matchLabels: + goodlabel: goodvalue + resourceNames: + - "{{ .name }}-secret" + - "{{ .kind }}-{{ .name }}-tls" + - "specificname" + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + include: + description: |- + Include contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, and + matches none of the selectors in the exclude array that resource is marked + as a tenant resource and is visible to users. + items: + description: |- + CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. + A resource matches this selector only if it satisfies ALL criteria: + - Label selector conditions (matchExpressions and matchLabels) + - AND has a name that matches one of the names in resourceNames (if specified) + + The resourceNames field supports Go templates with the following variables available: + - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) + - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) + - {{ .namespace }}: The namespace of the resource being processed + + Example YAML: + secrets: + include: + - matchExpressions: + - key: badlabel + operator: DoesNotExist + matchLabels: + goodlabel: goodvalue + resourceNames: + - "{{ .name }}-secret" + - "{{ .kind }}-{{ .name }}-tls" + - "specificname" + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + type: object + required: + - application + - release + type: object + type: object + served: true + storage: true diff --git a/packages/system/cozystack-resource-definition-crd/templates/crd.yaml b/packages/system/cozystack-resource-definition-crd/templates/crd.yaml new file mode 100644 index 00000000..40a93ad3 --- /dev/null +++ b/packages/system/cozystack-resource-definition-crd/templates/crd.yaml @@ -0,0 +1,2 @@ +--- +{{ .Files.Get "definition/cozystack.io_cozystackresourcedefinitions.yaml" }} diff --git a/packages/system/cozystack-resource-definition-crd/values.yaml b/packages/system/cozystack-resource-definition-crd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/cozystack-resource-definition-crd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/cozystack-resource-definitions/Chart.yaml b/packages/system/cozystack-resource-definitions/Chart.yaml new file mode 100644 index 00000000..39cb9431 --- /dev/null +++ b/packages/system/cozystack-resource-definitions/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: cozystack-resource-definitions +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/cozystack-resource-definitions/Makefile b/packages/system/cozystack-resource-definitions/Makefile new file mode 100644 index 00000000..00e8bece --- /dev/null +++ b/packages/system/cozystack-resource-definitions/Makefile @@ -0,0 +1,4 @@ +export NAME=cozystack-resource-definitions +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/cozystack-api/cozyrds/bootbox.yaml b/packages/system/cozystack-resource-definitions/cozyrds/bootbox.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/bootbox.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/bootbox.yaml diff --git a/packages/system/cozystack-api/cozyrds/bucket.yaml b/packages/system/cozystack-resource-definitions/cozyrds/bucket.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/bucket.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/bucket.yaml diff --git a/packages/system/cozystack-api/cozyrds/clickhouse.yaml b/packages/system/cozystack-resource-definitions/cozyrds/clickhouse.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/clickhouse.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/clickhouse.yaml diff --git a/packages/system/cozystack-api/cozyrds/etcd.yaml b/packages/system/cozystack-resource-definitions/cozyrds/etcd.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/etcd.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/etcd.yaml diff --git a/packages/system/cozystack-api/cozyrds/ferretdb.yaml b/packages/system/cozystack-resource-definitions/cozyrds/ferretdb.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/ferretdb.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/ferretdb.yaml diff --git a/packages/system/cozystack-api/cozyrds/http-cache.yaml b/packages/system/cozystack-resource-definitions/cozyrds/http-cache.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/http-cache.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/http-cache.yaml diff --git a/packages/system/cozystack-api/cozyrds/info.yaml b/packages/system/cozystack-resource-definitions/cozyrds/info.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/info.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/info.yaml diff --git a/packages/system/cozystack-api/cozyrds/ingress.yaml b/packages/system/cozystack-resource-definitions/cozyrds/ingress.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/ingress.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/ingress.yaml diff --git a/packages/system/cozystack-api/cozyrds/kafka.yaml b/packages/system/cozystack-resource-definitions/cozyrds/kafka.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/kafka.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/kafka.yaml diff --git a/packages/system/cozystack-api/cozyrds/kubernetes.yaml b/packages/system/cozystack-resource-definitions/cozyrds/kubernetes.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/kubernetes.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/kubernetes.yaml diff --git a/packages/system/cozystack-api/cozyrds/monitoring.yaml b/packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/monitoring.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml diff --git a/packages/system/cozystack-api/cozyrds/mysql.yaml b/packages/system/cozystack-resource-definitions/cozyrds/mysql.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/mysql.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/mysql.yaml diff --git a/packages/system/cozystack-api/cozyrds/nats.yaml b/packages/system/cozystack-resource-definitions/cozyrds/nats.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/nats.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/nats.yaml diff --git a/packages/system/cozystack-api/cozyrds/postgres.yaml b/packages/system/cozystack-resource-definitions/cozyrds/postgres.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/postgres.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/postgres.yaml diff --git a/packages/system/cozystack-api/cozyrds/rabbitmq.yaml b/packages/system/cozystack-resource-definitions/cozyrds/rabbitmq.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/rabbitmq.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/rabbitmq.yaml diff --git a/packages/system/cozystack-api/cozyrds/redis.yaml b/packages/system/cozystack-resource-definitions/cozyrds/redis.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/redis.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/redis.yaml diff --git a/packages/system/cozystack-api/cozyrds/seaweedfs.yaml b/packages/system/cozystack-resource-definitions/cozyrds/seaweedfs.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/seaweedfs.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/seaweedfs.yaml diff --git a/packages/system/cozystack-api/cozyrds/tcp-balancer.yaml b/packages/system/cozystack-resource-definitions/cozyrds/tcp-balancer.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/tcp-balancer.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/tcp-balancer.yaml diff --git a/packages/system/cozystack-api/cozyrds/tenant.yaml b/packages/system/cozystack-resource-definitions/cozyrds/tenant.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/tenant.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/tenant.yaml diff --git a/packages/system/cozystack-api/cozyrds/virtual-machine.yaml b/packages/system/cozystack-resource-definitions/cozyrds/virtual-machine.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/virtual-machine.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/virtual-machine.yaml diff --git a/packages/system/cozystack-api/cozyrds/vm-disk.yaml b/packages/system/cozystack-resource-definitions/cozyrds/vm-disk.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/vm-disk.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/vm-disk.yaml diff --git a/packages/system/cozystack-api/cozyrds/vm-instance.yaml b/packages/system/cozystack-resource-definitions/cozyrds/vm-instance.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/vm-instance.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/vm-instance.yaml diff --git a/packages/system/cozystack-api/cozyrds/vpn.yaml b/packages/system/cozystack-resource-definitions/cozyrds/vpn.yaml similarity index 100% rename from packages/system/cozystack-api/cozyrds/vpn.yaml rename to packages/system/cozystack-resource-definitions/cozyrds/vpn.yaml diff --git a/packages/system/cozystack-api/templates/cozystack-resource-definitions/cozyrds.yaml b/packages/system/cozystack-resource-definitions/templates/cozyrds.yaml similarity index 100% rename from packages/system/cozystack-api/templates/cozystack-resource-definitions/cozyrds.yaml rename to packages/system/cozystack-resource-definitions/templates/cozyrds.yaml diff --git a/packages/system/cozystack-resource-definitions/values.yaml b/packages/system/cozystack-resource-definitions/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/cozystack-resource-definitions/values.yaml @@ -0,0 +1 @@ +{} diff --git a/pkg/cmd/server/openapi.go b/pkg/cmd/server/openapi.go index aade9a80..e6a659c5 100644 --- a/pkg/cmd/server/openapi.go +++ b/pkg/cmd/server/openapi.go @@ -224,7 +224,7 @@ func buildPostProcessV3(kindSchemas map[string]string) func(*spec3.OpenAPI) (*sp base, ok1 := doc.Components.Schemas[baseRef] list, ok2 := doc.Components.Schemas[baseListRef] stat, ok3 := doc.Components.Schemas[baseStatusRef] - if !(ok1 && ok2 && ok3) { + if !(ok1 && ok2 && ok3) && len(kindSchemas) > 0 { return doc, fmt.Errorf("base Application* schemas not found") } @@ -339,7 +339,7 @@ func buildPostProcessV2(kindSchemas map[string]string) func(*spec.Swagger) (*spe base, ok1 := defs[baseRef] list, ok2 := defs[baseListRef] stat, ok3 := defs[baseStatusRef] - if !(ok1 && ok2 && ok3) { + if !(ok1 && ok2 && ok3) && len(kindSchemas) > 0 { return sw, fmt.Errorf("base Application* schemas not found") } diff --git a/pkg/cmd/server/start.go b/pkg/cmd/server/start.go index 25449ece..c6fd23a1 100644 --- a/pkg/cmd/server/start.go +++ b/pkg/cmd/server/start.go @@ -24,6 +24,7 @@ import ( "fmt" "io" "net" + "time" v1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" appsv1alpha1 "github.com/cozystack/cozystack/pkg/apis/apps/v1alpha1" @@ -161,8 +162,33 @@ func (o *CozyServerOptions) Complete() error { crdList := &v1alpha1.CozystackResourceDefinitionList{} - if err := o.Client.List(context.Background(), crdList); err != nil { - return fmt.Errorf("failed to list CozystackResourceDefinitions: %w", err) + // Retry with exponential backoff for at least 30 minutes + const maxRetryDuration = 30 * time.Minute + const initialDelay = time.Second + const maxDelay = 2 * time.Minute + + startTime := time.Now() + delay := initialDelay + + for { + err := o.Client.List(context.Background(), crdList) + if err == nil { + break + } + + // Check if we've exceeded the maximum retry duration + if time.Since(startTime) >= maxRetryDuration { + return fmt.Errorf("failed to list CozystackResourceDefinitions after %v: %w", maxRetryDuration, err) + } + + // Log the error and wait before retrying + fmt.Printf("Failed to list CozystackResourceDefinitions (retrying in %v): %v\n", delay, err) + time.Sleep(delay) + + delay = time.Duration(float64(delay) * 1.5) + if delay > maxDelay { + delay = maxDelay + } } // Convert to ResourceConfig