diff --git a/.github/workflows/backport.yaml b/.github/workflows/backport.yaml index 10968e38..ed427827 100644 --- a/.github/workflows/backport.yaml +++ b/.github/workflows/backport.yaml @@ -2,7 +2,7 @@ name: Automatic Backport on: pull_request_target: - types: [closed] # fires when PR is closed (merged) + types: [closed, labeled] # fires when PR is closed (merged) or labeled concurrency: group: backport-${{ github.workflow }}-${{ github.event.pull_request.number }} @@ -13,22 +13,46 @@ permissions: pull-requests: write jobs: - backport: + # Determine which backports are needed + prepare: if: | github.event.pull_request.merged == true && - contains(github.event.pull_request.labels.*.name, 'backport') + ( + contains(github.event.pull_request.labels.*.name, 'backport') || + contains(github.event.pull_request.labels.*.name, 'backport-previous') || + (github.event.action == 'labeled' && (github.event.label.name == 'backport' || github.event.label.name == 'backport-previous')) + ) runs-on: [self-hosted] - + outputs: + backport_current: ${{ steps.labels.outputs.backport }} + backport_previous: ${{ steps.labels.outputs.backport_previous }} + current_branch: ${{ steps.branches.outputs.current_branch }} + previous_branch: ${{ steps.branches.outputs.previous_branch }} steps: - # 1. Decide which maintenance branch should receive the back‑port - - name: Determine target maintenance branch - id: target + - name: Check which labels are present + id: labels uses: actions/github-script@v7 with: script: | - let rel; + const pr = context.payload.pull_request; + const labels = pr.labels.map(l => l.name); + const isBackport = labels.includes('backport'); + const isBackportPrevious = labels.includes('backport-previous'); + + core.setOutput('backport', isBackport ? 'true' : 'false'); + core.setOutput('backport_previous', isBackportPrevious ? 'true' : 'false'); + + console.log(`backport label: ${isBackport}, backport-previous label: ${isBackportPrevious}`); + + - name: Determine target branches + id: branches + uses: actions/github-script@v7 + with: + script: | + // Get latest release + let latestRelease; try { - rel = await github.rest.repos.getLatestRelease({ + latestRelease = await github.rest.repos.getLatestRelease({ owner: context.repo.owner, repo: context.repo.repo }); @@ -36,18 +60,70 @@ jobs: core.setFailed('No existing releases found; cannot determine backport target.'); return; } - const [maj, min] = rel.data.tag_name.replace(/^v/, '').split('.'); - const branch = `release-${maj}.${min}`; - core.setOutput('branch', branch); - console.log(`Latest release ${rel.data.tag_name}; backporting to ${branch}`); + + const [maj, min] = latestRelease.data.tag_name.replace(/^v/, '').split('.'); + const currentBranch = `release-${maj}.${min}`; + const prevMin = parseInt(min) - 1; + const previousBranch = prevMin >= 0 ? `release-${maj}.${prevMin}` : ''; + + core.setOutput('current_branch', currentBranch); + core.setOutput('previous_branch', previousBranch); + + console.log(`Current branch: ${currentBranch}, Previous branch: ${previousBranch || 'N/A'}`); + + // Verify previous branch exists if we need it + if (previousBranch && '${{ steps.labels.outputs.backport_previous }}' === 'true') { + try { + await github.rest.repos.getBranch({ + owner: context.repo.owner, + repo: context.repo.repo, + branch: previousBranch + }); + console.log(`Previous branch ${previousBranch} exists`); + } catch (e) { + core.setFailed(`Previous branch ${previousBranch} does not exist.`); + return; + } + } + + backport: + needs: prepare + if: | + github.event.pull_request.merged == true && + (needs.prepare.outputs.backport_current == 'true' || needs.prepare.outputs.backport_previous == 'true') + runs-on: [self-hosted] + strategy: + matrix: + backport_type: [current, previous] + steps: + # 1. Determine target branch based on matrix + - name: Set target branch + id: target + if: | + (matrix.backport_type == 'current' && needs.prepare.outputs.backport_current == 'true') || + (matrix.backport_type == 'previous' && needs.prepare.outputs.backport_previous == 'true') + run: | + if [ "${{ matrix.backport_type }}" == "current" ]; then + echo "branch=${{ needs.prepare.outputs.current_branch }}" >> $GITHUB_OUTPUT + echo "Target branch: ${{ needs.prepare.outputs.current_branch }}" + else + echo "branch=${{ needs.prepare.outputs.previous_branch }}" >> $GITHUB_OUTPUT + echo "Target branch: ${{ needs.prepare.outputs.previous_branch }}" + fi + # 2. Checkout (required by backport‑action) - name: Checkout repository + if: steps.target.outcome == 'success' uses: actions/checkout@v4 # 3. Create the back‑port pull request - name: Create back‑port PR - uses: korthout/backport-action@v3 + id: backport + if: steps.target.outcome == 'success' + uses: korthout/backport-action@v3.2.1 with: github_token: ${{ secrets.GITHUB_TOKEN }} label_pattern: '' # don't read labels for targets target_branches: ${{ steps.target.outputs.branch }} + merge_commits: skip + conflict_resolution: draft_commit_conflicts diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 685d41fe..ef1ce088 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -28,7 +28,7 @@ jobs: - name: Install generate run: | - curl -sSL https://github.com/cozystack/cozyvalues-gen/releases/download/v1.0.5/cozyvalues-gen-linux-amd64.tar.gz | tar -xzvf- -C /usr/local/bin/ cozyvalues-gen + curl -sSL https://github.com/cozystack/cozyvalues-gen/releases/download/v1.0.6/cozyvalues-gen-linux-amd64.tar.gz | tar -xzvf- -C /usr/local/bin/ cozyvalues-gen - name: Run pre-commit hooks run: | diff --git a/Makefile b/Makefile index 2038ff9f..718ef04f 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,9 @@ build: build-deps make -C packages/extra/monitoring image make -C packages/system/cozystack-api image make -C packages/system/cozystack-controller image + make -C packages/system/backup-controller image make -C packages/system/lineage-controller-webhook image make -C packages/system/cilium image - make -C packages/system/kubeovn image make -C packages/system/kubeovn-webhook image make -C packages/system/kubeovn-plunger image make -C packages/system/dashboard image diff --git a/api/.gitattributes b/api/.gitattributes new file mode 100644 index 00000000..39e882c9 --- /dev/null +++ b/api/.gitattributes @@ -0,0 +1 @@ +zz_generated_deepcopy.go linguist-generated diff --git a/api/backups/v1alpha1/DESIGN.md b/api/backups/v1alpha1/DESIGN.md new file mode 100644 index 00000000..455dab59 --- /dev/null +++ b/api/backups/v1alpha1/DESIGN.md @@ -0,0 +1,421 @@ +# Cozystack Backups – Core API & Contracts (Draft) + +## 1. Overview + +Cozystack’s backup subsystem provides a generic, composable way to back up and restore managed applications: + +* Every **application instance** can have one or more **backup plans**. +* Backups are stored in configurable **storage locations**. +* The mechanics of *how* a backup/restore is performed are delegated to **strategy drivers**, each implementing driver-specific **BackupStrategy** CRDs. + +The core API: + +* Orchestrates **when** backups happen and **where** they’re stored. +* Tracks **what** backups exist and their status. +* Defines contracts with drivers via shared resources (`BackupJob`, `Backup`, `RestoreJob`). + +It does **not** implement the backup logic itself. + +This document covers only the **core** API and its contracts with drivers, not driver implementations. + +--- + +## 2. Goals and non-goals + +### Goals + +* Provide a **stable core API** for: + + * Declaring **backup plans** per application. + * Configuring **storage targets** (S3, in-cluster bucket, etc.). + * Tracking **backup artifacts**. + * Initiating and tracking **restores**. +* Allow multiple **strategy drivers** to plug in, each supporting specific kinds of applications and strategies. +* Let application/product authors implement backup for their kinds by: + + * Creating **Plan** objects referencing a **driver-specific strategy**. + * Not having to write a backup engine themselves. + +### Non-goals + +* Implement backup logic for any specific application or storage backend. +* Define the internal structure of driver-specific strategy CRDs. +* Handle tenant-facing UI/UX (that’s built on top of these APIs). + +--- + +## 3. Architecture + +High-level components: + +* **Core backups controller(s)** (Cozystack-owned): + + * Group: `backups.cozystack.io` + * Own: + + * `Plan` + * `BackupJob` + * `Backup` + * `RestoreJob` + * Responsibilities: + + * Schedule backups based on `Plan`. + * Create `BackupJob` objects when due. + * Provide stable contracts for drivers to: + + * Perform backups and create `Backup`s. + * Perform restores based on `Backup`s. + +* **Strategy drivers** (pluggable, possibly third-party): + + * Their own API groups, e.g. `jobdriver.backups.cozystack.io`. + * Own **strategy CRDs** (e.g. `JobBackupStrategy`). + * Implement controllers that: + + * Watch `BackupJob` / `RestoreJob`. + * Match runs whose `strategyRef` GVK they support. + * Execute backup/restore logic. + * Create and update `Backup` and run statuses. + +Strategy drivers and core communicate entirely via Kubernetes objects; there are no webhook/HTTP calls between them. + +* **Storage drivers** (pluggable, possibly third-party): + + * **TBD** + +--- + +## 4. Core API resources + +### 4.1 Plan + +**Group/Kind** +`backups.cozystack.io/v1alpha1, Kind=Plan` + +**Purpose** +Describe **when**, **how**, and **where** to back up a specific managed application. + +**Key fields (spec)** + +```go +type PlanSpec struct { + // Application to back up. + ApplicationRef corev1.TypedLocalObjectReference `json:"applicationRef"` + + // Where backups should be stored. + StorageRef corev1.TypedLocalObjectReference `json:"storageRef"` + + // Driver-specific BackupStrategy to use. + StrategyRef corev1.TypedLocalObjectReference `json:"strategyRef"` + + // When backups should run. + Schedule PlanSchedule `json:"schedule"` +} +``` + +`PlanSchedule` (initially) supports only cron: + +```go +type PlanScheduleType string + +const ( + PlanScheduleTypeEmpty PlanScheduleType = "" + PlanScheduleTypeCron PlanScheduleType = "cron" +) +``` + +```go +type PlanSchedule struct { + // Type is the schedule type. Currently only "cron" is supported. + // Defaults to "cron". + Type PlanScheduleType `json:"type,omitempty"` + + // Cron expression (required for cron type). + Cron string `json:"cron,omitempty"` +} +``` + +**Plan reconciliation contract** + +Core Plan controller: + +1. **Read schedule** from `spec.schedule` and compute the next fire time. +2. When due: + + * Create a `BackupJob` in the same namespace: + + * `spec.planRef.name = plan.Name` + * `spec.applicationRef = plan.spec.applicationRef` + * `spec.storageRef = plan.spec.storageRef` + * `spec.strategyRef = plan.spec.strategyRef` + * `spec.triggeredBy = "Plan"` + * Set `ownerReferences` so the `BackupJob` is owned by the `Plan`. + +The Plan controller does **not**: + +* Execute backups itself. +* Modify driver resources or `Backup` objects. +* Touch `BackupJob.spec` after creation. + +--- + +### 4.2 Storage + +**API Shape** + +TBD + +**Storage usage** + +* `Plan` and `BackupJob` reference `Storage` via `TypedLocalObjectReference`. +* Drivers read `Storage` to know how/where to store or read artifacts. +* Core treats `Storage` spec as opaque; it does not directly talk to S3 or buckets. + +--- + +### 4.3 BackupJob + +**Group/Kind** +`backups.cozystack.io/v1alpha1, Kind=BackupJob` + +**Purpose** +Represent a single **execution** of a backup operation, typically created when a `Plan` fires or when a user triggers an ad-hoc backup. + +**Key fields (spec)** + +```go +type BackupJobSpec struct { + // Plan that triggered this run, if any. + PlanRef *corev1.LocalObjectReference `json:"planRef,omitempty"` + + // Application to back up. + ApplicationRef corev1.TypedLocalObjectReference `json:"applicationRef"` + + // Storage to use. + StorageRef corev1.TypedLocalObjectReference `json:"storageRef"` + + // Driver-specific BackupStrategy to use. + StrategyRef corev1.TypedLocalObjectReference `json:"strategyRef"` + + // Informational: what triggered this run ("Plan", "Manual", etc.). + TriggeredBy string `json:"triggeredBy,omitempty"` +} +``` + +**Key fields (status)** + +```go +type BackupJobStatus struct { + Phase BackupJobPhase `json:"phase,omitempty"` + BackupRef *corev1.LocalObjectReference `json:"backupRef,omitempty"` + StartedAt *metav1.Time `json:"startedAt,omitempty"` + CompletedAt *metav1.Time `json:"completedAt,omitempty"` + Message string `json:"message,omitempty"` + Conditions []metav1.Condition `json:"conditions,omitempty"` +} +``` + +`BackupJobPhase` is one of: `Pending`, `Running`, `Succeeded`, `Failed`. + +**BackupJob contract with drivers** + +* Core **creates** `BackupJob` and must treat `spec` as immutable afterwards. +* Each driver controller: + + * Watches `BackupJob`. + * Reconciles runs where `spec.strategyRef.apiGroup/kind` matches its **strategy type(s)**. +* Driver responsibilities: + + 1. On first reconcile: + + * Set `status.startedAt` if unset. + * Set `status.phase = Running`. + 2. Resolve inputs: + + * Read `Strategy` (driver-owned CRD), `Storage`, `Application`, optionally `Plan`. + 3. Execute backup logic (implementation-specific). + 4. On success: + + * Create a `Backup` resource (see below). + * Set `status.backupRef` to the created `Backup`. + * Set `status.completedAt`. + * Set `status.phase = Succeeded`. + 5. On failure: + + * Set `status.completedAt`. + * Set `status.phase = Failed`. + * Set `status.message` and conditions. + +Drivers must **not** modify `BackupJob.spec` or delete `BackupJob` themselves. + +--- + +### 4.4 Backup + +**Group/Kind** +`backups.cozystack.io/v1alpha1, Kind=Backup` + +**Purpose** +Represent a single **backup artifact** for a given application, decoupled from a particular run. usable as a stable, listable “thing you can restore from”. + +**Key fields (spec)** + +```go +type BackupSpec struct { + ApplicationRef corev1.TypedLocalObjectReference `json:"applicationRef"` + PlanRef *corev1.LocalObjectReference `json:"planRef,omitempty"` + StorageRef corev1.TypedLocalObjectReference `json:"storageRef"` + StrategyRef corev1.TypedLocalObjectReference `json:"strategyRef"` + TakenAt metav1.Time `json:"takenAt"` + DriverMetadata map[string]string `json:"driverMetadata,omitempty"` +} +``` + +**Key fields (status)** + +```go +type BackupStatus struct { + Phase BackupPhase `json:"phase,omitempty"` // Pending, Ready, Failed, etc. + Artifact *BackupArtifact `json:"artifact,omitempty"` + Conditions []metav1.Condition `json:"conditions,omitempty"` +} +``` + +`BackupArtifact` describes the artifact (URI, size, checksum). + +**Backup contract with drivers** + +* On successful completion of a `BackupJob`, the **driver**: + + * Creates a `Backup` in the same namespace (typically owned by the `BackupJob`). + * Populates `spec` fields with: + + * The application, storage, strategy references. + * `takenAt`. + * Optional `driverMetadata`. + * Sets `status` with: + + * `phase = Ready` (or equivalent when fully usable). + * `artifact` describing the stored object. +* Core: + + * Treats `Backup` spec as mostly immutable and opaque. + * Uses it to: + + * List backups for a given application/plan. + * Anchor `RestoreJob` operations. + * Implement higher-level policies (retention) if needed. + +--- + +### 4.5 RestoreJob + +**Group/Kind** +`backups.cozystack.io/v1alpha1, Kind=RestoreJob` + +**Purpose** +Represent a single **restore operation** from a `Backup`, either back into the same application or into a new target application. + +**Key fields (spec)** + +```go +type RestoreJobSpec struct { + // Backup to restore from. + BackupRef corev1.LocalObjectReference `json:"backupRef"` + + // Target application; if omitted, drivers SHOULD restore into + // backup.spec.applicationRef. + TargetApplicationRef *corev1.TypedLocalObjectReference `json:"targetApplicationRef,omitempty"` +} +``` + +**Key fields (status)** + +```go +type RestoreJobStatus struct { + Phase RestoreJobPhase `json:"phase,omitempty"` // Pending, Running, Succeeded, Failed + StartedAt *metav1.Time `json:"startedAt,omitempty"` + CompletedAt *metav1.Time `json:"completedAt,omitempty"` + Message string `json:"message,omitempty"` + Conditions []metav1.Condition `json:"conditions,omitempty"` +} +``` + +**RestoreJob contract with drivers** + +* RestoreJob is created either manually or by core. +* Driver controller: + + 1. Watches `RestoreJob`. + 2. On reconcile: + + * Fetches the referenced `Backup`. + * Determines effective: + + * **Strategy**: `backup.spec.strategyRef`. + * **Storage**: `backup.spec.storageRef`. + * **Target application**: `spec.targetApplicationRef` or `backup.spec.applicationRef`. + * If effective strategy’s GVK is one of its supported strategy types → driver is responsible. + 3. Behaviour: + + * On first reconcile, set `status.startedAt` and `phase = Running`. + * Resolve `Backup`, `Storage`, `Strategy`, target application. + * Execute restore logic (implementation-specific). + * On success: + + * Set `status.completedAt`. + * Set `status.phase = Succeeded`. + * On failure: + + * Set `status.completedAt`. + * Set `status.phase = Failed`. + * Set `status.message` and conditions. + +Drivers must not modify `RestoreJob.spec` or delete `RestoreJob`. + +--- + +## 5. Strategy drivers (high-level) + +Strategy drivers are separate controllers that: + +* Define their own **strategy CRDs** (e.g. `JobBackupStrategy`) in their own API groups: + + * e.g. `jobdriver.backups.cozystack.io/v1alpha1, Kind=JobBackupStrategy` +* Implement the **BackupJob contract**: + + * Watch `BackupJob`. + * Filter by `spec.strategyRef.apiGroup/kind`. + * Execute backup logic. + * Create/update `Backup`. +* Implement the **RestoreJob contract**: + + * Watch `RestoreJob`. + * Resolve `Backup`, then effective `strategyRef`. + * Filter by effective strategy GVK. + * Execute restore logic. + +The core backups API **does not** dictate: + +* The fields and structure of driver strategy specs. +* How drivers implement backup/restore internally (Jobs, snapshots, native operator CRDs, etc.). + +Drivers are interchangeable as long as they respect: + +* The `BackupJob` and `RestoreJob` contracts. +* The shapes and semantics of `Backup` objects. + +--- + +## 6. Summary + +The Cozystack backups core API: + +* Uses a single group, `backups.cozystack.io`, for all core CRDs. +* Cleanly separates: + + * **When & where** (Plan + Storage) – core-owned. + * **What backup artifacts exist** (Backup) – driver-created but cluster-visible. + * **Execution lifecycle** (BackupJob, RestoreJob) – shared contract boundary. +* Allows multiple strategy drivers to implement backup/restore logic without entangling their implementation with the core API. + diff --git a/api/backups/v1alpha1/backup_types.go b/api/backups/v1alpha1/backup_types.go new file mode 100644 index 00000000..ff6a8612 --- /dev/null +++ b/api/backups/v1alpha1/backup_types.go @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: Apache-2.0 +// Package v1alpha1 defines backups.cozystack.io API types. +// +// Group: backups.cozystack.io +// Version: v1alpha1 +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// BackupPhase represents the lifecycle phase of a Backup. +type BackupPhase string + +const ( + BackupPhaseEmpty BackupPhase = "" + BackupPhasePending BackupPhase = "Pending" + BackupPhaseReady BackupPhase = "Ready" + BackupPhaseFailed BackupPhase = "Failed" +) + +// BackupArtifact describes the stored backup object (tarball, snapshot, etc.). +type BackupArtifact struct { + // URI is a driver-/storage-specific URI pointing to the backup artifact. + // For example: s3://bucket/prefix/file.tar.gz + URI string `json:"uri"` + + // SizeBytes is the size of the artifact in bytes, if known. + // +optional + SizeBytes int64 `json:"sizeBytes,omitempty"` + + // Checksum is the checksum of the artifact, if computed. + // For example: "sha256:". + // +optional + Checksum string `json:"checksum,omitempty"` +} + +// BackupSpec describes an immutable backup artifact produced by a BackupJob. +type BackupSpec struct { + // ApplicationRef refers to the application that was backed up. + ApplicationRef corev1.TypedLocalObjectReference `json:"applicationRef"` + + // PlanRef refers to the Plan that produced this backup, if any. + // For manually triggered backups, this can be omitted. + // +optional + PlanRef *corev1.LocalObjectReference `json:"planRef,omitempty"` + + // StorageRef refers to the Storage object that describes where the backup + // artifact is stored. + StorageRef corev1.TypedLocalObjectReference `json:"storageRef"` + + // StrategyRef refers to the driver-specific BackupStrategy that was used + // to create this backup. This allows the driver to later perform restores. + StrategyRef corev1.TypedLocalObjectReference `json:"strategyRef"` + + // TakenAt is the time at which the backup was taken (as reported by the + // driver). It may differ slightly from metadata.creationTimestamp. + TakenAt metav1.Time `json:"takenAt"` + + // DriverMetadata holds driver-specific, opaque metadata associated with + // this backup (for example snapshot IDs, schema versions, etc.). + // This data is not interpreted by the core backup controllers. + // +optional + DriverMetadata map[string]string `json:"driverMetadata,omitempty"` +} + +// BackupStatus represents the observed state of a Backup. +type BackupStatus struct { + // Phase is a simple, high-level summary of the backup's state. + // Typical values are: Pending, Ready, Failed. + // +optional + Phase BackupPhase `json:"phase,omitempty"` + + // Artifact describes the stored backup object, if available. + // +optional + Artifact *BackupArtifact `json:"artifact,omitempty"` + + // Conditions represents the latest available observations of a Backup's state. + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// +kubebuilder:object:root=true + +// Backup represents a single backup artifact for a given application. +type Backup struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec BackupSpec `json:"spec,omitempty"` + Status BackupStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// BackupList contains a list of Backups. +type BackupList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Backup `json:"items"` +} diff --git a/api/backups/v1alpha1/backupjob_types.go b/api/backups/v1alpha1/backupjob_types.go new file mode 100644 index 00000000..56b4ec89 --- /dev/null +++ b/api/backups/v1alpha1/backupjob_types.go @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +// Package v1alpha1 defines backups.cozystack.io API types. +// +// Group: backups.cozystack.io +// Version: v1alpha1 +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// BackupJobPhase represents the lifecycle phase of a BackupJob. +type BackupJobPhase string + +const ( + BackupJobPhaseEmpty BackupJobPhase = "" + BackupJobPhasePending BackupJobPhase = "Pending" + BackupJobPhaseRunning BackupJobPhase = "Running" + BackupJobPhaseSucceeded BackupJobPhase = "Succeeded" + BackupJobPhaseFailed BackupJobPhase = "Failed" +) + +// BackupJobSpec describes the execution of a single backup operation. +type BackupJobSpec struct { + // PlanRef refers to the Plan that requested this backup run. + // For ad-hoc/manual backups, this can be omitted. + // +optional + PlanRef *corev1.LocalObjectReference `json:"planRef,omitempty"` + + // ApplicationRef holds a reference to the managed application whose state + // is being backed up. + ApplicationRef corev1.TypedLocalObjectReference `json:"applicationRef"` + + // StorageRef holds a reference to the Storage object that describes where + // the backup will be stored. + StorageRef corev1.TypedLocalObjectReference `json:"storageRef"` + + // StrategyRef holds a reference to the driver-specific BackupStrategy object + // that describes how the backup should be created. + StrategyRef corev1.TypedLocalObjectReference `json:"strategyRef"` +} + +// BackupJobStatus represents the observed state of a BackupJob. +type BackupJobStatus struct { + // Phase is a high-level summary of the run's state. + // Typical values: Pending, Running, Succeeded, Failed. + // +optional + Phase BackupJobPhase `json:"phase,omitempty"` + + // BackupRef refers to the Backup object created by this run, if any. + // +optional + BackupRef *corev1.LocalObjectReference `json:"backupRef,omitempty"` + + // StartedAt is the time at which the backup run started. + // +optional + StartedAt *metav1.Time `json:"startedAt,omitempty"` + + // CompletedAt is the time at which the backup run completed (successfully + // or otherwise). + // +optional + CompletedAt *metav1.Time `json:"completedAt,omitempty"` + + // Message is a human-readable message indicating details about why the + // backup run is in its current phase, if any. + // +optional + Message string `json:"message,omitempty"` + + // Conditions represents the latest available observations of a BackupJob's state. + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// +kubebuilder:object:root=true + +// BackupJob represents a single execution of a backup. +// It is typically created by a Plan controller when a schedule fires. +type BackupJob struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec BackupJobSpec `json:"spec,omitempty"` + Status BackupJobStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// BackupJobList contains a list of BackupJobs. +type BackupJobList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []BackupJob `json:"items"` +} diff --git a/api/backups/v1alpha1/groupversion_info.go b/api/backups/v1alpha1/groupversion_info.go new file mode 100644 index 00000000..a524c86d --- /dev/null +++ b/api/backups/v1alpha1/groupversion_info.go @@ -0,0 +1,53 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 contains API Schema definitions for the v1alpha1 API group. +// +kubebuilder:object:generate=true +// +groupName=backups.cozystack.io +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "backups.cozystack.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes( + GroupVersion, + &Plan{}, + &PlanList{}, + &BackupJob{}, + &BackupJobList{}, + &Backup{}, + &BackupList{}, + &RestoreJob{}, + &RestoreJobList{}, + ) + metav1.AddToGroupVersion(scheme, GroupVersion) + return nil +} diff --git a/api/backups/v1alpha1/plan_types.go b/api/backups/v1alpha1/plan_types.go new file mode 100644 index 00000000..e73608aa --- /dev/null +++ b/api/backups/v1alpha1/plan_types.go @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 +// Package v1alpha1 defines backups.cozystack.io API types. +// +// Group: backups.cozystack.io +// Version: v1alpha1 +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type PlanScheduleType string + +const ( + PlanScheduleTypeEmpty PlanScheduleType = "" + PlanScheduleTypeCron PlanScheduleType = "cron" +) + +// Condtions +const ( + PlanConditionError = "Error" +) + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status + +// Plan describes the schedule, method and storage location for the +// backup of a given target application. +type Plan struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PlanSpec `json:"spec,omitempty"` + Status PlanStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// PlanList contains a list of backup Plans. +type PlanList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Plan `json:"items"` +} + +// PlanSpec references the storage, the strategy, the application to be +// backed up and specifies the timetable on which the backups will run. +type PlanSpec struct { + // ApplicationRef holds a reference to the managed application, + // whose state and configuration must be backed up. + ApplicationRef corev1.TypedLocalObjectReference `json:"applicationRef"` + + // StorageRef holds a reference to the Storage object that + // describes the location where the backup will be stored. + StorageRef corev1.TypedLocalObjectReference `json:"storageRef"` + + // StrategyRef holds a reference to the Strategy object that + // describes, how a backup copy is to be created. + StrategyRef corev1.TypedLocalObjectReference `json:"strategyRef"` + + // Schedule specifies when backup copies are created. + Schedule PlanSchedule `json:"schedule"` +} + +// PlanSchedule specifies when backup copies are created. +type PlanSchedule struct { + // Type is the type of schedule specification. Supported values are + // [`cron`]. If omitted, defaults to `cron`. + // +optional + Type PlanScheduleType `json:"type,omitempty"` + + // Cron contains the cron spec for scheduling backups. Must be + // specified if the schedule type is `cron`. Since only `cron` is + // supported, omitting this field is not allowed. + // +optional + Cron string `json:"cron,omitempty"` +} + +type PlanStatus struct { + Conditions []metav1.Condition `json:"conditions,omitempty"` +} diff --git a/api/backups/v1alpha1/restorejob_types.go b/api/backups/v1alpha1/restorejob_types.go new file mode 100644 index 00000000..ddab2ff3 --- /dev/null +++ b/api/backups/v1alpha1/restorejob_types.go @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: Apache-2.0 +// Package v1alpha1 defines backups.cozystack.io API types. +// +// Group: backups.cozystack.io +// Version: v1alpha1 +package v1alpha1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// RestoreJobPhase represents the lifecycle phase of a RestoreJob. +type RestoreJobPhase string + +const ( + RestoreJobPhaseEmpty RestoreJobPhase = "" + RestoreJobPhasePending RestoreJobPhase = "Pending" + RestoreJobPhaseRunning RestoreJobPhase = "Running" + RestoreJobPhaseSucceeded RestoreJobPhase = "Succeeded" + RestoreJobPhaseFailed RestoreJobPhase = "Failed" +) + +// RestoreJobSpec describes the execution of a single restore operation. +type RestoreJobSpec struct { + // BackupRef refers to the Backup that should be restored. + BackupRef corev1.LocalObjectReference `json:"backupRef"` + + // TargetApplicationRef refers to the application into which the backup + // should be restored. If omitted, the driver SHOULD restore into the same + // application as referenced by backup.spec.applicationRef. + // +optional + TargetApplicationRef *corev1.TypedLocalObjectReference `json:"targetApplicationRef,omitempty"` +} + +// RestoreJobStatus represents the observed state of a RestoreJob. +type RestoreJobStatus struct { + // Phase is a high-level summary of the run's state. + // Typical values: Pending, Running, Succeeded, Failed. + // +optional + Phase RestoreJobPhase `json:"phase,omitempty"` + + // StartedAt is the time at which the restore run started. + // +optional + StartedAt *metav1.Time `json:"startedAt,omitempty"` + + // CompletedAt is the time at which the restore run completed (successfully + // or otherwise). + // +optional + CompletedAt *metav1.Time `json:"completedAt,omitempty"` + + // Message is a human-readable message indicating details about why the + // restore run is in its current phase, if any. + // +optional + Message string `json:"message,omitempty"` + + // Conditions represents the latest available observations of a RestoreJob's state. + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// +kubebuilder:object:root=true + +// RestoreJob represents a single execution of a restore from a Backup. +type RestoreJob struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec RestoreJobSpec `json:"spec,omitempty"` + Status RestoreJobStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// RestoreJobList contains a list of RestoreJobs. +type RestoreJobList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []RestoreJob `json:"items"` +} diff --git a/api/backups/v1alpha1/zz_generated.deepcopy.go b/api/backups/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000..3fd7005c --- /dev/null +++ b/api/backups/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,478 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2025 The Cozystack Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Backup) DeepCopyInto(out *Backup) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Backup. +func (in *Backup) DeepCopy() *Backup { + if in == nil { + return nil + } + out := new(Backup) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Backup) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupArtifact) DeepCopyInto(out *BackupArtifact) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupArtifact. +func (in *BackupArtifact) DeepCopy() *BackupArtifact { + if in == nil { + return nil + } + out := new(BackupArtifact) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupJob) DeepCopyInto(out *BackupJob) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupJob. +func (in *BackupJob) DeepCopy() *BackupJob { + if in == nil { + return nil + } + out := new(BackupJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BackupJob) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupJobList) DeepCopyInto(out *BackupJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]BackupJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupJobList. +func (in *BackupJobList) DeepCopy() *BackupJobList { + if in == nil { + return nil + } + out := new(BackupJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BackupJobList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupJobSpec) DeepCopyInto(out *BackupJobSpec) { + *out = *in + if in.PlanRef != nil { + in, out := &in.PlanRef, &out.PlanRef + *out = new(v1.LocalObjectReference) + **out = **in + } + in.ApplicationRef.DeepCopyInto(&out.ApplicationRef) + in.StorageRef.DeepCopyInto(&out.StorageRef) + in.StrategyRef.DeepCopyInto(&out.StrategyRef) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupJobSpec. +func (in *BackupJobSpec) DeepCopy() *BackupJobSpec { + if in == nil { + return nil + } + out := new(BackupJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupJobStatus) DeepCopyInto(out *BackupJobStatus) { + *out = *in + if in.BackupRef != nil { + in, out := &in.BackupRef, &out.BackupRef + *out = new(v1.LocalObjectReference) + **out = **in + } + if in.StartedAt != nil { + in, out := &in.StartedAt, &out.StartedAt + *out = (*in).DeepCopy() + } + if in.CompletedAt != nil { + in, out := &in.CompletedAt, &out.CompletedAt + *out = (*in).DeepCopy() + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupJobStatus. +func (in *BackupJobStatus) DeepCopy() *BackupJobStatus { + if in == nil { + return nil + } + out := new(BackupJobStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupList) DeepCopyInto(out *BackupList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Backup, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupList. +func (in *BackupList) DeepCopy() *BackupList { + if in == nil { + return nil + } + out := new(BackupList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BackupList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupSpec) DeepCopyInto(out *BackupSpec) { + *out = *in + in.ApplicationRef.DeepCopyInto(&out.ApplicationRef) + if in.PlanRef != nil { + in, out := &in.PlanRef, &out.PlanRef + *out = new(v1.LocalObjectReference) + **out = **in + } + in.StorageRef.DeepCopyInto(&out.StorageRef) + in.StrategyRef.DeepCopyInto(&out.StrategyRef) + in.TakenAt.DeepCopyInto(&out.TakenAt) + if in.DriverMetadata != nil { + in, out := &in.DriverMetadata, &out.DriverMetadata + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupSpec. +func (in *BackupSpec) DeepCopy() *BackupSpec { + if in == nil { + return nil + } + out := new(BackupSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackupStatus) DeepCopyInto(out *BackupStatus) { + *out = *in + if in.Artifact != nil { + in, out := &in.Artifact, &out.Artifact + *out = new(BackupArtifact) + **out = **in + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackupStatus. +func (in *BackupStatus) DeepCopy() *BackupStatus { + if in == nil { + return nil + } + out := new(BackupStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Plan) DeepCopyInto(out *Plan) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plan. +func (in *Plan) DeepCopy() *Plan { + if in == nil { + return nil + } + out := new(Plan) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Plan) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PlanList) DeepCopyInto(out *PlanList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Plan, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlanList. +func (in *PlanList) DeepCopy() *PlanList { + if in == nil { + return nil + } + out := new(PlanList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PlanList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PlanSchedule) DeepCopyInto(out *PlanSchedule) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlanSchedule. +func (in *PlanSchedule) DeepCopy() *PlanSchedule { + if in == nil { + return nil + } + out := new(PlanSchedule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PlanSpec) DeepCopyInto(out *PlanSpec) { + *out = *in + in.ApplicationRef.DeepCopyInto(&out.ApplicationRef) + in.StorageRef.DeepCopyInto(&out.StorageRef) + in.StrategyRef.DeepCopyInto(&out.StrategyRef) + out.Schedule = in.Schedule +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlanSpec. +func (in *PlanSpec) DeepCopy() *PlanSpec { + if in == nil { + return nil + } + out := new(PlanSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RestoreJob) DeepCopyInto(out *RestoreJob) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RestoreJob. +func (in *RestoreJob) DeepCopy() *RestoreJob { + if in == nil { + return nil + } + out := new(RestoreJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RestoreJob) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RestoreJobList) DeepCopyInto(out *RestoreJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RestoreJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RestoreJobList. +func (in *RestoreJobList) DeepCopy() *RestoreJobList { + if in == nil { + return nil + } + out := new(RestoreJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RestoreJobList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RestoreJobSpec) DeepCopyInto(out *RestoreJobSpec) { + *out = *in + out.BackupRef = in.BackupRef + if in.TargetApplicationRef != nil { + in, out := &in.TargetApplicationRef, &out.TargetApplicationRef + *out = new(v1.TypedLocalObjectReference) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RestoreJobSpec. +func (in *RestoreJobSpec) DeepCopy() *RestoreJobSpec { + if in == nil { + return nil + } + out := new(RestoreJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RestoreJobStatus) DeepCopyInto(out *RestoreJobStatus) { + *out = *in + if in.StartedAt != nil { + in, out := &in.StartedAt, &out.StartedAt + *out = (*in).DeepCopy() + } + if in.CompletedAt != nil { + in, out := &in.CompletedAt, &out.CompletedAt + *out = (*in).DeepCopy() + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RestoreJobStatus. +func (in *RestoreJobStatus) DeepCopy() *RestoreJobStatus { + if in == nil { + return nil + } + out := new(RestoreJobStatus) + in.DeepCopyInto(out) + return out +} diff --git a/cmd/backup-controller/main.go b/cmd/backup-controller/main.go new file mode 100644 index 00000000..d8436659 --- /dev/null +++ b/cmd/backup-controller/main.go @@ -0,0 +1,174 @@ +/* +Copyright 2025. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "crypto/tls" + "flag" + "os" + + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + // to ensure that exec-entrypoint and run can make use of them. + _ "k8s.io/client-go/plugin/pkg/client/auth" + + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/metrics/filters" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + backupsv1alpha1 "github.com/cozystack/cozystack/api/backups/v1alpha1" + "github.com/cozystack/cozystack/internal/backupcontroller" + // +kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + + utilruntime.Must(backupsv1alpha1.AddToScheme(scheme)) + // +kubebuilder:scaffold:scheme +} + +func main() { + var metricsAddr string + var enableLeaderElection bool + var probeAddr string + var secureMetrics bool + var enableHTTP2 bool + var tlsOpts []func(*tls.Config) + flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+ + "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.") + flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + flag.BoolVar(&enableLeaderElection, "leader-elect", false, + "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + flag.BoolVar(&secureMetrics, "metrics-secure", true, + "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") + flag.BoolVar(&enableHTTP2, "enable-http2", false, + "If set, HTTP/2 will be enabled for the metrics and webhook servers") + opts := zap.Options{ + Development: false, + } + opts.BindFlags(flag.CommandLine) + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + + // if the enable-http2 flag is false (the default), http/2 should be disabled + // due to its vulnerabilities. More specifically, disabling http/2 will + // prevent from being vulnerable to the HTTP/2 Stream Cancellation and + // Rapid Reset CVEs. For more information see: + // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 + // - https://github.com/advisories/GHSA-4374-p667-p6c8 + disableHTTP2 := func(c *tls.Config) { + setupLog.Info("disabling http/2") + c.NextProtos = []string{"http/1.1"} + } + + if !enableHTTP2 { + tlsOpts = append(tlsOpts, disableHTTP2) + } + + webhookServer := webhook.NewServer(webhook.Options{ + TLSOpts: tlsOpts, + }) + + // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server. + // More info: + // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/server + // - https://book.kubebuilder.io/reference/metrics.html + metricsServerOptions := metricsserver.Options{ + BindAddress: metricsAddr, + SecureServing: secureMetrics, + TLSOpts: tlsOpts, + } + + if secureMetrics { + // FilterProvider is used to protect the metrics endpoint with authn/authz. + // These configurations ensure that only authorized users and service accounts + // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: + // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/filters#WithAuthenticationAndAuthorization + metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization + + // TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically + // generate self-signed certificates for the metrics server. While convenient for development and testing, + // this setup is not recommended for production. + } + + // Configure rate limiting for the Kubernetes client + config := ctrl.GetConfigOrDie() + config.QPS = 50.0 // Increased from default 5.0 + config.Burst = 100 // Increased from default 10 + + mgr, err := ctrl.NewManager(config, ctrl.Options{ + Scheme: scheme, + Metrics: metricsServerOptions, + WebhookServer: webhookServer, + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "core.backups.cozystack.io", + // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily + // when the Manager ends. This requires the binary to immediately end when the + // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly + // speeds up voluntary leader transitions as the new leader don't have to wait + // LeaseDuration time first. + // + // In the default scaffold provided, the program ends immediately after + // the manager stops, so would be fine to enable this option. However, + // if you are doing or is intended to do any operation such as perform cleanups + // after the manager stops then its usage might be unsafe. + // LeaderElectionReleaseOnCancel: true, + }) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + if err = (&backupcontroller.PlanReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Plan") + os.Exit(1) + } + + // +kubebuilder:scaffold:builder + + if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up health check") + os.Exit(1) + } + if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up ready check") + os.Exit(1) + } + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/docs/changelogs/v0.38.2.md b/docs/changelogs/v0.38.2.md new file mode 100644 index 00000000..feb80d1f --- /dev/null +++ b/docs/changelogs/v0.38.2.md @@ -0,0 +1,13 @@ + + + +## Fixes + +* **[api] Revert dynamic list kinds representation fix (fixes namespace deletion regression)**: Reverted changes from #1630 that caused a regression affecting namespace deletion and upgrades from previous versions. The regression caused namespace deletion failures with errors like "content is not a list: []unstructured.Unstructured" during namespace finalization. This revert restores compatibility with namespace deletion controller and fixes upgrade issues from previous versions, particularly when running migration 20 ([**@kvaps**](https://github.com/kvaps) in #1677). + +--- + +**Full Changelog**: [v0.38.1...v0.38.2](https://github.com/cozystack/cozystack/compare/v0.38.1...v0.38.2) + diff --git a/go.mod b/go.mod index a843d2f3..6ae20909 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 github.com/prometheus/client_golang v1.19.1 + github.com/robfig/cron/v3 v3.0.1 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 diff --git a/go.sum b/go.sum index a32e6b3b..88c81e7b 100644 --- a/go.sum +++ b/go.sum @@ -147,6 +147,8 @@ github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index e181fc76..0069651e 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -23,6 +23,11 @@ CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code- API_KNOWN_VIOLATIONS_DIR="${API_KNOWN_VIOLATIONS_DIR:-"${SCRIPT_ROOT}/api/api-rules"}" UPDATE_API_KNOWN_VIOLATIONS="${UPDATE_API_KNOWN_VIOLATIONS:-true}" CONTROLLER_GEN="go run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.16.4" +TMPDIR=$(mktemp -d) +COZY_CONTROLLER_CRDDIR=packages/system/cozystack-controller/crds +COZY_RD_CRDDIR=packages/system/cozystack-resource-definition-crd/definition +BACKUPS_CORE_CRDDIR=packages/system/backup-controller/definitions +trap 'rm -rf ${TMPDIR}' EXIT source "${CODEGEN_PKG}/kube_codegen.sh" @@ -53,6 +58,11 @@ kube::codegen::gen_openapi \ "${SCRIPT_ROOT}/pkg/apis" $CONTROLLER_GEN object:headerFile="hack/boilerplate.go.txt" paths="./api/..." -$CONTROLLER_GEN rbac:roleName=manager-role crd paths="./api/..." output:crd:artifacts:config=packages/system/cozystack-controller/crds -mv packages/system/cozystack-controller/crds/cozystack.io_cozystackresourcedefinitions.yaml \ - packages/system/cozystack-resource-definition-crd/definition/cozystack.io_cozystackresourcedefinitions.yaml +$CONTROLLER_GEN rbac:roleName=manager-role crd paths="./api/..." output:crd:artifacts:config=${TMPDIR} + +mv ${TMPDIR}/cozystack.io_cozystackresourcedefinitions.yaml \ + ${COZY_RD_CRDDIR}/cozystack.io_cozystackresourcedefinitions.yaml + +mv ${TMPDIR}/backups.cozystack.io*.yaml ${BACKUPS_CORE_CRDDIR}/ + +mv ${TMPDIR}/*.yaml ${COZY_CONTROLLER_CRDDIR}/ diff --git a/internal/backupcontroller/factory/backupjob.go b/internal/backupcontroller/factory/backupjob.go new file mode 100644 index 00000000..722e5d99 --- /dev/null +++ b/internal/backupcontroller/factory/backupjob.go @@ -0,0 +1,28 @@ +package factory + +import ( + "fmt" + "time" + + backupsv1alpha1 "github.com/cozystack/cozystack/api/backups/v1alpha1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func BackupJob(p *backupsv1alpha1.Plan, scheduledFor time.Time) *backupsv1alpha1.BackupJob { + job := &backupsv1alpha1.BackupJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-%d", p.Name, scheduledFor.Unix()/60), + Namespace: p.Namespace, + }, + Spec: backupsv1alpha1.BackupJobSpec{ + PlanRef: &corev1.LocalObjectReference{ + Name: p.Name, + }, + ApplicationRef: *p.Spec.ApplicationRef.DeepCopy(), + StorageRef: *p.Spec.StorageRef.DeepCopy(), + StrategyRef: *p.Spec.StrategyRef.DeepCopy(), + }, + } + return job +} diff --git a/internal/backupcontroller/plan_controller.go b/internal/backupcontroller/plan_controller.go new file mode 100644 index 00000000..046fdce4 --- /dev/null +++ b/internal/backupcontroller/plan_controller.go @@ -0,0 +1,104 @@ +package backupcontroller + +import ( + "context" + "fmt" + "time" + + cron "github.com/robfig/cron/v3" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/log" + + backupsv1alpha1 "github.com/cozystack/cozystack/api/backups/v1alpha1" + "github.com/cozystack/cozystack/internal/backupcontroller/factory" +) + +const ( + minRequeueDelay = 30 * time.Second + startingDeadlineSeconds = 300 * time.Second +) + +// PlanReconciler reconciles a Plan object +type PlanReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +func (r *PlanReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + log := log.FromContext(ctx) + + log.V(2).Info("reconciling") + + p := &backupsv1alpha1.Plan{} + + if err := r.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: req.Name}, p); err != nil { + if apierrors.IsNotFound(err) { + log.V(3).Info("Plan not found") + return ctrl.Result{}, nil + } + return ctrl.Result{}, err + } + + tCheck := time.Now().Add(-startingDeadlineSeconds) + sch, err := cron.ParseStandard(p.Spec.Schedule.Cron) + if err != nil { + errWrapped := fmt.Errorf("could not parse cron %s: %w", p.Spec.Schedule.Cron, err) + log.Error(err, "could not parse cron", "cron", p.Spec.Schedule.Cron) + meta.SetStatusCondition(&p.Status.Conditions, metav1.Condition{ + Type: backupsv1alpha1.PlanConditionError, + Status: metav1.ConditionTrue, + Reason: "Failed to parse cron spec", + Message: errWrapped.Error(), + }) + if err := r.Status().Update(ctx, p); err != nil { + return ctrl.Result{}, err + } + return ctrl.Result{}, nil + } + + // Clear error condition if cron parsing succeeds + if condition := meta.FindStatusCondition(p.Status.Conditions, backupsv1alpha1.PlanConditionError); condition != nil && condition.Status == metav1.ConditionTrue { + meta.SetStatusCondition(&p.Status.Conditions, metav1.Condition{ + Type: backupsv1alpha1.PlanConditionError, + Status: metav1.ConditionFalse, + Reason: "Cron spec is valid", + Message: "The cron schedule has been successfully parsed", + }) + if err := r.Status().Update(ctx, p); err != nil { + return ctrl.Result{}, err + } + } + + tNext := sch.Next(tCheck) + + if time.Now().Before(tNext) { + return ctrl.Result{RequeueAfter: tNext.Sub(time.Now())}, nil + } + + job := factory.BackupJob(p, tNext) + if err := controllerutil.SetControllerReference(p, job, r.Scheme); err != nil { + return ctrl.Result{}, err + } + + if err := r.Create(ctx, job); err != nil { + if apierrors.IsAlreadyExists(err) { + return ctrl.Result{RequeueAfter: startingDeadlineSeconds}, nil + } + return ctrl.Result{}, err + } + + return ctrl.Result{RequeueAfter: startingDeadlineSeconds}, nil +} + +// SetupWithManager registers our controller with the Manager and sets up watches. +func (r *PlanReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&backupsv1alpha1.Plan{}). + Complete(r) +} diff --git a/internal/controller/dashboard/customformsoverride.go b/internal/controller/dashboard/customformsoverride.go index f88202bc..2b0daa08 100644 --- a/internal/controller/dashboard/customformsoverride.go +++ b/internal/controller/dashboard/customformsoverride.go @@ -105,8 +105,26 @@ func buildMultilineStringSchema(openAPISchema string) (map[string]any, error) { "properties": map[string]any{}, } + // Check if there's a spec property + specProp, ok := props["spec"].(map[string]any) + if !ok { + return map[string]any{}, nil + } + + specProps, ok := specProp["properties"].(map[string]any) + if !ok { + return map[string]any{}, nil + } + + // Create spec.properties structure in schema + schemaProps := schema["properties"].(map[string]any) + specSchema := map[string]any{ + "properties": map[string]any{}, + } + schemaProps["spec"] = specSchema + // Process spec properties recursively - processSpecProperties(props, schema["properties"].(map[string]any)) + processSpecProperties(specProps, specSchema["properties"].(map[string]any)) return schema, nil } diff --git a/internal/controller/dashboard/customformsoverride_test.go b/internal/controller/dashboard/customformsoverride_test.go index 2766bf17..9f7babe9 100644 --- a/internal/controller/dashboard/customformsoverride_test.go +++ b/internal/controller/dashboard/customformsoverride_test.go @@ -9,41 +9,46 @@ func TestBuildMultilineStringSchema(t *testing.T) { // Test OpenAPI schema with various field types openAPISchema := `{ "properties": { - "simpleString": { - "type": "string", - "description": "A simple string field" - }, - "stringWithEnum": { - "type": "string", - "enum": ["option1", "option2"], - "description": "String with enum should be skipped" - }, - "numberField": { - "type": "number", - "description": "Number field should be skipped" - }, - "nestedObject": { + "spec": { "type": "object", "properties": { - "nestedString": { + "simpleString": { "type": "string", - "description": "Nested string should get multilineString" + "description": "A simple string field" }, - "nestedStringWithEnum": { + "stringWithEnum": { "type": "string", - "enum": ["a", "b"], - "description": "Nested string with enum should be skipped" - } - } - }, - "arrayOfObjects": { - "type": "array", - "items": { - "type": "object", - "properties": { - "itemString": { - "type": "string", - "description": "String in array item" + "enum": ["option1", "option2"], + "description": "String with enum should be skipped" + }, + "numberField": { + "type": "number", + "description": "Number field should be skipped" + }, + "nestedObject": { + "type": "object", + "properties": { + "nestedString": { + "type": "string", + "description": "Nested string should get multilineString" + }, + "nestedStringWithEnum": { + "type": "string", + "enum": ["a", "b"], + "description": "Nested string with enum should be skipped" + } + } + }, + "arrayOfObjects": { + "type": "array", + "items": { + "type": "object", + "properties": { + "itemString": { + "type": "string", + "description": "String in array item" + } + } } } } @@ -70,33 +75,44 @@ func TestBuildMultilineStringSchema(t *testing.T) { t.Fatal("schema.properties is not a map") } - // Check simpleString - simpleString, ok := props["simpleString"].(map[string]any) + // Check spec property exists + spec, ok := props["spec"].(map[string]any) if !ok { - t.Fatal("simpleString not found in properties") + t.Fatal("spec not found in properties") + } + + specProps, ok := spec["properties"].(map[string]any) + if !ok { + t.Fatal("spec.properties is not a map") + } + + // Check simpleString + simpleString, ok := specProps["simpleString"].(map[string]any) + if !ok { + t.Fatal("simpleString not found in spec.properties") } if simpleString["type"] != "multilineString" { t.Errorf("simpleString should have type multilineString, got %v", simpleString["type"]) } // Check stringWithEnum should not be present (or should not have multilineString) - if stringWithEnum, ok := props["stringWithEnum"].(map[string]any); ok { + if stringWithEnum, ok := specProps["stringWithEnum"].(map[string]any); ok { if stringWithEnum["type"] == "multilineString" { t.Error("stringWithEnum should not have multilineString type") } } // Check numberField should not be present - if numberField, ok := props["numberField"].(map[string]any); ok { + if numberField, ok := specProps["numberField"].(map[string]any); ok { if numberField["type"] != nil { t.Error("numberField should not have any type override") } } // Check nested object - nestedObject, ok := props["nestedObject"].(map[string]any) + nestedObject, ok := specProps["nestedObject"].(map[string]any) if !ok { - t.Fatal("nestedObject not found in properties") + t.Fatal("nestedObject not found in spec.properties") } nestedProps, ok := nestedObject["properties"].(map[string]any) if !ok { @@ -113,9 +129,9 @@ func TestBuildMultilineStringSchema(t *testing.T) { } // Check array of objects - arrayOfObjects, ok := props["arrayOfObjects"].(map[string]any) + arrayOfObjects, ok := specProps["arrayOfObjects"].(map[string]any) if !ok { - t.Fatal("arrayOfObjects not found in properties") + t.Fatal("arrayOfObjects not found in spec.properties") } items, ok := arrayOfObjects["items"].(map[string]any) if !ok { diff --git a/packages/apps/kubernetes/.helmignore b/packages/apps/kubernetes/.helmignore index 1ea0ae84..3de7d4a5 100644 --- a/packages/apps/kubernetes/.helmignore +++ b/packages/apps/kubernetes/.helmignore @@ -1,3 +1,4 @@ .helmignore /logos /Makefile +/hack diff --git a/packages/apps/kubernetes/Makefile b/packages/apps/kubernetes/Makefile index 799a19bc..ae6dd757 100644 --- a/packages/apps/kubernetes/Makefile +++ b/packages/apps/kubernetes/Makefile @@ -6,9 +6,12 @@ include ../../../scripts/package.mk generate: cozyvalues-gen -v values.yaml -s values.schema.json -r README.md - yq -o=json -i '.properties.version.enum = (load("files/versions.yaml") | keys)' values.schema.json ../../../hack/update-crd.sh +update: + hack/update-versions.sh + make generate + image: image-ubuntu-container-disk image-kubevirt-cloud-provider image-kubevirt-csi-driver image-cluster-autoscaler image-ubuntu-container-disk: diff --git a/packages/apps/kubernetes/README.md b/packages/apps/kubernetes/README.md index 4bc344a2..8bff49aa 100644 --- a/packages/apps/kubernetes/README.md +++ b/packages/apps/kubernetes/README.md @@ -104,7 +104,7 @@ See the reference for components utilized in this service: | `nodeGroups[name].resources.memory` | Memory (RAM) available. | `quantity` | `""` | | `nodeGroups[name].gpus` | List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM). | `[]object` | `[]` | | `nodeGroups[name].gpus[i].name` | Name of GPU, such as "nvidia.com/AD102GL_L40S". | `string` | `""` | -| `version` | Kubernetes version (vMAJOR.MINOR). Supported: 1.28–1.33. | `string` | `v1.33` | +| `version` | Kubernetes major.minor version to deploy | `string` | `v1.33` | | `host` | External hostname for Kubernetes cluster. Defaults to `.` if empty. | `string` | `""` | diff --git a/packages/apps/kubernetes/files/versions.yaml b/packages/apps/kubernetes/files/versions.yaml index f9236751..51a36034 100644 --- a/packages/apps/kubernetes/files/versions.yaml +++ b/packages/apps/kubernetes/files/versions.yaml @@ -1,6 +1,6 @@ -"v1.28": "v1.28.15" -"v1.29": "v1.29.15" -"v1.30": "v1.30.14" -"v1.31": "v1.31.10" -"v1.32": "v1.32.6" "v1.33": "v1.33.0" +"v1.32": "v1.32.10" +"v1.31": "v1.31.14" +"v1.30": "v1.30.14" +"v1.29": "v1.29.15" +"v1.28": "v1.28.15" diff --git a/packages/apps/kubernetes/hack/update-versions.sh b/packages/apps/kubernetes/hack/update-versions.sh new file mode 100755 index 00000000..85c962c5 --- /dev/null +++ b/packages/apps/kubernetes/hack/update-versions.sh @@ -0,0 +1,260 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +KUBERNETES_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +VALUES_FILE="${KUBERNETES_DIR}/values.yaml" +VERSIONS_FILE="${KUBERNETES_DIR}/files/versions.yaml" +MAKEFILE="${KUBERNETES_DIR}/Makefile" +KAMAJI_DOCKERFILE="${KUBERNETES_DIR}/../../system/kamaji/images/kamaji/Dockerfile" + +# Check if skopeo is installed +if ! command -v skopeo &> /dev/null; then + echo "Error: skopeo is not installed. Please install skopeo and try again." >&2 + exit 1 +fi + +# Check if jq is installed +if ! command -v jq &> /dev/null; then + echo "Error: jq is not installed. Please install jq and try again." >&2 + exit 1 +fi + +# Get kamaji version from Dockerfile +echo "Reading kamaji version from Dockerfile..." +if [ ! -f "$KAMAJI_DOCKERFILE" ]; then + echo "Error: Kamaji Dockerfile not found at $KAMAJI_DOCKERFILE" >&2 + exit 1 +fi + +KAMAJI_VERSION=$(grep "^ARG VERSION=" "$KAMAJI_DOCKERFILE" | cut -d= -f2 | tr -d '"') +if [ -z "$KAMAJI_VERSION" ]; then + echo "Error: Could not extract kamaji version from Dockerfile" >&2 + exit 1 +fi + +echo "Kamaji version: $KAMAJI_VERSION" + +# Get Kubernetes version from kamaji repository +echo "Fetching Kubernetes version from kamaji repository..." +KUBERNETES_VERSION_FROM_KAMAJI=$(curl -sSL "https://raw.githubusercontent.com/clastix/kamaji/${KAMAJI_VERSION}/internal/upgrade/kubeadm_version.go" | grep "KubeadmVersion" | sed -E 's/.*KubeadmVersion = "([^"]+)".*/\1/') + +if [ -z "$KUBERNETES_VERSION_FROM_KAMAJI" ]; then + echo "Error: Could not fetch Kubernetes version from kamaji repository" >&2 + exit 1 +fi + +echo "Kubernetes version from kamaji: $KUBERNETES_VERSION_FROM_KAMAJI" + +# Extract major.minor version (e.g., "1.33" from "v1.33.0") +KUBERNETES_MAJOR_MINOR=$(echo "$KUBERNETES_VERSION_FROM_KAMAJI" | sed -E 's/v([0-9]+)\.([0-9]+)\.[0-9]+/\1.\2/') +KUBERNETES_MAJOR=$(echo "$KUBERNETES_MAJOR_MINOR" | cut -d. -f1) +KUBERNETES_MINOR=$(echo "$KUBERNETES_MAJOR_MINOR" | cut -d. -f2) + +echo "Kubernetes major.minor: $KUBERNETES_MAJOR_MINOR" + +# Get available image tags +echo "Fetching available image tags from registry..." +AVAILABLE_TAGS=$(skopeo list-tags docker://registry.k8s.io/kube-apiserver | jq -r '.Tags[] | select(test("^v[0-9]+\\.[0-9]+\\.[0-9]+$"))' | sort -V) + +if [ -z "$AVAILABLE_TAGS" ]; then + echo "Error: Could not fetch available image tags" >&2 + exit 1 +fi + +# Filter out versions higher than KUBERNETES_VERSION_FROM_KAMAJI +echo "Filtering versions above ${KUBERNETES_VERSION_FROM_KAMAJI}..." +FILTERED_TAGS=$(echo "$AVAILABLE_TAGS" | while read tag; do + if [ -n "$tag" ]; then + # Compare tag with KUBERNETES_VERSION_FROM_KAMAJI using version sort + # Include tag if it's less than or equal to KUBERNETES_VERSION_FROM_KAMAJI + if [ "$(printf '%s\n%s\n' "$tag" "$KUBERNETES_VERSION_FROM_KAMAJI" | sort -V | head -1)" = "$tag" ] || [ "$tag" = "$KUBERNETES_VERSION_FROM_KAMAJI" ]; then + echo "$tag" + fi + fi +done) + +if [ -z "$FILTERED_TAGS" ]; then + echo "Error: No versions found after filtering" >&2 + exit 1 +fi + +AVAILABLE_TAGS="$FILTERED_TAGS" +echo "Filtered to $(echo "$AVAILABLE_TAGS" | wc -l | tr -d ' ') versions" + +# Find the latest patch version for the supported major.minor version +echo "Finding latest patch version for ${KUBERNETES_MAJOR_MINOR}..." +SUPPORTED_PATCH_TAGS=$(echo "$AVAILABLE_TAGS" | grep "^v${KUBERNETES_MAJOR}\\.${KUBERNETES_MINOR}\\.") +if [ -z "$SUPPORTED_PATCH_TAGS" ]; then + echo "Error: Could not find any patch versions for ${KUBERNETES_MAJOR_MINOR}" >&2 + exit 1 +fi +KUBERNETES_VERSION=$(echo "$SUPPORTED_PATCH_TAGS" | tail -n1) +echo "Using latest patch version: $KUBERNETES_VERSION" + +# Build versions map: major.minor -> latest patch version +# First, collect all unique major.minor versions from available tags +echo "Collecting all available major.minor versions..." +ALL_MAJOR_MINOR_VERSIONS=$(echo "$AVAILABLE_TAGS" | sed -E 's/v([0-9]+)\.([0-9]+)\.[0-9]+/v\1.\2/' | sort -V -u) + +# Find the position of the supported version in the sorted list +SUPPORTED_MAJOR_MINOR="v${KUBERNETES_MAJOR}.${KUBERNETES_MINOR}" +echo "Looking for supported version: $SUPPORTED_MAJOR_MINOR" + +# Get all versions that are <= supported version +# Create a temporary file for filtering +TEMP_VERSIONS=$(mktemp) + +echo "$ALL_MAJOR_MINOR_VERSIONS" | while read version; do + # Compare versions using sort -V (version sort) + # If version <= supported, include it + if [ "$(printf '%s\n%s\n' "$version" "$SUPPORTED_MAJOR_MINOR" | sort -V | head -1)" = "$version" ] || [ "$version" = "$SUPPORTED_MAJOR_MINOR" ]; then + echo "$version" + fi +done > "$TEMP_VERSIONS" + +# Get the supported version and 5 previous versions (total 6 versions) +# First, find the position of supported version +SUPPORTED_POS=$(grep -n "^${SUPPORTED_MAJOR_MINOR}$" "$TEMP_VERSIONS" | cut -d: -f1) + +if [ -z "$SUPPORTED_POS" ]; then + echo "Error: Supported version $SUPPORTED_MAJOR_MINOR not found in available versions" >&2 + exit 1 +fi + +# Calculate start position (5 versions before supported, or from beginning if less than 5 available) +TOTAL_LINES=$(wc -l < "$TEMP_VERSIONS" | tr -d ' ') +START_POS=$((SUPPORTED_POS - 5)) +if [ $START_POS -lt 1 ]; then + START_POS=1 +fi + +# Extract versions from START_POS to SUPPORTED_POS (inclusive) +CANDIDATE_VERSIONS=$(sed -n "${START_POS},${SUPPORTED_POS}p" "$TEMP_VERSIONS") + +if [ -z "$CANDIDATE_VERSIONS" ]; then + echo "Error: Could not find supported version $SUPPORTED_MAJOR_MINOR in available versions" >&2 + exit 1 +fi + +declare -A VERSION_MAP +VERSIONS=() + +# Process each candidate version +for major_minor_key in $CANDIDATE_VERSIONS; do + # Extract major and minor for matching + major=$(echo "$major_minor_key" | sed -E 's/v([0-9]+)\.([0-9]+)/\1/') + minor=$(echo "$major_minor_key" | sed -E 's/v([0-9]+)\.([0-9]+)/\2/') + + # Find all tags that match this major.minor version + matching_tags=$(echo "$AVAILABLE_TAGS" | grep "^v${major}\\.${minor}\\.") + + if [ -n "$matching_tags" ]; then + # Get the latest patch version for this major.minor version + latest_tag=$(echo "$matching_tags" | tail -n1) + + VERSION_MAP["${major_minor_key}"]="${latest_tag}" + VERSIONS+=("${major_minor_key}") + echo "Found version: ${major_minor_key} -> ${latest_tag}" + fi +done + +if [ ${#VERSIONS[@]} -eq 0 ]; then + echo "Error: No matching versions found" >&2 + exit 1 +fi + +# Sort versions in descending order (newest first) +IFS=$'\n' VERSIONS=($(printf '%s\n' "${VERSIONS[@]}" | sort -V -r)) +unset IFS + +echo "Versions to add: ${VERSIONS[*]}" + +# Create/update versions.yaml file +echo "Updating $VERSIONS_FILE..." +{ + for ver in "${VERSIONS[@]}"; do + echo "\"${ver}\": \"${VERSION_MAP[$ver]}\"" + done +} > "$VERSIONS_FILE" + +echo "Successfully updated $VERSIONS_FILE" + +# Update values.yaml - enum with major.minor versions only +TEMP_FILE=$(mktemp) +trap "rm -f $TEMP_FILE $TEMP_VERSIONS" EXIT + +# Build new version section +NEW_VERSION_SECTION="## @enum {string} Version" +for ver in "${VERSIONS[@]}"; do + NEW_VERSION_SECTION="${NEW_VERSION_SECTION} +## @value $ver" +done +NEW_VERSION_SECTION="${NEW_VERSION_SECTION} + +## @param {Version} version - Kubernetes major.minor version to deploy +version: \"${VERSIONS[0]}\"" + +# Check if version section already exists +if grep -q "^## @enum {string} Version" "$VALUES_FILE"; then + # Version section exists, update it using awk + echo "Updating existing version section in $VALUES_FILE..." + + # Use awk to replace the section from "## @enum {string} Version" to "version: " (inclusive) + # Delete the old section and insert the new one + awk -v new_section="$NEW_VERSION_SECTION" ' + /^## @enum {string} Version/ { + in_section = 1 + print new_section + next + } + in_section && /^version: / { + in_section = 0 + next + } + in_section { + next + } + { print } + ' "$VALUES_FILE" > "$TEMP_FILE.tmp" + mv "$TEMP_FILE.tmp" "$VALUES_FILE" +else + # Version section doesn't exist, insert it before Application-specific parameters section + echo "Inserting new version section in $VALUES_FILE..." + + # Use awk to insert before "## @section Application-specific parameters" + awk -v new_section="$NEW_VERSION_SECTION" ' + /^## @section Application-specific parameters/ { + print new_section + print "" + } + { print } + ' "$VALUES_FILE" > "$TEMP_FILE.tmp" + mv "$TEMP_FILE.tmp" "$VALUES_FILE" +fi + +echo "Successfully updated $VALUES_FILE with versions: ${VERSIONS[*]}" + +# Update KUBERNETES_VERSION in Makefile +# Extract major.minor from KUBERNETES_VERSION (e.g., "v1.33" from "v1.33.4") +KUBERNETES_MAJOR_MINOR_FOR_MAKEFILE=$(echo "$KUBERNETES_VERSION" | sed -E 's/v([0-9]+)\.([0-9]+)\.[0-9]+/v\1.\2/') + +if grep -q "^KUBERNETES_VERSION" "$MAKEFILE"; then + # Update existing KUBERNETES_VERSION line using awk + echo "Updating KUBERNETES_VERSION in $MAKEFILE..." + awk -v new_version="${KUBERNETES_MAJOR_MINOR_FOR_MAKEFILE}" ' + /^KUBERNETES_VERSION = / { + print "KUBERNETES_VERSION = " new_version + next + } + { print } + ' "$MAKEFILE" > "$TEMP_FILE.tmp" + mv "$TEMP_FILE.tmp" "$MAKEFILE" + echo "Successfully updated KUBERNETES_VERSION in $MAKEFILE to ${KUBERNETES_MAJOR_MINOR_FOR_MAKEFILE}" +else + echo "Warning: KUBERNETES_VERSION not found in $MAKEFILE" >&2 +fi + diff --git a/packages/apps/kubernetes/templates/delete.yaml b/packages/apps/kubernetes/templates/delete.yaml index ae581226..702ba542 100644 --- a/packages/apps/kubernetes/templates/delete.yaml +++ b/packages/apps/kubernetes/templates/delete.yaml @@ -5,8 +5,8 @@ metadata: annotations: "helm.sh/hook": pre-delete "helm.sh/hook-weight": "10" - "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation,hook-failed - name: {{ .Release.Name }}-cleanup + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation + name: {{ .Release.Name }}-pre-cleanup spec: template: metadata: @@ -65,7 +65,6 @@ spec: echo "Cleanup completed successfully" - --- apiVersion: v1 kind: ServiceAccount @@ -73,7 +72,7 @@ metadata: name: {{ .Release.Name }}-cleanup annotations: helm.sh/hook: pre-delete - helm.sh/hook-delete-policy: before-hook-creation,hook-failed,hook-succeeded + helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation,hook-failed helm.sh/hook-weight: "0" --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/packages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yaml b/packages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yaml index 3bf7a5d2..73954e12 100644 --- a/packages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yaml @@ -45,8 +45,6 @@ spec: - name: {{ .Release.Name }} namespace: {{ .Release.Namespace }} {{- end }} - - name: {{ .Release.Name }}-cilium - namespace: {{ .Release.Namespace }} {{- if .Values.addons.certManager.valuesOverride }} --- apiVersion: v1 diff --git a/packages/apps/kubernetes/templates/helmreleases/csi.yaml b/packages/apps/kubernetes/templates/helmreleases/csi.yaml index 09927e8a..3ecbf1eb 100644 --- a/packages/apps/kubernetes/templates/helmreleases/csi.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/csi.yaml @@ -37,6 +37,8 @@ spec: dependsOn: - name: {{ .Release.Name }}-vsnap-crd namespace: {{ .Release.Namespace }} + - name: {{ .Release.Name }}-cilium + namespace: {{ .Release.Namespace }} {{- if lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" .Release.Namespace .Release.Name }} - name: {{ .Release.Name }} namespace: {{ .Release.Namespace }} diff --git a/packages/apps/kubernetes/templates/helmreleases/metrics-server.yaml b/packages/apps/kubernetes/templates/helmreleases/metrics-server.yaml new file mode 100644 index 00000000..394e6bb4 --- /dev/null +++ b/packages/apps/kubernetes/templates/helmreleases/metrics-server.yaml @@ -0,0 +1,42 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ .Release.Name }}-metrics-server + labels: + cozystack.io/repository: system + cozystack.io/target-cluster-name: {{ .Release.Name }} +spec: + releaseName: metrics-server + chart: + spec: + chart: cozy-metrics-server + reconcileStrategy: Revision + sourceRef: + kind: HelmRepository + name: cozystack-system + namespace: cozy-system + version: '>= 0.0.0-0' + kubeConfig: + secretRef: + name: {{ .Release.Name }}-admin-kubeconfig + key: super-admin.svc + targetNamespace: cozy-monitoring + storageNamespace: cozy-monitoring + interval: 5m + timeout: 10m + install: + createNamespace: true + remediation: + retries: -1 + upgrade: + remediation: + retries: -1 + dependsOn: + {{- if lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" .Release.Namespace .Release.Name }} + - name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + {{- end }} + - name: {{ .Release.Name }}-cilium + namespace: {{ .Release.Namespace }} + - name: {{ .Release.Name }}-prometheus-operator-crds + namespace: {{ .Release.Namespace }} diff --git a/packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml b/packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml index 8f914b08..cf93f233 100644 --- a/packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml @@ -44,6 +44,10 @@ spec: namespace: {{ .Release.Namespace }} - name: {{ .Release.Name }}-vertical-pod-autoscaler-crds namespace: {{ .Release.Namespace }} + - name: {{ .Release.Name }}-prometheus-operator-crds + namespace: {{ .Release.Namespace }} + - name: {{ .Release.Name }}-metrics-server + namespace: {{ .Release.Namespace }} values: vmagent: externalLabels: diff --git a/packages/apps/kubernetes/templates/helmreleases/prometheus-operator-crds.yaml b/packages/apps/kubernetes/templates/helmreleases/prometheus-operator-crds.yaml new file mode 100644 index 00000000..63972126 --- /dev/null +++ b/packages/apps/kubernetes/templates/helmreleases/prometheus-operator-crds.yaml @@ -0,0 +1,37 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ .Release.Name }}-prometheus-operator-crds + labels: + cozystack.io/repository: system + cozystack.io/target-cluster-name: {{ .Release.Name }} +spec: + releaseName: prometheus-operator-crds + chart: + spec: + chart: cozy-prometheus-operator-crds + reconcileStrategy: Revision + sourceRef: + kind: HelmRepository + name: cozystack-system + namespace: cozy-system + version: '>= 0.0.0-0' + kubeConfig: + secretRef: + name: {{ .Release.Name }}-admin-kubeconfig + key: super-admin.svc + targetNamespace: cozy-victoria-metrics-operator + storageNamespace: cozy-victoria-metrics-operator + interval: 5m + install: + createNamespace: true + remediation: + retries: -1 + upgrade: + remediation: + retries: -1 + dependsOn: + {{- if lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" .Release.Namespace .Release.Name }} + - name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + {{- end }} diff --git a/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yaml b/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yaml index 336c198b..71bdc9ee 100644 --- a/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yaml @@ -37,6 +37,4 @@ spec: - name: {{ .Release.Name }} namespace: {{ .Release.Namespace }} {{- end }} - - name: {{ .Release.Name }}-cilium - namespace: {{ .Release.Namespace }} {{- end }} diff --git a/packages/apps/kubernetes/templates/helmreleases/volumesnapshot_crd.yaml b/packages/apps/kubernetes/templates/helmreleases/volumesnapshot-crd.yaml similarity index 92% rename from packages/apps/kubernetes/templates/helmreleases/volumesnapshot_crd.yaml rename to packages/apps/kubernetes/templates/helmreleases/volumesnapshot-crd.yaml index 97cf06ad..83fa32d1 100644 --- a/packages/apps/kubernetes/templates/helmreleases/volumesnapshot_crd.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/volumesnapshot-crd.yaml @@ -37,5 +37,3 @@ spec: - name: {{ .Release.Name }} namespace: {{ .Release.Namespace }} {{- end }} - - name: {{ .Release.Name }}-cilium - namespace: {{ .Release.Namespace }} diff --git a/packages/apps/kubernetes/values.schema.json b/packages/apps/kubernetes/values.schema.json index 6092d35e..9ec0c416 100644 --- a/packages/apps/kubernetes/values.schema.json +++ b/packages/apps/kubernetes/values.schema.json @@ -492,7 +492,7 @@ } }, "host": { - "description": "External hostname for Kubernetes cluster. Defaults to `.` if empty.", + "description": "External hostname for Kubernetes cluster. Defaults to `\u003ccluster-name\u003e.\u003ctenant-host\u003e` if empty.", "type": "string", "default": "" }, @@ -615,17 +615,17 @@ "default": "replicated" }, "version": { - "description": "Kubernetes version (vMAJOR.MINOR). Supported: 1.28–1.33.", + "description": "Kubernetes major.minor version to deploy", "type": "string", "default": "v1.33", "enum": [ - "v1.28", - "v1.29", - "v1.30", - "v1.31", + "v1.33", "v1.32", - "v1.33" + "v1.31", + "v1.30", + "v1.29", + "v1.28" ] } } -} +} \ No newline at end of file diff --git a/packages/apps/kubernetes/values.yaml b/packages/apps/kubernetes/values.yaml index 312e0634..567d2e02 100644 --- a/packages/apps/kubernetes/values.yaml +++ b/packages/apps/kubernetes/values.yaml @@ -46,9 +46,19 @@ nodeGroups: resources: {} gpus: [] -## @param {string} version - Kubernetes version (vMAJOR.MINOR). Supported: 1.28–1.33. +## +## @enum {string} Version +## @value v1.33 +## @value v1.32 +## @value v1.31 +## @value v1.30 +## @value v1.29 +## @value v1.28 + +## @param {Version} version - Kubernetes major.minor version to deploy version: "v1.33" + ## @param {string} host - External hostname for Kubernetes cluster. Defaults to `.` if empty. host: "" diff --git a/packages/apps/mysql/.helmignore b/packages/apps/mysql/.helmignore index 1ea0ae84..3de7d4a5 100644 --- a/packages/apps/mysql/.helmignore +++ b/packages/apps/mysql/.helmignore @@ -1,3 +1,4 @@ .helmignore /logos /Makefile +/hack diff --git a/packages/apps/mysql/Makefile b/packages/apps/mysql/Makefile index 08c57889..f4ea3f78 100644 --- a/packages/apps/mysql/Makefile +++ b/packages/apps/mysql/Makefile @@ -7,6 +7,10 @@ generate: cozyvalues-gen -v values.yaml -s values.schema.json -r README.md ../../../hack/update-crd.sh +update: + hack/update-versions.sh + make generate + image: docker buildx build images/mariadb-backup \ --tag $(REGISTRY)/mariadb-backup:$(call settag,$(MARIADB_BACKUP_TAG)) \ diff --git a/packages/apps/mysql/README.md b/packages/apps/mysql/README.md index 6ea0352f..6d47a6d5 100644 --- a/packages/apps/mysql/README.md +++ b/packages/apps/mysql/README.md @@ -79,6 +79,7 @@ more details: | `size` | Persistent Volume Claim size available for application data. | `quantity` | `10Gi` | | `storageClass` | StorageClass used to store the data. | `string` | `""` | | `external` | Enable external access from outside the cluster. | `bool` | `false` | +| `version` | MariaDB major.minor version to deploy | `string` | `v11.8` | ### Application-specific parameters diff --git a/packages/apps/mysql/files/versions.yaml b/packages/apps/mysql/files/versions.yaml new file mode 100644 index 00000000..59c8814c --- /dev/null +++ b/packages/apps/mysql/files/versions.yaml @@ -0,0 +1,4 @@ +"v11.8": "11.8.5" +"v11.4": "11.4.9" +"v10.11": "10.11.15" +"v10.6": "10.6.24" diff --git a/packages/apps/mysql/hack/update-versions.sh b/packages/apps/mysql/hack/update-versions.sh new file mode 100755 index 00000000..1b58591a --- /dev/null +++ b/packages/apps/mysql/hack/update-versions.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +MYSQL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +VALUES_FILE="${MYSQL_DIR}/values.yaml" +VERSIONS_FILE="${MYSQL_DIR}/files/versions.yaml" +MARIADB_API_URL="https://downloads.mariadb.org/rest-api/mariadb/" + +# Check if jq is installed +if ! command -v jq &> /dev/null; then + echo "Error: jq is not installed. Please install jq and try again." >&2 + exit 1 +fi + +# Get LTS versions from MariaDB REST API +echo "Fetching LTS versions from MariaDB REST API..." +LTS_VERSIONS_JSON=$(curl -sSL "${MARIADB_API_URL}") + +if [ -z "$LTS_VERSIONS_JSON" ]; then + echo "Error: Could not fetch versions from MariaDB REST API" >&2 + exit 1 +fi + +# Extract LTS stable major versions +LTS_MAJOR_VERSIONS=$(echo "$LTS_VERSIONS_JSON" | jq -r '.major_releases[] | select(.release_support_type == "Long Term Support") | select(.release_status == "Stable") | .release_id' | sort -V -r) + +if [ -z "$LTS_MAJOR_VERSIONS" ]; then + echo "Error: Could not find any LTS stable versions" >&2 + exit 1 +fi + +echo "Found LTS major versions: $(echo "$LTS_MAJOR_VERSIONS" | tr '\n' ' ')" + +# Build versions map: major version -> latest patch version +declare -A VERSION_MAP +MAJOR_VERSIONS=() + +for major_version in $LTS_MAJOR_VERSIONS; do + echo "Fetching patch versions for ${major_version}..." + + # Get patch versions for this major version + PATCH_VERSIONS_JSON=$(curl -sSL "${MARIADB_API_URL}${major_version}") + + if [ -z "$PATCH_VERSIONS_JSON" ]; then + echo "Warning: Could not fetch patch versions for ${major_version}, skipping..." >&2 + continue + fi + + # Extract all stable patch version IDs (format: MAJOR.MINOR.PATCH) + # Filter only Stable releases + PATCH_VERSIONS=$(echo "$PATCH_VERSIONS_JSON" | jq -r --arg major "$major_version" '.releases | to_entries[] | select(.key | startswith($major + ".")) | select(.value.release_status == "Stable") | .key' | sort -V) + + # If no stable releases found, try to get any releases (for backwards compatibility) + if [ -z "$PATCH_VERSIONS" ]; then + PATCH_VERSIONS=$(echo "$PATCH_VERSIONS_JSON" | jq -r '.releases | keys[]' | grep -E "^${major_version}\." | sort -V) + fi + + if [ -z "$PATCH_VERSIONS" ]; then + echo "Warning: Could not find any patch versions for ${major_version}, skipping..." >&2 + continue + fi + + # Get the latest patch version + LATEST_PATCH=$(echo "$PATCH_VERSIONS" | tail -n1) + + # major_version already has format MAJOR.MINOR (e.g., "11.8") + VERSION_MAP["v${major_version}"]="${LATEST_PATCH}" + MAJOR_VERSIONS+=("v${major_version}") + echo "Found version: v${major_version} -> ${LATEST_PATCH}" +done + +if [ ${#MAJOR_VERSIONS[@]} -eq 0 ]; then + echo "Error: No matching versions found" >&2 + exit 1 +fi + +# Sort major versions in descending order (newest first) +IFS=$'\n' MAJOR_VERSIONS=($(printf '%s\n' "${MAJOR_VERSIONS[@]}" | sort -V -r)) +unset IFS + +echo "Major versions to add: ${MAJOR_VERSIONS[*]}" + +# Create/update versions.yaml file +echo "Updating $VERSIONS_FILE..." +{ + for major_ver in "${MAJOR_VERSIONS[@]}"; do + echo "\"${major_ver}\": \"${VERSION_MAP[$major_ver]}\"" + done +} > "$VERSIONS_FILE" + +echo "Successfully updated $VERSIONS_FILE" + +# Update values.yaml - enum with major.minor versions only +TEMP_FILE=$(mktemp) +trap "rm -f $TEMP_FILE" EXIT + +# Build new version section +NEW_VERSION_SECTION="## @enum {string} Version" +for major_ver in "${MAJOR_VERSIONS[@]}"; do + NEW_VERSION_SECTION="${NEW_VERSION_SECTION} +## @value $major_ver" +done +NEW_VERSION_SECTION="${NEW_VERSION_SECTION} + +## @param {Version} version - MariaDB major.minor version to deploy +version: ${MAJOR_VERSIONS[0]}" + +# Check if version section already exists +if grep -q "^## @enum {string} Version" "$VALUES_FILE"; then + # Version section exists, update it using awk + echo "Updating existing version section in $VALUES_FILE..." + + # Use awk to replace the section from "## @enum {string} Version" to "version: " (inclusive) + # Delete the old section and insert the new one + awk -v new_section="$NEW_VERSION_SECTION" ' + /^## @enum {string} Version/ { + in_section = 1 + print new_section + next + } + in_section && /^version: / { + in_section = 0 + next + } + in_section { + next + } + { print } + ' "$VALUES_FILE" > "$TEMP_FILE.tmp" + mv "$TEMP_FILE.tmp" "$VALUES_FILE" +else + # Version section doesn't exist, insert it before Application-specific parameters section + echo "Inserting new version section in $VALUES_FILE..." + + # Use awk to insert before "## @section Application-specific parameters" + awk -v new_section="$NEW_VERSION_SECTION" ' + /^## @section Application-specific parameters/ { + print new_section + print "" + } + { print } + ' "$VALUES_FILE" > "$TEMP_FILE.tmp" + mv "$TEMP_FILE.tmp" "$VALUES_FILE" +fi + +echo "Successfully updated $VALUES_FILE with major.minor versions: ${MAJOR_VERSIONS[*]}" + diff --git a/packages/apps/mysql/templates/_versions.tpl b/packages/apps/mysql/templates/_versions.tpl new file mode 100644 index 00000000..cd4ee0e1 --- /dev/null +++ b/packages/apps/mysql/templates/_versions.tpl @@ -0,0 +1,8 @@ +{{- define "mysql.versionMap" }} +{{- $versionMap := .Files.Get "files/versions.yaml" | fromYaml }} +{{- if not (hasKey $versionMap .Values.version) }} + {{- printf `MariaDB version %s is not supported, allowed versions are %s` $.Values.version (keys $versionMap) | fail }} +{{- end }} +{{- index $versionMap .Values.version }} +{{- end }} + diff --git a/packages/apps/mysql/templates/mariadb.yaml b/packages/apps/mysql/templates/mariadb.yaml index 1c95f9f5..b4a888d8 100644 --- a/packages/apps/mysql/templates/mariadb.yaml +++ b/packages/apps/mysql/templates/mariadb.yaml @@ -8,7 +8,7 @@ spec: name: {{ .Release.Name }}-credentials key: root - image: "mariadb:11.0.2" + image: "mariadb:{{ include "mysql.versionMap" $ }}" port: 3306 diff --git a/packages/apps/mysql/values.schema.json b/packages/apps/mysql/values.schema.json index d5db33ab..a36754b2 100644 --- a/packages/apps/mysql/values.schema.json +++ b/packages/apps/mysql/values.schema.json @@ -186,6 +186,17 @@ } } } + }, + "version": { + "description": "MariaDB major.minor version to deploy", + "type": "string", + "default": "v11.8", + "enum": [ + "v11.8", + "v11.4", + "v10.11", + "v10.6" + ] } } } \ No newline at end of file diff --git a/packages/apps/mysql/values.yaml b/packages/apps/mysql/values.yaml index 0d08ca58..c7726b7a 100644 --- a/packages/apps/mysql/values.yaml +++ b/packages/apps/mysql/values.yaml @@ -33,6 +33,16 @@ storageClass: "" ## @param {bool} external - Enable external access from outside the cluster. external: false +## +## @enum {string} Version +## @value v11.8 +## @value v11.4 +## @value v10.11 +## @value v10.6 + +## @param {Version} version - MariaDB major.minor version to deploy +version: v11.8 + ## ## @section Application-specific parameters ## diff --git a/packages/apps/postgres/.helmignore b/packages/apps/postgres/.helmignore index 1ea0ae84..3de7d4a5 100644 --- a/packages/apps/postgres/.helmignore +++ b/packages/apps/postgres/.helmignore @@ -1,3 +1,4 @@ .helmignore /logos /Makefile +/hack diff --git a/packages/apps/postgres/Makefile b/packages/apps/postgres/Makefile index 8b1dce9d..a2ba188f 100644 --- a/packages/apps/postgres/Makefile +++ b/packages/apps/postgres/Makefile @@ -3,3 +3,7 @@ include ../../../scripts/package.mk generate: cozyvalues-gen -v values.yaml -s values.schema.json -r README.md ../../../hack/update-crd.sh + +update: + hack/update-versions.sh + make generate diff --git a/packages/apps/postgres/README.md b/packages/apps/postgres/README.md index 61e8e05f..5a550f7a 100644 --- a/packages/apps/postgres/README.md +++ b/packages/apps/postgres/README.md @@ -76,6 +76,7 @@ See: | `size` | Persistent Volume Claim size available for application data. | `quantity` | `10Gi` | | `storageClass` | StorageClass used to store the data. | `string` | `""` | | `external` | Enable external access from outside the cluster. | `bool` | `false` | +| `version` | PostgreSQL major version to deploy | `string` | `v18` | ### Application-specific parameters diff --git a/packages/apps/postgres/files/versions.yaml b/packages/apps/postgres/files/versions.yaml new file mode 100644 index 00000000..e4fe13ea --- /dev/null +++ b/packages/apps/postgres/files/versions.yaml @@ -0,0 +1,6 @@ +"v18": "v18.1" +"v17": "v17.7" +"v16": "v16.11" +"v15": "v15.15" +"v14": "v14.20" +"v13": "v13.22" diff --git a/packages/apps/postgres/hack/update-versions.sh b/packages/apps/postgres/hack/update-versions.sh new file mode 100755 index 00000000..c92b3895 --- /dev/null +++ b/packages/apps/postgres/hack/update-versions.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +POSTGRES_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +VALUES_FILE="${POSTGRES_DIR}/values.yaml" +VERSIONS_FILE="${POSTGRES_DIR}/files/versions.yaml" + +# Get supported major versions from GitHub README +echo "Fetching supported major versions from GitHub..." +SUPPORTED_MAJOR_VERSIONS=$(curl -sSL 'https://raw.githubusercontent.com/cloudnative-pg/postgres-containers/refs/heads/main/README.md' | sed -n '/# CNPG PostgreSQL Container Images/,/#/p' | awk -F' +| +' '$4 ~ /[0-9]+\-[0-9]+\-[0-9]+/ && $6 ~ /[0-9]+\-[0-9]+\-[0-9]+/ {print $2}' | sort -u | xargs) + +if [ -z "$SUPPORTED_MAJOR_VERSIONS" ]; then + echo "Error: Could not fetch supported major versions" >&2 + exit 1 +fi + +echo "Supported major versions: $SUPPORTED_MAJOR_VERSIONS" + +# Check if skopeo is installed +if ! command -v skopeo &> /dev/null; then + echo "Error: skopeo is not installed. Please install skopeo and try again." >&2 + exit 1 +fi + +# Check if jq is installed +if ! command -v jq &> /dev/null; then + echo "Error: jq is not installed. Please install jq and try again." >&2 + exit 1 +fi + +# Get available image tags +echo "Fetching available image tags from registry..." +AVAILABLE_TAGS=$(skopeo list-tags docker://ghcr.io/cloudnative-pg/postgresql | jq -r '.Tags[] | select(test("^[0-9]+\\.[0-9]+$"))' | sort -V) + +if [ -z "$AVAILABLE_TAGS" ]; then + echo "Error: Could not fetch available image tags" >&2 + exit 1 +fi + +# Build versions map: major version -> latest minor version +declare -A VERSION_MAP +MAJOR_VERSIONS=() + +for major_version in $SUPPORTED_MAJOR_VERSIONS; do + # Extract major version number (e.g., "18" from "18.1") + major_num=$(echo "$major_version" | cut -d. -f1) + + # Find all tags that match this major version + matching_tags=$(echo "$AVAILABLE_TAGS" | grep "^${major_num}\\.") + + if [ -n "$matching_tags" ]; then + # Get the latest minor version for this major version + latest_tag=$(echo "$matching_tags" | tail -n1) + VERSION_MAP["v${major_num}"]="v${latest_tag}" + MAJOR_VERSIONS+=("v${major_num}") + echo "Found version: v${major_num} -> v${latest_tag}" + fi +done + +if [ ${#MAJOR_VERSIONS[@]} -eq 0 ]; then + echo "Error: No matching versions found" >&2 + exit 1 +fi + +# Sort major versions in descending order (newest first) +IFS=$'\n' MAJOR_VERSIONS=($(printf '%s\n' "${MAJOR_VERSIONS[@]}" | sort -V -r)) +unset IFS + +echo "Major versions to add: ${MAJOR_VERSIONS[*]}" + +# Create/update versions.yaml file +echo "Updating $VERSIONS_FILE..." +{ + for major_ver in "${MAJOR_VERSIONS[@]}"; do + echo "\"${major_ver}\": \"${VERSION_MAP[$major_ver]}\"" + done +} > "$VERSIONS_FILE" + +echo "Successfully updated $VERSIONS_FILE" + +# Update values.yaml - enum with major versions only +TEMP_FILE=$(mktemp) +trap "rm -f $TEMP_FILE" EXIT + +# Build new version section +NEW_VERSION_SECTION="## @enum {string} Version" +for major_ver in "${MAJOR_VERSIONS[@]}"; do + NEW_VERSION_SECTION="${NEW_VERSION_SECTION} +## @value $major_ver" +done +NEW_VERSION_SECTION="${NEW_VERSION_SECTION} + +## @param {Version} version - PostgreSQL major version to deploy +version: ${MAJOR_VERSIONS[0]}" + +# Check if version section already exists +if grep -q "^## @enum {string} Version" "$VALUES_FILE"; then + # Version section exists, update it using awk + echo "Updating existing version section in $VALUES_FILE..." + + # Use awk to replace the section from "## @enum {string} Version" to "version: " (inclusive) + # Delete the old section and insert the new one + awk -v new_section="$NEW_VERSION_SECTION" ' + /^## @enum {string} Version/ { + in_section = 1 + print new_section + next + } + in_section && /^version: / { + in_section = 0 + next + } + in_section { + next + } + { print } + ' "$VALUES_FILE" > "$TEMP_FILE.tmp" + mv "$TEMP_FILE.tmp" "$VALUES_FILE" +else + # Version section doesn't exist, insert it before Application-specific parameters section + echo "Inserting new version section in $VALUES_FILE..." + + # Use awk to insert before "## @section Application-specific parameters" + awk -v new_section="$NEW_VERSION_SECTION" ' + /^## @section Application-specific parameters/ { + print new_section + print "" + } + { print } + ' "$VALUES_FILE" > "$TEMP_FILE.tmp" + mv "$TEMP_FILE.tmp" "$VALUES_FILE" +fi + +echo "Successfully updated $VALUES_FILE with major versions: ${MAJOR_VERSIONS[*]}" diff --git a/packages/apps/postgres/templates/_versions.tpl b/packages/apps/postgres/templates/_versions.tpl new file mode 100644 index 00000000..ca0ff2a2 --- /dev/null +++ b/packages/apps/postgres/templates/_versions.tpl @@ -0,0 +1,8 @@ +{{- define "postgres.versionMap" }} +{{- $versionMap := .Files.Get "files/versions.yaml" | fromYaml }} +{{- if not (hasKey $versionMap .Values.version) }} + {{- printf `PostgreSQL version %s is not supported, allowed versions are %s` $.Values.version (keys $versionMap) | fail }} +{{- end }} +{{- index $versionMap .Values.version }} +{{- end }} + diff --git a/packages/apps/postgres/templates/db.yaml b/packages/apps/postgres/templates/db.yaml index de4f51a3..92fb34c6 100644 --- a/packages/apps/postgres/templates/db.yaml +++ b/packages/apps/postgres/templates/db.yaml @@ -44,6 +44,7 @@ spec: resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 4 }} + imageName: ghcr.io/cloudnative-pg/postgresql:{{ include "postgres.versionMap" $ | trimPrefix "v" }} enableSuperuserAccess: true {{- $configMap := lookup "v1" "ConfigMap" "cozy-system" "cozystack-scheduling" }} {{- if $configMap }} diff --git a/packages/apps/postgres/templates/init-job.yaml b/packages/apps/postgres/templates/init-job.yaml index f6c42dbd..323bfcaf 100644 --- a/packages/apps/postgres/templates/init-job.yaml +++ b/packages/apps/postgres/templates/init-job.yaml @@ -16,7 +16,7 @@ spec: restartPolicy: Never containers: - name: postgres - image: ghcr.io/cloudnative-pg/postgresql:15.3 + image: ghcr.io/cloudnative-pg/postgresql:{{ include "postgres.versionMap" $ | trimPrefix "v" }} command: - bash - /scripts/init.sh diff --git a/packages/apps/postgres/values.schema.json b/packages/apps/postgres/values.schema.json index ba4f6b36..005ff26c 100644 --- a/packages/apps/postgres/values.schema.json +++ b/packages/apps/postgres/values.schema.json @@ -243,6 +243,19 @@ } } } + }, + "version": { + "description": "PostgreSQL major version to deploy", + "type": "string", + "default": "v18", + "enum": [ + "v18", + "v17", + "v16", + "v15", + "v14", + "v13" + ] } } } \ No newline at end of file diff --git a/packages/apps/postgres/values.yaml b/packages/apps/postgres/values.yaml index a0d5e741..b8f07f63 100644 --- a/packages/apps/postgres/values.yaml +++ b/packages/apps/postgres/values.yaml @@ -34,6 +34,17 @@ storageClass: "" external: false ## +## @enum {string} Version +## @value v18 +## @value v17 +## @value v16 +## @value v15 +## @value v14 +## @value v13 + +## @param {Version} version - PostgreSQL major version to deploy +version: v18 + ## @section Application-specific parameters ## diff --git a/packages/apps/redis/.helmignore b/packages/apps/redis/.helmignore index 1ea0ae84..3de7d4a5 100644 --- a/packages/apps/redis/.helmignore +++ b/packages/apps/redis/.helmignore @@ -1,3 +1,4 @@ .helmignore /logos /Makefile +/hack diff --git a/packages/apps/redis/Makefile b/packages/apps/redis/Makefile index 8b1dce9d..a2ba188f 100644 --- a/packages/apps/redis/Makefile +++ b/packages/apps/redis/Makefile @@ -3,3 +3,7 @@ include ../../../scripts/package.mk generate: cozyvalues-gen -v values.yaml -s values.schema.json -r README.md ../../../hack/update-crd.sh + +update: + hack/update-versions.sh + make generate diff --git a/packages/apps/redis/README.md b/packages/apps/redis/README.md index 00f41d36..7f82d229 100644 --- a/packages/apps/redis/README.md +++ b/packages/apps/redis/README.md @@ -23,6 +23,7 @@ Service utilizes the Spotahome Redis Operator for efficient management and orche | `size` | Persistent Volume Claim size available for application data. | `quantity` | `1Gi` | | `storageClass` | StorageClass used to store the data. | `string` | `""` | | `external` | Enable external access from outside the cluster. | `bool` | `false` | +| `version` | Redis major version to deploy | `string` | `v8` | ### Application-specific parameters diff --git a/packages/apps/redis/files/versions.yaml b/packages/apps/redis/files/versions.yaml new file mode 100644 index 00000000..be1e42d6 --- /dev/null +++ b/packages/apps/redis/files/versions.yaml @@ -0,0 +1,2 @@ +"v8": "8.4.0" +"v7": "7.4.7" diff --git a/packages/apps/redis/hack/update-versions.sh b/packages/apps/redis/hack/update-versions.sh new file mode 100755 index 00000000..daad973e --- /dev/null +++ b/packages/apps/redis/hack/update-versions.sh @@ -0,0 +1,161 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REDIS_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +VALUES_FILE="${REDIS_DIR}/values.yaml" +VERSIONS_FILE="${REDIS_DIR}/files/versions.yaml" +REDIS_IMAGE="docker://docker.io/redis" + +# Check if skopeo is installed +if ! command -v skopeo &> /dev/null; then + echo "Error: skopeo is not installed. Please install skopeo and try again." >&2 + exit 1 +fi + +# Check if jq is installed +if ! command -v jq &> /dev/null; then + echo "Error: jq is not installed. Please install jq and try again." >&2 + exit 1 +fi + +# Get available image tags +echo "Fetching available image tags from registry..." +AVAILABLE_TAGS=$(skopeo list-tags "${REDIS_IMAGE}" | jq -r '.Tags[] | select(test("^[0-9]+\\.[0-9]+\\.[0-9]+$"))' | sort -V) + +if [ -z "$AVAILABLE_TAGS" ]; then + echo "Error: Could not fetch available image tags" >&2 + exit 1 +fi + +# Get all unique major versions and find Latest and Previous +echo "Finding Latest and Previous major versions..." +ALL_MAJOR_VERSIONS=$(echo "$AVAILABLE_TAGS" | cut -d. -f1 | sort -u -n -r) +MAJOR_VERSIONS_ARRAY=($ALL_MAJOR_VERSIONS) + +if [ ${#MAJOR_VERSIONS_ARRAY[@]} -lt 1 ]; then + echo "Error: Could not find any major versions" >&2 + exit 1 +fi + +# Get Latest and Previous major versions +LATEST_MAJOR=${MAJOR_VERSIONS_ARRAY[0]} +PREVIOUS_MAJOR="" + +if [ ${#MAJOR_VERSIONS_ARRAY[@]} -ge 2 ]; then + PREVIOUS_MAJOR=${MAJOR_VERSIONS_ARRAY[1]} +fi + +if [ -z "$PREVIOUS_MAJOR" ]; then + echo "Warning: Only one major version found (${LATEST_MAJOR}), using it as both Latest and Previous" + PREVIOUS_MAJOR=$LATEST_MAJOR +fi + +echo "Latest major version: ${LATEST_MAJOR}" +echo "Previous major version: ${PREVIOUS_MAJOR}" + +# Build versions map: major version -> latest patch version +declare -A VERSION_MAP +MAJOR_VERSIONS=() +PROCESSED_MAJORS=() + +for major_version in "$LATEST_MAJOR" "$PREVIOUS_MAJOR"; do + # Skip if we already processed this major version + if [[ " ${PROCESSED_MAJORS[@]} " =~ " ${major_version} " ]]; then + continue + fi + PROCESSED_MAJORS+=("${major_version}") + + # Find all tags that match this major version + matching_tags=$(echo "$AVAILABLE_TAGS" | grep "^${major_version}\\.") + + if [ -n "$matching_tags" ]; then + # Get the latest patch version for this major version + latest_tag=$(echo "$matching_tags" | tail -n1) + VERSION_MAP["v${major_version}"]="${latest_tag}" + MAJOR_VERSIONS+=("v${major_version}") + echo "Found version: v${major_version} -> ${latest_tag}" + else + echo "Warning: Could not find any patch versions for ${major_version}, skipping..." >&2 + fi +done + +if [ ${#MAJOR_VERSIONS[@]} -eq 0 ]; then + echo "Error: No matching versions found" >&2 + exit 1 +fi + +# Sort major versions in descending order (newest first) +IFS=$'\n' MAJOR_VERSIONS=($(printf '%s\n' "${MAJOR_VERSIONS[@]}" | sort -V -r)) +unset IFS + +echo "Major versions to add: ${MAJOR_VERSIONS[*]}" + +# Create/update versions.yaml file +echo "Updating $VERSIONS_FILE..." +{ + for major_ver in "${MAJOR_VERSIONS[@]}"; do + echo "\"${major_ver}\": \"${VERSION_MAP[$major_ver]}\"" + done +} > "$VERSIONS_FILE" + +echo "Successfully updated $VERSIONS_FILE" + +# Update values.yaml - enum with major versions only +TEMP_FILE=$(mktemp) +trap "rm -f $TEMP_FILE" EXIT + +# Build new version section +NEW_VERSION_SECTION="## @enum {string} Version" +for major_ver in "${MAJOR_VERSIONS[@]}"; do + NEW_VERSION_SECTION="${NEW_VERSION_SECTION} +## @value $major_ver" +done +NEW_VERSION_SECTION="${NEW_VERSION_SECTION} + +## @param {Version} version - Redis major version to deploy +version: ${MAJOR_VERSIONS[0]}" + +# Check if version section already exists +if grep -q "^## @enum {string} Version" "$VALUES_FILE"; then + # Version section exists, update it using awk + echo "Updating existing version section in $VALUES_FILE..." + + # Use awk to replace the section from "## @enum {string} Version" to "version: " (inclusive) + # Delete the old section and insert the new one + awk -v new_section="$NEW_VERSION_SECTION" ' + /^## @enum {string} Version/ { + in_section = 1 + print new_section + next + } + in_section && /^version: / { + in_section = 0 + next + } + in_section { + next + } + { print } + ' "$VALUES_FILE" > "$TEMP_FILE.tmp" + mv "$TEMP_FILE.tmp" "$VALUES_FILE" +else + # Version section doesn't exist, insert it before Application-specific parameters section + echo "Inserting new version section in $VALUES_FILE..." + + # Use awk to insert before "## @section Application-specific parameters" + awk -v new_section="$NEW_VERSION_SECTION" ' + /^## @section Application-specific parameters/ { + print new_section + print "" + } + { print } + ' "$VALUES_FILE" > "$TEMP_FILE.tmp" + mv "$TEMP_FILE.tmp" "$VALUES_FILE" +fi + +echo "Successfully updated $VALUES_FILE with major versions: ${MAJOR_VERSIONS[*]}" + diff --git a/packages/apps/redis/templates/_versions.tpl b/packages/apps/redis/templates/_versions.tpl new file mode 100644 index 00000000..758e3800 --- /dev/null +++ b/packages/apps/redis/templates/_versions.tpl @@ -0,0 +1,8 @@ +{{- define "redis.versionMap" }} +{{- $versionMap := .Files.Get "files/versions.yaml" | fromYaml }} +{{- if not (hasKey $versionMap .Values.version) }} + {{- printf `Redis version %s is not supported, allowed versions are %s` $.Values.version (keys $versionMap) | fail }} +{{- end }} +{{- index $versionMap .Values.version }} +{{- end }} + diff --git a/packages/apps/redis/templates/redisfailover.yaml b/packages/apps/redis/templates/redisfailover.yaml index 20e91646..936217a3 100644 --- a/packages/apps/redis/templates/redisfailover.yaml +++ b/packages/apps/redis/templates/redisfailover.yaml @@ -27,7 +27,7 @@ spec: replicas: 3 resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 6 }} redis: - image: "redis:8.2.0" + image: "redis:{{ include "redis.versionMap" $ }}" resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 6 }} replicas: {{ .Values.replicas }} {{- with .Values.size }} diff --git a/packages/apps/redis/values.schema.json b/packages/apps/redis/values.schema.json index db338803..5c01cc31 100644 --- a/packages/apps/redis/values.schema.json +++ b/packages/apps/redis/values.schema.json @@ -82,6 +82,15 @@ "description": "StorageClass used to store the data.", "type": "string", "default": "" + }, + "version": { + "description": "Redis major version to deploy", + "type": "string", + "default": "v8", + "enum": [ + "v8", + "v7" + ] } } } \ No newline at end of file diff --git a/packages/apps/redis/values.yaml b/packages/apps/redis/values.yaml index 87b01a57..efe80d07 100644 --- a/packages/apps/redis/values.yaml +++ b/packages/apps/redis/values.yaml @@ -33,6 +33,13 @@ storageClass: "" ## @param {bool} external - Enable external access from outside the cluster. external: false +## @enum {string} Version +## @value v8 +## @value v7 + +## @param {Version} version - Redis major version to deploy +version: v8 + ## ## @section Application-specific parameters ## diff --git a/packages/apps/virtual-machine/templates/vm-update-hook.yaml b/packages/apps/virtual-machine/templates/vm-update-hook.yaml index 74f76cc5..1197c027 100644 --- a/packages/apps/virtual-machine/templates/vm-update-hook.yaml +++ b/packages/apps/virtual-machine/templates/vm-update-hook.yaml @@ -27,7 +27,11 @@ {{- if and $existingPVC $desiredStorage -}} {{- $currentStorage := $existingPVC.spec.resources.requests.storage | toString -}} {{- if not (eq $currentStorage $desiredStorage) -}} - {{- $needResizePVC = true -}} + {{- $oldSize := (include "cozy-lib.resources.toFloat" $currentStorage) | float64 -}} + {{- $newSize := (include "cozy-lib.resources.toFloat" $desiredStorage) | float64 -}} + {{- if gt $newSize $oldSize -}} + {{- $needResizePVC = true -}} + {{- end -}} {{- end -}} {{- end -}} diff --git a/packages/apps/vm-disk/templates/pvc-resize-hook.yaml b/packages/apps/vm-disk/templates/pvc-resize-hook.yaml index 2619ed15..2454c599 100644 --- a/packages/apps/vm-disk/templates/pvc-resize-hook.yaml +++ b/packages/apps/vm-disk/templates/pvc-resize-hook.yaml @@ -1,5 +1,17 @@ {{- $existingPVC := lookup "v1" "PersistentVolumeClaim" .Release.Namespace .Release.Name }} -{{- if and $existingPVC (ne ($existingPVC.spec.resources.requests.storage | toString) .Values.storage) -}} +{{- $shouldResize := false -}} +{{- if and $existingPVC .Values.storage -}} + {{- $currentStorage := $existingPVC.spec.resources.requests.storage | toString -}} + {{- if ne $currentStorage .Values.storage -}} + {{- $oldSize := (include "cozy-lib.resources.toFloat" $currentStorage) | float64 -}} + {{- $newSize := (include "cozy-lib.resources.toFloat" .Values.storage) | float64 -}} + {{- if gt $newSize $oldSize -}} + {{- $shouldResize = true -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- if $shouldResize -}} apiVersion: batch/v1 kind: Job metadata: @@ -23,6 +35,7 @@ spec: command: ["sh", "-xec"] args: - | + echo "Resizing PVC to {{ .Values.storage }}..." kubectl patch pvc {{ .Release.Name }} -p '{"spec":{"resources":{"requests":{"storage":"{{ .Values.storage }}"}}}}' --- apiVersion: v1 diff --git a/packages/core/installer/images/cozystack/Dockerfile b/packages/core/installer/images/cozystack/Dockerfile index 7327698e..c964c027 100644 --- a/packages/core/installer/images/cozystack/Dockerfile +++ b/packages/core/installer/images/cozystack/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.24-alpine as k8s-await-election-builder +FROM golang:1.24-alpine AS k8s-await-election-builder ARG K8S_AWAIT_ELECTION_GITREPO=https://github.com/LINBIT/k8s-await-election ARG K8S_AWAIT_ELECTION_VERSION=0.4.1 @@ -13,7 +13,7 @@ RUN git clone ${K8S_AWAIT_ELECTION_GITREPO} /usr/local/go/k8s-await-election/ \ && make \ && mv ./out/k8s-await-election-${TARGETARCH} /k8s-await-election -FROM golang:1.24-alpine as builder +FROM golang:1.24-alpine AS builder ARG TARGETOS ARG TARGETARCH diff --git a/packages/core/platform/bundles/distro-full.yaml b/packages/core/platform/bundles/distro-full.yaml index ed52a83a..107cbb23 100644 --- a/packages/core/platform/bundles/distro-full.yaml +++ b/packages/core/platform/bundles/distro-full.yaml @@ -74,6 +74,18 @@ releases: namespace: cozy-system dependsOn: [cozystack-controller,cilium,cert-manager] +- name: cozystack-resource-definition-crd + releaseName: cozystack-resource-definition-crd + chart: cozystack-resource-definition-crd + namespace: cozy-system + dependsOn: [cilium] + +- name: cozystack-resource-definitions + releaseName: cozystack-resource-definitions + chart: cozystack-resource-definitions + namespace: cozy-system + dependsOn: [cilium,cozystack-controller,cozystack-resource-definition-crd] + - name: cert-manager releaseName: cert-manager chart: cozy-cert-manager @@ -84,15 +96,26 @@ releases: releaseName: cert-manager-issuers chart: cozy-cert-manager-issuers namespace: cozy-cert-manager - optional: true dependsOn: [cilium,cert-manager] +- name: prometheus-operator-crds + releaseName: prometheus-operator-crds + chart: cozy-prometheus-operator-crds + namespace: cozy-victoria-metrics-operator + dependsOn: [] + +- name: metrics-server + releaseName: metrics-server + chart: cozy-metrics-server + namespace: cozy-monitoring + dependsOn: [cilium,prometheus-operator-crds] + - name: victoria-metrics-operator releaseName: victoria-metrics-operator chart: cozy-victoria-metrics-operator namespace: cozy-victoria-metrics-operator optional: true - dependsOn: [cilium,cert-manager] + dependsOn: [cilium,cert-manager,prometheus-operator-crds] - name: monitoring-agents releaseName: monitoring-agents @@ -100,7 +123,7 @@ releases: namespace: cozy-monitoring privileged: true optional: true - dependsOn: [cilium,victoria-metrics-operator] + dependsOn: [cilium,victoria-metrics-operator,metrics-server] values: scrapeRules: etcd: @@ -192,7 +215,7 @@ releases: releaseName: snapshot-controller chart: cozy-snapshot-controller namespace: cozy-snapshot-controller - dependsOn: [cilium] + dependsOn: [cilium,cert-manager-issuers] - name: objectstorage-controller releaseName: objectstorage-controller diff --git a/packages/core/platform/bundles/distro-hosted.yaml b/packages/core/platform/bundles/distro-hosted.yaml index 83aa81d9..02653a21 100644 --- a/packages/core/platform/bundles/distro-hosted.yaml +++ b/packages/core/platform/bundles/distro-hosted.yaml @@ -55,12 +55,24 @@ releases: optional: true dependsOn: [cert-manager] +- name: prometheus-operator-crds + releaseName: prometheus-operator-crds + chart: cozy-prometheus-operator-crds + namespace: cozy-victoria-metrics-operator + dependsOn: [] + +- name: metrics-server + releaseName: metrics-server + chart: cozy-metrics-server + namespace: cozy-monitoring + dependsOn: [prometheus-operator-crds] + - name: victoria-metrics-operator releaseName: victoria-metrics-operator chart: cozy-victoria-metrics-operator namespace: cozy-victoria-metrics-operator optional: true - dependsOn: [cert-manager] + dependsOn: [prometheus-operator-crds,cert-manager] - name: monitoring-agents releaseName: monitoring-agents @@ -68,7 +80,7 @@ releases: namespace: cozy-monitoring privileged: true optional: true - dependsOn: [victoria-metrics-operator] + dependsOn: [victoria-metrics-operator, metrics-server] values: scrapeRules: etcd: diff --git a/packages/core/platform/bundles/paas-full.yaml b/packages/core/platform/bundles/paas-full.yaml index 4382bd62..829f06f6 100644 --- a/packages/core/platform/bundles/paas-full.yaml +++ b/packages/core/platform/bundles/paas-full.yaml @@ -112,6 +112,12 @@ releases: disableTelemetry: true {{- end }} +- name: backup-controller + releaseName: backup-controller + chart: cozy-backup-controller + namespace: cozy-backup-controller + dependsOn: [cilium,kubeovn] + - name: lineage-controller-webhook releaseName: lineage-controller-webhook chart: cozy-lineage-controller-webhook @@ -142,18 +148,30 @@ releases: namespace: cozy-cert-manager dependsOn: [cilium,kubeovn,cert-manager] +- name: prometheus-operator-crds + releaseName: prometheus-operator-crds + chart: cozy-prometheus-operator-crds + namespace: cozy-victoria-metrics-operator + dependsOn: [] + +- name: metrics-server + releaseName: metrics-server + chart: cozy-metrics-server + namespace: cozy-monitoring + dependsOn: [cilium,kubeovn,prometheus-operator-crds] + - name: victoria-metrics-operator releaseName: victoria-metrics-operator chart: cozy-victoria-metrics-operator namespace: cozy-victoria-metrics-operator - dependsOn: [cilium,kubeovn,cert-manager] + dependsOn: [cilium,kubeovn,cert-manager,prometheus-operator-crds] - name: monitoring-agents releaseName: monitoring-agents chart: cozy-monitoring-agents namespace: cozy-monitoring privileged: true - dependsOn: [victoria-metrics-operator, vertical-pod-autoscaler-crds] + dependsOn: [victoria-metrics-operator, vertical-pod-autoscaler-crds, metrics-server] values: scrapeRules: etcd: diff --git a/packages/core/platform/bundles/paas-hosted.yaml b/packages/core/platform/bundles/paas-hosted.yaml index 560578c7..906da056 100644 --- a/packages/core/platform/bundles/paas-hosted.yaml +++ b/packages/core/platform/bundles/paas-hosted.yaml @@ -56,6 +56,11 @@ releases: disableTelemetry: true {{- end }} +- name: backup-controller + releaseName: backup-controller + chart: cozy-backup-controller + namespace: cozy-backup-controller + - name: lineage-controller-webhook releaseName: lineage-controller-webhook chart: cozy-lineage-controller-webhook @@ -86,18 +91,30 @@ releases: namespace: cozy-cert-manager dependsOn: [cert-manager] +- name: prometheus-operator-crds + releaseName: prometheus-operator-crds + chart: cozy-prometheus-operator-crds + namespace: cozy-victoria-metrics-operator + dependsOn: [] + +- name: metrics-server + releaseName: metrics-server + chart: cozy-metrics-server + namespace: cozy-monitoring + dependsOn: [prometheus-operator-crds] + - name: victoria-metrics-operator releaseName: victoria-metrics-operator chart: cozy-victoria-metrics-operator namespace: cozy-victoria-metrics-operator - dependsOn: [cert-manager] + dependsOn: [cert-manager,prometheus-operator-crds] - name: monitoring-agents releaseName: monitoring-agents chart: cozy-monitoring-agents namespace: cozy-monitoring privileged: true - dependsOn: [victoria-metrics-operator, vertical-pod-autoscaler-crds] + dependsOn: [victoria-metrics-operator, vertical-pod-autoscaler-crds, metrics-server] values: scrapeRules: etcd: diff --git a/packages/extra/monitoring/README.md b/packages/extra/monitoring/README.md index 3666765b..20327fd9 100644 --- a/packages/extra/monitoring/README.md +++ b/packages/extra/monitoring/README.md @@ -91,3 +91,12 @@ | `grafana.resources.limits.cpu` | CPU limit. | `quantity` | `1` | | `grafana.resources.limits.memory` | Memory limit. | `quantity` | `1Gi` | + +### Vmagent configuration + +| Name | Description | Type | Value | +| ------------------------ | ---------------------------------------- | -------- | ----- | +| `vmagent` | Configuration for VictoriaMetrics Agent. | `object` | `{}` | +| `vmagent.externalLabels` | External labels applied to all metrics. | `object` | `{}` | +| `vmagent.remoteWrite` | Remote write configuration. | `object` | `{}` | + diff --git a/packages/extra/monitoring/templates/vm/vmagent.yaml b/packages/extra/monitoring/templates/vm/vmagent.yaml new file mode 100644 index 00000000..2c6c391a --- /dev/null +++ b/packages/extra/monitoring/templates/vm/vmagent.yaml @@ -0,0 +1,30 @@ +{{- if ne .Release.Namespace "tenant-root" }} +apiVersion: operator.victoriametrics.com/v1beta1 +kind: VMAgent +metadata: + name: vmagent +spec: + podMetadata: + labels: + policy.cozystack.io/allow-to-apiserver: "true" + shardCount: 1 + externalLabels: + cluster: {{ .Values.vmagent.externalLabels.cluster }} + tenant: {{ .Release.Namespace }} + extraArgs: + promscrape.maxScrapeSize: "32MB" + promscrape.streamParse: "true" + remoteWrite: + {{- range .Values.vmagent.remoteWrite.urls }} + - url: {{ . | quote }} + {{- end }} + + scrapeInterval: 30s + selectAllByDefault: false + podScrapeNamespaceSelector: + matchLabels: + namespace.cozystack.io/monitoring: {{ .Release.Namespace }} + serviceScrapeNamespaceSelector: + matchLabels: + namespace.cozystack.io/monitoring: {{ .Release.Namespace }} +{{- end }} diff --git a/packages/extra/monitoring/values.schema.json b/packages/extra/monitoring/values.schema.json index de81acd1..21b3b798 100644 --- a/packages/extra/monitoring/values.schema.json +++ b/packages/extra/monitoring/values.schema.json @@ -560,6 +560,28 @@ } } } + }, + "vmagent": { + "description": "Configuration for VictoriaMetrics Agent.", + "type": "object", + "default": {}, + "properties": { + "externalLabels": { + "description": "External labels applied to all metrics.", + "default": { + "cluster": "cozystack" + } + }, + "remoteWrite": { + "description": "Remote write configuration.", + "default": { + "urls": [ + "http://vminsert-shortterm:8480/insert/0/prometheus", + "http://vminsert-longterm:8480/insert/0/prometheus" + ] + } + } + } } } } \ No newline at end of file diff --git a/packages/extra/monitoring/values.yaml b/packages/extra/monitoring/values.yaml index d687f213..f4e1043e 100644 --- a/packages/extra/monitoring/values.yaml +++ b/packages/extra/monitoring/values.yaml @@ -154,3 +154,25 @@ grafana: requests: cpu: 100m memory: 256Mi +## +## @section Vmagent configuration +## + +## @typedef {struct} VmagentRemoteWrite - Remote write configuration. +## @typedef {stringSlice} VmagentRemoteWriteURLs - List of remoteWrite endpoint URLs. + +## @typedef {struct} VmagentExternalLabels - External labels for metrics. +## @field {string} [] - Label value for the given key. + +## @typedef {struct} Vmagent - VictoriaMetrics Agent configuration. +## @field {VmagentExternalLabels} [externalLabels] - External labels applied to all metrics. +## @field {VmagentRemoteWrite} [remoteWrite] - Remote write configuration. + +## @param {Vmagent} vmagent - Configuration for VictoriaMetrics Agent. +vmagent: + externalLabels: + cluster: cozystack + remoteWrite: + urls: + - http://vminsert-shortterm:8480/insert/0/prometheus + - http://vminsert-longterm:8480/insert/0/prometheus diff --git a/packages/system/Makefile b/packages/system/Makefile index 2104647b..e068be8a 100644 --- a/packages/system/Makefile +++ b/packages/system/Makefile @@ -1,11 +1,13 @@ OUT=../../_out/repos/system -CHARTS := $(shell find . -maxdepth 2 -name Chart.yaml | awk -F/ '{print $$2}') +CHARTS := $(shell grep -F 'version: 0.0.0' */Chart.yaml | cut -f1 -d/) +VERSIONED_CHARTS := $(shell grep '^version:' */Chart.yaml | grep -Fv '0.0.0' | cut -f1 -d/) include ../../scripts/common-envs.mk repo: rm -rf "$(OUT)" helm package -d "$(OUT)" $(CHARTS) --version $(COZYSTACK_VERSION) + helm package -d "$(OUT)" $(VERSIONED_CHARTS) cd "$(OUT)" && helm repo index . fix-charts: diff --git a/packages/system/backup-controller/Chart.yaml b/packages/system/backup-controller/Chart.yaml new file mode 100644 index 00000000..fd135712 --- /dev/null +++ b/packages/system/backup-controller/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: cozy-backup-controller +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/backup-controller/Makefile b/packages/system/backup-controller/Makefile new file mode 100644 index 00000000..56d58f20 --- /dev/null +++ b/packages/system/backup-controller/Makefile @@ -0,0 +1,18 @@ +NAME=backup-controller +NAMESPACE=cozy-backup-controller + +include ../../../scripts/common-envs.mk +include ../../../scripts/package.mk + +image: image-backup-controller + +image-backup-controller: + docker buildx build -f images/backup-controller/Dockerfile ../../.. \ + --tag $(REGISTRY)/backup-controller:$(call settag,$(TAG)) \ + --cache-from type=registry,ref=$(REGISTRY)/backup-controller:latest \ + --cache-to type=inline \ + --metadata-file images/backup-controller.json \ + $(BUILDX_ARGS) + IMAGE="$(REGISTRY)/backup-controller:$(call settag,$(TAG))@$$(yq e '."containerimage.digest"' images/backup-controller.json -o json -r)" \ + yq -i '.backupController.image = strenv(IMAGE)' values.yaml + rm -f images/backup-controller.json diff --git a/packages/system/backup-controller/definitions/.gitattributes b/packages/system/backup-controller/definitions/.gitattributes new file mode 100644 index 00000000..aae64e23 --- /dev/null +++ b/packages/system/backup-controller/definitions/.gitattributes @@ -0,0 +1 @@ +* linguist-generated diff --git a/packages/system/backup-controller/definitions/backups.cozystack.io_backupjobs.yaml b/packages/system/backup-controller/definitions/backups.cozystack.io_backupjobs.yaml new file mode 100644 index 00000000..794d8121 --- /dev/null +++ b/packages/system/backup-controller/definitions/backups.cozystack.io_backupjobs.yaml @@ -0,0 +1,231 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: backupjobs.backups.cozystack.io +spec: + group: backups.cozystack.io + names: + kind: BackupJob + listKind: BackupJobList + plural: backupjobs + singular: backupjob + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + BackupJob represents a single execution of a backup. + It is typically created by a Plan controller when a schedule fires. + 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: + description: BackupJobSpec describes the execution of a single backup + operation. + properties: + applicationRef: + description: |- + ApplicationRef holds a reference to the managed application whose state + is being backed up. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + planRef: + description: |- + PlanRef refers to the Plan that requested this backup run. + For ad-hoc/manual backups, this can be omitted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + storageRef: + description: |- + StorageRef holds a reference to the Storage object that describes where + the backup will be stored. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + strategyRef: + description: |- + StrategyRef holds a reference to the driver-specific BackupStrategy object + that describes how the backup should be created. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + required: + - applicationRef + - storageRef + - strategyRef + type: object + status: + description: BackupJobStatus represents the observed state of a BackupJob. + properties: + backupRef: + description: BackupRef refers to the Backup object created by this + run, if any. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + completedAt: + description: |- + CompletedAt is the time at which the backup run completed (successfully + or otherwise). + format: date-time + type: string + conditions: + description: Conditions represents the latest available observations + of a BackupJob's state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + message: + description: |- + Message is a human-readable message indicating details about why the + backup run is in its current phase, if any. + type: string + phase: + description: |- + Phase is a high-level summary of the run's state. + Typical values: Pending, Running, Succeeded, Failed. + type: string + startedAt: + description: StartedAt is the time at which the backup run started. + format: date-time + type: string + type: object + type: object + served: true + storage: true diff --git a/packages/system/backup-controller/definitions/backups.cozystack.io_backups.yaml b/packages/system/backup-controller/definitions/backups.cozystack.io_backups.yaml new file mode 100644 index 00000000..1bae551f --- /dev/null +++ b/packages/system/backup-controller/definitions/backups.cozystack.io_backups.yaml @@ -0,0 +1,234 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: backups.backups.cozystack.io +spec: + group: backups.cozystack.io + names: + kind: Backup + listKind: BackupList + plural: backups + singular: backup + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Backup represents a single backup artifact for a given application. + 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: + description: BackupSpec describes an immutable backup artifact produced + by a BackupJob. + properties: + applicationRef: + description: ApplicationRef refers to the application that was backed + up. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + driverMetadata: + additionalProperties: + type: string + description: |- + DriverMetadata holds driver-specific, opaque metadata associated with + this backup (for example snapshot IDs, schema versions, etc.). + This data is not interpreted by the core backup controllers. + type: object + planRef: + description: |- + PlanRef refers to the Plan that produced this backup, if any. + For manually triggered backups, this can be omitted. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + storageRef: + description: |- + StorageRef refers to the Storage object that describes where the backup + artifact is stored. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + strategyRef: + description: |- + StrategyRef refers to the driver-specific BackupStrategy that was used + to create this backup. This allows the driver to later perform restores. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + takenAt: + description: |- + TakenAt is the time at which the backup was taken (as reported by the + driver). It may differ slightly from metadata.creationTimestamp. + format: date-time + type: string + required: + - applicationRef + - storageRef + - strategyRef + - takenAt + type: object + status: + description: BackupStatus represents the observed state of a Backup. + properties: + artifact: + description: Artifact describes the stored backup object, if available. + properties: + checksum: + description: |- + Checksum is the checksum of the artifact, if computed. + For example: "sha256:". + type: string + sizeBytes: + description: SizeBytes is the size of the artifact in bytes, if + known. + format: int64 + type: integer + uri: + description: |- + URI is a driver-/storage-specific URI pointing to the backup artifact. + For example: s3://bucket/prefix/file.tar.gz + type: string + required: + - uri + type: object + conditions: + description: Conditions represents the latest available observations + of a Backup's state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + phase: + description: |- + Phase is a simple, high-level summary of the backup's state. + Typical values are: Pending, Ready, Failed. + type: string + type: object + type: object + served: true + storage: true diff --git a/packages/system/backup-controller/definitions/backups.cozystack.io_plans.yaml b/packages/system/backup-controller/definitions/backups.cozystack.io_plans.yaml new file mode 100644 index 00000000..b41d8e45 --- /dev/null +++ b/packages/system/backup-controller/definitions/backups.cozystack.io_plans.yaml @@ -0,0 +1,135 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: plans.backups.cozystack.io +spec: + group: backups.cozystack.io + names: + kind: Plan + listKind: PlanList + plural: plans + singular: plan + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + Plan describes the schedule, method and storage location for the + backup of a given target application. + 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: + description: |- + PlanSpec references the storage, the strategy, the application to be + backed up and specifies the timetable on which the backups will run. + properties: + applicationRef: + description: |- + ApplicationRef holds a reference to the managed application, + whose state and configuration must be backed up. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + schedule: + description: Schedule specifies when backup copies are created. + properties: + cron: + description: |- + Cron contains the cron spec for scheduling backups. Must be + specified if the schedule type is `cron`. Since only `cron` is + supported, omitting this field is not allowed. + type: string + type: + description: |- + Type is the type of schedule specification. Supported values are + [`cron`]. If omitted, defaults to `cron`. + type: string + type: object + storageRef: + description: |- + StorageRef holds a reference to the Storage object that + describes the location where the backup will be stored. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + strategyRef: + description: |- + StrategyRef holds a reference to the Strategy object that + describes, how a backup copy is to be created. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + required: + - applicationRef + - schedule + - storageRef + - strategyRef + type: object + type: object + served: true + storage: true diff --git a/packages/system/backup-controller/definitions/backups.cozystack.io_restorejobs.yaml b/packages/system/backup-controller/definitions/backups.cozystack.io_restorejobs.yaml new file mode 100644 index 00000000..607a69b2 --- /dev/null +++ b/packages/system/backup-controller/definitions/backups.cozystack.io_restorejobs.yaml @@ -0,0 +1,168 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: restorejobs.backups.cozystack.io +spec: + group: backups.cozystack.io + names: + kind: RestoreJob + listKind: RestoreJobList + plural: restorejobs + singular: restorejob + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: RestoreJob represents a single execution of a restore from a + Backup. + 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: + description: RestoreJobSpec describes the execution of a single restore + operation. + properties: + backupRef: + description: BackupRef refers to the Backup that should be restored. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + targetApplicationRef: + description: |- + TargetApplicationRef refers to the application into which the backup + should be restored. If omitted, the driver SHOULD restore into the same + application as referenced by backup.spec.applicationRef. + properties: + apiGroup: + description: |- + APIGroup is the group for the resource being referenced. + If APIGroup is not specified, the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + required: + - backupRef + type: object + status: + description: RestoreJobStatus represents the observed state of a RestoreJob. + properties: + completedAt: + description: |- + CompletedAt is the time at which the restore run completed (successfully + or otherwise). + format: date-time + type: string + conditions: + description: Conditions represents the latest available observations + of a RestoreJob's state. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + message: + description: |- + Message is a human-readable message indicating details about why the + restore run is in its current phase, if any. + type: string + phase: + description: |- + Phase is a high-level summary of the run's state. + Typical values: Pending, Running, Succeeded, Failed. + type: string + startedAt: + description: StartedAt is the time at which the restore run started. + format: date-time + type: string + type: object + type: object + served: true + storage: true diff --git a/packages/system/backup-controller/images/backup-controller/Dockerfile b/packages/system/backup-controller/images/backup-controller/Dockerfile new file mode 100644 index 00000000..cdf53c7b --- /dev/null +++ b/packages/system/backup-controller/images/backup-controller/Dockerfile @@ -0,0 +1,23 @@ +FROM golang:1.24-alpine AS builder + +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /workspace + +COPY go.mod go.sum ./ +RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go mod download + +COPY api api/ +COPY pkg pkg/ +COPY cmd cmd/ +COPY internal internal/ + +RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -ldflags="-extldflags=-static" -o /backup-controller cmd/backup-controller/main.go + +FROM scratch + +COPY --from=builder /backup-controller /backup-controller +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt + +ENTRYPOINT ["/backup-controller"] diff --git a/packages/system/backup-controller/templates/crds.yaml b/packages/system/backup-controller/templates/crds.yaml new file mode 100644 index 00000000..2cf3183b --- /dev/null +++ b/packages/system/backup-controller/templates/crds.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "definitions/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/backup-controller/templates/deployment.yaml b/packages/system/backup-controller/templates/deployment.yaml new file mode 100644 index 00000000..a8c3d07e --- /dev/null +++ b/packages/system/backup-controller/templates/deployment.yaml @@ -0,0 +1,57 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: backup-controller + labels: + app: backup-controller +spec: + replicas: {{ .Values.backupController.replicas }} + selector: + matchLabels: + app: backup-controller + template: + metadata: + labels: + app: backup-controller + spec: + tolerations: + - key: "node-role.kubernetes.io/control-plane" + operator: "Exists" + effect: "NoSchedule" + - key: "node-role.kubernetes.io/master" + operator: "Exists" + effect: "NoSchedule" + serviceAccountName: backup-controller + containers: + - name: backup-controller + image: "{{ .Values.backupController.image }}" + args: + - --leader-elect + {{- if .Values.backupController.metrics.enable }} + - --metrics-bind-address={{ .Values.backupController.metrics.bindAddress }} + {{- end }} + {{- if .Values.backupController.debug }} + - --zap-log-level=debug + {{- else }} + - --zap-log-level=info + {{- end }} + ports: + - name: metrics + containerPort: {{ split ":" .Values.backupController.metrics.bindAddress | mustLast }} + - name: health + containerPort: 8081 + readinessProbe: + httpGet: + path: /readyz + port: health + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /healthz + port: health + initialDelaySeconds: 15 + periodSeconds: 20 + {{- with .Values.backupController.resources }} + resources: {{- . | toYaml | nindent 10 }} + {{- end }} diff --git a/packages/system/backup-controller/templates/rbac-bind.yaml b/packages/system/backup-controller/templates/rbac-bind.yaml new file mode 100644 index 00000000..cbe9b5b8 --- /dev/null +++ b/packages/system/backup-controller/templates/rbac-bind.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: backups.cozystack.io:core-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: backups.cozystack.io:core-controller +subjects: +- kind: ServiceAccount + name: backup-controller + namespace: {{ .Release.Namespace }} diff --git a/packages/system/backup-controller/templates/rbac.yaml b/packages/system/backup-controller/templates/rbac.yaml new file mode 100644 index 00000000..71c4af69 --- /dev/null +++ b/packages/system/backup-controller/templates/rbac.yaml @@ -0,0 +1,11 @@ +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: backups.cozystack.io:core-controller +rules: +- apiGroups: ["backups.cozystack.io"] + resources: ["plans"] + verbs: ["get", "list", "watch"] +- apiGroups: ["backups.cozystack.io"] + resources: ["backupjobs"] + verbs: ["create", "get", "list", "watch"] diff --git a/packages/system/backup-controller/templates/sa.yaml b/packages/system/backup-controller/templates/sa.yaml new file mode 100644 index 00000000..4a180dd2 --- /dev/null +++ b/packages/system/backup-controller/templates/sa.yaml @@ -0,0 +1,4 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: backup-controller diff --git a/packages/system/backup-controller/values.yaml b/packages/system/backup-controller/values.yaml new file mode 100644 index 00000000..557c201a --- /dev/null +++ b/packages/system/backup-controller/values.yaml @@ -0,0 +1,14 @@ +backupController: + image: "" + replicas: 2 + debug: false + metrics: + enabled: true + bindAddress: ":8443" + resources: + requests: + cpu: 10m + memory: 64Mi + limits: + cpu: 500m + memory: 128Mi diff --git a/packages/system/coredns/values.yaml b/packages/system/coredns/values.yaml index b52efda2..a1061a1e 100644 --- a/packages/system/coredns/values.yaml +++ b/packages/system/coredns/values.yaml @@ -3,3 +3,6 @@ coredns: repository: registry.k8s.io/coredns/coredns tag: v1.12.4 replicaCount: 2 + k8sAppLabelOverride: kube-dns + service: + name: kube-dns diff --git a/packages/system/cozystack-resource-definitions/cozyrds/kubernetes.yaml b/packages/system/cozystack-resource-definitions/cozyrds/kubernetes.yaml index 86e8694d..05ed110f 100644 --- a/packages/system/cozystack-resource-definitions/cozyrds/kubernetes.yaml +++ b/packages/system/cozystack-resource-definitions/cozyrds/kubernetes.yaml @@ -8,7 +8,7 @@ spec: singular: kubernetes plural: kuberneteses openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"addons":{"description":"Cluster addons configuration.","type":"object","default":{},"required":["certManager","cilium","coredns","fluxcd","gatewayAPI","gpuOperator","ingressNginx","monitoringAgents","velero","verticalPodAutoscaler"],"properties":{"certManager":{"description":"Cert-manager addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable cert-manager.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"cilium":{"description":"Cilium CNI plugin.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"coredns":{"description":"CoreDNS addon.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"fluxcd":{"description":"FluxCD GitOps operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable FluxCD.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"gatewayAPI":{"description":"Gateway API addon.","type":"object","default":{},"required":["enabled"],"properties":{"enabled":{"description":"Enable Gateway API.","type":"boolean","default":false}}},"gpuOperator":{"description":"NVIDIA GPU Operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable GPU Operator.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"ingressNginx":{"description":"Ingress-NGINX controller.","type":"object","default":{},"required":["enabled","exposeMethod","valuesOverride"],"properties":{"enabled":{"description":"Enable the controller (requires nodes labeled `ingress-nginx`).","type":"boolean","default":false},"exposeMethod":{"description":"Method to expose the controller. Allowed values: `Proxied`, `LoadBalancer`.","type":"string","default":"Proxied"},"hosts":{"description":"Domains routed to this tenant cluster when `exposeMethod` is `Proxied`.","type":"array","default":[],"items":{"type":"string"}},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"monitoringAgents":{"description":"Monitoring agents.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable monitoring agents.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"velero":{"description":"Velero backup/restore addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable Velero.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"verticalPodAutoscaler":{"description":"Vertical Pod Autoscaler.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}}}},"controlPlane":{"description":"Kubernetes control-plane configuration.","type":"object","default":{},"required":["apiServer","controllerManager","konnectivity","replicas","scheduler"],"properties":{"apiServer":{"description":"API Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for API Server.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"medium","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"controllerManager":{"description":"Controller Manager configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Controller Manager.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"konnectivity":{"description":"Konnectivity configuration.","type":"object","default":{},"required":["server"],"properties":{"server":{"description":"Konnectivity Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Konnectivity.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"replicas":{"description":"Number of control-plane replicas.","type":"integer","default":2},"scheduler":{"description":"Scheduler configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Scheduler.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"host":{"description":"External hostname for Kubernetes cluster. Defaults to `.` if empty.","type":"string","default":""},"nodeGroups":{"description":"Worker nodes configuration map.","type":"object","default":{"md0":{"ephemeralStorage":"20Gi","gpus":[],"instanceType":"u1.medium","maxReplicas":10,"minReplicas":0,"resources":{},"roles":["ingress-nginx"]}},"additionalProperties":{"type":"object","required":["ephemeralStorage","instanceType","maxReplicas","minReplicas","resources"],"properties":{"ephemeralStorage":{"description":"Ephemeral storage size.","default":"20Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","items":{"type":"object","required":["name"],"properties":{"name":{"description":"Name of GPU, such as \"nvidia.com/AD102GL_L40S\".","type":"string"}}}},"instanceType":{"description":"Virtual machine instance type.","type":"string","default":"u1.medium"},"maxReplicas":{"description":"Maximum number of replicas.","type":"integer","default":10},"minReplicas":{"description":"Minimum number of replicas.","type":"integer","default":0},"resources":{"description":"CPU and memory resources for each worker node.","type":"object","properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"roles":{"description":"List of node roles.","type":"array","items":{"type":"string"}}}}},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"},"version":{"description":"Kubernetes version (vMAJOR.MINOR). Supported: 1.28–1.33.","type":"string","default":"v1.33","enum":["v1.28","v1.29","v1.30","v1.31","v1.32","v1.33"]}}} + {"title":"Chart Values","type":"object","properties":{"addons":{"description":"Cluster addons configuration.","type":"object","default":{},"required":["certManager","cilium","coredns","fluxcd","gatewayAPI","gpuOperator","ingressNginx","monitoringAgents","velero","verticalPodAutoscaler"],"properties":{"certManager":{"description":"Cert-manager addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable cert-manager.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"cilium":{"description":"Cilium CNI plugin.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"coredns":{"description":"CoreDNS addon.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"fluxcd":{"description":"FluxCD GitOps operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable FluxCD.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"gatewayAPI":{"description":"Gateway API addon.","type":"object","default":{},"required":["enabled"],"properties":{"enabled":{"description":"Enable Gateway API.","type":"boolean","default":false}}},"gpuOperator":{"description":"NVIDIA GPU Operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable GPU Operator.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"ingressNginx":{"description":"Ingress-NGINX controller.","type":"object","default":{},"required":["enabled","exposeMethod","valuesOverride"],"properties":{"enabled":{"description":"Enable the controller (requires nodes labeled `ingress-nginx`).","type":"boolean","default":false},"exposeMethod":{"description":"Method to expose the controller. Allowed values: `Proxied`, `LoadBalancer`.","type":"string","default":"Proxied"},"hosts":{"description":"Domains routed to this tenant cluster when `exposeMethod` is `Proxied`.","type":"array","default":[],"items":{"type":"string"}},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"monitoringAgents":{"description":"Monitoring agents.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable monitoring agents.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"velero":{"description":"Velero backup/restore addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable Velero.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"verticalPodAutoscaler":{"description":"Vertical Pod Autoscaler.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}}}},"controlPlane":{"description":"Kubernetes control-plane configuration.","type":"object","default":{},"required":["apiServer","controllerManager","konnectivity","replicas","scheduler"],"properties":{"apiServer":{"description":"API Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for API Server.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"medium","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"controllerManager":{"description":"Controller Manager configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Controller Manager.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"konnectivity":{"description":"Konnectivity configuration.","type":"object","default":{},"required":["server"],"properties":{"server":{"description":"Konnectivity Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Konnectivity.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"replicas":{"description":"Number of control-plane replicas.","type":"integer","default":2},"scheduler":{"description":"Scheduler configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Scheduler.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"host":{"description":"External hostname for Kubernetes cluster. Defaults to `.` if empty.","type":"string","default":""},"nodeGroups":{"description":"Worker nodes configuration map.","type":"object","default":{"md0":{"ephemeralStorage":"20Gi","gpus":[],"instanceType":"u1.medium","maxReplicas":10,"minReplicas":0,"resources":{},"roles":["ingress-nginx"]}},"additionalProperties":{"type":"object","required":["ephemeralStorage","instanceType","maxReplicas","minReplicas","resources"],"properties":{"ephemeralStorage":{"description":"Ephemeral storage size.","default":"20Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","items":{"type":"object","required":["name"],"properties":{"name":{"description":"Name of GPU, such as \"nvidia.com/AD102GL_L40S\".","type":"string"}}}},"instanceType":{"description":"Virtual machine instance type.","type":"string","default":"u1.medium"},"maxReplicas":{"description":"Maximum number of replicas.","type":"integer","default":10},"minReplicas":{"description":"Minimum number of replicas.","type":"integer","default":0},"resources":{"description":"CPU and memory resources for each worker node.","type":"object","properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"roles":{"description":"List of node roles.","type":"array","items":{"type":"string"}}}}},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"},"version":{"description":"Kubernetes major.minor version to deploy","type":"string","default":"v1.33","enum":["v1.33","v1.32","v1.31","v1.30","v1.29","v1.28"]}}} release: prefix: kubernetes- labels: diff --git a/packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml b/packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml index 520e4671..720dc161 100644 --- a/packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml +++ b/packages/system/cozystack-resource-definitions/cozyrds/monitoring.yaml @@ -8,7 +8,7 @@ spec: singular: monitoring plural: monitorings openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"alerta":{"description":"Configuration for the Alerta service.","type":"object","default":{},"properties":{"alerts":{"description":"Alert routing configuration.","type":"object","default":{},"properties":{"slack":{"description":"Configuration for Slack alerts.","type":"object","default":{},"required":["url"],"properties":{"url":{"description":"Configuration uri for Slack alerts.","type":"string","default":""}}},"telegram":{"description":"Configuration for Telegram alerts.","type":"object","default":{},"required":["chatID","token"],"properties":{"chatID":{"description":"Telegram chat ID(s), separated by commas.","type":"string","default":""},"disabledSeverity":{"description":"List of severities without alerts (e.g. \"informational,warning\").","type":"string","default":""},"token":{"description":"Telegram bot token.","type":"string","default":""}}}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"storage":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the database.","type":"string","default":""}}},"grafana":{"description":"Configuration for Grafana.","type":"object","default":{},"properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"size":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}},"host":{"description":"The hostname used to access Grafana externally (defaults to 'grafana' subdomain for the tenant host).","type":"string","default":""},"logsStorages":{"description":"Configuration of logs storage instances.","type":"array","default":[{"name":"generic","retentionPeriod":"1","storage":"10Gi","storageClassName":"replicated"}],"items":{"type":"object","required":["name","retentionPeriod","storage","storageClassName"],"properties":{"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for logs.","type":"string","default":"1"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}},"metricsStorages":{"description":"Configuration of metrics storage instances.","type":"array","default":[{"deduplicationInterval":"15s","name":"shortterm","retentionPeriod":"3d","storage":"10Gi","storageClassName":""},{"deduplicationInterval":"5m","name":"longterm","retentionPeriod":"14d","storage":"10Gi","storageClassName":""}],"items":{"type":"object","required":["deduplicationInterval","name","retentionPeriod","storage"],"properties":{"deduplicationInterval":{"description":"Deduplication interval for metrics.","type":"string"},"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for metrics.","type":"string"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the data.","type":"string"},"vminsert":{"description":"Configuration for vminsert.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmselect":{"description":"Configuration for vmselect.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmstorage":{"description":"Configuration for vmstorage.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}}}}} + {"title":"Chart Values","type":"object","properties":{"alerta":{"description":"Configuration for the Alerta service.","type":"object","default":{},"properties":{"alerts":{"description":"Alert routing configuration.","type":"object","default":{},"properties":{"slack":{"description":"Configuration for Slack alerts.","type":"object","default":{},"required":["url"],"properties":{"url":{"description":"Configuration uri for Slack alerts.","type":"string","default":""}}},"telegram":{"description":"Configuration for Telegram alerts.","type":"object","default":{},"required":["chatID","token"],"properties":{"chatID":{"description":"Telegram chat ID(s), separated by commas.","type":"string","default":""},"disabledSeverity":{"description":"List of severities without alerts (e.g. \"informational,warning\").","type":"string","default":""},"token":{"description":"Telegram bot token.","type":"string","default":""}}}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"storage":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the database.","type":"string","default":""}}},"grafana":{"description":"Configuration for Grafana.","type":"object","default":{},"properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"size":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}},"host":{"description":"The hostname used to access Grafana externally (defaults to 'grafana' subdomain for the tenant host).","type":"string","default":""},"logsStorages":{"description":"Configuration of logs storage instances.","type":"array","default":[{"name":"generic","retentionPeriod":"1","storage":"10Gi","storageClassName":"replicated"}],"items":{"type":"object","required":["name","retentionPeriod","storage","storageClassName"],"properties":{"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for logs.","type":"string","default":"1"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}},"metricsStorages":{"description":"Configuration of metrics storage instances.","type":"array","default":[{"deduplicationInterval":"15s","name":"shortterm","retentionPeriod":"3d","storage":"10Gi","storageClassName":""},{"deduplicationInterval":"5m","name":"longterm","retentionPeriod":"14d","storage":"10Gi","storageClassName":""}],"items":{"type":"object","required":["deduplicationInterval","name","retentionPeriod","storage"],"properties":{"deduplicationInterval":{"description":"Deduplication interval for metrics.","type":"string"},"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for metrics.","type":"string"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the data.","type":"string"},"vminsert":{"description":"Configuration for vminsert.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmselect":{"description":"Configuration for vmselect.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmstorage":{"description":"Configuration for vmstorage.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}}},"vmagent":{"description":"Configuration for VictoriaMetrics Agent.","type":"object","default":{},"properties":{"externalLabels":{"description":"External labels applied to all metrics.","default":{"cluster":"cozystack"}},"remoteWrite":{"description":"Remote write configuration.","default":{"urls":["http://vminsert-shortterm:8480/insert/0/prometheus","http://vminsert-longterm:8480/insert/0/prometheus"]}}}}}} release: prefix: "" labels: @@ -28,7 +28,7 @@ spec: description: Monitoring and observability stack module: true icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzI2OCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zMjY4KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMzg0NTRGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNNTQuMTcyMiAzOC43NzU3SDMzLjEwMzJDMzIuMTMwNyAzOC43NzU3IDMxLjQ4MjQgMzguMTI3NCAzMS40ODI0IDM3LjE1NDlDMzEuNDgyNCAzNi4xODI0IDMyLjEzMDcgMzUuNTM0MiAzMy4xMDMyIDM1LjUzNDJINTQuMTcyMkM1NS4xNDQ3IDM1LjUzNDIgNTUuNzkzIDM2LjE4MjQgNTUuNzkzIDM3LjE1NDlDNTUuNzkyOCAzOC4xMjc0IDU1LjE0NDUgMzguNzc1NyA1NC4xNzIyIDM4Ljc3NTdaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik02My44OTYzIDQ1LjI1OTFINDEuMjA2N0M0MC4yMzQyIDQ1LjI1OTEgMzkuNTg1OSA0NC42MTA4IDM5LjU4NTkgNDMuNjM4M0MzOS41ODU5IDQyLjY2NTggNDAuMjM0MiA0Mi4wMTc2IDQxLjIwNjcgNDIuMDE3Nkg2My44OTYzQzY0Ljg2ODggNDIuMDE3NiA2NS41MTcxIDQyLjY2NTggNjUuNTE3MSA0My42MzgzQzY1LjUxNzEgNDQuNjEwOCA2NC44Njg4IDQ1LjI1OTEgNjMuODk2MyA0NS4yNTkxWiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMzQuNzI0IDQ1LjI1OTFIMzMuMTAzMkMzMi4xMzA3IDQ1LjI1OTEgMzEuNDgyNCA0NC42MTA4IDMxLjQ4MjQgNDMuNjM4M0MzMS40ODI0IDQyLjY2NTggMzIuMTMwNyA0Mi4wMTc2IDMzLjEwMzIgNDIuMDE3NkgzNC43MjRDMzUuNjk2NCA0Mi4wMTc2IDM2LjM0NDcgNDIuNjY1OCAzNi4zNDQ3IDQzLjYzODNDMzYuMzQ0NyA0NC42MTA4IDM1LjY5NjMgNDUuMjU5MSAzNC43MjQgNDUuMjU5MVoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgMzguNzc1N0g2MC42NTQ5QzU5LjY4MjQgMzguNzc1NyA1OS4wMzQyIDM4LjEyNzQgNTkuMDM0MiAzNy4xNTQ5QzU5LjAzNDIgMzYuMTgyNCA1OS42ODI0IDM1LjUzNDIgNjAuNjU0OSAzNS41MzQySDYzLjg5NjNDNjQuODY4OCAzNS41MzQyIDY1LjUxNzEgMzYuMTgyNCA2NS41MTcxIDM3LjE1NDlDNjUuNTE3MSAzOC4xMjc0IDY0Ljg2ODggMzguNzc1NyA2My44OTYzIDM4Ljc3NTdaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik00Ny42ODkzIDUxLjc0MTNIMzMuMTAzMkMzMi4xMzA3IDUxLjc0MTMgMzEuNDgyNCA1MS4wOTMxIDMxLjQ4MjQgNTAuMTIwNkMzMS40ODI0IDQ5LjE0ODEgMzIuMTMwNyA0OC41IDMzLjEwMzIgNDguNUg0Ny42ODkzQzQ4LjY2MTggNDguNSA0OS4zMTAxIDQ5LjE0ODMgNDkuMzEwMSA1MC4xMjA4QzQ5LjMxMDEgNTEuMDkzMyA0OC42NjE4IDUxLjc0MTMgNDcuNjg5MyA1MS43NDEzWiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNjMuODk2OCA1MS43NDEzSDU0LjE3MjVDNTMuMiA1MS43NDEzIDUyLjU1MTggNTEuMDkzMSA1Mi41NTE4IDUwLjEyMDZDNTIuNTUxOCA0OS4xNDgxIDUzLjIwMDIgNDguNSA1NC4xNzI3IDQ4LjVINjMuODk2OUM2NC44Njk0IDQ4LjUgNjUuNTE3NyA0OS4xNDgzIDY1LjUxNzcgNTAuMTIwOEM2NS41MTc3IDUxLjA5MzMgNjQuODY5MiA1MS43NDEzIDYzLjg5NjggNTEuNzQxM1oiIGZpbGw9IiNFQ0JBMTYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNTguMjI0SDMzLjEwMzJDMzIuMTMwNyA1OC4yMjQgMzEuNDgyNCA1Ny41NzU3IDMxLjQ4MjQgNTYuNjAzMkMzMS40ODI0IDU1LjYzMDcgMzIuMTMwNyA1NC45ODI0IDMzLjEwMzIgNTQuOTgyNEg1NC4xNzIyQzU1LjE0NDcgNTQuOTgyNCA1NS43OTMgNTUuNjMwNyA1NS43OTMgNTYuNjAzMkM1NS43OTMgNTcuNTc1NyA1NS4xNDQ1IDU4LjIyNCA1NC4xNzIyIDU4LjIyNFoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgNjQuNzA3NEg0MS4yMDY3QzQwLjIzNDIgNjQuNzA3NCAzOS41ODU5IDY0LjA1OTEgMzkuNTg1OSA2My4wODY2QzM5LjU4NTkgNjIuMTE0MSA0MC4yMzQyIDYxLjQ2NTggNDEuMjA2NyA2MS40NjU4SDYzLjg5NjNDNjQuODY4OCA2MS40NjU4IDY1LjUxNzEgNjIuMTE0MSA2NS41MTcxIDYzLjA4NjZDNjUuNTE3MSA2NC4wNTkxIDY0Ljg2ODggNjQuNzA3NCA2My44OTYzIDY0LjcwNzRaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik0zNC43MjQgNjQuNzA3NEgzMy4xMDMyQzMyLjEzMDcgNjQuNzA3NCAzMS40ODI0IDY0LjA1OTEgMzEuNDgyNCA2My4wODY2QzMxLjQ4MjQgNjIuMTE0MSAzMi4xMzA3IDYxLjQ2NTggMzMuMTAzMiA2MS40NjU4SDM0LjcyNEMzNS42OTY0IDYxLjQ2NTggMzYuMzQ0NyA2Mi4xMTQxIDM2LjM0NDcgNjMuMDg2NkMzNi4zNDQ3IDY0LjA1OTEgMzUuNjk2MyA2NC43MDc0IDM0LjcyNCA2NC43MDc0WiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNDcuNjg5MyA3MS4xODk4SDMzLjEwMzJDMzIuMTMwNyA3MS4xODk4IDMxLjQ4MjQgNzAuNTQxNSAzMS40ODI0IDY5LjU2OUMzMS40ODI0IDY4LjU5NjUgMzIuMTMwNyA2Ny45NDgyIDMzLjEwMzIgNjcuOTQ4Mkg0Ny42ODkzQzQ4LjY2MTggNjcuOTQ4MiA0OS4zMTAxIDY4LjU5NjUgNDkuMzEwMSA2OS41NjlDNDkuMzEwMSA3MC41NDE1IDQ4LjY2MTggNzEuMTg5OCA0Ny42ODkzIDcxLjE4OThaIiBmaWxsPSIjNDJCMDVDIi8+CjxwYXRoIGQ9Ik02My44OTY4IDcxLjE4OThINTQuMTcyNUM1My4yIDcxLjE4OTggNTIuNTUxOCA3MC41NDE1IDUyLjU1MTggNjkuNTY5QzUyLjU1MTggNjguNTk2NSA1My4yIDY3Ljk0ODIgNTQuMTcyNSA2Ny45NDgySDYzLjg5NjhDNjQuODY5MiA2Ny45NDgyIDY1LjUxNzUgNjguNTk2NSA2NS41MTc1IDY5LjU2OUM2NS41MTc1IDcwLjU0MTUgNjQuODY5MiA3MS4xODk4IDYzLjg5NjggNzEuMTg5OFoiIGZpbGw9IiM3MzgzQkYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNzcuNjcyMkgzMy4xMDMyQzMyLjEzMDcgNzcuNjcyMiAzMS40ODI0IDc3LjAyMzkgMzEuNDgyNCA3Ni4wNTE0QzMxLjQ4MjQgNzUuMDc4OSAzMi4xMzA3IDc0LjQzMDcgMzMuMTAzMiA3NC40MzA3SDU0LjE3MjJDNTUuMTQ0NyA3NC40MzA3IDU1Ljc5MyA3NS4wNzg5IDU1Ljc5MyA3Ni4wNTE0QzU1Ljc5MjggNzcuMDIzOSA1NS4xNDQ1IDc3LjY3MjIgNTQuMTcyMiA3Ny42NzIyWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNNjMuODk2MyA3Ny42NzIySDYwLjY1NDlDNTkuNjgyNCA3Ny42NzIyIDU5LjAzNDIgNzcuMDIzOSA1OS4wMzQyIDc2LjA1MTRDNTkuMDM0MiA3NS4wNzg5IDU5LjY4MjQgNzQuNDMwNyA2MC42NTQ5IDc0LjQzMDdINjMuODk2M0M2NC44Njg4IDc0LjQzMDcgNjUuNTE3MSA3NS4wNzg5IDY1LjUxNzEgNzYuMDUxNEM2NS41MTcxIDc3LjAyMzkgNjQuODY4OCA3Ny42NzIyIDYzLjg5NjMgNzcuNjcyMloiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTEwMS4xNzIgNzcuNjcyMkg4MC4xMDMyQzc5LjEzMDcgNzcuNjcyMiA3OC40ODI0IDc3LjAyMzkgNzguNDgyNCA3Ni4wNTE0Qzc4LjQ4MjQgNzUuMDc4OSA3OS4xMzA3IDc0LjQzMDcgODAuMTAzMiA3NC40MzA3SDEwMS4xNzJDMTAyLjE0NSA3NC40MzA3IDEwMi43OTMgNzUuMDc4OSAxMDIuNzkzIDc2LjA1MTRDMTAyLjc5MyA3Ny4wMjM5IDEwMi4xNDUgNzcuNjcyMiAxMDEuMTcyIDc3LjY3MjJaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik0xMTAuODk2IDc3LjY3MjJIMTA3LjY1NUMxMDYuNjgyIDc3LjY3MjIgMTA2LjAzNCA3Ny4wMjM5IDEwNi4wMzQgNzYuMDUxNEMxMDYuMDM0IDc1LjA3ODkgMTA2LjY4MiA3NC40MzA3IDEwNy42NTUgNzQuNDMwN0gxMTAuODk2QzExMS44NjkgNzQuNDMwNyAxMTIuNTE3IDc1LjA3ODkgMTEyLjUxNyA3Ni4wNTE0QzExMi41MTcgNzcuMDIzOSAxMTEuODY5IDc3LjY3MjIgMTEwLjg5NiA3Ny42NzIyWiIgZmlsbD0iIzQyQjA1QyIvPgo8cGF0aCBkPSJNNjMuODk2MyA1OC4yMjRINjAuNjU0OUM1OS42ODI0IDU4LjIyNCA1OS4wMzQyIDU3LjU3NTcgNTkuMDM0MiA1Ni42MDMyQzU5LjAzNDIgNTUuNjMwNyA1OS42ODI0IDU0Ljk4MjQgNjAuNjU0OSA1NC45ODI0SDYzLjg5NjNDNjQuODY4OCA1NC45ODI0IDY1LjUxNzEgNTUuNjMwNyA2NS41MTcxIDU2LjYwMzJDNjUuNTE3MSA1Ny41NzU3IDY0Ljg2ODggNTguMjI0IDYzLjg5NjMgNTguMjI0WiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMTEyLjUxNyA1MS43NDExQzExMi41MTcgNjAuNjU0OSAxMDUuMjI0IDY3Ljk0OCA5Ni4zMTA0IDY3Ljk0OEM4Ny4zOTY2IDY3Ljk0OCA4MC4xMDM1IDYwLjY1NDkgODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNDIuODI3MyA4Ny4zOTY2IDM1LjUzNDIgOTYuMzEwNCAzNS41MzQyQzEwNS4yMjQgMzUuNTM0MiAxMTIuNTE3IDQyLjgyNzMgMTEyLjUxNyA1MS43NDExWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNTIuMjI3MyA4MC4xMDM1IDUyLjg3NTUgODAuMTAzNSA1My4zNjE5SDk2LjMxMDRWMzUuNTM0MkM4Ny4zOTY2IDM1LjUzNDIgODAuMTAzNSA0Mi44MjczIDgwLjEwMzUgNTEuNzQxMVoiIGZpbGw9IiM0MkIwNUMiLz4KPC9nPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zMjY4IiB4MT0iMS4yMzIzOWUtMDYiIHkxPSItOS41MDAwMSIgeDI9IjE2OCIgeTI9IjE2MiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjOEZEREZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNzVGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzY4N18zMjY4Ij4KPHJlY3Qgd2lkdGg9Ijk0IiBoZWlnaHQ9Ijk0IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjUgMjUpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "metricsStorages"], ["spec", "logsStorages"], ["spec", "alerta"], ["spec", "alerta", "storage"], ["spec", "alerta", "storageClassName"], ["spec", "alerta", "resources"], ["spec", "alerta", "resources", "limits"], ["spec", "alerta", "resources", "limits", "cpu"], ["spec", "alerta", "resources", "limits", "memory"], ["spec", "alerta", "resources", "requests"], ["spec", "alerta", "resources", "requests", "cpu"], ["spec", "alerta", "resources", "requests", "memory"], ["spec", "alerta", "alerts"], ["spec", "alerta", "alerts", "telegram"], ["spec", "alerta", "alerts", "telegram", "token"], ["spec", "alerta", "alerts", "telegram", "chatID"], ["spec", "alerta", "alerts", "telegram", "disabledSeverity"], ["spec", "alerta", "alerts", "slack"], ["spec", "alerta", "alerts", "slack", "url"], ["spec", "grafana"], ["spec", "grafana", "db"], ["spec", "grafana", "db", "size"], ["spec", "grafana", "resources"], ["spec", "grafana", "resources", "limits"], ["spec", "grafana", "resources", "limits", "cpu"], ["spec", "grafana", "resources", "limits", "memory"], ["spec", "grafana", "resources", "requests"], ["spec", "grafana", "resources", "requests", "cpu"], ["spec", "grafana", "resources", "requests", "memory"]] + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "metricsStorages"], ["spec", "logsStorages"], ["spec", "alerta"], ["spec", "alerta", "storage"], ["spec", "alerta", "storageClassName"], ["spec", "alerta", "resources"], ["spec", "alerta", "resources", "limits"], ["spec", "alerta", "resources", "limits", "cpu"], ["spec", "alerta", "resources", "limits", "memory"], ["spec", "alerta", "resources", "requests"], ["spec", "alerta", "resources", "requests", "cpu"], ["spec", "alerta", "resources", "requests", "memory"], ["spec", "alerta", "alerts"], ["spec", "alerta", "alerts", "telegram"], ["spec", "alerta", "alerts", "telegram", "token"], ["spec", "alerta", "alerts", "telegram", "chatID"], ["spec", "alerta", "alerts", "telegram", "disabledSeverity"], ["spec", "alerta", "alerts", "slack"], ["spec", "alerta", "alerts", "slack", "url"], ["spec", "grafana"], ["spec", "grafana", "db"], ["spec", "grafana", "db", "size"], ["spec", "grafana", "resources"], ["spec", "grafana", "resources", "limits"], ["spec", "grafana", "resources", "limits", "cpu"], ["spec", "grafana", "resources", "limits", "memory"], ["spec", "grafana", "resources", "requests"], ["spec", "grafana", "resources", "requests", "cpu"], ["spec", "grafana", "resources", "requests", "memory"], ["spec", "vmagent"], ["spec", "vmagent", "externalLabels"], ["spec", "vmagent", "externalLabels", "cluster"], ["spec", "vmagent", "remoteWrite"], ["spec", "vmagent", "remoteWrite", "urls"]] secrets: exclude: [] include: diff --git a/packages/system/cozystack-resource-definitions/cozyrds/mysql.yaml b/packages/system/cozystack-resource-definitions/cozyrds/mysql.yaml index 142b55b1..ba8251b8 100644 --- a/packages/system/cozystack-resource-definitions/cozyrds/mysql.yaml +++ b/packages/system/cozystack-resource-definitions/cozyrds/mysql.yaml @@ -8,7 +8,7 @@ spec: plural: mysqls singular: mysql openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["cleanupStrategy","enabled","resticPassword","s3AccessKey","s3Bucket","s3Region","s3SecretKey","schedule"],"properties":{"cleanupStrategy":{"description":"Retention strategy for cleaning up old backups.","type":"string","default":"--keep-last=3 --keep-daily=3 --keep-within-weekly=1m"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"resticPassword":{"description":"Password for Restic backup encryption.","type":"string","default":""},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3Bucket":{"description":"S3 bucket used for storing backups.","type":"string","default":"s3.example.org/mysql-backups"},"s3Region":{"description":"AWS S3 region where backups are stored.","type":"string","default":"us-east-1"},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * *"}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of MariaDB replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each MariaDB replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","required":["maxUserConnections","password"],"properties":{"maxUserConnections":{"description":"Maximum number of connections.","type":"integer"},"password":{"description":"Password for the user.","type":"string"}}}}}} + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["cleanupStrategy","enabled","resticPassword","s3AccessKey","s3Bucket","s3Region","s3SecretKey","schedule"],"properties":{"cleanupStrategy":{"description":"Retention strategy for cleaning up old backups.","type":"string","default":"--keep-last=3 --keep-daily=3 --keep-within-weekly=1m"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"resticPassword":{"description":"Password for Restic backup encryption.","type":"string","default":""},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3Bucket":{"description":"S3 bucket used for storing backups.","type":"string","default":"s3.example.org/mysql-backups"},"s3Region":{"description":"AWS S3 region where backups are stored.","type":"string","default":"us-east-1"},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * *"}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of MariaDB replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each MariaDB replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","required":["maxUserConnections","password"],"properties":{"maxUserConnections":{"description":"Maximum number of connections.","type":"integer"},"password":{"description":"Password for the user.","type":"string"}}}},"version":{"description":"MariaDB major.minor version to deploy","type":"string","default":"v11.8","enum":["v11.8","v11.4","v10.11","v10.6"]}}} release: prefix: mysql- labels: @@ -27,7 +27,7 @@ spec: tags: - database icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5MzApIi8+CjxwYXRoIGQ9Ik0xMzMuMTkxIDI5LjAwMjJDMTMxLjIxMyAyOS4wNjU0IDEzMS44MzkgMjkuNjM1NCAxMjcuNTY0IDMwLjY4NzNDMTIzLjI0OCAzMS43NDk2IDExNy45NzUgMzEuNDIzOSAxMTMuMzI3IDMzLjM3MzNDOTkuNDUxNiAzOS4xOTI0IDk2LjY2NzYgNTkuMDgxMyA4NC4wNTM1IDY2LjIwNTlDNzQuNjI0NyA3MS41MzE4IDY1LjExMiA3MS45NTY1IDU2LjU1OTQgNzQuNjM2NUM1MC45Mzg5IDc2LjM5OSA0NC43OTA2IDgwLjAxMzUgMzkuNjk4MiA4NC40MDE4QzM1Ljc0NTUgODcuODA5MyAzNS42NDIzIDkwLjgwNTQgMzEuNTEyMyA5NS4wNzkxQzI3LjA5NDcgOTkuNjUwNCAxMy45NTUxIDk1LjE1NjQgOCAxMDIuMTUzQzkuOTE4MzUgMTA0LjA5MyAxMC43NTk0IDEwNC42MzYgMTQuNTM5OCAxMDQuMTMzQzEzLjc1NzEgMTA1LjYxNiA5LjE0MzMyIDEwNi44NjYgMTAuMDQ2NSAxMDkuMDQ5QzEwLjk5NjggMTExLjM0NSAyMi4xNTExIDExMi45MDEgMzIuMjkwOCAxMDYuNzhDMzcuMDEzMSAxMDMuOTI5IDQwLjc3NDMgOTkuODE5MyA0OC4xMjg4IDk4LjgzODRDNTcuNjQ1OSA5Ny41Njk5IDY4LjYwOTMgOTkuNjUyIDc5LjYyNjggMTAxLjI0MUM3Ny45OTMyIDEwNi4xMTIgNzQuNzEzMyAxMDkuMzUxIDcyLjA4NiAxMTMuMjMxQzcxLjI3MjQgMTE0LjEwNyA3My43MjAyIDExNC4yMDUgNzYuNTEyNiAxMTMuNjc1QzgxLjUzNTkgMTEyLjQzMyA4NS4xNTYxIDExMS40MzMgODguOTQ3MiAxMDkuMjI3QzkzLjYwNDcgMTA2LjUxNSA5NC4zMTA0IDk5LjU2MzkgMTAwLjAyNSA5OC4wNTk5QzEwMy4yMDkgMTAyLjk1NCAxMTEuODY5IDEwNC4xMSAxMTcuMjQyIDEwMC4xOTVDMTEyLjUyNyA5OC44NjA3IDExMS4yMjQgODguODI0NCAxMTIuODE1IDg0LjQwMThDMTE0LjMyMyA4MC4yMTU2IDExNS44MTMgNzMuNTE5MiAxMTcuMzMxIDY3Ljk4NTVDMTE4Ljk2MSA2Mi4wNDI1IDExOS41NjIgNTQuNTUxOSAxMjEuNTM1IDUxLjUyNDdDMTI0LjUwMyA0Ni45NzAxIDEyNy43ODMgNDUuNDA2IDEzMC42MyA0Mi44Mzc3QzEzMy40NzcgNDAuMjY5NSAxMzYuMDgzIDM3Ljc2OTQgMTM1Ljk5OCAzMS44OTI3QzEzNS45NyAyOS45OTk4IDEzNC45OTIgMjguOTQ0NyAxMzMuMTkxIDI5LjAwMjJaIiBmaWxsPSIjMDQyNDRFIi8+CjxwYXRoIGQ9Ik0xMjguOTUzIDMyLjQ4NDRDMTI5LjQyNyAzNC4xMDA0IDEzMC4xNjggMzQuODQyMSAxMzMuMzc1IDM1LjEzODdDMTMyLjkwNiAzOS4yMDQxIDEzMC4xOTUgNDEuNDI3NiAxMjcuMTU0IDQzLjU2MTFDMTI0LjQ3OSA0NS40Mzc2IDEyMS41NDcgNDcuMjQ0NSAxMTkuNjY0IDUwLjE3NTdDMTE3LjczNCA1My4xNzg1IDExNi41MDkgNjMuNDU1NCAxMTMuNTE3IDczLjYwNDRDMTEwLjkzMSA4Mi4zNzM4IDEwNy4wMjUgOTEuMDQ0NSAxMDAuMjA0IDk0Ljg0MzdDOTkuNDkxOSA5My4wNTAyIDEwMC4yOTUgODkuNzQgOTguODc4IDg4LjY1MkM5Ny45NjExIDkxLjI2NzQgOTYuOTI0MiA5My43NjI3IDk1LjcwOTggOTYuMDgyMUM5MS43MDc3IDEwMy43MzIgODUuNzgyMiAxMDkuNDU5IDc1Ljg4MDEgMTExLjIwOEM4MC41Nzg1IDEwNC44NSA4NS4wNzEgOTguMjg0NCA4NS4xNjgzIDg3LjMyNjJDODEuODYxNyA4OC4wNDE3IDgxLjkzMTkgOTUuODUyMiA3OC41MzQ1IDk3Ljk0MDJDNzYuMzU2MyA5OC4xNzcyIDc0LjE0OTggOTguMTc1OCA3MS45MjkxIDk4LjA0MjRDNjIuODA5MSA5Ny40OTU5IDUzLjQ1MzUgOTQuNzU0OSA0NC45MjE5IDk3LjQ5MjNDMzkuMTEyOCA5OS4zNTY4IDM0LjM2MTkgMTAzLjc1NSAyOS40NDI4IDEwNS44ODhDMjMuNjYxNCAxMDguMzk2IDE5LjI4MzEgMTA5LjQyNyAxMi4wODM2IDEwOC4zOTZDMTEuMTY5NSAxMDcuMTY0IDE3LjM1MjYgMTA1LjU3NSAxNi45ODI5IDEwMi45MDJDMTQuMTY1MyAxMDIuNTkgMTIuNTI5MyAxMDMuMjczIDEwLjA4MDEgMTAyLjE2QzEwLjM1MDUgMTAxLjY2MiAxMC43NDc5IDEwMS4yNDcgMTEuMjQ4MyAxMDAuOTAxQzE1LjczNzMgOTcuNzk0IDI4LjQ4ODIgMTAwLjE2NyAzMS45MDA2IDk2LjgxNjdDMzQuMDA3IDk0Ljc1IDM1LjM4ODkgOTIuNTg2NyAzNi44MTk3IDkwLjQ4MzhDMzguMjA3MiA4OC40NDM0IDM5LjY0MTUgODYuNDU5NyA0MS44MjY4IDg0LjY3MTlDNDIuNjMzNyA4NC4wMTE4IDQzLjUxMSA4My4zNTk2IDQ0LjQ0MjEgODIuNzIzQzQ4LjE2NiA4MC4xNzQzIDUyLjc3MjkgNzcuODYyOCA1Ny4zMDY2IDc2LjI2OTRDNjMuNDgyNiA3NC4wOTg0IDY5Ljc0MSA3My45MTk1IDc2LjMyMzcgNzEuNDA0M0M4MC4zOTA0IDY5Ljg1IDg0LjgxMjcgNjcuOTMwMiA4OC40MTc0IDY1LjI0MzlDODkuMjczMyA2NC42MDUxIDkwLjA4MzEgNjMuOTI0NSA5MC44MzE5IDYzLjE5NDlDMTAxLjEyNSA1My4xNjA4IDEwMy4xNjUgMzUuNDYxIDExOS4yMjQgMzMuODExNkMxMjEuMTY2IDMzLjYxMjEgMTIyLjc1NiAzMy42NzY3IDEyNC4yMDMgMzMuNjMyN0MxMjUuODcxIDMzLjU4MyAxMjcuMzQ3IDMzLjM4OTMgMTI4Ljk1MyAzMi40ODQ0Wk0xMDkuMzc1IDg5LjEzMzlDMTA5LjU2NyA5Mi4yMDEzIDExMS4zNDggOTguMjg3MiAxMTIuOTIgOTkuNzY2M0MxMDkuODQxIDEwMC41MTUgMTA0LjUzNyA5OS4yNzggMTAzLjE3NyA5Ny4xMDYyQzEwMy44NzYgOTMuOTcwNyAxMDcuNTE0IDkxLjEwNDEgMTA5LjM3NSA4OS4xMzM5WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEzMC4xMDkgMzUuOTE4N0MxMjkuNDkgMzcuMjE2OSAxMjguMzA1IDM4Ljg5MDggMTI4LjMwNSA0Mi4xOTU2QzEyOC4zIDQyLjc2MyAxMjcuODc1IDQzLjE1MTcgMTI3Ljg2NyA0Mi4yNzdDMTI3Ljg5OSAzOS4wNDcgMTI4Ljc1NCAzNy42NTA3IDEyOS42NjIgMzUuODE1NUMxMzAuMDg1IDM1LjA2MzYgMTMwLjMzOSAzNS4zNzM4IDEzMC4xMDkgMzUuOTE4N1pNMTI5LjQ4NiAzNS40Mjk3QzEyOC43NTYgMzYuNjY4NCAxMjYuOTk4IDM4LjkyNzggMTI2LjcwNyA0Mi4yMjAzQzEyNi42NTMgNDIuNzg0OCAxMjYuMTk0IDQzLjEzNDMgMTI2LjI2NCA0Mi4yNjE4QzEyNi41ODEgMzkuMDQ3NyAxMjcuOTg2IDM3LjAzNiAxMjkuMDUyIDM1LjI4NzNDMTI5LjUzNiAzNC41NzYxIDEyOS43NjMgMzQuOTA3NCAxMjkuNDg2IDM1LjQyOTdaTTEyOC45MTggMzQuNzgxN0MxMjguMDg2IDM1Ljk1NDMgMTI1LjM4IDM4LjY2NzggMTI0LjgxNCA0MS45MjQ3QzEyNC43MTIgNDIuNDgxOSAxMjQuMjI1IDQyLjc5MjggMTI0LjM2OCA0MS45MjlDMTI0Ljk1NCAzOC43NTIgMTI3LjI4NyAzNi4yNTUgMTI4LjQ5NiAzNC42MDM3QzEyOS4wMzggMzMuOTM0NiAxMjkuMjM3IDM0LjI4NCAxMjguOTE4IDM0Ljc4MTdaTTEyOC40MTEgMzQuMDU4OEwxMjguMTM3IDM0LjM0OTlDMTI2LjkyNyAzNS42NDcyIDEyNC4xMTYgMzguODExNCAxMjMuMTc5IDQxLjcwNzRDMTIyLjk5OSA0Mi4yNDUgMTIyLjQ3NCA0Mi40ODQ4IDEyMi43MzcgNDEuNjQ5M0MxMjMuNzYzIDM4LjU4NjQgMTI2LjU4OSAzNS4yODczIDEyOC4wMTggMzMuODIyN0MxMjguNjUgMzMuMjM2NCAxMjguNzk2IDMzLjYxMDYgMTI4LjQxMSAzNC4wNTg4Wk0xMTMuODg2IDQwLjYxNjJDMTE0LjUxMyAzNy45MjMxIDExNi42MDcgMzYuNjk2IDEyMC4yMjMgMzYuOTk1M0MxMjEuMDk2IDQxLjAxNTEgMTE2LjIxMyA0Mi42MzY2IDExMy44ODYgNDAuNjE2MloiIGZpbGw9IiMwNDI0NEUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMjkzMCIgeDE9IjE0MC41IiB5MT0iMTQxIiB4Mj0iNS45OTk5OSIgeTI9Ii01LjUwMjI4ZS0wNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQzQ5QTZDIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0U3QkY5MyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "s3Region"], ["spec", "backup", "s3Bucket"], ["spec", "backup", "schedule"], ["spec", "backup", "cleanupStrategy"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "backup", "resticPassword"]] + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "version"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "s3Region"], ["spec", "backup", "s3Bucket"], ["spec", "backup", "schedule"], ["spec", "backup", "cleanupStrategy"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "backup", "resticPassword"]] secrets: exclude: [] include: diff --git a/packages/system/cozystack-resource-definitions/cozyrds/postgres.yaml b/packages/system/cozystack-resource-definitions/cozyrds/postgres.yaml index 010586fe..c3d16cb7 100644 --- a/packages/system/cozystack-resource-definitions/cozyrds/postgres.yaml +++ b/packages/system/cozystack-resource-definitions/cozyrds/postgres.yaml @@ -8,7 +8,7 @@ spec: singular: postgres plural: postgreses openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["enabled"],"properties":{"destinationPath":{"description":"Destination path for backups (e.g. s3://bucket/path/).","type":"string","default":"s3://bucket/path/to/folder/"},"enabled":{"description":"Enable regular backups.","type":"boolean","default":false},"endpointURL":{"description":"S3 endpoint URL for uploads.","type":"string","default":"http://minio-gateway-service:9000"},"retentionPolicy":{"description":"Retention policy (e.g. \"30d\").","type":"string","default":"30d"},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * * *"}}},"bootstrap":{"description":"Bootstrap configuration.","type":"object","default":{},"required":["enabled","oldName"],"properties":{"enabled":{"description":"Whether to restore from a backup.","type":"boolean","default":false},"oldName":{"description":"Previous cluster name before deletion.","type":"string","default":""},"recoveryTime":{"description":"Timestamp (RFC3339) for point-in-time recovery; empty means latest.","type":"string","default":""}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"extensions":{"description":"List of enabled PostgreSQL extensions.","type":"array","items":{"type":"string"}},"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"postgresql":{"description":"PostgreSQL server configuration.","type":"object","default":{},"properties":{"parameters":{"description":"PostgreSQL server parameters.","type":"object","default":{},"properties":{"max_connections":{"description":"Maximum number of concurrent connections to the database server.","type":"integer","default":100}}}}},"quorum":{"description":"Quorum configuration for synchronous replication.","type":"object","default":{},"required":["maxSyncReplicas","minSyncReplicas"],"properties":{"maxSyncReplicas":{"description":"Maximum number of synchronous replicas allowed (must be less than total replicas).","type":"integer","default":0},"minSyncReplicas":{"description":"Minimum number of synchronous replicas required for commit.","type":"integer","default":0}}},"replicas":{"description":"Number of Postgres replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each PostgreSQL replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"},"replication":{"description":"Whether the user has replication privileges.","type":"boolean"}}}}}} + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["enabled"],"properties":{"destinationPath":{"description":"Destination path for backups (e.g. s3://bucket/path/).","type":"string","default":"s3://bucket/path/to/folder/"},"enabled":{"description":"Enable regular backups.","type":"boolean","default":false},"endpointURL":{"description":"S3 endpoint URL for uploads.","type":"string","default":"http://minio-gateway-service:9000"},"retentionPolicy":{"description":"Retention policy (e.g. \"30d\").","type":"string","default":"30d"},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * * *"}}},"bootstrap":{"description":"Bootstrap configuration.","type":"object","default":{},"required":["enabled","oldName"],"properties":{"enabled":{"description":"Whether to restore from a backup.","type":"boolean","default":false},"oldName":{"description":"Previous cluster name before deletion.","type":"string","default":""},"recoveryTime":{"description":"Timestamp (RFC3339) for point-in-time recovery; empty means latest.","type":"string","default":""}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"extensions":{"description":"List of enabled PostgreSQL extensions.","type":"array","items":{"type":"string"}},"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"postgresql":{"description":"PostgreSQL server configuration.","type":"object","default":{},"properties":{"parameters":{"description":"PostgreSQL server parameters.","type":"object","default":{},"properties":{"max_connections":{"description":"Maximum number of concurrent connections to the database server.","type":"integer","default":100}}}}},"quorum":{"description":"Quorum configuration for synchronous replication.","type":"object","default":{},"required":["maxSyncReplicas","minSyncReplicas"],"properties":{"maxSyncReplicas":{"description":"Maximum number of synchronous replicas allowed (must be less than total replicas).","type":"integer","default":0},"minSyncReplicas":{"description":"Minimum number of synchronous replicas required for commit.","type":"integer","default":0}}},"replicas":{"description":"Number of Postgres replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each PostgreSQL replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"},"replication":{"description":"Whether the user has replication privileges.","type":"boolean"}}}},"version":{"description":"PostgreSQL major version to deploy","type":"string","default":"v18","enum":["v18","v17","v16","v15","v14","v13"]}}} release: prefix: postgres- labels: @@ -35,7 +35,7 @@ spec: # labelSelector: # helm.toolkit.fluxcd.io/name: "{reqs[0]['metadata','name']}" - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "postgresql"], ["spec", "postgresql", "parameters"], ["spec", "postgresql", "parameters", "max_connections"], ["spec", "quorum"], ["spec", "quorum", "minSyncReplicas"], ["spec", "quorum", "maxSyncReplicas"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "retentionPolicy"], ["spec", "backup", "destinationPath"], ["spec", "backup", "endpointURL"], ["spec", "backup", "schedule"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "bootstrap"], ["spec", "bootstrap", "enabled"], ["spec", "bootstrap", "recoveryTime"], ["spec", "bootstrap", "oldName"]] + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "version"], ["spec", "postgresql"], ["spec", "postgresql", "parameters"], ["spec", "postgresql", "parameters", "max_connections"], ["spec", "quorum"], ["spec", "quorum", "minSyncReplicas"], ["spec", "quorum", "maxSyncReplicas"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "retentionPolicy"], ["spec", "backup", "destinationPath"], ["spec", "backup", "endpointURL"], ["spec", "backup", "schedule"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "bootstrap"], ["spec", "bootstrap", "enabled"], ["spec", "bootstrap", "recoveryTime"], ["spec", "bootstrap", "oldName"]] secrets: exclude: [] include: diff --git a/packages/system/cozystack-resource-definitions/cozyrds/redis.yaml b/packages/system/cozystack-resource-definitions/cozyrds/redis.yaml index 1c5131d3..d23f8d2c 100644 --- a/packages/system/cozystack-resource-definitions/cozyrds/redis.yaml +++ b/packages/system/cozystack-resource-definitions/cozyrds/redis.yaml @@ -8,7 +8,7 @@ spec: plural: redises singular: redis openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"authEnabled":{"description":"Enable password generation.","type":"boolean","default":true},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of Redis replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each Redis replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}} + {"title":"Chart Values","type":"object","properties":{"authEnabled":{"description":"Enable password generation.","type":"boolean","default":true},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of Redis replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each Redis replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"version":{"description":"Redis major version to deploy","type":"string","default":"v8","enum":["v8","v7"]}}} release: prefix: redis- labels: @@ -27,7 +27,7 @@ spec: tags: - cache icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzIxMykiLz4KPHBhdGggZD0iTTEyMC4xNDkgOTUuNTQ5MUMxMTQuNTg2IDk4LjQ0ODUgODUuNzcwOSAxMTAuMjk2IDc5LjYzNjMgMTEzLjQ5NUM3My41MDE2IDExNi42OTMgNzAuMDkzNyAxMTYuNjYyIDY1LjI0NzIgMTE0LjM0NkM2MC40MDEyIDExMi4wMjkgMjkuNzM2NCA5OS42NDIzIDI0LjIxMjUgOTcuMDAxOUMyMS40NTE5IDk1LjY4MjcgMjAgOTQuNTY4NyAyMCA5My41MTY2VjgyLjk4MDlDMjAgODIuOTgwOSA1OS45MjIgNzQuMjkwMSA2Ni4zNjY5IDcxLjk3NzhDNzIuODExNSA2OS42NjU2IDc1LjA0NzYgNjkuNTgyMSA4MC41MzIgNzEuNTkxQzg2LjAxNzMgNzMuNjAwOCAxMTguODEyIDc5LjUxNzYgMTI0LjIzMyA4MS41MDI5TDEyNC4yMyA5MS44ODk2QzEyNC4yMzEgOTIuOTMxMSAxMjIuOTggOTQuMDczNiAxMjAuMTQ5IDk1LjU0OTFaIiBmaWxsPSIjOTEyNjI2Ii8+CjxwYXRoIGQ9Ik0xMjAuMTQ3IDg1LjA3NTJDMTE0LjU4NSA4Ny45NzM0IDg1Ljc3IDk5LjgyMTggNzkuNjM1NCAxMDMuMDJDNzMuNTAxMSAxMDYuMjE5IDcwLjA5MzIgMTA2LjE4NyA2NS4yNDcyIDEwMy44NzFDNjAuNDAwNyAxMDEuNTU1IDI5LjczNzEgODkuMTY2OCAyNC4yMTM2IDg2LjUyOEMxOC42OTAxIDgzLjg4NzYgMTguNTc0NCA4Mi4wNzA0IDI0LjAwMDMgNzkuOTQ1OEMyOS40MjYxIDc3LjgyMDUgNTkuOTIxNSA2NS44NTYxIDY2LjM2NzIgNjMuNTQzOEM3Mi44MTE4IDYxLjIzMjQgNzUuMDQ3NSA2MS4xNDgxIDgwLjUzMTkgNjMuMTU3OEM4Ni4wMTY4IDY1LjE2NjggMTE0LjY2IDc2LjU2NzYgMTIwLjA3OSA3OC41NTI1QzEyNS41MDEgODAuNTM5OSAxMjUuNzA5IDgyLjE3NjMgMTIwLjE0NyA4NS4wNzUyWiIgZmlsbD0iI0M2MzAyQiIvPgo8cGF0aCBkPSJNMTIwLjE0OSA3OC41MDJDMTE0LjU4NiA4MS40MDE4IDg1Ljc3MDkgOTMuMjQ5MyA3OS42MzYzIDk2LjQ0ODhDNzMuNTAxNiA5OS42NDYyIDcwLjA5MzcgOTkuNjE1MiA2NS4yNDcyIDk3LjI5ODVDNjAuNDAwOCA5NC45ODMgMjkuNzM2NCA4Mi41OTUyIDI0LjIxMjUgNzkuOTU0N0MyMS40NTE5IDc4LjYzNTUgMjAgNzcuNTIzMiAyMCA3Ni40NzA3VjY1LjkzMzhDMjAgNjUuOTMzOCA1OS45MjIgNTcuMjQzNCA2Ni4zNjY5IDU0LjkzMTFDNzIuODExNSA1Mi42MTg5IDc1LjA0NzYgNTIuNTM1IDgwLjUzMiA1NC41NDQzQzg2LjAxNzcgNTYuNTUzNiAxMTguODEzIDYyLjQ2OTMgMTI0LjIzMyA2NC40NTVMMTI0LjIzIDc0Ljg0MjhDMTI0LjIzMSA3NS44ODQgMTIyLjk4IDc3LjAyNjQgMTIwLjE0OSA3OC41MDJaIiBmaWxsPSIjOTEyNjI2Ii8+CjxwYXRoIGQ9Ik0xMjAuMTQ3IDY4LjAyODJDMTE0LjU4NSA3MC45MjcxIDg1Ljc3IDgyLjc3NDcgNzkuNjM1NCA4NS45NzM3QzczLjUwMTEgODkuMTcxNiA3MC4wOTMyIDg5LjE0MDIgNjUuMjQ3MiA4Ni44MjM1QzYwLjQwMDcgODQuNTA4NCAyOS43MzcxIDcyLjEyMDEgMjQuMjEzNiA2OS40ODA5QzE4LjY5MDEgNjYuODQxMyAxOC41NzQ0IDY1LjAyMzcgMjQuMDAwMyA2Mi44OTg0QzI5LjQyNjEgNjAuNzc0MiA1OS45MjE5IDQ4LjgwOSA2Ni4zNjcyIDQ2LjQ5NzJDNzIuODExOCA0NC4xODUzIDc1LjA0NzUgNDQuMTAxNCA4MC41MzE5IDQ2LjExMDhDODYuMDE2OCA0OC4xMTk3IDExNC42NiA1OS41MTk3IDEyMC4wNzkgNjEuNTA1NUMxMjUuNTAxIDYzLjQ5MjQgMTI1LjcwOSA2NS4xMjkyIDEyMC4xNDcgNjguMDI4MloiIGZpbGw9IiNDNjMwMkIiLz4KPHBhdGggZD0iTTEyMC4xNDkgNjAuODIyNEMxMTQuNTg2IDYzLjcyMTQgODUuNzcwOSA3NS41Njk4IDc5LjYzNjMgNzguNzY5MkM3My41MDE2IDgxLjk2NzEgNzAuMDkzNyA4MS45MzU3IDY1LjI0NzIgNzkuNjE5QzYwLjQwMDggNzcuMzAzNSAyOS43MzY0IDY0LjkxNTIgMjQuMjEyNSA2Mi4yNzZDMjEuNDUxOSA2MC45NTU2IDIwIDU5Ljg0MjggMjAgNTguNzkxNVY0OC4yNTQyQzIwIDQ4LjI1NDIgNTkuOTIyIDM5LjU2NDIgNjYuMzY2OSAzNy4yNTI0QzcyLjgxMTUgMzQuOTM5NyA3NS4wNDc2IDM0Ljg1NjcgODAuNTMyIDM2Ljg2NTZDODYuMDE3NyAzOC44NzQ5IDExOC44MTMgNDQuNzkwNSAxMjQuMjMzIDQ2Ljc3NjNMMTI0LjIzIDU3LjE2MzdDMTI0LjIzMSA1OC4yMDQgMTIyLjk4IDU5LjM0NjUgMTIwLjE0OSA2MC44MjI0WiIgZmlsbD0iIzkxMjYyNiIvPgo8cGF0aCBkPSJNMTIwLjE0NyA1MC4zNDlDMTE0LjU4NSA1My4yNDc5IDg1Ljc2OTggNjUuMDk2MyA3OS42MzUyIDY4LjI5NDFDNzMuNTAwOSA3MS40OTIgNzAuMDkzIDcxLjQ2MDYgNjUuMjQ2OSA2OS4xNDUxQzYwLjQwMDkgNjYuODI4MyAyOS43MzY5IDU0LjQ0MDkgMjQuMjEzOCA1MS44MDEzQzE4LjY4OTkgNDkuMTYyMSAxOC41NzQ2IDQ3LjM0NDEgMjQgNDUuMjE5MkMyOS40MjU5IDQzLjA5NDYgNTkuOTIxNyAzMS4xMzEgNjYuMzY3IDI4LjgxODRDNzIuODExNiAyNi41MDYxIDc1LjA0NzMgMjYuNDIzIDgwLjUzMTcgMjguNDMyNEM4Ni4wMTY2IDMwLjQ0MTcgMTE0LjY1OSA0MS44NDE4IDEyMC4wNzkgNDMuODI3NUMxMjUuNTAxIDQ1LjgxMjggMTI1LjcwOSA0Ny40NSAxMjAuMTQ3IDUwLjM0OVoiIGZpbGw9IiNDNjMwMkIiLz4KPHBhdGggZD0iTTg0Ljg1NDEgNDAuMDk5NEw3NS44OTI2IDQxLjAyOThMNzMuODg2NSA0NS44NTdMNzAuNjQ2MyA0MC40NzAzTDYwLjI5ODMgMzkuNTQwNEw2OC4wMTk3IDM2Ljc1NThMNjUuNzAzIDMyLjQ4MTRMNzIuOTMyMSAzNS4zMDg4TDc5Ljc0NzEgMzMuMDc3NUw3Ny45MDUyIDM3LjQ5NzJMODQuODU0MSA0MC4wOTk0Wk03My4zNTE1IDYzLjUxODRMNTYuNjI2NiA1Ni41ODE2TDgwLjU5MiA1Mi45MDI5TDczLjM1MTUgNjMuNTE4NFpNNTAuMTYzNyA0Mi43ODI2QzU3LjIzODEgNDIuNzgyNiA2Mi45NzMgNDUuMDA1NyA2Mi45NzMgNDcuNzQ3NUM2Mi45NzMgNTAuNDkwMSA1Ny4yMzgxIDUyLjcxMjggNTAuMTYzNyA1Mi43MTI4QzQzLjA4OTMgNTIuNzEyOCAzNy4zNTQ1IDUwLjQ4OTcgMzcuMzU0NSA0Ny43NDc1QzM3LjM1NDUgNDUuMDA1NyA0My4wODkzIDQyLjc4MjYgNTAuMTYzNyA0Mi43ODI2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTk1LjQ0MzQgNDEuNDE3NEwxMDkuNjI3IDQ3LjAyMjRMOTUuNDU1NiA1Mi42MjJMOTUuNDQzNCA0MS40MTc0WiIgZmlsbD0iIzYyMUIxQyIvPgo8cGF0aCBkPSJNNzkuNzUyOSA0Ny42MjYxTDk1LjQ0NDkgNDEuNDE4OUw5NS40NTcxIDUyLjYyMzZMOTMuOTE4NCA1My4yMjU0TDc5Ljc1MjkgNDcuNjI2MVoiIGZpbGw9IiM5QTI5MjgiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMzIxMyIgeDE9IjE4OSIgeTE9IjIxMC41IiB4Mj0iMCIgeTI9IjAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0E4MDAwMCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkNGQ0YiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "authEnabled"]] + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "version"], ["spec", "authEnabled"]] secrets: exclude: [] include: diff --git a/packages/system/fluxcd-operator/charts/flux-operator/Chart.yaml b/packages/system/fluxcd-operator/charts/flux-operator/Chart.yaml index b95a2a04..d59dedfa 100644 --- a/packages/system/fluxcd-operator/charts/flux-operator/Chart.yaml +++ b/packages/system/fluxcd-operator/charts/flux-operator/Chart.yaml @@ -8,7 +8,7 @@ annotations: - name: Upstream Project url: https://github.com/controlplaneio-fluxcd/flux-operator apiVersion: v2 -appVersion: v0.30.0 +appVersion: v0.33.0 description: 'A Helm chart for deploying the Flux Operator. ' home: https://github.com/controlplaneio-fluxcd icon: https://raw.githubusercontent.com/cncf/artwork/main/projects/flux/icon/color/flux-icon-color.png @@ -25,4 +25,4 @@ sources: - https://github.com/controlplaneio-fluxcd/flux-operator - https://github.com/controlplaneio-fluxcd/charts type: application -version: 0.30.0 +version: 0.33.0 diff --git a/packages/system/fluxcd-operator/charts/flux-operator/README.md b/packages/system/fluxcd-operator/charts/flux-operator/README.md index 0367d113..036fc534 100644 --- a/packages/system/fluxcd-operator/charts/flux-operator/README.md +++ b/packages/system/fluxcd-operator/charts/flux-operator/README.md @@ -1,6 +1,6 @@ # flux-operator -![Version: 0.30.0](https://img.shields.io/badge/Version-0.30.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.30.0](https://img.shields.io/badge/AppVersion-v0.30.0-informational?style=flat-square) +![Version: 0.33.0](https://img.shields.io/badge/Version-0.33.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.33.0](https://img.shields.io/badge/AppVersion-v0.33.0-informational?style=flat-square) The [Flux Operator](https://github.com/controlplaneio-fluxcd/flux-operator) provides a declarative API for the installation and upgrade of CNCF [Flux](https://fluxcd.io) and the diff --git a/packages/system/fluxcd-operator/charts/flux-operator/templates/crds.yaml b/packages/system/fluxcd-operator/charts/flux-operator/templates/crds.yaml index 764382d2..fdd6fe76 100644 --- a/packages/system/fluxcd-operator/charts/flux-operator/templates/crds.yaml +++ b/packages/system/fluxcd-operator/charts/flux-operator/templates/crds.yaml @@ -203,6 +203,15 @@ spec: Registry address to pull the distribution images from e.g. 'ghcr.io/fluxcd'. type: string + variant: + description: |- + Variant specifies the Flux distribution flavor stored + in the registry. + enum: + - upstream-alpine + - enterprise-alpine + - enterprise-distroless + type: string version: description: Version semver expression e.g. '2.x', '2.3.x'. type: string @@ -583,6 +592,12 @@ spec: LastAttemptedRevision is the version and digest of the distribution config that was last attempted to reconcile. type: string + lastHandledForceAt: + description: |- + LastHandledForceAt holds the value of the most recent + force request value, so a change of the annotation value + can be detected. + type: string lastHandledReconcileAt: description: |- LastHandledReconcileAt holds the value of the most recent diff --git a/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml b/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml index 0a9db1cc..f97ddba3 100644 --- a/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml +++ b/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml @@ -1,5 +1,4 @@ {{- if .Capabilities.APIVersions.Has "cilium.io/v2/CiliumClusterwideNetworkPolicy" }} ---- apiVersion: cilium.io/v2 kind: CiliumClusterwideNetworkPolicy metadata: diff --git a/packages/system/fluxcd-operator/patches/networkPolicy.diff b/packages/system/fluxcd-operator/patches/networkPolicy.diff index a7bf3207..e074ae2f 100644 --- a/packages/system/fluxcd-operator/patches/networkPolicy.diff +++ b/packages/system/fluxcd-operator/patches/networkPolicy.diff @@ -1,8 +1,8 @@ -diff --git a/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml b/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml +diff --git a/charts/flux-operator/templates/network-policy.yaml b/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml new file mode 100644 --- /dev/null (revision 52a23eacfc32430d8b008b765c64a81526521bae) -+++ b/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml (revision 52a23eacfc32430d8b008b765c64a81526521bae) -@@ -0,0 +1,18 @@ ++++ b/charts/flux-operator/templates/network-policy.yaml (revision 52a23eacfc32430d8b008b765c64a81526521bae) +@@ -0,0 +1,20 @@ +{{- if .Capabilities.APIVersions.Has "cilium.io/v2/CiliumClusterwideNetworkPolicy" }} +apiVersion: cilium.io/v2 +kind: CiliumClusterwideNetworkPolicy diff --git a/packages/system/fluxcd/charts/flux-instance/Chart.yaml b/packages/system/fluxcd/charts/flux-instance/Chart.yaml index 90dfadb5..448e6600 100644 --- a/packages/system/fluxcd/charts/flux-instance/Chart.yaml +++ b/packages/system/fluxcd/charts/flux-instance/Chart.yaml @@ -8,7 +8,7 @@ annotations: - name: Upstream Project url: https://github.com/controlplaneio-fluxcd/flux-operator apiVersion: v2 -appVersion: v0.30.0 +appVersion: v0.33.0 description: 'A Helm chart for deploying a Flux instance managed by Flux Operator. ' home: https://github.com/controlplaneio-fluxcd icon: https://raw.githubusercontent.com/cncf/artwork/main/projects/flux/icon/color/flux-icon-color.png @@ -25,4 +25,4 @@ sources: - https://github.com/controlplaneio-fluxcd/flux-operator - https://github.com/controlplaneio-fluxcd/charts type: application -version: 0.30.0 +version: 0.33.0 diff --git a/packages/system/fluxcd/charts/flux-instance/README.md b/packages/system/fluxcd/charts/flux-instance/README.md index a6611caf..e788edf1 100644 --- a/packages/system/fluxcd/charts/flux-instance/README.md +++ b/packages/system/fluxcd/charts/flux-instance/README.md @@ -1,6 +1,6 @@ # flux-instance -![Version: 0.30.0](https://img.shields.io/badge/Version-0.30.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.30.0](https://img.shields.io/badge/AppVersion-v0.30.0-informational?style=flat-square) +![Version: 0.33.0](https://img.shields.io/badge/Version-0.33.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.33.0](https://img.shields.io/badge/AppVersion-v0.33.0-informational?style=flat-square) This chart is a thin wrapper around the `FluxInstance` custom resource, which is used by the [Flux Operator](https://github.com/controlplaneio-fluxcd/flux-operator) diff --git a/packages/system/fluxcd/values.yaml b/packages/system/fluxcd/values.yaml index 837be8d8..3559a330 100644 --- a/packages/system/fluxcd/values.yaml +++ b/packages/system/fluxcd/values.yaml @@ -5,7 +5,7 @@ flux-instance: domain: cozy.local # -- default value is overriden in patches distribution: artifact: "" - version: 2.6.x + version: 2.7.x registry: ghcr.io/fluxcd components: - source-controller diff --git a/packages/system/kubeovn/Chart.yaml b/packages/system/kubeovn/Chart.yaml index 16cb9dc5..d1532794 100644 --- a/packages/system/kubeovn/Chart.yaml +++ b/packages/system/kubeovn/Chart.yaml @@ -1,3 +1,3 @@ apiVersion: v2 name: cozy-kubeovn -version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process +version: 0.39.0 diff --git a/packages/system/kubeovn/Makefile b/packages/system/kubeovn/Makefile index 15373d2f..a4a0d1ed 100644 --- a/packages/system/kubeovn/Makefile +++ b/packages/system/kubeovn/Makefile @@ -1,4 +1,4 @@ -KUBEOVN_TAG=$(shell awk '$$1 == "version:" {print $$2}' charts/kube-ovn/Chart.yaml) +KUBEOVN_TAG=v0.39.0 export NAME=kubeovn export NAMESPACE=cozy-$(NAME) @@ -7,28 +7,7 @@ include ../../../scripts/common-envs.mk include ../../../scripts/package.mk update: - rm -rf charts && mkdir -p charts/kube-ovn - tag=$$(git ls-remote --tags --sort="v:refname" https://github.com/kubeovn/kube-ovn | awk -F'[/^]' '{print $$3}' | grep '^v1\.14\.' | tail -n1 ) && \ - curl -sSL https://github.com/kubeovn/kube-ovn/archive/refs/tags/$${tag}.tar.gz | \ - tar xzvf - --strip 1 kube-ovn-$${tag#*v}/charts/kube-ovn - patch --no-backup-if-mismatch -p4 < patches/cozyconfig.diff - patch --no-backup-if-mismatch -p4 < patches/mtu.diff - version=$$(awk '$$1 == "version:" {print $$2}' charts/kube-ovn/Chart.yaml) && \ - sed -i "s/ARG VERSION=.*/ARG VERSION=$${version}/" images/kubeovn/Dockerfile && \ - sed -i "s/ARG TAG=.*/ARG TAG=$${version}/" images/kubeovn/Dockerfile - -image: - docker buildx build images/kubeovn \ - --tag $(REGISTRY)/kubeovn:$(call settag,$(KUBEOVN_TAG)) \ - --tag $(REGISTRY)/kubeovn:$(call settag,$(KUBEOVN_TAG)-$(TAG)) \ - --cache-from type=registry,ref=$(REGISTRY)/kubeovn:latest \ - --cache-to type=inline \ - --metadata-file images/kubeovn.json \ - $(BUILDX_ARGS) - REGISTRY="$(REGISTRY)" \ - yq -i '.global.registry.address = strenv(REGISTRY)' values.yaml - REPOSITORY="kubeovn" \ - yq -i '.global.images.kubeovn.repository = strenv(REPOSITORY)' values.yaml - TAG="$(call settag,$(KUBEOVN_TAG))@$$(yq e '."containerimage.digest"' images/kubeovn.json -o json -r)" \ - yq -i '.global.images.kubeovn.tag = strenv(TAG)' values.yaml - rm -f images/kubeovn.json + rm -rf charts values.yaml Chart.yaml + tag=$(KUBEOVN_TAG) && \ + curl -sSL https://github.com/cozystack/kubeovn/archive/refs/tags/$${tag}.tar.gz | \ + tar xzvf - --strip 2 kubeovn-$${tag#*v}/chart diff --git a/packages/system/kubeovn/images/kubeovn/Dockerfile b/packages/system/kubeovn/images/kubeovn/Dockerfile deleted file mode 100644 index 5ea19c93..00000000 --- a/packages/system/kubeovn/images/kubeovn/Dockerfile +++ /dev/null @@ -1,47 +0,0 @@ -# syntax = docker/dockerfile:experimental -ARG VERSION=v1.14.11 -ARG BASE_TAG=$VERSION - -FROM golang:1.25-bookworm as builder - -ARG TAG=v1.14.11 -RUN git clone --branch ${TAG} --depth 1 https://github.com/kubeovn/kube-ovn /source - -WORKDIR /source - -COPY patches /patches -RUN git apply /patches/*.diff -RUN make build-go - -WORKDIR /source/dist/images - -# imported from https://github.com/kubeovn/kube-ovn/blob/master/dist/images/Dockerfile -FROM kubeovn/kube-ovn-base:$BASE_TAG AS setcap - -COPY --from=builder /source/dist/images/*.sh /kube-ovn/ -COPY --from=builder /source/dist/images/kubectl-ko /kube-ovn/kubectl-ko -COPY --from=builder /source/dist/images/01-kube-ovn.conflist /kube-ovn/01-kube-ovn.conflist - -COPY --from=builder /source/dist/images/kube-ovn /kube-ovn/kube-ovn -COPY --from=builder /source/dist/images/kube-ovn-cmd /kube-ovn/kube-ovn-cmd -COPY --from=builder /source/dist/images/kube-ovn-daemon /kube-ovn/kube-ovn-daemon -COPY --from=builder /source/dist/images/kube-ovn-controller /kube-ovn/kube-ovn-controller -RUN ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-monitor && \ - ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-speaker && \ - ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-webhook && \ - ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-leader-checker && \ - ln -s /kube-ovn/kube-ovn-cmd /kube-ovn/kube-ovn-ic-controller && \ - ln -s /kube-ovn/kube-ovn-controller /kube-ovn/kube-ovn-pinger && \ - setcap CAP_NET_BIND_SERVICE+eip /kube-ovn/kube-ovn-cmd && \ - setcap CAP_NET_RAW,CAP_NET_BIND_SERVICE+eip /kube-ovn/kube-ovn-controller && \ - setcap CAP_NET_ADMIN,CAP_NET_RAW,CAP_NET_BIND_SERVICE,CAP_SYS_ADMIN+eip /kube-ovn/kube-ovn-daemon - -FROM kubeovn/kube-ovn-base:$BASE_TAG - -COPY --chmod=0644 --from=builder /source/dist/images/logrotate/* /etc/logrotate.d/ -COPY --from=builder /source/dist/images/grace_stop_ovn_controller /usr/share/ovn/scripts/grace_stop_ovn_controller - -COPY --from=setcap /kube-ovn /kube-ovn -RUN /kube-ovn/iptables-wrapper-installer.sh --no-sanity-check - -WORKDIR /kube-ovn diff --git a/packages/system/kubeovn/images/kubeovn/patches/northd_probe.diff b/packages/system/kubeovn/images/kubeovn/patches/northd_probe.diff deleted file mode 100644 index 93edd879..00000000 --- a/packages/system/kubeovn/images/kubeovn/patches/northd_probe.diff +++ /dev/null @@ -1,109 +0,0 @@ -diff --git a/pkg/ovn_leader_checker/ovn.go b/pkg/ovn_leader_checker/ovn.go -index 0f86a371d..8ddf7bca6 100755 ---- a/pkg/ovn_leader_checker/ovn.go -+++ b/pkg/ovn_leader_checker/ovn.go -@@ -10,6 +10,7 @@ import ( - "os/exec" - "strconv" - "strings" -+ "sync" - "syscall" - "time" - -@@ -271,19 +272,56 @@ func checkNorthdSvcExist(cfg *Configuration, namespace, svcName string) bool { - return true - } - --func checkNorthdEpAvailable(ip string) bool { -- address := net.JoinHostPort(ip, OvnNorthdPort) -- conn, err := net.DialTimeout("tcp", address, 3*time.Second) -- if err != nil { -- klog.Errorf("failed to connect to northd leader %s, err: %v", ip, err) -- failCount++ -- if failCount >= MaxFailCount { -- return false -- } -- } else { -+func checkNorthdEpAvailable(ips ...string) bool { -+ var wg sync.WaitGroup -+ success := make(chan struct{}, 1) -+ failure := make(chan struct{}) -+ ctx, cancel := context.WithCancel(context.Background()) -+ defer cancel() -+ d := net.Dialer{Timeout: 3 * time.Second} -+ for _, ip := range ips { -+ address := net.JoinHostPort(ip, OvnNorthdPort) -+ wg.Add(1) -+ go func() { -+ defer wg.Done() -+ conn, err := d.DialContext(ctx, "tcp", address) -+ if err != nil { -+ klog.Errorf("failed to connect to northd leader %s, err: %v", ip, err) -+ return -+ } else { -+ defer conn.Close() -+ select { -+ case success <- struct{}{}: -+ klog.V(5).Infof("succeed to connect to northd leader %s", ip) -+ cancel() -+ default: -+ // someone else already succeeded -+ } -+ } -+ }() -+ } -+ go func() { -+ wg.Wait() -+ close(failure) -+ }() -+ select { -+ case <-success: - failCount = 0 -- klog.V(5).Infof("succeed to connect to northd leader %s", ip) -- _ = conn.Close() -+ return true -+ case <-failure: -+ // if the last groroutine is the one to succeed, -+ // there's a small chance that failure is selected, -+ // this is a guard for this -+ select { -+ case <-success: -+ failCount = 0 -+ return true -+ default: -+ failCount++ -+ if failCount >= MaxFailCount { -+ return false -+ } -+ } - } - return true - } -@@ -295,6 +333,8 @@ func checkNorthdEpAlive(cfg *Configuration, namespace, service string) bool { - return false - } - -+ addresses := []string{} -+ - for _, eps := range epsList.Items { - for _, ep := range eps.Endpoints { - if (ep.Conditions.Ready != nil && !*ep.Conditions.Ready) || len(ep.Addresses) == 0 { -@@ -303,12 +343,15 @@ func checkNorthdEpAlive(cfg *Configuration, namespace, service string) bool { - - // Found an address, check its availability. We only need one. - klog.V(5).Infof("found address %s in endpoint slice %s/%s for service %s, checking availability", ep.Addresses[0], eps.Namespace, eps.Name, service) -- return checkNorthdEpAvailable(ep.Addresses[0]) -+ addresses = append(addresses, ep.Addresses[0]) // Addresses are fungible by k8s API design - } - } - -- klog.V(5).Infof("no address found in any endpoint slices for service %s/%s", namespace, service) -- return false -+ if len(addresses) == 0 { -+ klog.V(5).Infof("no address found in any endpoint slices for service %s/%s", namespace, service) -+ return false -+ } -+ return checkNorthdEpAvailable(addresses...) - } - - func compactOvnDatabase(db string) { diff --git a/packages/system/kubeovn/patches/cozyconfig.diff b/packages/system/kubeovn/patches/cozyconfig.diff deleted file mode 100644 index f7a683f7..00000000 --- a/packages/system/kubeovn/patches/cozyconfig.diff +++ /dev/null @@ -1,103 +0,0 @@ - -diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -index d9a9a67..b2e12dd 100644 ---- a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -+++ b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -@@ -51,18 +51,15 @@ spec: - - bash - - /kube-ovn/start-cniserver.sh - args: -+ {{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} - - --enable-mirror={{- .Values.debug.ENABLE_MIRROR }} - - --mirror-iface={{- .Values.debug.MIRROR_IFACE }} - - --node-switch={{ .Values.networking.NODE_SUBNET }} - - --encap-checksum=true -- - --service-cluster-ip-range= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.SVC_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.SVC_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.SVC_CIDR }} -- {{- end }} -+ - --service-cluster-ip-range={{ index $cozyConfig.data "ipv4-svc-cidr" }} -+ {{- if .Values.global.logVerbosity }} -+ - --v={{ .Values.global.logVerbosity }} -+ {{- end }} - {{- if eq .Values.networking.NETWORK_TYPE "vlan" }} - - --iface= - {{- else}} -diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml -index 0e69494..756eb7c 100644 ---- a/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml -+++ b/packages/system/kubeovn/charts/kube-ovn/templates/controller-deploy.yaml -@@ -52,46 +52,22 @@ spec: - image: {{ .Values.global.registry.address }}/{{ .Values.global.images.kubeovn.repository }}:{{ .Values.global.images.kubeovn.tag }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - args: -+ {{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} - - /kube-ovn/start-controller.sh - - --default-ls={{ .Values.networking.DEFAULT_SUBNET }} -- - --default-cidr= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.POD_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.POD_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.POD_CIDR }} -- {{- end }} -- - --default-gateway= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.POD_GATEWAY }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.POD_GATEWAY }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.POD_GATEWAY }} -- {{- end }} -+ - --default-cidr={{ index $cozyConfig.data "ipv4-pod-cidr" }} -+ - --default-gateway={{ index $cozyConfig.data "ipv4-pod-gateway" }} - - --default-gateway-check={{- .Values.func.CHECK_GATEWAY }} - - --default-logical-gateway={{- .Values.func.LOGICAL_GATEWAY }} - - --default-u2o-interconnection={{- .Values.func.U2O_INTERCONNECTION }} - - --default-exclude-ips={{- .Values.networking.EXCLUDE_IPS }} - - --cluster-router={{ .Values.networking.DEFAULT_VPC }} - - --node-switch={{ .Values.networking.NODE_SUBNET }} -- - --node-switch-cidr= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.JOIN_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.JOIN_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.JOIN_CIDR }} -- {{- end }} -- - --service-cluster-ip-range= -- {{- if eq .Values.networking.NET_STACK "dual_stack" -}} -- {{ .Values.dual_stack.SVC_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv4" -}} -- {{ .Values.ipv4.SVC_CIDR }} -- {{- else if eq .Values.networking.NET_STACK "ipv6" -}} -- {{ .Values.ipv6.SVC_CIDR }} -- {{- end }} -+ - --node-switch-cidr={{ index $cozyConfig.data "ipv4-join-cidr" }} -+ - --service-cluster-ip-range={{ index $cozyConfig.data "ipv4-svc-cidr" }} -+ {{- if .Values.global.logVerbosity }} -+ - --v={{ .Values.global.logVerbosity }} -+ {{- end }} - - --network-type={{- .Values.networking.NETWORK_TYPE }} - - --default-provider-name={{ .Values.networking.vlan.PROVIDER_NAME }} - - --default-interface-name={{- .Values.networking.vlan.VLAN_INTERFACE_NAME }} -diff --git a/packages/system/kubeovn/charts/kube-ovn/values.yaml b/packages/system/kubeovn/charts/kube-ovn/values.yaml -index bfffc4d..b880749 100644 ---- a/packages/system/kubeovn/charts/kube-ovn/values.yaml -+++ b/packages/system/kubeovn/charts/kube-ovn/values.yaml -@@ -70,10 +70,6 @@ func: - ENABLE_TPROXY: false - - ipv4: -- POD_CIDR: "10.16.0.0/16" -- POD_GATEWAY: "10.16.0.1" -- SVC_CIDR: "10.96.0.0/12" -- JOIN_CIDR: "100.64.0.0/16" - PINGER_EXTERNAL_ADDRESS: "1.1.1.1" - PINGER_EXTERNAL_DOMAIN: "alauda.cn." - diff --git a/packages/system/kubeovn/patches/mtu.diff b/packages/system/kubeovn/patches/mtu.diff deleted file mode 100644 index da3de3aa..00000000 --- a/packages/system/kubeovn/patches/mtu.diff +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -index 63f4258..dafe1fd 100644 ---- a/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -+++ b/packages/system/kubeovn/charts/kube-ovn/templates/ovncni-ds.yaml -@@ -112,6 +112,9 @@ spec: - - --secure-serving={{- .Values.func.SECURE_SERVING }} - - --enable-ovn-ipsec={{- .Values.func.ENABLE_OVN_IPSEC }} - - --set-vxlan-tx-off={{- .Values.func.SET_VXLAN_TX_OFF }} -+ {{- with .Values.mtu }} -+ - --mtu={{ . }} -+ {{- end }} - securityContext: - runAsUser: 0 - privileged: false diff --git a/packages/system/kubeovn/values.yaml b/packages/system/kubeovn/values.yaml index 72d62674..89f20e7c 100644 --- a/packages/system/kubeovn/values.yaml +++ b/packages/system/kubeovn/values.yaml @@ -65,4 +65,4 @@ global: images: kubeovn: repository: kubeovn - tag: v1.14.11@sha256:8e6cf216687b4a80c35fa7c60bb4d511dd6aaaaf19d1ec53321dfef98d343f51 + tag: v1.14.11@sha256:0e3e9db960a9600d58c33c0787cabd0e9bf263930fd8c9fe65417e258c383d01 diff --git a/packages/system/metrics-server/.helmignore b/packages/system/metrics-server/.helmignore new file mode 100644 index 00000000..e69de29b diff --git a/packages/system/metrics-server/Chart.yaml b/packages/system/metrics-server/Chart.yaml new file mode 100644 index 00000000..d035ddb3 --- /dev/null +++ b/packages/system/metrics-server/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: cozy-metrics-server +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/metrics-server/Makefile b/packages/system/metrics-server/Makefile new file mode 100644 index 00000000..fb89db64 --- /dev/null +++ b/packages/system/metrics-server/Makefile @@ -0,0 +1,10 @@ +export NAME=metrics-server +export NAMESPACE=cozy-monitoring + +include ../../../scripts/package.mk + +update: + rm -rf charts + helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/ + helm repo update metrics-server + helm pull metrics-server/metrics-server --untar --untardir charts diff --git a/packages/system/monitoring-agents/charts/metrics-server/.helmignore b/packages/system/metrics-server/charts/metrics-server/.helmignore similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/.helmignore rename to packages/system/metrics-server/charts/metrics-server/.helmignore diff --git a/packages/system/monitoring-agents/charts/metrics-server/CHANGELOG.md b/packages/system/metrics-server/charts/metrics-server/CHANGELOG.md similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/CHANGELOG.md rename to packages/system/metrics-server/charts/metrics-server/CHANGELOG.md diff --git a/packages/system/monitoring-agents/charts/metrics-server/Chart.yaml b/packages/system/metrics-server/charts/metrics-server/Chart.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/Chart.yaml rename to packages/system/metrics-server/charts/metrics-server/Chart.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/README.md b/packages/system/metrics-server/charts/metrics-server/README.md similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/README.md rename to packages/system/metrics-server/charts/metrics-server/README.md diff --git a/packages/system/monitoring-agents/charts/metrics-server/RELEASE.md b/packages/system/metrics-server/charts/metrics-server/RELEASE.md similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/RELEASE.md rename to packages/system/metrics-server/charts/metrics-server/RELEASE.md diff --git a/packages/system/monitoring-agents/charts/metrics-server/ci/ci-values.yaml b/packages/system/metrics-server/charts/metrics-server/ci/ci-values.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/ci/ci-values.yaml rename to packages/system/metrics-server/charts/metrics-server/ci/ci-values.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/NOTES.txt b/packages/system/metrics-server/charts/metrics-server/templates/NOTES.txt similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/NOTES.txt rename to packages/system/metrics-server/charts/metrics-server/templates/NOTES.txt diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/_helpers.tpl b/packages/system/metrics-server/charts/metrics-server/templates/_helpers.tpl similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/_helpers.tpl rename to packages/system/metrics-server/charts/metrics-server/templates/_helpers.tpl diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/apiservice.yaml b/packages/system/metrics-server/charts/metrics-server/templates/apiservice.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/apiservice.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/apiservice.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/clusterrole-aggregated-reader.yaml b/packages/system/metrics-server/charts/metrics-server/templates/clusterrole-aggregated-reader.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/clusterrole-aggregated-reader.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/clusterrole-aggregated-reader.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/clusterrole-nanny.yaml b/packages/system/metrics-server/charts/metrics-server/templates/clusterrole-nanny.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/clusterrole-nanny.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/clusterrole-nanny.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/clusterrole.yaml b/packages/system/metrics-server/charts/metrics-server/templates/clusterrole.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/clusterrole.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/clusterrole.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/clusterrolebinding-auth-delegator.yaml b/packages/system/metrics-server/charts/metrics-server/templates/clusterrolebinding-auth-delegator.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/clusterrolebinding-auth-delegator.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/clusterrolebinding-auth-delegator.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/clusterrolebinding-nanny.yaml b/packages/system/metrics-server/charts/metrics-server/templates/clusterrolebinding-nanny.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/clusterrolebinding-nanny.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/clusterrolebinding-nanny.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/clusterrolebinding.yaml b/packages/system/metrics-server/charts/metrics-server/templates/clusterrolebinding.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/clusterrolebinding.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/clusterrolebinding.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/configmaps-nanny.yaml b/packages/system/metrics-server/charts/metrics-server/templates/configmaps-nanny.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/configmaps-nanny.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/configmaps-nanny.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/deployment.yaml b/packages/system/metrics-server/charts/metrics-server/templates/deployment.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/deployment.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/deployment.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/pdb.yaml b/packages/system/metrics-server/charts/metrics-server/templates/pdb.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/pdb.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/pdb.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/psp.yaml b/packages/system/metrics-server/charts/metrics-server/templates/psp.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/psp.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/psp.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/role-nanny.yaml b/packages/system/metrics-server/charts/metrics-server/templates/role-nanny.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/role-nanny.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/role-nanny.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/rolebinding-nanny.yaml b/packages/system/metrics-server/charts/metrics-server/templates/rolebinding-nanny.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/rolebinding-nanny.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/rolebinding-nanny.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/rolebinding.yaml b/packages/system/metrics-server/charts/metrics-server/templates/rolebinding.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/rolebinding.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/rolebinding.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/service.yaml b/packages/system/metrics-server/charts/metrics-server/templates/service.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/service.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/service.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/serviceaccount.yaml b/packages/system/metrics-server/charts/metrics-server/templates/serviceaccount.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/serviceaccount.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/serviceaccount.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/templates/servicemonitor.yaml b/packages/system/metrics-server/charts/metrics-server/templates/servicemonitor.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/templates/servicemonitor.yaml rename to packages/system/metrics-server/charts/metrics-server/templates/servicemonitor.yaml diff --git a/packages/system/monitoring-agents/charts/metrics-server/values.yaml b/packages/system/metrics-server/charts/metrics-server/values.yaml similarity index 100% rename from packages/system/monitoring-agents/charts/metrics-server/values.yaml rename to packages/system/metrics-server/charts/metrics-server/values.yaml diff --git a/packages/system/metrics-server/values.yaml b/packages/system/metrics-server/values.yaml new file mode 100644 index 00000000..98d74b6c --- /dev/null +++ b/packages/system/metrics-server/values.yaml @@ -0,0 +1,15 @@ +metrics-server: + defaultArgs: + - --cert-dir=/tmp + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=15s + - --kubelet-insecure-tls + + metrics: + enabled: true + + serviceMonitor: + enabled: true + + diff --git a/packages/system/monitoring-agents/Makefile b/packages/system/monitoring-agents/Makefile index 42e762c3..f324bfef 100644 --- a/packages/system/monitoring-agents/Makefile +++ b/packages/system/monitoring-agents/Makefile @@ -11,10 +11,6 @@ update: helm pull prometheus-community/kube-state-metrics --untar --untardir charts # Node-exporter helm pull prometheus-community/prometheus-node-exporter --untar --untardir charts - # Metrics-server - helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/ - helm repo update metrics-server - helm pull metrics-server/metrics-server --untar --untardir charts # Fluent-bit helm repo add fluent https://fluent.github.io/helm-charts helm repo update fluent diff --git a/packages/system/monitoring-agents/templates/coredns-scrape.yaml b/packages/system/monitoring-agents/templates/coredns-scrape.yaml index 9c7253eb..223d553f 100644 --- a/packages/system/monitoring-agents/templates/coredns-scrape.yaml +++ b/packages/system/monitoring-agents/templates/coredns-scrape.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: - name: coredns + name: coredns-metrics namespace: kube-system labels: app: coredns @@ -19,7 +19,7 @@ spec: apiVersion: operator.victoriametrics.com/v1beta1 kind: VMServiceScrape metadata: - name: coredns + name: coredns-metrics namespace: cozy-monitoring spec: selector: diff --git a/packages/system/monitoring-agents/values.yaml b/packages/system/monitoring-agents/values.yaml index 8c13c079..7b095c6c 100644 --- a/packages/system/monitoring-agents/values.yaml +++ b/packages/system/monitoring-agents/values.yaml @@ -1,32 +1,3 @@ -metrics-server: - defaultArgs: - - --cert-dir=/tmp - - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - - --kubelet-use-node-status-port - - --metric-resolution=15s - - --kubelet-insecure-tls - - metrics: - enabled: true - - serviceMonitor: - enabled: true - - victoria-logs-single: - server: - persistentVolume: - enabled: true - size: 10Gi - - grafana: - enabled: false - kube-state-metrics: - enabled: false - prometheus-node-exporter: - enabled: false - alertmanager: - name: vmalertmanager-alertmanager - kube-state-metrics: extraArgs: - --metric-labels-allowlist=pods=[*],deployments=[*] diff --git a/packages/system/piraeus-operator/charts/piraeus/Chart.yaml b/packages/system/piraeus-operator/charts/piraeus/Chart.yaml index 38bd15db..777722f3 100644 --- a/packages/system/piraeus-operator/charts/piraeus/Chart.yaml +++ b/packages/system/piraeus-operator/charts/piraeus/Chart.yaml @@ -3,8 +3,8 @@ name: piraeus description: | The Piraeus Operator manages software defined storage clusters using LINSTOR in Kubernetes. type: application -version: 2.10.1 -appVersion: "v2.10.1" +version: 2.10.2 +appVersion: "v2.10.2" maintainers: - name: Piraeus Datastore url: https://piraeus.io diff --git a/packages/system/piraeus-operator/charts/piraeus/templates/config.yaml b/packages/system/piraeus-operator/charts/piraeus/templates/config.yaml index a57dffd3..2e6963f0 100644 --- a/packages/system/piraeus-operator/charts/piraeus/templates/config.yaml +++ b/packages/system/piraeus-operator/charts/piraeus/templates/config.yaml @@ -23,10 +23,10 @@ data: tag: v1.32.3 image: piraeus-server linstor-csi: - tag: v1.10.2 + tag: v1.10.3 image: piraeus-csi nfs-server: - tag: v1.10.2 + tag: v1.10.3 image: piraeus-csi-nfs-server drbd-reactor: tag: v1.10.0 @@ -44,7 +44,7 @@ data: tag: v1.3.0 image: linstor-affinity-controller drbd-module-loader: - tag: v9.2.15 + tag: v9.2.16 # The special "match" attribute is used to select an image based on the node's reported OS. # The operator will first check the k8s node's ".status.nodeInfo.osImage" field, and compare it against the list # here. If one matches, that specific image name will be used instead of the fallback image. @@ -99,7 +99,7 @@ data: tag: v2.17.0 image: livenessprobe csi-provisioner: - tag: v6.0.0 + tag: v6.1.0 image: csi-provisioner csi-snapshotter: tag: v8.4.0 diff --git a/packages/system/piraeus-operator/charts/piraeus/templates/crds.yaml b/packages/system/piraeus-operator/charts/piraeus/templates/crds.yaml index 1821cb61..5bd9212c 100644 --- a/packages/system/piraeus-operator/charts/piraeus/templates/crds.yaml +++ b/packages/system/piraeus-operator/charts/piraeus/templates/crds.yaml @@ -993,6 +993,24 @@ spec: - Retain - Delete type: string + evacuationStrategy: + description: EvacuationStrategy configures the evacuation of volumes + from a Satellite when DeletionPolicy "Evacuate" is used. + nullable: true + properties: + attachedVolumeReattachTimeout: + default: 5m + description: |- + AttachedVolumeReattachTimeout configures how long evacuation waits for attached volumes to reattach on + different nodes. Setting this to 0 disable this evacuation step. + type: string + unattachedVolumeAttachTimeout: + default: 5m + description: |- + UnattachedVolumeAttachTimeout configures how long evacuation waits for unattached volumes to attach on + different nodes. Setting this to 0 disable this evacuation step. + type: string + type: object internalTLS: description: |- InternalTLS configures secure communication for the LINSTOR Satellite. @@ -1683,6 +1701,23 @@ spec: - Retain - Delete type: string + evacuationStrategy: + description: EvacuationStrategy configures the evacuation of volumes + from a Satellite when DeletionPolicy "Evacuate" is used. + properties: + attachedVolumeReattachTimeout: + default: 5m + description: |- + AttachedVolumeReattachTimeout configures how long evacuation waits for attached volumes to reattach on + different nodes. Setting this to 0 disable this evacuation step. + type: string + unattachedVolumeAttachTimeout: + default: 5m + description: |- + UnattachedVolumeAttachTimeout configures how long evacuation waits for unattached volumes to attach on + different nodes. Setting this to 0 disable this evacuation step. + type: string + type: object internalTLS: description: |- InternalTLS configures secure communication for the LINSTOR Satellite. diff --git a/packages/system/prometheus-operator-crds/Chart.yaml b/packages/system/prometheus-operator-crds/Chart.yaml new file mode 100644 index 00000000..576c241f --- /dev/null +++ b/packages/system/prometheus-operator-crds/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: cozy-prometheus-operator-crds +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/prometheus-operator-crds/Makefile b/packages/system/prometheus-operator-crds/Makefile new file mode 100644 index 00000000..173da9c1 --- /dev/null +++ b/packages/system/prometheus-operator-crds/Makefile @@ -0,0 +1,10 @@ +export NAME=prometheus-operator-crds +export NAMESPACE=cozy-victoria-metrics-operator + +include ../../../scripts/package.mk + +update: + helm repo add prometheus-community https://prometheus-community.github.io/helm-charts + helm repo update prometheus-community + helm pull prometheus-community/prometheus-operator-crds --untar --untardir charts + rm -f -- `find charts/prometheus-operator-crds/charts/crds/templates -maxdepth 1 -mindepth 1 | grep -v 'servicemonitor\|podmonitor\|prometheusrule\|probe'` diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/.helmignore b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/.helmignore similarity index 100% rename from packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/.helmignore rename to packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/.helmignore diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/Chart.lock b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/Chart.lock similarity index 76% rename from packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/Chart.lock rename to packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/Chart.lock index f1acf647..336e8e35 100644 --- a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/Chart.lock +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/Chart.lock @@ -3,4 +3,4 @@ dependencies: repository: "" version: 0.0.0 digest: sha256:aeada3fbffa2565a325406ad014001fd2685f7c0c9cfc1167da4f10c75a1bd65 -generated: "2025-03-15T22:08:36.140314181Z" +generated: "2025-11-21T15:12:44.500376661Z" diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/Chart.yaml b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/Chart.yaml similarity index 97% rename from packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/Chart.yaml rename to packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/Chart.yaml index 6c0097f0..20e194ee 100644 --- a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/Chart.yaml +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/Chart.yaml @@ -10,7 +10,7 @@ annotations: - name: QuentinBisson email: quentin.bisson@gmail.com apiVersion: v2 -appVersion: v0.81.0 +appVersion: v0.87.0 dependencies: - name: crds repository: "" @@ -39,4 +39,4 @@ name: prometheus-operator-crds sources: - https://github.com/prometheus-community/helm-charts type: application -version: 19.0.0 +version: 25.0.0 diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/README.md b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/README.md similarity index 63% rename from packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/README.md rename to packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/README.md index b4dfcedd..21e979b5 100644 --- a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/README.md +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/README.md @@ -9,27 +9,26 @@ For more information on Prometheus Operator and CRDs, please, see [documentation - Kubernetes >= 1.16.0 - Helm 3 -## Get Repository Info - -```console -helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -helm repo update -``` +## Usage -_See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._ - +The chart is distributed as an [OCI Artifact](https://helm.sh/docs/topics/registries/) as well as via a traditional [Helm Repository](https://helm.sh/docs/topics/chart_repository/). -## Install Chart +- OCI Artifact: `oci://ghcr.io/prometheus-community/charts/prometheus-operator-crds` +- Helm Repository: `https://prometheus-community.github.io/helm-charts` with chart `prometheus-operator-crds` + +The installation instructions use the OCI registry. Refer to the [`helm repo`]([`helm repo`](https://helm.sh/docs/helm/helm_repo/)) command documentation for information on installing charts via the traditional repository. + +### Install Chart ```console -helm install [RELEASE_NAME] prometheus-community/prometheus-operator-crds +helm install [RELEASE_NAME] oci://ghcr.io/prometheus-community/charts/prometheus-operator-crds ``` _See [configuration](#configuring) below._ _See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ -## Uninstall Chart +### Uninstall Chart ```console helm uninstall [RELEASE_NAME] @@ -40,7 +39,7 @@ _including_ resources of Kind `Prometheus`, `Alertmanager`, `ServiceMonitor`, et _See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ -## Upgrading Chart +### Upgrading Chart ```console helm upgrade [RELEASE_NAME] [CHART] --install @@ -48,7 +47,7 @@ helm upgrade [RELEASE_NAME] [CHART] --install _See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ -## Upgrading to v6.0.0 +#### Upgrading to v6.0.0 The upgraded chart now the following changes: @@ -59,5 +58,5 @@ The upgraded chart now the following changes: See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: ```console -helm show values prometheus-community/prometheus-operator-crds +helm show values oci://ghcr.io/prometheus-community/charts/prometheus-operator-crds ``` diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/Chart.yaml b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/Chart.yaml similarity index 100% rename from packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/Chart.yaml rename to packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/Chart.yaml diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-podmonitors.yaml b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-podmonitors.yaml similarity index 69% rename from packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-podmonitors.yaml rename to packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-podmonitors.yaml index dcb71f7c..608d53e5 100644 --- a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-podmonitors.yaml +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-podmonitors.yaml @@ -1,4 +1,5 @@ -# https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.81.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml +{{- if .Values.podmonitors.enabled -}} +# https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.87.0/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -7,8 +8,8 @@ metadata: {{- with .Values.annotations }} {{- toYaml . | nindent 4 }} {{- end }} - controller-gen.kubebuilder.io/version: v0.17.2 - operator.prometheus.io/version: 0.81.0 + controller-gen.kubebuilder.io/version: v0.19.0 + operator.prometheus.io/version: 0.87.0 name: podmonitors.monitoring.coreos.com spec: group: monitoring.coreos.com @@ -54,19 +55,19 @@ spec: metadata: type: object spec: - description: Specification of desired Pod selection for target discovery - by Prometheus. + description: spec defines the specification of desired Pod selection for + target discovery by Prometheus. properties: attachMetadata: description: |- - `attachMetadata` defines additional metadata which is added to the + attachMetadata defines additional metadata which is added to the discovered targets. It requires Prometheus >= v2.35.0. properties: node: description: |- - When set to true, Prometheus attaches node metadata to the discovered + node when set to true, Prometheus attaches node metadata to the discovered targets. The Prometheus service account must have the `list` and `watch` @@ -75,15 +76,20 @@ spec: type: object bodySizeLimit: description: |- - When defined, bodySizeLimit specifies a job level limit on the size + bodySizeLimit when defined specifies a job level limit on the size of uncompressed response body that will be accepted by Prometheus. It requires Prometheus >= v2.28.0. pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ type: string + convertClassicHistogramsToNHCB: + description: |- + convertClassicHistogramsToNHCB defines whether to convert all scraped classic histograms into a native histogram with custom buckets. + It requires Prometheus >= v3.0.0. + type: boolean fallbackScrapeProtocol: description: |- - The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. + fallbackScrapeProtocol defines the protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. It requires Prometheus >= v3.0.0. enum: @@ -95,7 +101,7 @@ spec: type: string jobLabel: description: |- - The label to use to retrieve the job name from. + jobLabel defines the label to use to retrieve the job name from. `jobLabel` selects the label from the associated Kubernetes `Pod` object which will be used as the `job` label for all metrics. @@ -108,7 +114,7 @@ spec: type: string keepDroppedTargets: description: |- - Per-scrape limit on the number of targets dropped by relabeling + keepDroppedTargets defines the per-scrape limit on the number of targets dropped by relabeling that will be kept in memory. 0 means no limit. It requires Prometheus >= v2.47.0. @@ -116,44 +122,45 @@ spec: type: integer labelLimit: description: |- - Per-scrape limit on number of labels that will be accepted for a sample. + labelLimit defines the per-scrape limit on number of labels that will be accepted for a sample. It requires Prometheus >= v2.27.0. format: int64 type: integer labelNameLengthLimit: description: |- - Per-scrape limit on length of labels name that will be accepted for a sample. + labelNameLengthLimit defines the per-scrape limit on length of labels name that will be accepted for a sample. It requires Prometheus >= v2.27.0. format: int64 type: integer labelValueLengthLimit: description: |- - Per-scrape limit on length of labels value that will be accepted for a sample. + labelValueLengthLimit defines the per-scrape limit on length of labels value that will be accepted for a sample. It requires Prometheus >= v2.27.0. format: int64 type: integer namespaceSelector: description: |- - `namespaceSelector` defines in which namespace(s) Prometheus should discover the pods. + namespaceSelector defines in which namespace(s) Prometheus should discover the pods. By default, the pods are discovered in the same namespace as the `PodMonitor` object but it is possible to select pods across different/all namespaces. properties: any: description: |- - Boolean describing whether all namespaces are selected in contrast to a + any defines the boolean describing whether all namespaces are selected in contrast to a list restricting them. type: boolean matchNames: - description: List of namespace names to select from. + description: matchNames defines the list of namespace names to + select from. items: type: string type: array type: object nativeHistogramBucketLimit: description: |- - If there are more than this many buckets in a native histogram, + nativeHistogramBucketLimit defines ff there are more than this many buckets in a native histogram, buckets will be merged to stay within the limit. It requires Prometheus >= v2.45.0. format: int64 @@ -163,13 +170,14 @@ spec: - type: integer - type: string description: |- - If the growth factor of one bucket to the next is smaller than this, + nativeHistogramMinBucketFactor defines if the growth factor of one bucket to the next is smaller than this, buckets will be merged to increase the factor sufficiently. It requires Prometheus >= v2.50.0. pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true podMetricsEndpoints: - description: Defines how to scrape metrics from the selected pods. + description: podMetricsEndpoints defines how to scrape metrics from + the selected pods. items: description: |- PodMetricsEndpoint defines an endpoint serving Prometheus metrics to be scraped by @@ -177,14 +185,14 @@ spec: properties: authorization: description: |- - `authorization` configures the Authorization header credentials to use when - scraping the target. + authorization configures the Authorization header credentials used by + the client. - Cannot be set at the same time as `basicAuth`, or `oauth2`. + Cannot be set at the same time as `basicAuth`, `bearerTokenSecret` or `oauth2`. properties: credentials: - description: Selects a key of a Secret in the namespace - that contains the credentials for authentication. + description: credentials defines a key of a Secret in the + namespace that contains the credentials for authentication. properties: key: description: The key of the secret to select from. Must @@ -209,7 +217,7 @@ spec: x-kubernetes-map-type: atomic type: description: |- - Defines the authentication type. The value is case-insensitive. + type defines the authentication type. The value is case-insensitive. "Basic" is not a supported value. @@ -218,14 +226,14 @@ spec: type: object basicAuth: description: |- - `basicAuth` configures the Basic Authentication credentials to use when - scraping the target. + basicAuth defines the Basic Authentication credentials used by the + client. - Cannot be set at the same time as `authorization`, or `oauth2`. + Cannot be set at the same time as `authorization`, `bearerTokenSecret` or `oauth2`. properties: password: description: |- - `password` specifies a key of a Secret containing the password for + password defines a key of a Secret containing the password for authentication. properties: key: @@ -251,7 +259,7 @@ spec: x-kubernetes-map-type: atomic username: description: |- - `username` specifies a key of a Secret containing the username for + username defines a key of a Secret containing the username for authentication. properties: key: @@ -278,9 +286,12 @@ spec: type: object bearerTokenSecret: description: |- - `bearerTokenSecret` specifies a key of a Secret containing the bearer - token for scraping targets. The secret needs to be in the same namespace - as the PodMonitor object and readable by the Prometheus Operator. + bearerTokenSecret defines a key of a Secret containing the bearer token + used by the client for authentication. The secret needs to be in the + same namespace as the custom resource and readable by the Prometheus + Operator. + + Cannot be set at the same time as `authorization`, `basicAuth` or `oauth2`. Deprecated: use `authorization` instead. properties: @@ -306,12 +317,11 @@ spec: type: object x-kubernetes-map-type: atomic enableHttp2: - description: '`enableHttp2` can be used to disable HTTP2 when - scraping the target.' + description: enableHttp2 can be used to disable HTTP2. type: boolean filterRunning: description: |- - When true, the pods which are not running (e.g. either in Failed or + filterRunning when true, the pods which are not running (e.g. either in Failed or Succeeded state) are dropped during the target discovery. If unset, the filtering is enabled. @@ -320,29 +330,29 @@ spec: type: boolean followRedirects: description: |- - `followRedirects` defines whether the scrape requests should follow HTTP - 3xx redirects. + followRedirects defines whether the client should follow HTTP 3xx + redirects. type: boolean honorLabels: description: |- - When true, `honorLabels` preserves the metric's labels when they collide + honorLabels when true preserves the metric's labels when they collide with the target's labels. type: boolean honorTimestamps: description: |- - `honorTimestamps` controls whether Prometheus preserves the timestamps + honorTimestamps defines whether Prometheus preserves the timestamps when exposed by the target. type: boolean interval: description: |- - Interval at which Prometheus scrapes the metrics from the target. + interval at which Prometheus scrapes the metrics from the target. If empty, Prometheus uses the global scrape interval. pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ type: string metricRelabelings: description: |- - `metricRelabelings` configures the relabeling rules to apply to the + metricRelabelings defines the relabeling rules to apply to the samples before ingestion. items: description: |- @@ -354,7 +364,7 @@ spec: action: default: replace description: |- - Action to perform based on the regex matching. + action to perform based on the regex matching. `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. @@ -386,41 +396,41 @@ spec: type: string modulus: description: |- - Modulus to take of the hash of the source label values. + modulus to take of the hash of the source label values. Only applicable when the action is `HashMod`. format: int64 type: integer regex: - description: Regular expression against which the extracted - value is matched. + description: regex defines the regular expression against + which the extracted value is matched. type: string replacement: description: |- - Replacement value against which a Replace action is performed if the + replacement value against which a Replace action is performed if the regular expression matches. Regex capture groups are available. type: string separator: - description: Separator is the string between concatenated + description: separator defines the string between concatenated SourceLabels. type: string sourceLabels: description: |- - The source labels select values from existing labels. Their content is + sourceLabels defines the source labels select values from existing labels. Their content is concatenated using the configured Separator and matched against the configured regular expression. items: description: |- - LabelName is a valid Prometheus label name which may only contain ASCII - letters, numbers, as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + LabelName is a valid Prometheus label name. + For Prometheus 3.x, a label name is valid if it contains UTF-8 characters. + For Prometheus 2.x, a label name is only valid if it contains ASCII characters, letters, numbers, as well as underscores. type: string type: array targetLabel: description: |- - Label to which the resulting string is written in a replacement. + targetLabel defines the label to which the resulting string is written in a replacement. It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, `KeepEqual` and `DropEqual` actions. @@ -429,22 +439,30 @@ spec: type: string type: object type: array + noProxy: + description: |- + noProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string oauth2: description: |- - `oauth2` configures the OAuth2 settings to use when scraping the target. + oauth2 defines the OAuth2 settings used by the client. It requires Prometheus >= 2.27.0. - Cannot be set at the same time as `authorization`, or `basicAuth`. + Cannot be set at the same time as `authorization`, `basicAuth` or `bearerTokenSecret`. properties: clientId: description: |- - `clientId` specifies a key of a Secret or ConfigMap containing the + clientId defines a key of a Secret or ConfigMap containing the OAuth2 client's ID. properties: configMap: - description: ConfigMap containing data to use for the - targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -467,7 +485,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data + to use for the targets. properties: key: description: The key of the secret to select from. Must @@ -493,7 +512,7 @@ spec: type: object clientSecret: description: |- - `clientSecret` specifies a key of a Secret containing the OAuth2 + clientSecret defines a key of a Secret containing the OAuth2 client's secret. properties: key: @@ -521,16 +540,16 @@ spec: additionalProperties: type: string description: |- - `endpointParams` configures the HTTP parameters to append to the token + endpointParams configures the HTTP parameters to append to the token URL. type: object noProxy: description: |- - `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + noProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. IP and domain names can contain port numbers. - It requires Prometheus >= v2.43.0 or Alertmanager >= 0.25.0. + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. type: string proxyConnectHeader: additionalProperties: @@ -560,41 +579,40 @@ spec: x-kubernetes-map-type: atomic type: array description: |- - ProxyConnectHeader optionally specifies headers to send to + proxyConnectHeader optionally specifies headers to send to proxies during CONNECT requests. - It requires Prometheus >= v2.43.0 or Alertmanager >= 0.25.0. + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. type: object x-kubernetes-map-type: atomic proxyFromEnvironment: description: |- - Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + proxyFromEnvironment defines whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). - It requires Prometheus >= v2.43.0 or Alertmanager >= 0.25.0. + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. type: boolean proxyUrl: - description: '`proxyURL` defines the HTTP proxy server to - use.' - pattern: ^http(s)?://.+$ + description: proxyUrl defines the HTTP proxy server to use. + pattern: ^(http|https|socks5)://.+$ type: string scopes: - description: '`scopes` defines the OAuth2 scopes used for - the token request.' + description: scopes defines the OAuth2 scopes used for the + token request. items: type: string type: array tlsConfig: description: |- - TLS configuration to use when connecting to the OAuth2 server. + tlsConfig defines the TLS configuration to use when connecting to the OAuth2 server. It requires Prometheus >= v2.43.0. properties: ca: - description: Certificate authority used when verifying - server certificates. + description: ca defines the Certificate authority used + when verifying server certificates. properties: configMap: - description: ConfigMap containing data to use for - the targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -617,8 +635,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the - targets. + description: secret defines the Secret containing + data to use for the targets. properties: key: description: The key of the secret to select @@ -643,12 +661,12 @@ spec: x-kubernetes-map-type: atomic type: object cert: - description: Client certificate to present when doing - client-authentication. + description: cert defines the Client certificate to + present when doing client-authentication. properties: configMap: - description: ConfigMap containing data to use for - the targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -671,8 +689,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the - targets. + description: secret defines the Secret containing + data to use for the targets. properties: key: description: The key of the secret to select @@ -697,11 +715,12 @@ spec: x-kubernetes-map-type: atomic type: object insecureSkipVerify: - description: Disable target certificate validation. + description: insecureSkipVerify defines how to disable + target certificate validation. type: boolean keySecret: - description: Secret containing the client key file for - the targets. + description: keySecret defines the Secret containing + the client key file for the targets. properties: key: description: The key of the secret to select from. Must @@ -726,9 +745,9 @@ spec: x-kubernetes-map-type: atomic maxVersion: description: |- - Maximum acceptable TLS version. + maxVersion defines the maximum acceptable TLS version. - It requires Prometheus >= v2.41.0. + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. enum: - TLS10 - TLS11 @@ -737,9 +756,9 @@ spec: type: string minVersion: description: |- - Minimum acceptable TLS version. + minVersion defines the minimum acceptable TLS version. - It requires Prometheus >= v2.35.0. + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. enum: - TLS10 - TLS11 @@ -747,12 +766,13 @@ spec: - TLS13 type: string serverName: - description: Used to verify the hostname for the targets. + description: serverName is used to verify the hostname + for the targets. type: string type: object tokenUrl: - description: '`tokenURL` configures the URL to fetch the - token from.' + description: tokenUrl defines the URL to fetch the token + from. minLength: 1 type: string required: @@ -765,34 +785,92 @@ spec: items: type: string type: array - description: '`params` define optional HTTP URL parameters.' + description: params define optional HTTP URL parameters. type: object path: description: |- - HTTP path from which to scrape for metrics. + path defines the HTTP path from which to scrape for metrics. If empty, Prometheus uses the default value (e.g. `/metrics`). type: string port: description: |- - The `Pod` port name which exposes the endpoint. + port defines the `Pod` port name which exposes the endpoint. + + If the pod doesn't expose a port with the same name, it will result + in no targets being discovered. + + If a `Pod` has multiple `Port`s with the same name (which is not + recommended), one target instance per unique port number will be + generated. It takes precedence over the `portNumber` and `targetPort` fields. type: string portNumber: - description: The `Pod` port number which exposes the endpoint. + description: |- + portNumber defines the `Pod` port number which exposes the endpoint. + + The `Pod` must declare the specified `Port` in its spec or the + target will be dropped by Prometheus. + + This cannot be used to enable scraping of an undeclared port. + To scrape targets on a port which isn't exposed, you need to use + relabeling to override the `__address__` label (but beware of + duplicate targets if the `Pod` has other declared ports). + + In practice Prometheus will select targets for which the + matches the target's __meta_kubernetes_pod_container_port_number. format: int32 maximum: 65535 minimum: 1 type: integer - proxyUrl: + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array description: |- - `proxyURL` configures the HTTP Proxy URL (e.g. - "http://proxyserver:2195") to go through when scraping the target. + proxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + proxyFromEnvironment defines whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: proxyUrl defines the HTTP proxy server to use. + pattern: ^(http|https|socks5)://.+$ type: string relabelings: description: |- - `relabelings` configures the relabeling rules to apply the target's + relabelings defines the relabeling rules to apply the target's metadata labels. The Operator automatically adds relabelings for a few standard Kubernetes fields. @@ -810,7 +888,7 @@ spec: action: default: replace description: |- - Action to perform based on the regex matching. + action to perform based on the regex matching. `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. @@ -842,41 +920,41 @@ spec: type: string modulus: description: |- - Modulus to take of the hash of the source label values. + modulus to take of the hash of the source label values. Only applicable when the action is `HashMod`. format: int64 type: integer regex: - description: Regular expression against which the extracted - value is matched. + description: regex defines the regular expression against + which the extracted value is matched. type: string replacement: description: |- - Replacement value against which a Replace action is performed if the + replacement value against which a Replace action is performed if the regular expression matches. Regex capture groups are available. type: string separator: - description: Separator is the string between concatenated + description: separator defines the string between concatenated SourceLabels. type: string sourceLabels: description: |- - The source labels select values from existing labels. Their content is + sourceLabels defines the source labels select values from existing labels. Their content is concatenated using the configured Separator and matched against the configured regular expression. items: description: |- - LabelName is a valid Prometheus label name which may only contain ASCII - letters, numbers, as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + LabelName is a valid Prometheus label name. + For Prometheus 3.x, a label name is valid if it contains UTF-8 characters. + For Prometheus 2.x, a label name is only valid if it contains ASCII characters, letters, numbers, as well as underscores. type: string type: array targetLabel: description: |- - Label to which the resulting string is written in a replacement. + targetLabel defines the label to which the resulting string is written in a replacement. It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, `KeepEqual` and `DropEqual` actions. @@ -886,20 +964,16 @@ spec: type: object type: array scheme: - description: |- - HTTP scheme to use for scraping. - - `http` and `https` are the expected values unless you rewrite the - `__scheme__` label via relabeling. - - If empty, Prometheus uses the default value `http`. + description: scheme defines the HTTP scheme to use for scraping. enum: - http - https + - HTTP + - HTTPS type: string scrapeTimeout: description: |- - Timeout after which Prometheus considers the scrape to be failed. + scrapeTimeout defines the timeout after which Prometheus considers the scrape to be failed. If empty, Prometheus uses the global scrape timeout unless it is less than the target's scrape interval value in which the latter is used. @@ -911,21 +985,22 @@ spec: - type: integer - type: string description: |- - Name or number of the target port of the `Pod` object behind the Service, the + targetPort defines the name or number of the target port of the `Pod` object behind the Service, the port must be specified with container port property. Deprecated: use 'port' or 'portNumber' instead. x-kubernetes-int-or-string: true tlsConfig: - description: TLS configuration to use when scraping the target. + description: tlsConfig defines the TLS configuration used by + the client. properties: ca: - description: Certificate authority used when verifying server - certificates. + description: ca defines the Certificate authority used when + verifying server certificates. properties: configMap: - description: ConfigMap containing data to use for the - targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -948,7 +1023,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data + to use for the targets. properties: key: description: The key of the secret to select from. Must @@ -973,11 +1049,12 @@ spec: x-kubernetes-map-type: atomic type: object cert: - description: Client certificate to present when doing client-authentication. + description: cert defines the Client certificate to present + when doing client-authentication. properties: configMap: - description: ConfigMap containing data to use for the - targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -1000,7 +1077,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data + to use for the targets. properties: key: description: The key of the secret to select from. Must @@ -1025,11 +1103,12 @@ spec: x-kubernetes-map-type: atomic type: object insecureSkipVerify: - description: Disable target certificate validation. + description: insecureSkipVerify defines how to disable target + certificate validation. type: boolean keySecret: - description: Secret containing the client key file for the - targets. + description: keySecret defines the Secret containing the + client key file for the targets. properties: key: description: The key of the secret to select from. Must @@ -1054,9 +1133,9 @@ spec: x-kubernetes-map-type: atomic maxVersion: description: |- - Maximum acceptable TLS version. + maxVersion defines the maximum acceptable TLS version. - It requires Prometheus >= v2.41.0. + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. enum: - TLS10 - TLS11 @@ -1065,9 +1144,9 @@ spec: type: string minVersion: description: |- - Minimum acceptable TLS version. + minVersion defines the minimum acceptable TLS version. - It requires Prometheus >= v2.35.0. + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. enum: - TLS10 - TLS11 @@ -1075,12 +1154,13 @@ spec: - TLS13 type: string serverName: - description: Used to verify the hostname for the targets. + description: serverName is used to verify the hostname for + the targets. type: string type: object trackTimestampsStaleness: description: |- - `trackTimestampsStaleness` defines whether Prometheus tracks staleness of + trackTimestampsStaleness defines whether Prometheus tracks staleness of the metrics that have an explicit timestamp present in scraped data. Has no effect if `honorTimestamps` is false. @@ -1090,29 +1170,31 @@ spec: type: array podTargetLabels: description: |- - `podTargetLabels` defines the labels which are transferred from the + podTargetLabels defines the labels which are transferred from the associated Kubernetes `Pod` object onto the ingested metrics. items: type: string type: array sampleLimit: description: |- - `sampleLimit` defines a per-scrape limit on the number of scraped samples + sampleLimit defines a per-scrape limit on the number of scraped samples that will be accepted. format: int64 type: integer scrapeClass: - description: The scrape class to apply. + description: scrapeClass defines the scrape class to apply. minLength: 1 type: string scrapeClassicHistograms: description: |- - Whether to scrape a classic histogram that is also exposed as a native histogram. + scrapeClassicHistograms defines whether to scrape a classic histogram that is also exposed as a native histogram. It requires Prometheus >= v2.45.0. + + Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration. type: boolean scrapeProtocols: description: |- - `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the + scrapeProtocols defines the protocols to negotiate during a scrape. It tells clients the protocols supported by Prometheus in order of preference (from most to least preferred). If unset, Prometheus uses its default value. @@ -1137,8 +1219,8 @@ spec: type: array x-kubernetes-list-type: set selector: - description: Label selector to select the Kubernetes `Pod` objects - to scrape metrics from. + description: selector defines the label selector to select the Kubernetes + `Pod` objects to scrape metrics from. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -1185,7 +1267,7 @@ spec: x-kubernetes-map-type: atomic selectorMechanism: description: |- - Mechanism used to select the endpoints to scrape. + selectorMechanism defines the mechanism used to select the endpoints to scrape. By default, the selection process relies on relabel configurations to filter the discovered targets. Alternatively, you can opt in for role selectors, which may offer better efficiency in large clusters. Which strategy is best for your use case needs to be carefully evaluated. @@ -1197,15 +1279,121 @@ spec: type: string targetLimit: description: |- - `targetLimit` defines a limit on the number of scraped targets that will + targetLimit defines a limit on the number of scraped targets that will be accepted. format: int64 type: integer required: - selector type: object + status: + description: |- + status defines the status subresource. It is under active development and is updated only when the + "StatusForConfigurationResources" feature gate is enabled. + + Most recent observed status of the PodMonitor. Read-only. + More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bindings: + description: bindings defines the list of workload resources (Prometheus, + PrometheusAgent, ThanosRuler or Alertmanager) which select the configuration + resource. + items: + description: WorkloadBinding is a link between a configuration resource + and a workload resource. + properties: + conditions: + description: conditions defines the current state of the configuration + resource when bound to the referenced Workload object. + items: + description: ConfigResourceCondition describes the status + of configuration resources linked to Prometheus, PrometheusAgent, + Alertmanager or ThanosRuler. + properties: + lastTransitionTime: + description: lastTransitionTime defines the time of the + last update to the current status property. + format: date-time + type: string + message: + description: message defines the human-readable message + indicating details for the condition's last transition. + type: string + observedGeneration: + description: |- + observedGeneration defines the .metadata.generation that the + condition was set based upon. For instance, if `.metadata.generation` is + currently 12, but the `.status.conditions[].observedGeneration` is 9, the + condition is out of date with respect to the current state of the object. + format: int64 + type: integer + reason: + description: reason for the condition's last transition. + type: string + status: + description: status of the condition. + minLength: 1 + type: string + type: + description: |- + type of the condition being reported. + Currently, only "Accepted" is supported. + enum: + - Accepted + minLength: 1 + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + group: + description: group defines the group of the referenced resource. + enum: + - monitoring.coreos.com + type: string + name: + description: name defines the name of the referenced object. + minLength: 1 + type: string + namespace: + description: namespace defines the namespace of the referenced + object. + minLength: 1 + type: string + resource: + description: resource defines the type of resource being referenced + (e.g. Prometheus, PrometheusAgent, ThanosRuler or Alertmanager). + enum: + - prometheuses + - prometheusagents + - thanosrulers + - alertmanagers + type: string + required: + - group + - name + - namespace + - resource + type: object + type: array + x-kubernetes-list-map-keys: + - group + - resource + - name + - namespace + x-kubernetes-list-type: map + type: object required: - spec type: object served: true storage: true + subresources: + status: {} +{{- end -}} diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-probes.yaml b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-probes.yaml similarity index 69% rename from packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-probes.yaml rename to packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-probes.yaml index 05a75775..f2d06e03 100644 --- a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-probes.yaml +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-probes.yaml @@ -1,4 +1,5 @@ -# https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.81.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml +{{- if .Values.probes.enabled -}} +# https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.87.0/example/prometheus-operator-crd/monitoring.coreos.com_probes.yaml --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -7,8 +8,8 @@ metadata: {{- with .Values.annotations }} {{- toYaml . | nindent 4 }} {{- end }} - controller-gen.kubebuilder.io/version: v0.17.2 - operator.prometheus.io/version: 0.81.0 + controller-gen.kubebuilder.io/version: v0.19.0 + operator.prometheus.io/version: 0.87.0 name: probes.monitoring.coreos.com spec: group: monitoring.coreos.com @@ -53,15 +54,15 @@ spec: metadata: type: object spec: - description: Specification of desired Ingress selection for target discovery - by Prometheus. + description: spec defines the specification of desired Ingress selection + for target discovery by Prometheus. properties: authorization: - description: Authorization section for this endpoint + description: authorization section for this endpoint properties: credentials: - description: Selects a key of a Secret in the namespace that contains - the credentials for authentication. + description: credentials defines a key of a Secret in the namespace + that contains the credentials for authentication. properties: key: description: The key of the secret to select from. Must be @@ -86,7 +87,7 @@ spec: x-kubernetes-map-type: atomic type: description: |- - Defines the authentication type. The value is case-insensitive. + type defines the authentication type. The value is case-insensitive. "Basic" is not a supported value. @@ -95,12 +96,12 @@ spec: type: object basicAuth: description: |- - BasicAuth allow an endpoint to authenticate over basic authentication. + basicAuth allow an endpoint to authenticate over basic authentication. More info: https://prometheus.io/docs/operating/configuration/#endpoint properties: password: description: |- - `password` specifies a key of a Secret containing the password for + password defines a key of a Secret containing the password for authentication. properties: key: @@ -126,7 +127,7 @@ spec: x-kubernetes-map-type: atomic username: description: |- - `username` specifies a key of a Secret containing the username for + username defines a key of a Secret containing the username for authentication. properties: key: @@ -153,7 +154,7 @@ spec: type: object bearerTokenSecret: description: |- - Secret to mount to read bearer token for scraping targets. The secret + bearerTokenSecret defines the secret to mount to read bearer token for scraping targets. The secret needs to be in the same namespace as the probe and accessible by the Prometheus Operator. properties: @@ -177,9 +178,14 @@ spec: - key type: object x-kubernetes-map-type: atomic + convertClassicHistogramsToNHCB: + description: |- + convertClassicHistogramsToNHCB defines whether to convert all scraped classic histograms into a native histogram with custom buckets. + It requires Prometheus >= v3.0.0. + type: boolean fallbackScrapeProtocol: description: |- - The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. + fallbackScrapeProtocol defines the protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. It requires Prometheus >= v3.0.0. enum: @@ -191,16 +197,16 @@ spec: type: string interval: description: |- - Interval at which targets are probed using the configured prober. + interval at which targets are probed using the configured prober. If not specified Prometheus' global scrape interval is used. pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ type: string jobName: - description: The job name assigned to scraped metrics by default. + description: jobName assigned to scraped metrics by default. type: string keepDroppedTargets: description: |- - Per-scrape limit on the number of targets dropped by relabeling + keepDroppedTargets defines the per-scrape limit on the number of targets dropped by relabeling that will be kept in memory. 0 means no limit. It requires Prometheus >= v2.47.0. @@ -208,24 +214,25 @@ spec: type: integer labelLimit: description: |- - Per-scrape limit on number of labels that will be accepted for a sample. + labelLimit defines the per-scrape limit on number of labels that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. format: int64 type: integer labelNameLengthLimit: description: |- - Per-scrape limit on length of labels name that will be accepted for a sample. + labelNameLengthLimit defines the per-scrape limit on length of labels name that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. format: int64 type: integer labelValueLengthLimit: description: |- - Per-scrape limit on length of labels value that will be accepted for a sample. + labelValueLengthLimit defines the per-scrape limit on length of labels value that will be accepted for a sample. Only valid in Prometheus versions 2.27.0 and newer. format: int64 type: integer metricRelabelings: - description: MetricRelabelConfigs to apply to samples before ingestion. + description: metricRelabelings defines the RelabelConfig to apply + to samples before ingestion. items: description: |- RelabelConfig allows dynamic rewriting of the label set for targets, alerts, @@ -236,7 +243,7 @@ spec: action: default: replace description: |- - Action to perform based on the regex matching. + action to perform based on the regex matching. `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. @@ -268,40 +275,41 @@ spec: type: string modulus: description: |- - Modulus to take of the hash of the source label values. + modulus to take of the hash of the source label values. Only applicable when the action is `HashMod`. format: int64 type: integer regex: - description: Regular expression against which the extracted - value is matched. + description: regex defines the regular expression against which + the extracted value is matched. type: string replacement: description: |- - Replacement value against which a Replace action is performed if the + replacement value against which a Replace action is performed if the regular expression matches. Regex capture groups are available. type: string separator: - description: Separator is the string between concatenated SourceLabels. + description: separator defines the string between concatenated + SourceLabels. type: string sourceLabels: description: |- - The source labels select values from existing labels. Their content is + sourceLabels defines the source labels select values from existing labels. Their content is concatenated using the configured Separator and matched against the configured regular expression. items: description: |- - LabelName is a valid Prometheus label name which may only contain ASCII - letters, numbers, as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + LabelName is a valid Prometheus label name. + For Prometheus 3.x, a label name is valid if it contains UTF-8 characters. + For Prometheus 2.x, a label name is only valid if it contains ASCII characters, letters, numbers, as well as underscores. type: string type: array targetLabel: description: |- - Label to which the resulting string is written in a replacement. + targetLabel defines the label to which the resulting string is written in a replacement. It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, `KeepEqual` and `DropEqual` actions. @@ -312,13 +320,13 @@ spec: type: array module: description: |- - The module to use for probing specifying how to probe the target. + module to use for probing specifying how to probe the target. Example module configuring in the blackbox exporter: https://github.com/prometheus/blackbox_exporter/blob/master/example.yml type: string nativeHistogramBucketLimit: description: |- - If there are more than this many buckets in a native histogram, + nativeHistogramBucketLimit defines ff there are more than this many buckets in a native histogram, buckets will be merged to stay within the limit. It requires Prometheus >= v2.45.0. format: int64 @@ -328,22 +336,23 @@ spec: - type: integer - type: string description: |- - If the growth factor of one bucket to the next is smaller than this, + nativeHistogramMinBucketFactor defines if the growth factor of one bucket to the next is smaller than this, buckets will be merged to increase the factor sufficiently. It requires Prometheus >= v2.50.0. pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true oauth2: - description: OAuth2 for the URL. Only valid in Prometheus versions + description: oauth2 for the URL. Only valid in Prometheus versions 2.27.0 and newer. properties: clientId: description: |- - `clientId` specifies a key of a Secret or ConfigMap containing the + clientId defines a key of a Secret or ConfigMap containing the OAuth2 client's ID. properties: configMap: - description: ConfigMap containing data to use for the targets. + description: configMap defines the ConfigMap containing data + to use for the targets. properties: key: description: The key to select. @@ -366,7 +375,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data to + use for the targets. properties: key: description: The key of the secret to select from. Must @@ -392,7 +402,7 @@ spec: type: object clientSecret: description: |- - `clientSecret` specifies a key of a Secret containing the OAuth2 + clientSecret defines a key of a Secret containing the OAuth2 client's secret. properties: key: @@ -420,16 +430,16 @@ spec: additionalProperties: type: string description: |- - `endpointParams` configures the HTTP parameters to append to the token + endpointParams configures the HTTP parameters to append to the token URL. type: object noProxy: description: |- - `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + noProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. IP and domain names can contain port numbers. - It requires Prometheus >= v2.43.0 or Alertmanager >= 0.25.0. + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. type: string proxyConnectHeader: additionalProperties: @@ -459,40 +469,40 @@ spec: x-kubernetes-map-type: atomic type: array description: |- - ProxyConnectHeader optionally specifies headers to send to + proxyConnectHeader optionally specifies headers to send to proxies during CONNECT requests. - It requires Prometheus >= v2.43.0 or Alertmanager >= 0.25.0. + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. type: object x-kubernetes-map-type: atomic proxyFromEnvironment: description: |- - Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + proxyFromEnvironment defines whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). - It requires Prometheus >= v2.43.0 or Alertmanager >= 0.25.0. + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. type: boolean proxyUrl: - description: '`proxyURL` defines the HTTP proxy server to use.' - pattern: ^http(s)?://.+$ + description: proxyUrl defines the HTTP proxy server to use. + pattern: ^(http|https|socks5)://.+$ type: string scopes: - description: '`scopes` defines the OAuth2 scopes used for the - token request.' + description: scopes defines the OAuth2 scopes used for the token + request. items: type: string type: array tlsConfig: description: |- - TLS configuration to use when connecting to the OAuth2 server. + tlsConfig defines the TLS configuration to use when connecting to the OAuth2 server. It requires Prometheus >= v2.43.0. properties: ca: - description: Certificate authority used when verifying server - certificates. + description: ca defines the Certificate authority used when + verifying server certificates. properties: configMap: - description: ConfigMap containing data to use for the - targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -515,7 +525,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data + to use for the targets. properties: key: description: The key of the secret to select from. Must @@ -540,11 +551,12 @@ spec: x-kubernetes-map-type: atomic type: object cert: - description: Client certificate to present when doing client-authentication. + description: cert defines the Client certificate to present + when doing client-authentication. properties: configMap: - description: ConfigMap containing data to use for the - targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -567,7 +579,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data + to use for the targets. properties: key: description: The key of the secret to select from. Must @@ -592,11 +605,12 @@ spec: x-kubernetes-map-type: atomic type: object insecureSkipVerify: - description: Disable target certificate validation. + description: insecureSkipVerify defines how to disable target + certificate validation. type: boolean keySecret: - description: Secret containing the client key file for the - targets. + description: keySecret defines the Secret containing the client + key file for the targets. properties: key: description: The key of the secret to select from. Must @@ -621,9 +635,9 @@ spec: x-kubernetes-map-type: atomic maxVersion: description: |- - Maximum acceptable TLS version. + maxVersion defines the maximum acceptable TLS version. - It requires Prometheus >= v2.41.0. + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. enum: - TLS10 - TLS11 @@ -632,9 +646,9 @@ spec: type: string minVersion: description: |- - Minimum acceptable TLS version. + minVersion defines the minimum acceptable TLS version. - It requires Prometheus >= v2.35.0. + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. enum: - TLS10 - TLS11 @@ -642,12 +656,12 @@ spec: - TLS13 type: string serverName: - description: Used to verify the hostname for the targets. + description: serverName is used to verify the hostname for + the targets. type: string type: object tokenUrl: - description: '`tokenURL` configures the URL to fetch the token - from.' + description: tokenUrl defines the URL to fetch the token from. minLength: 1 type: string required: @@ -655,52 +669,137 @@ spec: - clientSecret - tokenUrl type: object + params: + description: |- + params defines the list of HTTP query parameters for the scrape. + Please note that the `.spec.module` field takes precedence over the `module` parameter from this list when both are defined. + The module name must be added using Module under ProbeSpec. + items: + description: ProbeParam defines specification of extra parameters + for a Probe. + properties: + name: + description: name defines the parameter name + minLength: 1 + type: string + values: + description: values defines the parameter values + items: + minLength: 1 + type: string + minItems: 1 + type: array + required: + - name + type: object + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map prober: description: |- - Specification for the prober to use for probing targets. + prober defines the specification for the prober to use for probing targets. The prober.URL parameter is required. Targets cannot be probed if left empty. properties: + noProxy: + description: |- + noProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string path: default: /probe description: |- - Path to collect metrics from. + path to collect metrics from. Defaults to `/probe`. type: string + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + description: |- + proxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + proxyFromEnvironment defines whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean proxyUrl: - description: Optional ProxyURL. + description: proxyUrl defines the HTTP proxy server to use. + pattern: ^(http|https|socks5)://.+$ type: string scheme: - description: |- - HTTP scheme to use for scraping. - `http` and `https` are the expected values unless you rewrite the `__scheme__` label via relabeling. - If empty, Prometheus uses the default value `http`. + description: scheme defines the HTTP scheme to use when scraping + the prober. enum: - http - https + - HTTP + - HTTPS type: string url: - description: Mandatory URL of the prober. + description: |- + url defines the address of the prober. + + Unlike what the name indicates, the value should be in the form of + `address:port` without any scheme which should be specified in the + `scheme` field. + minLength: 1 type: string required: - url type: object sampleLimit: - description: SampleLimit defines per-scrape limit on number of scraped + description: sampleLimit defines per-scrape limit on number of scraped samples that will be accepted. format: int64 type: integer scrapeClass: - description: The scrape class to apply. + description: scrapeClass defines the scrape class to apply. minLength: 1 type: string scrapeClassicHistograms: description: |- - Whether to scrape a classic histogram that is also exposed as a native histogram. + scrapeClassicHistograms defines whether to scrape a classic histogram that is also exposed as a native histogram. It requires Prometheus >= v2.45.0. + + Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration. type: boolean scrapeProtocols: description: |- - `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the + scrapeProtocols defines the protocols to negotiate during a scrape. It tells clients the protocols supported by Prometheus in order of preference (from most to least preferred). If unset, Prometheus uses its default value. @@ -726,18 +825,18 @@ spec: x-kubernetes-list-type: set scrapeTimeout: description: |- - Timeout for scraping metrics from the Prometheus exporter. + scrapeTimeout defines the timeout for scraping metrics from the Prometheus exporter. If not specified, the Prometheus global scrape timeout is used. The value cannot be greater than the scrape interval otherwise the operator will reject the resource. pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ type: string targetLimit: - description: TargetLimit defines a limit on the number of scraped + description: targetLimit defines a limit on the number of scraped targets that will be accepted. format: int64 type: integer targets: - description: Targets defines a set of static or dynamically discovered + description: targets defines a set of static or dynamically discovered targets to probe. properties: ingress: @@ -747,22 +846,24 @@ spec: If `staticConfig` is also defined, `staticConfig` takes precedence. properties: namespaceSelector: - description: From which namespaces to select Ingress objects. + description: namespaceSelector defines from which namespaces + to select Ingress objects. properties: any: description: |- - Boolean describing whether all namespaces are selected in contrast to a + any defines the boolean describing whether all namespaces are selected in contrast to a list restricting them. type: boolean matchNames: - description: List of namespace names to select from. + description: matchNames defines the list of namespace + names to select from. items: type: string type: array type: object relabelingConfigs: description: |- - RelabelConfigs to apply to the label set of the target before it gets + relabelingConfigs to apply to the label set of the target before it gets scraped. The original ingress address is available via the `__tmp_prometheus_ingress_address` label. It can be used to customize the @@ -779,7 +880,7 @@ spec: action: default: replace description: |- - Action to perform based on the regex matching. + action to perform based on the regex matching. `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. @@ -811,41 +912,41 @@ spec: type: string modulus: description: |- - Modulus to take of the hash of the source label values. + modulus to take of the hash of the source label values. Only applicable when the action is `HashMod`. format: int64 type: integer regex: - description: Regular expression against which the extracted - value is matched. + description: regex defines the regular expression against + which the extracted value is matched. type: string replacement: description: |- - Replacement value against which a Replace action is performed if the + replacement value against which a Replace action is performed if the regular expression matches. Regex capture groups are available. type: string separator: - description: Separator is the string between concatenated + description: separator defines the string between concatenated SourceLabels. type: string sourceLabels: description: |- - The source labels select values from existing labels. Their content is + sourceLabels defines the source labels select values from existing labels. Their content is concatenated using the configured Separator and matched against the configured regular expression. items: description: |- - LabelName is a valid Prometheus label name which may only contain ASCII - letters, numbers, as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + LabelName is a valid Prometheus label name. + For Prometheus 3.x, a label name is valid if it contains UTF-8 characters. + For Prometheus 2.x, a label name is only valid if it contains ASCII characters, letters, numbers, as well as underscores. type: string type: array targetLabel: description: |- - Label to which the resulting string is written in a replacement. + targetLabel defines the label to which the resulting string is written in a replacement. It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, `KeepEqual` and `DropEqual` actions. @@ -855,7 +956,7 @@ spec: type: object type: array selector: - description: Selector to select the Ingress objects. + description: selector to select the Ingress objects. properties: matchExpressions: description: matchExpressions is a list of label selector @@ -911,12 +1012,12 @@ spec: labels: additionalProperties: type: string - description: Labels assigned to all metrics scraped from the - targets. + description: labels defines all labels assigned to all metrics + scraped from the targets. type: object relabelingConfigs: description: |- - RelabelConfigs to apply to the label set of the targets before it gets + relabelingConfigs defines relabelings to be apply to the label set of the targets before it gets scraped. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config items: @@ -929,7 +1030,7 @@ spec: action: default: replace description: |- - Action to perform based on the regex matching. + action to perform based on the regex matching. `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. @@ -961,41 +1062,41 @@ spec: type: string modulus: description: |- - Modulus to take of the hash of the source label values. + modulus to take of the hash of the source label values. Only applicable when the action is `HashMod`. format: int64 type: integer regex: - description: Regular expression against which the extracted - value is matched. + description: regex defines the regular expression against + which the extracted value is matched. type: string replacement: description: |- - Replacement value against which a Replace action is performed if the + replacement value against which a Replace action is performed if the regular expression matches. Regex capture groups are available. type: string separator: - description: Separator is the string between concatenated + description: separator defines the string between concatenated SourceLabels. type: string sourceLabels: description: |- - The source labels select values from existing labels. Their content is + sourceLabels defines the source labels select values from existing labels. Their content is concatenated using the configured Separator and matched against the configured regular expression. items: description: |- - LabelName is a valid Prometheus label name which may only contain ASCII - letters, numbers, as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + LabelName is a valid Prometheus label name. + For Prometheus 3.x, a label name is valid if it contains UTF-8 characters. + For Prometheus 2.x, a label name is only valid if it contains ASCII characters, letters, numbers, as well as underscores. type: string type: array targetLabel: description: |- - Label to which the resulting string is written in a replacement. + targetLabel defines the label to which the resulting string is written in a replacement. It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, `KeepEqual` and `DropEqual` actions. @@ -1005,21 +1106,23 @@ spec: type: object type: array static: - description: The list of hosts to probe. + description: static defines the list of hosts to probe. items: type: string type: array type: object type: object tlsConfig: - description: TLS configuration to use when scraping the endpoint. + description: tlsConfig defines the TLS configuration to use when scraping + the endpoint. properties: ca: - description: Certificate authority used when verifying server - certificates. + description: ca defines the Certificate authority used when verifying + server certificates. properties: configMap: - description: ConfigMap containing data to use for the targets. + description: configMap defines the ConfigMap containing data + to use for the targets. properties: key: description: The key to select. @@ -1042,7 +1145,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data to + use for the targets. properties: key: description: The key of the secret to select from. Must @@ -1067,10 +1171,12 @@ spec: x-kubernetes-map-type: atomic type: object cert: - description: Client certificate to present when doing client-authentication. + description: cert defines the Client certificate to present when + doing client-authentication. properties: configMap: - description: ConfigMap containing data to use for the targets. + description: configMap defines the ConfigMap containing data + to use for the targets. properties: key: description: The key to select. @@ -1093,7 +1199,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data to + use for the targets. properties: key: description: The key of the secret to select from. Must @@ -1118,10 +1225,12 @@ spec: x-kubernetes-map-type: atomic type: object insecureSkipVerify: - description: Disable target certificate validation. + description: insecureSkipVerify defines how to disable target + certificate validation. type: boolean keySecret: - description: Secret containing the client key file for the targets. + description: keySecret defines the Secret containing the client + key file for the targets. properties: key: description: The key of the secret to select from. Must be @@ -1146,9 +1255,9 @@ spec: x-kubernetes-map-type: atomic maxVersion: description: |- - Maximum acceptable TLS version. + maxVersion defines the maximum acceptable TLS version. - It requires Prometheus >= v2.41.0. + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. enum: - TLS10 - TLS11 @@ -1157,9 +1266,9 @@ spec: type: string minVersion: description: |- - Minimum acceptable TLS version. + minVersion defines the minimum acceptable TLS version. - It requires Prometheus >= v2.35.0. + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. enum: - TLS10 - TLS11 @@ -1167,12 +1276,119 @@ spec: - TLS13 type: string serverName: - description: Used to verify the hostname for the targets. + description: serverName is used to verify the hostname for the + targets. type: string type: object type: object + status: + description: |- + status defines the status subresource. It is under active development and is updated only when the + "StatusForConfigurationResources" feature gate is enabled. + + Most recent observed status of the Probe. Read-only. + More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bindings: + description: bindings defines the list of workload resources (Prometheus, + PrometheusAgent, ThanosRuler or Alertmanager) which select the configuration + resource. + items: + description: WorkloadBinding is a link between a configuration resource + and a workload resource. + properties: + conditions: + description: conditions defines the current state of the configuration + resource when bound to the referenced Workload object. + items: + description: ConfigResourceCondition describes the status + of configuration resources linked to Prometheus, PrometheusAgent, + Alertmanager or ThanosRuler. + properties: + lastTransitionTime: + description: lastTransitionTime defines the time of the + last update to the current status property. + format: date-time + type: string + message: + description: message defines the human-readable message + indicating details for the condition's last transition. + type: string + observedGeneration: + description: |- + observedGeneration defines the .metadata.generation that the + condition was set based upon. For instance, if `.metadata.generation` is + currently 12, but the `.status.conditions[].observedGeneration` is 9, the + condition is out of date with respect to the current state of the object. + format: int64 + type: integer + reason: + description: reason for the condition's last transition. + type: string + status: + description: status of the condition. + minLength: 1 + type: string + type: + description: |- + type of the condition being reported. + Currently, only "Accepted" is supported. + enum: + - Accepted + minLength: 1 + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + group: + description: group defines the group of the referenced resource. + enum: + - monitoring.coreos.com + type: string + name: + description: name defines the name of the referenced object. + minLength: 1 + type: string + namespace: + description: namespace defines the namespace of the referenced + object. + minLength: 1 + type: string + resource: + description: resource defines the type of resource being referenced + (e.g. Prometheus, PrometheusAgent, ThanosRuler or Alertmanager). + enum: + - prometheuses + - prometheusagents + - thanosrulers + - alertmanagers + type: string + required: + - group + - name + - namespace + - resource + type: object + type: array + x-kubernetes-list-map-keys: + - group + - resource + - name + - namespace + x-kubernetes-list-type: map + type: object required: - spec type: object served: true storage: true + subresources: + status: {} +{{- end -}} diff --git a/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-prometheusrules.yaml b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-prometheusrules.yaml new file mode 100644 index 00000000..cf13c7c3 --- /dev/null +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-prometheusrules.yaml @@ -0,0 +1,272 @@ +{{- if .Values.prometheusrules.enabled -}} +# https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.87.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: +{{- with .Values.annotations }} +{{- toYaml . | nindent 4 }} +{{- end }} + controller-gen.kubebuilder.io/version: v0.19.0 + operator.prometheus.io/version: 0.87.0 + name: prometheusrules.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: PrometheusRule + listKind: PrometheusRuleList + plural: prometheusrules + shortNames: + - promrule + singular: prometheusrule + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + The `PrometheusRule` custom resource definition (CRD) defines [alerting](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) and [recording](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) rules to be evaluated by `Prometheus` or `ThanosRuler` objects. + + `Prometheus` and `ThanosRuler` objects select `PrometheusRule` objects using label and namespace selectors. + 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: + description: spec defines the specification of desired alerting rule definitions + for Prometheus. + properties: + groups: + description: groups defines the content of Prometheus rule file + items: + description: RuleGroup is a list of sequentially evaluated recording + and alerting rules. + properties: + interval: + description: interval defines how often rules in the group are + evaluated. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + labels: + additionalProperties: + type: string + description: |- + labels define the labels to add or overwrite before storing the result for its rules. + The labels defined at the rule level take precedence. + + It requires Prometheus >= 3.0.0. + The field is ignored for Thanos Ruler. + type: object + limit: + description: |- + limit defines the number of alerts an alerting rule and series a recording + rule can produce. + Limit is supported starting with Prometheus >= 2.31 and Thanos Ruler >= 0.24. + type: integer + name: + description: name defines the name of the rule group. + minLength: 1 + type: string + partial_response_strategy: + description: |- + partial_response_strategy is only used by ThanosRuler and will + be ignored by Prometheus instances. + More info: https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md#partial-response + pattern: ^(?i)(abort|warn)?$ + type: string + query_offset: + description: |- + query_offset defines the offset the rule evaluation timestamp of this particular group by the specified duration into the past. + + It requires Prometheus >= v2.53.0. + It is not supported for ThanosRuler. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + rules: + description: rules defines the list of alerting and recording + rules. + items: + description: |- + Rule describes an alerting or recording rule + See Prometheus documentation: [alerting](https://www.prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) or [recording](https://www.prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules) rule + properties: + alert: + description: |- + alert defines the name of the alert. Must be a valid label value. + Only one of `record` and `alert` must be set. + type: string + annotations: + additionalProperties: + type: string + description: |- + annotations defines annotations to add to each alert. + Only valid for alerting rules. + type: object + expr: + anyOf: + - type: integer + - type: string + description: expr defines the PromQL expression to evaluate. + x-kubernetes-int-or-string: true + for: + description: for defines how alerts are considered firing + once they have been returned for this long. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + keep_firing_for: + description: keep_firing_for defines how long an alert + will continue firing after the condition that triggered + it has cleared. + minLength: 1 + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + labels: + additionalProperties: + type: string + description: labels defines labels to add or overwrite. + type: object + record: + description: |- + record defines the name of the time series to output to. Must be a valid metric name. + Only one of `record` and `alert` must be set. + type: string + required: + - expr + type: object + type: array + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + status: + description: |- + status defines the status subresource. It is under active development and is updated only when the + "StatusForConfigurationResources" feature gate is enabled. + + Most recent observed status of the PrometheusRule. Read-only. + More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bindings: + description: bindings defines the list of workload resources (Prometheus, + PrometheusAgent, ThanosRuler or Alertmanager) which select the configuration + resource. + items: + description: WorkloadBinding is a link between a configuration resource + and a workload resource. + properties: + conditions: + description: conditions defines the current state of the configuration + resource when bound to the referenced Workload object. + items: + description: ConfigResourceCondition describes the status + of configuration resources linked to Prometheus, PrometheusAgent, + Alertmanager or ThanosRuler. + properties: + lastTransitionTime: + description: lastTransitionTime defines the time of the + last update to the current status property. + format: date-time + type: string + message: + description: message defines the human-readable message + indicating details for the condition's last transition. + type: string + observedGeneration: + description: |- + observedGeneration defines the .metadata.generation that the + condition was set based upon. For instance, if `.metadata.generation` is + currently 12, but the `.status.conditions[].observedGeneration` is 9, the + condition is out of date with respect to the current state of the object. + format: int64 + type: integer + reason: + description: reason for the condition's last transition. + type: string + status: + description: status of the condition. + minLength: 1 + type: string + type: + description: |- + type of the condition being reported. + Currently, only "Accepted" is supported. + enum: + - Accepted + minLength: 1 + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + group: + description: group defines the group of the referenced resource. + enum: + - monitoring.coreos.com + type: string + name: + description: name defines the name of the referenced object. + minLength: 1 + type: string + namespace: + description: namespace defines the namespace of the referenced + object. + minLength: 1 + type: string + resource: + description: resource defines the type of resource being referenced + (e.g. Prometheus, PrometheusAgent, ThanosRuler or Alertmanager). + enum: + - prometheuses + - prometheusagents + - thanosrulers + - alertmanagers + type: string + required: + - group + - name + - namespace + - resource + type: object + type: array + x-kubernetes-list-map-keys: + - group + - resource + - name + - namespace + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end -}} diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-servicemonitors.yaml b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-servicemonitors.yaml similarity index 70% rename from packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-servicemonitors.yaml rename to packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-servicemonitors.yaml index 64e19e48..ff4472f2 100644 --- a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-servicemonitors.yaml +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/charts/crds/templates/crd-servicemonitors.yaml @@ -1,4 +1,5 @@ -# https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.81.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml +{{- if .Values.servicemonitors.enabled -}} +# https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.87.0/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -7,8 +8,8 @@ metadata: {{- with .Values.annotations }} {{- toYaml . | nindent 4 }} {{- end }} - controller-gen.kubebuilder.io/version: v0.17.2 - operator.prometheus.io/version: 0.81.0 + controller-gen.kubebuilder.io/version: v0.19.0 + operator.prometheus.io/version: 0.87.0 name: servicemonitors.monitoring.coreos.com spec: group: monitoring.coreos.com @@ -55,19 +56,19 @@ spec: type: object spec: description: |- - Specification of desired Service selection for target discovery by + spec defines the specification of desired Service selection for target discovery by Prometheus. properties: attachMetadata: description: |- - `attachMetadata` defines additional metadata which is added to the + attachMetadata defines additional metadata which is added to the discovered targets. It requires Prometheus >= v2.37.0. properties: node: description: |- - When set to true, Prometheus attaches node metadata to the discovered + node when set to true, Prometheus attaches node metadata to the discovered targets. The Prometheus service account must have the `list` and `watch` @@ -76,15 +77,20 @@ spec: type: object bodySizeLimit: description: |- - When defined, bodySizeLimit specifies a job level limit on the size + bodySizeLimit when defined, bodySizeLimit specifies a job level limit on the size of uncompressed response body that will be accepted by Prometheus. It requires Prometheus >= v2.28.0. pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ type: string + convertClassicHistogramsToNHCB: + description: |- + convertClassicHistogramsToNHCB defines whether to convert all scraped classic histograms into a native histogram with custom buckets. + It requires Prometheus >= v3.0.0. + type: boolean endpoints: description: |- - List of endpoints part of this ServiceMonitor. + endpoints defines the list of endpoints part of this ServiceMonitor. Defines how to scrape metrics from Kubernetes [Endpoints](https://kubernetes.io/docs/concepts/services-networking/service/#endpoints) objects. In most cases, an Endpoints object is backed by a Kubernetes [Service](https://kubernetes.io/docs/concepts/services-networking/service/) object with the same name and labels. items: @@ -94,14 +100,14 @@ spec: properties: authorization: description: |- - `authorization` configures the Authorization header credentials to use when + authorization configures the Authorization header credentials to use when scraping the target. Cannot be set at the same time as `basicAuth`, or `oauth2`. properties: credentials: - description: Selects a key of a Secret in the namespace - that contains the credentials for authentication. + description: credentials defines a key of a Secret in the + namespace that contains the credentials for authentication. properties: key: description: The key of the secret to select from. Must @@ -126,7 +132,7 @@ spec: x-kubernetes-map-type: atomic type: description: |- - Defines the authentication type. The value is case-insensitive. + type defines the authentication type. The value is case-insensitive. "Basic" is not a supported value. @@ -135,14 +141,14 @@ spec: type: object basicAuth: description: |- - `basicAuth` configures the Basic Authentication credentials to use when + basicAuth defines the Basic Authentication credentials to use when scraping the target. Cannot be set at the same time as `authorization`, or `oauth2`. properties: password: description: |- - `password` specifies a key of a Secret containing the password for + password defines a key of a Secret containing the password for authentication. properties: key: @@ -168,7 +174,7 @@ spec: x-kubernetes-map-type: atomic username: description: |- - `username` specifies a key of a Secret containing the username for + username defines a key of a Secret containing the username for authentication. properties: key: @@ -195,13 +201,13 @@ spec: type: object bearerTokenFile: description: |- - File to read bearer token for scraping the target. + bearerTokenFile defines the file to read bearer token for scraping the target. Deprecated: use `authorization` instead. type: string bearerTokenSecret: description: |- - `bearerTokenSecret` specifies a key of a Secret containing the bearer + bearerTokenSecret defines a key of a Secret containing the bearer token for scraping targets. The secret needs to be in the same namespace as the ServiceMonitor object and readable by the Prometheus Operator. @@ -229,12 +235,12 @@ spec: type: object x-kubernetes-map-type: atomic enableHttp2: - description: '`enableHttp2` can be used to disable HTTP2 when - scraping the target.' + description: enableHttp2 can be used to disable HTTP2 when scraping + the target. type: boolean filterRunning: description: |- - When true, the pods which are not running (e.g. either in Failed or + filterRunning when true, the pods which are not running (e.g. either in Failed or Succeeded state) are dropped during the target discovery. If unset, the filtering is enabled. @@ -243,29 +249,29 @@ spec: type: boolean followRedirects: description: |- - `followRedirects` defines whether the scrape requests should follow HTTP + followRedirects defines whether the scrape requests should follow HTTP 3xx redirects. type: boolean honorLabels: description: |- - When true, `honorLabels` preserves the metric's labels when they collide + honorLabels defines when true the metric's labels when they collide with the target's labels. type: boolean honorTimestamps: description: |- - `honorTimestamps` controls whether Prometheus preserves the timestamps + honorTimestamps defines whether Prometheus preserves the timestamps when exposed by the target. type: boolean interval: description: |- - Interval at which Prometheus scrapes the metrics from the target. + interval at which Prometheus scrapes the metrics from the target. If empty, Prometheus uses the global scrape interval. pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ type: string metricRelabelings: description: |- - `metricRelabelings` configures the relabeling rules to apply to the + metricRelabelings defines the relabeling rules to apply to the samples before ingestion. items: description: |- @@ -277,7 +283,7 @@ spec: action: default: replace description: |- - Action to perform based on the regex matching. + action to perform based on the regex matching. `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. @@ -309,41 +315,41 @@ spec: type: string modulus: description: |- - Modulus to take of the hash of the source label values. + modulus to take of the hash of the source label values. Only applicable when the action is `HashMod`. format: int64 type: integer regex: - description: Regular expression against which the extracted - value is matched. + description: regex defines the regular expression against + which the extracted value is matched. type: string replacement: description: |- - Replacement value against which a Replace action is performed if the + replacement value against which a Replace action is performed if the regular expression matches. Regex capture groups are available. type: string separator: - description: Separator is the string between concatenated + description: separator defines the string between concatenated SourceLabels. type: string sourceLabels: description: |- - The source labels select values from existing labels. Their content is + sourceLabels defines the source labels select values from existing labels. Their content is concatenated using the configured Separator and matched against the configured regular expression. items: description: |- - LabelName is a valid Prometheus label name which may only contain ASCII - letters, numbers, as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + LabelName is a valid Prometheus label name. + For Prometheus 3.x, a label name is valid if it contains UTF-8 characters. + For Prometheus 2.x, a label name is only valid if it contains ASCII characters, letters, numbers, as well as underscores. type: string type: array targetLabel: description: |- - Label to which the resulting string is written in a replacement. + targetLabel defines the label to which the resulting string is written in a replacement. It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, `KeepEqual` and `DropEqual` actions. @@ -352,9 +358,17 @@ spec: type: string type: object type: array + noProxy: + description: |- + noProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names + that should be excluded from proxying. IP and domain names can + contain port numbers. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: string oauth2: description: |- - `oauth2` configures the OAuth2 settings to use when scraping the target. + oauth2 defines the OAuth2 settings to use when scraping the target. It requires Prometheus >= 2.27.0. @@ -362,12 +376,12 @@ spec: properties: clientId: description: |- - `clientId` specifies a key of a Secret or ConfigMap containing the + clientId defines a key of a Secret or ConfigMap containing the OAuth2 client's ID. properties: configMap: - description: ConfigMap containing data to use for the - targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -390,7 +404,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data + to use for the targets. properties: key: description: The key of the secret to select from. Must @@ -416,7 +431,7 @@ spec: type: object clientSecret: description: |- - `clientSecret` specifies a key of a Secret containing the OAuth2 + clientSecret defines a key of a Secret containing the OAuth2 client's secret. properties: key: @@ -444,16 +459,16 @@ spec: additionalProperties: type: string description: |- - `endpointParams` configures the HTTP parameters to append to the token + endpointParams configures the HTTP parameters to append to the token URL. type: object noProxy: description: |- - `noProxy` is a comma-separated string that can contain IPs, CIDR notation, domain names + noProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. IP and domain names can contain port numbers. - It requires Prometheus >= v2.43.0 or Alertmanager >= 0.25.0. + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. type: string proxyConnectHeader: additionalProperties: @@ -483,41 +498,40 @@ spec: x-kubernetes-map-type: atomic type: array description: |- - ProxyConnectHeader optionally specifies headers to send to + proxyConnectHeader optionally specifies headers to send to proxies during CONNECT requests. - It requires Prometheus >= v2.43.0 or Alertmanager >= 0.25.0. + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. type: object x-kubernetes-map-type: atomic proxyFromEnvironment: description: |- - Whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + proxyFromEnvironment defines whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). - It requires Prometheus >= v2.43.0 or Alertmanager >= 0.25.0. + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. type: boolean proxyUrl: - description: '`proxyURL` defines the HTTP proxy server to - use.' - pattern: ^http(s)?://.+$ + description: proxyUrl defines the HTTP proxy server to use. + pattern: ^(http|https|socks5)://.+$ type: string scopes: - description: '`scopes` defines the OAuth2 scopes used for - the token request.' + description: scopes defines the OAuth2 scopes used for the + token request. items: type: string type: array tlsConfig: description: |- - TLS configuration to use when connecting to the OAuth2 server. + tlsConfig defines the TLS configuration to use when connecting to the OAuth2 server. It requires Prometheus >= v2.43.0. properties: ca: - description: Certificate authority used when verifying - server certificates. + description: ca defines the Certificate authority used + when verifying server certificates. properties: configMap: - description: ConfigMap containing data to use for - the targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -540,8 +554,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the - targets. + description: secret defines the Secret containing + data to use for the targets. properties: key: description: The key of the secret to select @@ -566,12 +580,12 @@ spec: x-kubernetes-map-type: atomic type: object cert: - description: Client certificate to present when doing - client-authentication. + description: cert defines the Client certificate to + present when doing client-authentication. properties: configMap: - description: ConfigMap containing data to use for - the targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -594,8 +608,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the - targets. + description: secret defines the Secret containing + data to use for the targets. properties: key: description: The key of the secret to select @@ -620,11 +634,12 @@ spec: x-kubernetes-map-type: atomic type: object insecureSkipVerify: - description: Disable target certificate validation. + description: insecureSkipVerify defines how to disable + target certificate validation. type: boolean keySecret: - description: Secret containing the client key file for - the targets. + description: keySecret defines the Secret containing + the client key file for the targets. properties: key: description: The key of the secret to select from. Must @@ -649,9 +664,9 @@ spec: x-kubernetes-map-type: atomic maxVersion: description: |- - Maximum acceptable TLS version. + maxVersion defines the maximum acceptable TLS version. - It requires Prometheus >= v2.41.0. + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. enum: - TLS10 - TLS11 @@ -660,9 +675,9 @@ spec: type: string minVersion: description: |- - Minimum acceptable TLS version. + minVersion defines the minimum acceptable TLS version. - It requires Prometheus >= v2.35.0. + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. enum: - TLS10 - TLS11 @@ -670,12 +685,13 @@ spec: - TLS13 type: string serverName: - description: Used to verify the hostname for the targets. + description: serverName is used to verify the hostname + for the targets. type: string type: object tokenUrl: - description: '`tokenURL` configures the URL to fetch the - token from.' + description: tokenUrl defines the URL to fetch the token + from. minLength: 1 type: string required: @@ -692,24 +708,63 @@ spec: type: object path: description: |- - HTTP path from which to scrape for metrics. + path defines the HTTP path from which to scrape for metrics. If empty, Prometheus uses the default value (e.g. `/metrics`). type: string port: description: |- - Name of the Service port which this endpoint refers to. + port defines the name of the Service port which this endpoint refers to. It takes precedence over `targetPort`. type: string - proxyUrl: + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array description: |- - `proxyURL` configures the HTTP Proxy URL (e.g. - "http://proxyserver:2195") to go through when scraping the target. + proxyConnectHeader optionally specifies headers to send to + proxies during CONNECT requests. + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: object + x-kubernetes-map-type: atomic + proxyFromEnvironment: + description: |- + proxyFromEnvironment defines whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + + It requires Prometheus >= v2.43.0, Alertmanager >= v0.25.0 or Thanos >= v0.32.0. + type: boolean + proxyUrl: + description: proxyUrl defines the HTTP proxy server to use. + pattern: ^(http|https|socks5)://.+$ type: string relabelings: description: |- - `relabelings` configures the relabeling rules to apply the target's + relabelings defines the relabeling rules to apply the target's metadata labels. The Operator automatically adds relabelings for a few standard Kubernetes fields. @@ -727,7 +782,7 @@ spec: action: default: replace description: |- - Action to perform based on the regex matching. + action to perform based on the regex matching. `Uppercase` and `Lowercase` actions require Prometheus >= v2.36.0. `DropEqual` and `KeepEqual` actions require Prometheus >= v2.41.0. @@ -759,41 +814,41 @@ spec: type: string modulus: description: |- - Modulus to take of the hash of the source label values. + modulus to take of the hash of the source label values. Only applicable when the action is `HashMod`. format: int64 type: integer regex: - description: Regular expression against which the extracted - value is matched. + description: regex defines the regular expression against + which the extracted value is matched. type: string replacement: description: |- - Replacement value against which a Replace action is performed if the + replacement value against which a Replace action is performed if the regular expression matches. Regex capture groups are available. type: string separator: - description: Separator is the string between concatenated + description: separator defines the string between concatenated SourceLabels. type: string sourceLabels: description: |- - The source labels select values from existing labels. Their content is + sourceLabels defines the source labels select values from existing labels. Their content is concatenated using the configured Separator and matched against the configured regular expression. items: description: |- - LabelName is a valid Prometheus label name which may only contain ASCII - letters, numbers, as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + LabelName is a valid Prometheus label name. + For Prometheus 3.x, a label name is valid if it contains UTF-8 characters. + For Prometheus 2.x, a label name is only valid if it contains ASCII characters, letters, numbers, as well as underscores. type: string type: array targetLabel: description: |- - Label to which the resulting string is written in a replacement. + targetLabel defines the label to which the resulting string is written in a replacement. It is mandatory for `Replace`, `HashMod`, `Lowercase`, `Uppercase`, `KeepEqual` and `DropEqual` actions. @@ -803,20 +858,17 @@ spec: type: object type: array scheme: - description: |- - HTTP scheme to use for scraping. - - `http` and `https` are the expected values unless you rewrite the - `__scheme__` label via relabeling. - - If empty, Prometheus uses the default value `http`. + description: scheme defines the HTTP scheme to use when scraping + the metrics. enum: - http - https + - HTTP + - HTTPS type: string scrapeTimeout: description: |- - Timeout after which Prometheus considers the scrape to be failed. + scrapeTimeout defines the timeout after which Prometheus considers the scrape to be failed. If empty, Prometheus uses the global scrape timeout unless it is less than the target's scrape interval value in which the latter is used. @@ -828,19 +880,20 @@ spec: - type: integer - type: string description: |- - Name or number of the target port of the `Pod` object behind the + targetPort defines the name or number of the target port of the `Pod` object behind the Service. The port must be specified with the container's port property. x-kubernetes-int-or-string: true tlsConfig: - description: TLS configuration to use when scraping the target. + description: tlsConfig defines the TLS configuration to use + when scraping the target. properties: ca: - description: Certificate authority used when verifying server - certificates. + description: ca defines the Certificate authority used when + verifying server certificates. properties: configMap: - description: ConfigMap containing data to use for the - targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -863,7 +916,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data + to use for the targets. properties: key: description: The key of the secret to select from. Must @@ -888,15 +942,16 @@ spec: x-kubernetes-map-type: atomic type: object caFile: - description: Path to the CA cert in the Prometheus container - to use for the targets. + description: caFile defines the path to the CA cert in the + Prometheus container to use for the targets. type: string cert: - description: Client certificate to present when doing client-authentication. + description: cert defines the Client certificate to present + when doing client-authentication. properties: configMap: - description: ConfigMap containing data to use for the - targets. + description: configMap defines the ConfigMap containing + data to use for the targets. properties: key: description: The key to select. @@ -919,7 +974,8 @@ spec: type: object x-kubernetes-map-type: atomic secret: - description: Secret containing data to use for the targets. + description: secret defines the Secret containing data + to use for the targets. properties: key: description: The key of the secret to select from. Must @@ -944,19 +1000,20 @@ spec: x-kubernetes-map-type: atomic type: object certFile: - description: Path to the client cert file in the Prometheus - container for the targets. + description: certFile defines the path to the client cert + file in the Prometheus container for the targets. type: string insecureSkipVerify: - description: Disable target certificate validation. + description: insecureSkipVerify defines how to disable target + certificate validation. type: boolean keyFile: - description: Path to the client key file in the Prometheus - container for the targets. + description: keyFile defines the path to the client key + file in the Prometheus container for the targets. type: string keySecret: - description: Secret containing the client key file for the - targets. + description: keySecret defines the Secret containing the + client key file for the targets. properties: key: description: The key of the secret to select from. Must @@ -981,9 +1038,9 @@ spec: x-kubernetes-map-type: atomic maxVersion: description: |- - Maximum acceptable TLS version. + maxVersion defines the maximum acceptable TLS version. - It requires Prometheus >= v2.41.0. + It requires Prometheus >= v2.41.0 or Thanos >= v0.31.0. enum: - TLS10 - TLS11 @@ -992,9 +1049,9 @@ spec: type: string minVersion: description: |- - Minimum acceptable TLS version. + minVersion defines the minimum acceptable TLS version. - It requires Prometheus >= v2.35.0. + It requires Prometheus >= v2.35.0 or Thanos >= v0.28.0. enum: - TLS10 - TLS11 @@ -1002,12 +1059,13 @@ spec: - TLS13 type: string serverName: - description: Used to verify the hostname for the targets. + description: serverName is used to verify the hostname for + the targets. type: string type: object trackTimestampsStaleness: description: |- - `trackTimestampsStaleness` defines whether Prometheus tracks staleness of + trackTimestampsStaleness defines whether Prometheus tracks staleness of the metrics that have an explicit timestamp present in scraped data. Has no effect if `honorTimestamps` is false. @@ -1017,7 +1075,7 @@ spec: type: array fallbackScrapeProtocol: description: |- - The protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. + fallbackScrapeProtocol defines the protocol to use if a scrape returns blank, unparseable, or otherwise invalid Content-Type. It requires Prometheus >= v3.0.0. enum: @@ -1029,7 +1087,7 @@ spec: type: string jobLabel: description: |- - `jobLabel` selects the label from the associated Kubernetes `Service` + jobLabel selects the label from the associated Kubernetes `Service` object which will be used as the `job` label for all metrics. For example if `jobLabel` is set to `foo` and the Kubernetes `Service` @@ -1042,7 +1100,7 @@ spec: type: string keepDroppedTargets: description: |- - Per-scrape limit on the number of targets dropped by relabeling + keepDroppedTargets defines the per-scrape limit on the number of targets dropped by relabeling that will be kept in memory. 0 means no limit. It requires Prometheus >= v2.47.0. @@ -1050,44 +1108,45 @@ spec: type: integer labelLimit: description: |- - Per-scrape limit on number of labels that will be accepted for a sample. + labelLimit defines the per-scrape limit on number of labels that will be accepted for a sample. It requires Prometheus >= v2.27.0. format: int64 type: integer labelNameLengthLimit: description: |- - Per-scrape limit on length of labels name that will be accepted for a sample. + labelNameLengthLimit defines the per-scrape limit on length of labels name that will be accepted for a sample. It requires Prometheus >= v2.27.0. format: int64 type: integer labelValueLengthLimit: description: |- - Per-scrape limit on length of labels value that will be accepted for a sample. + labelValueLengthLimit defines the per-scrape limit on length of labels value that will be accepted for a sample. It requires Prometheus >= v2.27.0. format: int64 type: integer namespaceSelector: description: |- - `namespaceSelector` defines in which namespace(s) Prometheus should discover the services. + namespaceSelector defines in which namespace(s) Prometheus should discover the services. By default, the services are discovered in the same namespace as the `ServiceMonitor` object but it is possible to select pods across different/all namespaces. properties: any: description: |- - Boolean describing whether all namespaces are selected in contrast to a + any defines the boolean describing whether all namespaces are selected in contrast to a list restricting them. type: boolean matchNames: - description: List of namespace names to select from. + description: matchNames defines the list of namespace names to + select from. items: type: string type: array type: object nativeHistogramBucketLimit: description: |- - If there are more than this many buckets in a native histogram, + nativeHistogramBucketLimit defines ff there are more than this many buckets in a native histogram, buckets will be merged to stay within the limit. It requires Prometheus >= v2.45.0. format: int64 @@ -1097,36 +1156,38 @@ spec: - type: integer - type: string description: |- - If the growth factor of one bucket to the next is smaller than this, + nativeHistogramMinBucketFactor defines if the growth factor of one bucket to the next is smaller than this, buckets will be merged to increase the factor sufficiently. It requires Prometheus >= v2.50.0. pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true podTargetLabels: description: |- - `podTargetLabels` defines the labels which are transferred from the + podTargetLabels defines the labels which are transferred from the associated Kubernetes `Pod` object onto the ingested metrics. items: type: string type: array sampleLimit: description: |- - `sampleLimit` defines a per-scrape limit on the number of scraped samples + sampleLimit defines a per-scrape limit on the number of scraped samples that will be accepted. format: int64 type: integer scrapeClass: - description: The scrape class to apply. + description: scrapeClass defines the scrape class to apply. minLength: 1 type: string scrapeClassicHistograms: description: |- - Whether to scrape a classic histogram that is also exposed as a native histogram. + scrapeClassicHistograms defines whether to scrape a classic histogram that is also exposed as a native histogram. It requires Prometheus >= v2.45.0. + + Notice: `scrapeClassicHistograms` corresponds to the `always_scrape_classic_histograms` field in the Prometheus configuration. type: boolean scrapeProtocols: description: |- - `scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the + scrapeProtocols defines the protocols to negotiate during a scrape. It tells clients the protocols supported by Prometheus in order of preference (from most to least preferred). If unset, Prometheus uses its default value. @@ -1151,8 +1212,8 @@ spec: type: array x-kubernetes-list-type: set selector: - description: Label selector to select the Kubernetes `Endpoints` objects - to scrape metrics from. + description: selector defines the label selector to select the Kubernetes + `Endpoints` objects to scrape metrics from. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -1199,7 +1260,7 @@ spec: x-kubernetes-map-type: atomic selectorMechanism: description: |- - Mechanism used to select the endpoints to scrape. + selectorMechanism defines the mechanism used to select the endpoints to scrape. By default, the selection process relies on relabel configurations to filter the discovered targets. Alternatively, you can opt in for role selectors, which may offer better efficiency in large clusters. Which strategy is best for your use case needs to be carefully evaluated. @@ -1209,16 +1270,27 @@ spec: - RelabelConfig - RoleSelector type: string + serviceDiscoveryRole: + description: |- + serviceDiscoveryRole defines the service discovery role used to discover targets. + + If set, the value should be either "Endpoints" or "EndpointSlice". + Otherwise it defaults to the value defined in the + Prometheus/PrometheusAgent resource. + enum: + - Endpoints + - EndpointSlice + type: string targetLabels: description: |- - `targetLabels` defines the labels which are transferred from the + targetLabels defines the labels which are transferred from the associated Kubernetes `Service` object onto the ingested metrics. items: type: string type: array targetLimit: description: |- - `targetLimit` defines a limit on the number of scraped targets that will + targetLimit defines a limit on the number of scraped targets that will be accepted. format: int64 type: integer @@ -1226,8 +1298,114 @@ spec: - endpoints - selector type: object + status: + description: |- + status defines the status subresource. It is under active development and is updated only when the + "StatusForConfigurationResources" feature gate is enabled. + + Most recent observed status of the ServiceMonitor. Read-only. + More info: + https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + bindings: + description: bindings defines the list of workload resources (Prometheus, + PrometheusAgent, ThanosRuler or Alertmanager) which select the configuration + resource. + items: + description: WorkloadBinding is a link between a configuration resource + and a workload resource. + properties: + conditions: + description: conditions defines the current state of the configuration + resource when bound to the referenced Workload object. + items: + description: ConfigResourceCondition describes the status + of configuration resources linked to Prometheus, PrometheusAgent, + Alertmanager or ThanosRuler. + properties: + lastTransitionTime: + description: lastTransitionTime defines the time of the + last update to the current status property. + format: date-time + type: string + message: + description: message defines the human-readable message + indicating details for the condition's last transition. + type: string + observedGeneration: + description: |- + observedGeneration defines the .metadata.generation that the + condition was set based upon. For instance, if `.metadata.generation` is + currently 12, but the `.status.conditions[].observedGeneration` is 9, the + condition is out of date with respect to the current state of the object. + format: int64 + type: integer + reason: + description: reason for the condition's last transition. + type: string + status: + description: status of the condition. + minLength: 1 + type: string + type: + description: |- + type of the condition being reported. + Currently, only "Accepted" is supported. + enum: + - Accepted + minLength: 1 + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + group: + description: group defines the group of the referenced resource. + enum: + - monitoring.coreos.com + type: string + name: + description: name defines the name of the referenced object. + minLength: 1 + type: string + namespace: + description: namespace defines the namespace of the referenced + object. + minLength: 1 + type: string + resource: + description: resource defines the type of resource being referenced + (e.g. Prometheus, PrometheusAgent, ThanosRuler or Alertmanager). + enum: + - prometheuses + - prometheusagents + - thanosrulers + - alertmanagers + type: string + required: + - group + - name + - namespace + - resource + type: object + type: array + x-kubernetes-list-map-keys: + - group + - resource + - name + - namespace + x-kubernetes-list-type: map + type: object required: - spec type: object served: true storage: true + subresources: + status: {} +{{- end -}} diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/ci/lint.sh b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/ci/lint.sh similarity index 100% rename from packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/ci/lint.sh rename to packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/ci/lint.sh diff --git a/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/hack/renovate-post-upgrade-hook.sh b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/hack/renovate-post-upgrade-hook.sh new file mode 100644 index 00000000..f7f3c35d --- /dev/null +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/hack/renovate-post-upgrade-hook.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${0}")" &>/dev/null && pwd)" + +"${SCRIPT_DIR}/update_crds.sh" diff --git a/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/hack/update_crds.sh b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/hack/update_crds.sh new file mode 100644 index 00000000..bfa576de --- /dev/null +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/hack/update_crds.sh @@ -0,0 +1,51 @@ +#!/bin/bash +set -euo pipefail + +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) + +if [[ $(uname -s) = "Darwin" ]]; then + VERSION="$(grep ^appVersion "${SCRIPT_DIR}/../Chart.yaml" | sed 's/appVersion: //g')" +else + VERSION="$(grep ^appVersion "${SCRIPT_DIR}/../Chart.yaml" | sed 's/appVersion:\s//g')" +fi + +CRDS=( + "alertmanagerconfigs : monitoring.coreos.com_alertmanagerconfigs.yaml" + "alertmanagers : monitoring.coreos.com_alertmanagers.yaml" + "podmonitors : monitoring.coreos.com_podmonitors.yaml" + "probes : monitoring.coreos.com_probes.yaml" + "prometheusagents : monitoring.coreos.com_prometheusagents.yaml" + "prometheuses : monitoring.coreos.com_prometheuses.yaml" + "prometheusrules : monitoring.coreos.com_prometheusrules.yaml" + "scrapeconfigs : monitoring.coreos.com_scrapeconfigs.yaml" + "servicemonitors : monitoring.coreos.com_servicemonitors.yaml" + "thanosrulers : monitoring.coreos.com_thanosrulers.yaml" +) + +for line in "${CRDS[@]}"; do + CRD=$(echo "${line%%:*}" | xargs) + SOURCE=$(echo "${line##*:}" | xargs) + DESTINATION="crd-${CRD}".yaml + + URL="https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/$VERSION/example/prometheus-operator-crd/$SOURCE" + + echo -e "Downloading Prometheus Operator CRD with Version ${VERSION}:\n${URL}\n" + + echo "# ${URL}" >"${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" + + if ! curl --silent --retry-all-errors --fail --location "${URL}" >>"${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}"; then + echo -e "Failed to download ${URL}!" + exit 1 + fi + + # Update or insert annotations block + if yq -e '.metadata.annotations' "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" >/dev/null; then + sed -i '/^ annotations:$/a {{- with .Values.annotations }}\n{{- toYaml . | nindent 4 }}\n{{- end }}' "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" + else + sed -i '/^metadata:$/a {{- with .Values.annotations }}\n annotations:\n{{- toYaml . | nindent 4 }}\n{{- end }}' "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" + fi + + # Insert enable option + sed -i "1i\{{- if .Values.${CRD}.enabled -}}" "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" + echo "{{- end -}}" >>"${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" +done diff --git a/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/values.yaml b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/values.yaml new file mode 100644 index 00000000..f462daf0 --- /dev/null +++ b/packages/system/prometheus-operator-crds/charts/prometheus-operator-crds/values.yaml @@ -0,0 +1,55 @@ +## Settings for CRDs +## +crds: + ## annotations add additional annotations to all CRDs + annotations: {} + + ## alertmanagerconfigs configures the AlertManagerConfig CRD + alertmanagerconfigs: + ## enabled defines if the CRD should be installed + enabled: true + + ## alertmanagers configures the AlertManager CRD + alertmanagers: + ## enabled defines if the CRD should be installed + enabled: true + + ## podmonitors configures the PodMonitor CRD + podmonitors: + ## enabled defines if the CRD should be installed + enabled: true + + ## probes configures the Probe CRD + probes: + ## enabled defines if the CRD should be installed + enabled: true + + ## prometheusagents configures the PrometheusAgent CRD + prometheusagents: + ## enabled defines if the CRD should be installed + enabled: true + + ## prometheuses configures the Prometheus CRD + prometheuses: + ## enabled defines if the CRD should be installed + enabled: true + + ## prometheusrules configures the PrometheusRule CRD + prometheusrules: + ## enabled defines if the CRD should be installed + enabled: true + + ## prometheusrules configures the PrometheusRule CRD + scrapeconfigs: + ## enabled defines if the CRD should be installed + enabled: true + + ## servicemonitors configures the ServiceMonitor CRD + servicemonitors: + ## enabled defines if the CRD should be installed + enabled: true + + ## thanosrulers configures the ThanosRuler CRD + thanosrulers: + ## enabled defines if the CRD should be installed + enabled: true diff --git a/packages/system/prometheus-operator-crds/values.yaml b/packages/system/prometheus-operator-crds/values.yaml new file mode 100644 index 00000000..e69de29b diff --git a/packages/system/victoria-metrics-operator/Makefile b/packages/system/victoria-metrics-operator/Makefile index 0f31d7b7..a78b7b76 100644 --- a/packages/system/victoria-metrics-operator/Makefile +++ b/packages/system/victoria-metrics-operator/Makefile @@ -9,8 +9,3 @@ update: helm repo add vm https://victoriametrics.github.io/helm-charts/ helm repo update vm helm pull vm/victoria-metrics-operator --untar --untardir charts - # Prometheus CRDs - helm repo add prometheus-community https://prometheus-community.github.io/helm-charts - helm repo update prometheus-community - helm pull prometheus-community/prometheus-operator-crds --untar --untardir charts - rm -f -- `find charts/prometheus-operator-crds/charts/crds/templates -maxdepth 1 -mindepth 1 | grep -v 'servicemonitor\|podmonitor\|prometheusrule\|probe'` diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-prometheusrules.yaml b/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-prometheusrules.yaml deleted file mode 100644 index dd13e8fd..00000000 --- a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/charts/crds/templates/crd-prometheusrules.yaml +++ /dev/null @@ -1,163 +0,0 @@ -# https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.81.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: -{{- with .Values.annotations }} -{{- toYaml . | nindent 4 }} -{{- end }} - controller-gen.kubebuilder.io/version: v0.17.2 - operator.prometheus.io/version: 0.81.0 - name: prometheusrules.monitoring.coreos.com -spec: - group: monitoring.coreos.com - names: - categories: - - prometheus-operator - kind: PrometheusRule - listKind: PrometheusRuleList - plural: prometheusrules - shortNames: - - promrule - singular: prometheusrule - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: |- - The `PrometheusRule` custom resource definition (CRD) defines [alerting](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) and [recording](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) rules to be evaluated by `Prometheus` or `ThanosRuler` objects. - - `Prometheus` and `ThanosRuler` objects select `PrometheusRule` objects using label and namespace selectors. - 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: - description: Specification of desired alerting rule definitions for Prometheus. - properties: - groups: - description: Content of Prometheus rule file - items: - description: RuleGroup is a list of sequentially evaluated recording - and alerting rules. - properties: - interval: - description: Interval determines how often rules in the group - are evaluated. - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - labels: - additionalProperties: - type: string - description: |- - Labels to add or overwrite before storing the result for its rules. - The labels defined at the rule level take precedence. - - It requires Prometheus >= 3.0.0. - The field is ignored for Thanos Ruler. - type: object - limit: - description: |- - Limit the number of alerts an alerting rule and series a recording - rule can produce. - Limit is supported starting with Prometheus >= 2.31 and Thanos Ruler >= 0.24. - type: integer - name: - description: Name of the rule group. - minLength: 1 - type: string - partial_response_strategy: - description: |- - PartialResponseStrategy is only used by ThanosRuler and will - be ignored by Prometheus instances. - More info: https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md#partial-response - pattern: ^(?i)(abort|warn)?$ - type: string - query_offset: - description: |- - Defines the offset the rule evaluation timestamp of this particular group by the specified duration into the past. - - It requires Prometheus >= v2.53.0. - It is not supported for ThanosRuler. - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - rules: - description: List of alerting and recording rules. - items: - description: |- - Rule describes an alerting or recording rule - See Prometheus documentation: [alerting](https://www.prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) or [recording](https://www.prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules) rule - properties: - alert: - description: |- - Name of the alert. Must be a valid label value. - Only one of `record` and `alert` must be set. - type: string - annotations: - additionalProperties: - type: string - description: |- - Annotations to add to each alert. - Only valid for alerting rules. - type: object - expr: - anyOf: - - type: integer - - type: string - description: PromQL expression to evaluate. - x-kubernetes-int-or-string: true - for: - description: Alerts are considered firing once they have - been returned for this long. - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - keep_firing_for: - description: KeepFiringFor defines how long an alert will - continue firing after the condition that triggered it - has cleared. - minLength: 1 - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - labels: - additionalProperties: - type: string - description: Labels to add or overwrite. - type: object - record: - description: |- - Name of the time series to output to. Must be a valid metric name. - Only one of `record` and `alert` must be set. - type: string - required: - - expr - type: object - type: array - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: true diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/hack/update_crds.sh b/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/hack/update_crds.sh deleted file mode 100644 index d950ec16..00000000 --- a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/hack/update_crds.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) - -if [[ $(uname -s) = "Darwin" ]]; then - VERSION="$(grep ^appVersion "${SCRIPT_DIR}/../Chart.yaml" | sed 's/appVersion: //g')" -else - VERSION="$(grep ^appVersion "${SCRIPT_DIR}/../Chart.yaml" | sed 's/appVersion:\s//g')" -fi - -FILES=( - "crd-alertmanagerconfigs.yaml : monitoring.coreos.com_alertmanagerconfigs.yaml" - "crd-alertmanagers.yaml : monitoring.coreos.com_alertmanagers.yaml" - "crd-podmonitors.yaml : monitoring.coreos.com_podmonitors.yaml" - "crd-probes.yaml : monitoring.coreos.com_probes.yaml" - "crd-prometheusagents.yaml : monitoring.coreos.com_prometheusagents.yaml" - "crd-prometheuses.yaml : monitoring.coreos.com_prometheuses.yaml" - "crd-prometheusrules.yaml : monitoring.coreos.com_prometheusrules.yaml" - "crd-scrapeconfigs.yaml : monitoring.coreos.com_scrapeconfigs.yaml" - "crd-servicemonitors.yaml : monitoring.coreos.com_servicemonitors.yaml" - "crd-thanosrulers.yaml : monitoring.coreos.com_thanosrulers.yaml" -) - -for line in "${FILES[@]}"; do - DESTINATION=$(echo "${line%%:*}" | xargs) - SOURCE=$(echo "${line##*:}" | xargs) - - URL="https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/$VERSION/example/prometheus-operator-crd/$SOURCE" - - echo -e "Downloading Prometheus Operator CRD with Version ${VERSION}:\n${URL}\n" - - echo "# ${URL}" > "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" - - if ! curl --silent --retry-all-errors --fail --location "${URL}" >> "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}"; then - echo -e "Failed to download ${URL}!" - exit 1 - fi - - # Update or insert annotations block - if yq -e '.metadata.annotations' "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" >/dev/null; then - sed -i '/^ annotations:$/a {{- with .Values.annotations }}\n{{- toYaml . | nindent 4 }}\n{{- end }}' "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" - else - sed -i '/^metadata:$/a {{- with .Values.annotations }}\n annotations:\n{{- toYaml . | nindent 4 }}\n{{- end }}' "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" - fi -done diff --git a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/values.yaml b/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/values.yaml deleted file mode 100644 index 7990c631..00000000 --- a/packages/system/victoria-metrics-operator/charts/prometheus-operator-crds/values.yaml +++ /dev/null @@ -1,4 +0,0 @@ -## Annotations for CRDs -## -crds: - annotations: {}