mirror of
https://github.com/cozystack/cozystack.git
synced 2026-03-13 02:18:55 +00:00
Compare commits
90 Commits
release-0.
...
testing/ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eeb85eed39 | ||
|
|
5acf62824a | ||
|
|
93e33a0921 | ||
|
|
c4fa795491 | ||
|
|
f93042499b | ||
|
|
7cbe564ff1 | ||
|
|
62ff0c0b39 | ||
|
|
198b30887a | ||
|
|
9632772337 | ||
|
|
603dcbe27e | ||
|
|
0bb538b1a1 | ||
|
|
c63fb203b6 | ||
|
|
dfaf51d3e4 | ||
|
|
992c7d54fe | ||
|
|
4e3c8eafa1 | ||
|
|
05cd1a1c82 | ||
|
|
ee1c83ec85 | ||
|
|
1f784db3f7 | ||
|
|
f4e0145c1c | ||
|
|
efd96877ab | ||
|
|
5a20693d67 | ||
|
|
448fc61570 | ||
|
|
dc0eebd81e | ||
|
|
a545ff3781 | ||
|
|
82cebe3ad7 | ||
|
|
184441d82f | ||
|
|
ebbc76582c | ||
|
|
8e57ac487e | ||
|
|
766f6e9a9e | ||
|
|
d1fa0e6586 | ||
|
|
3e41504b2d | ||
|
|
06f68d28d9 | ||
|
|
21de4f7584 | ||
|
|
840c264e86 | ||
|
|
bbb92ba497 | ||
|
|
b163a5913f | ||
|
|
ba8a9cc1f7 | ||
|
|
b858745cdd | ||
|
|
d9d6fa1a5a | ||
|
|
9e635fcc3f | ||
|
|
2791e3e96a | ||
|
|
1a977bd4b4 | ||
|
|
10516c38ec | ||
|
|
d57f9acc7a | ||
|
|
466f0fed52 | ||
|
|
c1edc5d711 | ||
|
|
354507a4ea | ||
|
|
a9c2bfb33b | ||
|
|
85c9da58de | ||
|
|
b1d5de1006 | ||
|
|
af96e3da94 | ||
|
|
bf1ece5f7c | ||
|
|
c3f70abc99 | ||
|
|
ea85856b1a | ||
|
|
e9bdbcf60d | ||
|
|
43ec8f0877 | ||
|
|
1f0edc5f79 | ||
|
|
fe8ec75ac7 | ||
|
|
671e13df70 | ||
|
|
36df9bda05 | ||
|
|
2a82273902 | ||
|
|
bb8f2047bf | ||
|
|
2a508c4f29 | ||
|
|
a4cbc7341d | ||
|
|
fdc2b8f3ec | ||
|
|
e6070210f6 | ||
|
|
e1e9eef63b | ||
|
|
f2a8e2d45d | ||
|
|
1a49cbef2d | ||
|
|
346dce83d4 | ||
|
|
4d8dca8049 | ||
|
|
7a19215f0a | ||
|
|
2d9dc9fe01 | ||
|
|
d86742eb36 | ||
|
|
857416d1d2 | ||
|
|
6bd7d3add5 | ||
|
|
2fcf975e6a | ||
|
|
b7bebecb64 | ||
|
|
edc12e3f7e | ||
|
|
27b06f4fbd | ||
|
|
3f6888a470 | ||
|
|
1a4e979e63 | ||
|
|
a3be02132d | ||
|
|
c6ec3168f7 | ||
|
|
5b58ec5cdd | ||
|
|
7e622181ed | ||
|
|
bf38316163 | ||
|
|
1475196437 | ||
|
|
076d69a10b | ||
|
|
5654ac4e3d |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1 +1 @@
|
||||
* @kvaps @lllamnyp @klinch0
|
||||
* @kvaps @lllamnyp @nbykov0
|
||||
|
||||
2
.github/workflows/pre-commit.yml
vendored
2
.github/workflows/pre-commit.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
|
||||
- name: Install generate
|
||||
run: |
|
||||
curl -sSL https://github.com/cozystack/cozyvalues-gen/releases/download/v0.9.0/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.5/cozyvalues-gen-linux-amd64.tar.gz | tar -xzvf- -C /usr/local/bin/ cozyvalues-gen
|
||||
|
||||
- name: Run pre-commit hooks
|
||||
run: |
|
||||
|
||||
3
.github/workflows/pull-requests.yaml
vendored
3
.github/workflows/pull-requests.yaml
vendored
@@ -1,7 +1,8 @@
|
||||
name: Pull Request
|
||||
|
||||
env:
|
||||
REGISTRY: ${{ vars.OCIR_REPO }}
|
||||
# TODO: unhardcode this
|
||||
REGISTRY: iad.ocir.io/idyksih5sir9/cozystack
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
@@ -229,15 +229,6 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
dashboardManager := &dashboard.Manager{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: mgr.GetScheme(),
|
||||
}
|
||||
if err = dashboardManager.SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "DashboardReconciler")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// +kubebuilder:scaffold:builder
|
||||
|
||||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
||||
@@ -263,9 +254,7 @@ func main() {
|
||||
}
|
||||
|
||||
setupLog.Info("starting manager")
|
||||
ctx := ctrl.SetupSignalHandler()
|
||||
dashboardManager.InitializeStaticResources(ctx)
|
||||
if err := mgr.Start(ctx); err != nil {
|
||||
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
|
||||
setupLog.Error(err, "problem running manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
18
docs/changelogs/patch-template.md
Normal file
18
docs/changelogs/patch-template.md
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
<!--
|
||||
https://github.com/cozystack/cozystack/releases/tag/v0..
|
||||
-->
|
||||
|
||||
## Features and Improvements
|
||||
|
||||
## Security
|
||||
|
||||
## Fixes
|
||||
|
||||
## Dependencies
|
||||
|
||||
## Development, Testing, and CI/CD
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: https://github.com/cozystack/cozystack/compare/v0.36.0...main
|
||||
@@ -17,4 +17,4 @@ https://github.com/cozystack/cozystack/releases/tag/v0..
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: **Full Changelog**: https://github.com/cozystack/cozystack/compare/v0.34.0...v0.35.0
|
||||
**Full Changelog**: https://github.com/cozystack/cozystack/compare/v0.34.0...v0.35.0
|
||||
|
||||
10
docs/changelogs/v0.35.3.md
Normal file
10
docs/changelogs/v0.35.3.md
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
<!--
|
||||
https://github.com/cozystack/cozystack/releases/tag/v0.35.3
|
||||
-->
|
||||
|
||||
## Fixes
|
||||
|
||||
* [seaweedfs] Add a liveness check for the SeaweedFS S3 endpoint to improve health monitoring and enable automatic recovery. (@IvanHunters in https://github.com/cozystack/cozystack/pull/1368)
|
||||
|
||||
**Full Changelog**: https://github.com/cozystack/cozystack/compare/v0.35.2...v0.35.3
|
||||
14
docs/changelogs/v0.35.4.md
Normal file
14
docs/changelogs/v0.35.4.md
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
<!--
|
||||
https://github.com/cozystack/cozystack/releases/tag/v0.35.4
|
||||
-->
|
||||
|
||||
## Fixes
|
||||
|
||||
* [virtual-machine] Fix the regression in VM update hook introduced in https://github.com/cozystack/cozystack/pull/1169 by targeting the correct API resource and avoiding conflicts with KubeVirt resources. (@kvaps in https://github.com/cozystack/cozystack/pull/1376, backported in https://github.com/cozystack/cozystack/pull/1377)
|
||||
* [cozy-lib] Add the missing template `cozy-lib.resources.flatten`. (@kvaps in https://github.com/cozystack/cozystack/pull/1372, backported in https://github.com/cozystack/cozystack/pull/1375)
|
||||
* [platform] Fix a boolean override bug in Helm merge. ConfigMap values now correctly take precedence over bundle defaults. (@dyudin0821 in https://github.com/cozystack/cozystack/pull/1385, backported in https://github.com/cozystack/cozystack/pull/1388)
|
||||
* [seaweedfs] Resolve connectivity issues in SeaweedFS. Increase Nginx ingress timeouts for SeaweedFS S3 endpoint. (@kvaps in https://github.com/cozystack/cozystack/pull/1386, backported in https://github.com/cozystack/cozystack/pull/1390)
|
||||
* [dx] Remove the BUILDER and PLATFORM autodetect logic in Makefiles. (@kvaps in https://github.com/cozystack/cozystack/pull/1391, backported in https://github.com/cozystack/cozystack/pull/1392)
|
||||
|
||||
**Full Changelog**: https://github.com/cozystack/cozystack/compare/v0.35.3...v0.35.4
|
||||
11
docs/changelogs/v0.35.5.md
Normal file
11
docs/changelogs/v0.35.5.md
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
<!--
|
||||
https://github.com/cozystack/cozystack/releases/tag/v0.35.5
|
||||
-->
|
||||
|
||||
## Fixes
|
||||
|
||||
* [etcd] Ensure that TopologySpreadConstraints consistently target etcd pods. (@kvaps in https://github.com/cozystack/cozystack/pull/1405, backported in https://github.com/cozystack/cozystack/pull/1406)
|
||||
* [tests] Add resource quota for testing namespaces. (@IvanHunters in https://github.com/cozystack/cozystack/commit/4982cdf5024c8bb9aa794b91d55545ea6b105d17)
|
||||
|
||||
**Full Changelog**: https://github.com/cozystack/cozystack/compare/v0.35.4...v0.35.5
|
||||
117
docs/changelogs/v0.36.0.md
Normal file
117
docs/changelogs/v0.36.0.md
Normal file
@@ -0,0 +1,117 @@
|
||||
|
||||
<!--
|
||||
https://github.com/cozystack/cozystack/releases/tag/v0.36.0
|
||||
-->
|
||||
|
||||
|
||||
## Feature Highlights
|
||||
|
||||
Release v0.36.0 focuses on the stability, observability, and flexible configuration of managed applications.
|
||||
|
||||
### Per-Namespace Resource Limits for Tenants
|
||||
|
||||
Resource management for Cozystack tenants has received a final patch and is now graduated to a stable feature.
|
||||
Platform administrators can define explicit CPU, memory, and storage limits for each tenant's namespace
|
||||
via the tenant specification.
|
||||
This prevents any single tenant from consuming more than their share of cluster resources,
|
||||
ensuring cluster stability and a guaranteed service level for each tenant.
|
||||
|
||||
### Kube-OVN Cluster Health Monitor
|
||||
|
||||
A new component called the Kube-OVN Plunger continuously monitors the health of the Kube-OVN network's central control cluster.
|
||||
This external agent gathers OVN cluster status and consensus information, exposing Prometheus metrics and live events stream via SSE.
|
||||
As a result, it provides much better visibility of the virtual network layer and helps maintain a reliable and observable network in Cozystack.
|
||||
This change opens the road to automated Kube-OVN database operations and recovery in specific corner cases.
|
||||
|
||||
### Configurable CoreDNS Addon for Kubernetes
|
||||
|
||||
Cozystack introduces a dedicated CoreDNS addon for managing cluster DNS with greater flexibility.
|
||||
CoreDNS is now deployed via a Helm chart and can be tuned through custom values in the cluster specification,
|
||||
including autoscaling, replica count, and adjusting service IP.
|
||||
CoreDNS can now be configured in the dashboard and using Cozystack API.
|
||||
|
||||
### Granular SeaweedFS Service Configuration
|
||||
|
||||
The SeaweedFS S3 storage service in Cozystack is now far more configurable at a component level.
|
||||
The Helm chart for SeaweedFS now includes independent configuration for each component and its resources.
|
||||
It includes the master nodes, volume servers with support for multiple zones, filers, the backing database, and the S3 gateway.
|
||||
Administrators can set per-component parameters such as the number of replicas, available CPU, memory, and storage size.
|
||||
|
||||
### Server-side Encryption for S3
|
||||
|
||||
Cozystack v0.36.0 includes SeaweedFS 3.97, bringing support for server-side encryption of S3 buckets (SSE-C, SSE-KMS, and SSE-S3).
|
||||
|
||||
**Breaking change:** upon updating Cozystack, SeaweedFS will be updated to a newer version, and the services specification
|
||||
will be converted to the new format.
|
||||
|
||||
### Custom Resource Profiles for Ingress Controller
|
||||
|
||||
NGINX controller is now configurable on a per-replica basis.
|
||||
Configurations include the ingress controller pods' CPU and memory requests/limits, either with direct values or using one of the available presets.
|
||||
|
||||
### Cozystack REST API Documentation
|
||||
|
||||
[Cozystack REST API reference](https://cozystack.io/docs/cozystack-api/rest/) is now published on the website.
|
||||
It includes endpoints and methods for listing, creating, updating, and removing each managed application, defined as Cozystack CRD.
|
||||
|
||||
|
||||
### Built-in LLDP-Based Neighbor Discovery in Talos
|
||||
|
||||
Cozystack now includes the LLDPD extension in its Talos OS image, enabling Link Layer Discovery Protocol (LLDP) out of the box.
|
||||
This means each node can automatically discover and advertise its network neighbors and topology without any manual setup.
|
||||
|
||||
### Use external IP for Egress Traffic in VMs
|
||||
|
||||
When a virtual machine has an external IP assigned to it, it will now always use it for egress traffic, independently of the external method used.
|
||||
|
||||
## Major Features and Improvements
|
||||
|
||||
* [talos] Add LLDPD (`ghcr.io/siderolabs/lldpd`) as a built-in system extension, enabling LLDP-based neighbor discovery out of the box. (@lllamnyp in https://github.com/cozystack/cozystack/pull/1351 and https://github.com/cozystack/cozystack/pull/1360)
|
||||
* [kubernetes] Add a configurable CoreDNS addon with valuesOverride, packaged chart, and managed deployment (metrics, autoscaling, HPA, customizable Service). (@klinch0 in https://github.com/cozystack/cozystack/pull/1362)
|
||||
* [kube-ovn] Implement the Kube-OVN plunger, an external monitoring agent for the ovn-central cluster. (@lllamnyp in https://github.com/cozystack/cozystack/pull/1380, patched in https://github.com/cozystack/cozystack/pull/1414 and https://github.com/cozystack/cozystack/pull/1418)
|
||||
* [tenant] Enable per-namespace resource quota settings in tenants, with explicit cpu, memory, and storage values. (@IvanHunters in https://github.com/cozystack/cozystack/pull/1389)
|
||||
* [seaweedfs] Add detailed resource configuration for each component of the SeaweedFS service. (@klinch0 and @kvaps in https://github.com/cozystack/cozystack/pull/1415)
|
||||
* [ingress] Enable per-replica resource configuration to the ingress controller. (@kvaps in https://github.com/cozystack/cozystack/pull/1416)
|
||||
* [virtual-machine] Use external IP for egress traffic with `PortList` method. (@kvaps in https://github.com/cozystack/cozystack/pull/1349)
|
||||
|
||||
|
||||
## Fixes
|
||||
|
||||
* [cozy-lib] Fix malformed retrieval of `cozyConfig` in the cozy-lib template. (@lllamnyp in https://github.com/cozystack/cozystack/pull/1348)
|
||||
* [cozy-lib] Add the missing template `cozy-lib.resources.flatten`. (@kvaps in https://github.com/cozystack/cozystack/pull/1372)
|
||||
* [cozystack-api] Sanitize the OpenAPI v2 schema. (@kvaps in https://github.com/cozystack/cozystack/pull/1353)
|
||||
* [kube-ovn] Improve northd leader detection. Patch the northd leader check to test against all endpoints instead of just the first one marked as ready. (@lllamnyp in https://github.com/cozystack/cozystack/pull/1363)
|
||||
* [seaweedfs] Add a liveness check for the SeaweedFS S3 endpoint to improve health monitoring and enable automatic recovery. (@IvanHunters in https://github.com/cozystack/cozystack/pull/1368)
|
||||
* [seaweedfs] Resolve race conditions in SeaweedFS. Increase deployment timeouts and set install/upgrade remediation to unlimited retries to improve deployment resilience. (@IvanHunters in https://github.com/cozystack/cozystack/pull/1371)
|
||||
* [seaweedfs] Resolve connectivity issues in SeaweedFS. Increase Nginx ingress timeouts for SeaweedFS S3 endpoint. (@kvaps in https://github.com/cozystack/cozystack/pull/1386)
|
||||
* [virtual-machine] Fix the reg ression in VM update hook introduced in https://github.com/cozystack/cozystack/pull/1169. Target the correct API resource and avoid conflicts with KubeVirt resources. (@kvaps in https://github.com/cozystack/cozystack/pull/1376)
|
||||
* [virtual-machine] Correct app version references in `virtual-machine` and `vm-instance`, ensuring accurate versioning during migrations. (@kvaps in https://github.com/cozystack/cozystack/pull/1378).
|
||||
* [cozyreport] Fix an error where cozyreport tried to parse non-existent objects and generated garbage output in CI debug logs. (@lllamnyp in https://github.com/cozystack/cozystack/pull/1383)
|
||||
* [platform] Fix a boolean override bug in Helm merge. ConfigMap values now correctly take precedence over bundle defaults. (@dyudin0821 in https://github.com/cozystack/cozystack/pull/1385)
|
||||
* [kubernetes] CoreDNS release now installs and stores state in the `kube-system` namespace. (@kvaps in https://github.com/cozystack/cozystack/pull/1395)
|
||||
* [kubernetes] Expose configuration for CoreDNS, enabling setting the image repository and replica count via `values.yaml`. (@kvaps in https://github.com/cozystack/cozystack/pull/1410)
|
||||
* [etcd] Ensure that TopologySpreadConstraints consistently target etcd pods. (@kvaps in https://github.com/cozystack/cozystack/pull/1405)
|
||||
* [tenant] Use force-upgrade for ingress controller charts. (@klinch0 in https://github.com/cozystack/cozystack/pull/1404)
|
||||
* [cozystack-controller] Fix an RBAC error that prevented the workload labelling feature from working. (@lllamnyp in https://github.com/cozystack/cozystack/pull/1419)
|
||||
* [seaweedfs] Remove VerticalPodAutoscaler for SeaweedFS. (@kvaps in https://github.com/cozystack/cozystack/pull/1421)
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
* Update LINSTOR to v1.31.3. (@kvaps in https://github.com/cozystack/cozystack/pull/1358)
|
||||
* Update SeaweedFS to v3.97. (@kvaps in https://github.com/cozystack/cozystack/pull/1361 and https://github.com/cozystack/cozystack/pull/1373)
|
||||
* Update Kube-OVN to 1.14.5. (@lllamnyp in https://github.com/cozystack/cozystack/pull/1363)
|
||||
* Replace Bitnami images with alternatives in all charts. (@kvaps in https://github.com/cozystack/cozystack/pull/1374)
|
||||
|
||||
## Documentation
|
||||
|
||||
## Development, Testing, and CI/CD
|
||||
|
||||
* [dx] Remove the BUILDER and PLATFORM autodetect logic in Makefiles. (@kvaps in https://github.com/cozystack/cozystack/pull/1391)
|
||||
* [ci] Use the host buildx config in CI. (@kvaps in https://github.com/cozystack/cozystack/pull/1015)
|
||||
* [ci] Add `jq` and `git` to the installer image. (@kvaps in https://github.com/cozystack/cozystack/pull/1417)
|
||||
* [ci] Source the `REGISTRY` environment variable from actions' variables, not secrets, so external pull requests can work. (@lllamnyp in https://github.com/cozystack/cozystack/pull/1423)
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: https://github.com/cozystack/cozystack/compare/v0.35.0...v0.36.0
|
||||
22
docs/changelogs/v0.36.1.md
Normal file
22
docs/changelogs/v0.36.1.md
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
<!--
|
||||
https://github.com/cozystack/cozystack/releases/tag/v0.36.1
|
||||
-->
|
||||
|
||||
## Major Features and Improvements
|
||||
|
||||
* [cozystack-api] Implement recursive, Kubernetes-like defaulting for applications: missing fields in nested objects and arrays are auto-populated safely without mutating shared defaults. (@kvaps in https://github.com/cozystack/cozystack/pull/1432)
|
||||
|
||||
## Fixes
|
||||
|
||||
* [cozystack-api] Update defaulting API schemas. (@kvaps in https://github.com/cozystack/cozystack/pull/1433)
|
||||
* [dashboard] Fix Bitnami dependencies. (@kvaps in https://github.com/cozystack/cozystack/pull/1431)
|
||||
* [seaweedfs] Fix SeaweedFS migration. (@kvaps in https://github.com/cozystack/cozystack/pull/1430)
|
||||
|
||||
## Development, Testing, and CI/CD
|
||||
|
||||
* [adopters] Add [Hidora](https://hikube.cloud) to the Cozystack adopters list. (@matthieu-robin in https://github.com/cozystack/cozystack/pull/1429)
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: https://github.com/cozystack/cozystack/compare/v0.36.0...v0.36.1
|
||||
18
docs/changelogs/v0.36.2.md
Normal file
18
docs/changelogs/v0.36.2.md
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
<!--
|
||||
https://github.com/cozystack/cozystack/releases/tag/v0.36.2
|
||||
-->
|
||||
|
||||
## Features and Improvements
|
||||
|
||||
## Security
|
||||
|
||||
## Fixes
|
||||
|
||||
## Dependencies
|
||||
|
||||
## Development, Testing, and CI/CD
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: [v0.36.1...v0.36.2](https://github.com/cozystack/cozystack/compare/v0.36.1...v0.36.2)
|
||||
117
docs/changelogs/v0.37.0.md
Normal file
117
docs/changelogs/v0.37.0.md
Normal file
@@ -0,0 +1,117 @@
|
||||
# Cozystack v0.37 — “OpenAPI Dashboard & Lineage Everywhere”
|
||||
|
||||
We’ve shipped a big usability push this cycle: a brand-new **OpenAPI-driven dashboard**, lineage labeling across core resource types, and several reliability improvements to smooth upgrades from 0.36→ 0.37. Below are the highlights and the full categorized lists.
|
||||
|
||||
## Highlights
|
||||
|
||||
* **New OpenAPI-based Dashboard** replaces the old UI, adds module-aware navigation, dynamic branding, and richer Kubernetes resource views ([**@kvaps**](https://github.com/kvaps) in #1269, #1463, #1460).
|
||||
* **Lineage Webhook** tags Pods, PVCs, Services, Ingresses, and Secrets, adding labels referencing the managing Cozystack application ([**@lllamnyp**](https://github.com/lllamnyp) in #1448, #1452, #1477, #1486, #1497; [**@kvaps**](https://github.com/kvaps) in #1454).
|
||||
* **Smoother upgrades** with installer and migration hardening, decoupled CRDs vs. API server ([**@lllamnyp**](https://github.com/lllamnyp) in #1494, #1498; [**@kvaps**](https://github.com/kvaps) in #1506).
|
||||
* **Operations quality**: Kubernetes tests with smarter waits/readiness checks ([**@IvanHunters**](https://github.com/IvanHunters) in #1485).
|
||||
|
||||
---
|
||||
|
||||
## New features
|
||||
|
||||
### Dashboard
|
||||
|
||||
* Introduce the OpenAPI-based dashboard and controller; implement TenantNamespace, TenantModules, TenantSecret/SecretsTable resources ([**@kvaps**](https://github.com/kvaps) in #1269).
|
||||
* Module-aware navigation, richer detail views (Services/Secrets/Ingresses), improved sidebars; “Tenant Modules” grouping ([**@kvaps**](https://github.com/kvaps) in #1463).
|
||||
* Dynamic branding via cluster config (tenant name, footer/title, logo/icon SVGs) ([**@kvaps**](https://github.com/kvaps) in #1460).
|
||||
* Dashboard: fix namespace listing for unprivileged users and stabilize streamed requests; build-time patching ([**@kvaps**](https://github.com/kvaps) in #1456).
|
||||
* Dashboard UX set: marketplace hides module resources; consistent navigation/links; prefill “name” in forms; ingress factory; formatted TenantNamespaces tables ([**@kvaps**](https://github.com/kvaps) in #1463).
|
||||
* **Dashboard**: list modules reliably; remove Tenant from Marketplace; fix field override while typing ([**@kvaps**](https://github.com/kvaps) in #1501, #1503).
|
||||
* **Dashboard**: correct API group for applications; sidebars; disable auto-expand; fix `/docs` redirect ([**@kvaps**](https://github.com/kvaps) in #1463, #1465, #1462).
|
||||
* **Dashboard**: show Secrets with empty values correctly ([**@kvaps**](https://github.com/kvaps) in #1480).
|
||||
* Dashboard configuration refactor: generate static resources at startup; auto-cleanup stale objects; higher controller client throughput ([**@kvaps**](https://github.com/kvaps) in #1457).
|
||||
|
||||
### Migration to v0.37
|
||||
* **Installer/Migrations**: prevent unintended deletion of platform resource definitions; resilient timestamping; tolerant annotations; stronger migrate-then-reconcile flow ([**@kvaps**](https://github.com/kvaps) in #1475; Andrei Kvapil & [**@lllamnyp**](https://github.com/lllamnyp) in #1498).
|
||||
* Installer hardening for **migration #20**: packaged apply, ordered waits/readiness checks, RFC3339(nano) stamping; Helm in installer image (Andrei Kvapil & [**@lllamnyp**](https://github.com/lllamnyp) in #1498).
|
||||
* **Decoupled API & CozyRDs**: You can now upgrade the Cozystack API server independently of CRDs/CozyRD instances, easing 0.36 → 0.37 migrations ([**@lllamnyp**](https://github.com/lllamnyp) in #1494).
|
||||
* **Migration #20**: The installer runs migration from packaged Helm charts with ordered waits/readiness checks; annotations are tolerant; timestamps are environment-robust (Andrei Kvapil & [**@lllamnyp**](https://github.com/lllamnyp) in #1498; [**@kvaps**](https://github.com/kvaps) in #1475).
|
||||
|
||||
### Webhook / Lineage
|
||||
|
||||
* Add a lineage mutating webhook to auto-label Pods/Secrets/PVCs/Ingresses/WorkloadMonitors with owning app ([**@lllamnyp**](https://github.com/lllamnyp) in #1448, #1497, [**@kvaps**](https://github.com/kvaps) in #1454).
|
||||
* **Name-based** selectors for Secret visibility (templates supported) ([**@lllamnyp**](https://github.com/lllamnyp) in #1477).
|
||||
* Select **Services** and **Ingresses** in CRDs/API; treat them as user-facing when configured ([**@lllamnyp**](https://github.com/lllamnyp) in #1486).
|
||||
* **VictoriaMetrics integration**: Lineage labels are explicitly set on VM resources; `managedMetadata` is configured to avoid controller “fights” over labels ([**@lllamnyp**](https://github.com/lllamnyp) in #1452).
|
||||
* Webhook **excludes** `default` and `kube-system` to avoid unintended mutations (part of the installer/migration hardening by Andrei Kvapil & [**@lllamnyp**](https://github.com/lllamnyp) in #1498).
|
||||
|
||||
### API / Platform
|
||||
|
||||
* Decouple the Cozystack API from Cozystack Resource Definitions to allow independent upgrades ([**@lllamnyp**](https://github.com/lllamnyp) in #1494).
|
||||
* Add **label selectors** to app definitions for Secret include/exclude ([**@lllamnyp**](https://github.com/lllamnyp) in #1447).
|
||||
|
||||
### Monitoring & Ops
|
||||
|
||||
* Reduce node labelsets in target relabeling configs on cadvisor/kubelet metrics to reduce cardinality while keeping useful CPU metrics ([**@IvanHunters**](https://github.com/IvanHunters) in #1455).
|
||||
|
||||
### Storage & Backups
|
||||
|
||||
* PVC expansion in tenant clusters via KubeVirt CSI resizer; RBAC updates (Klinch0 in #1438).
|
||||
* Velero upgraded to **v1.17.0**; node agent enabled by default and a raft of usability features ([**@kvaps**](https://github.com/kvaps) in #1484).
|
||||
|
||||
### Kubernetes/tests & Tooling
|
||||
|
||||
* Smarter Kubernetes test flows: node readiness checks, kubelet version validation, longer rollout waits, per-component readiness ([**@IvanHunters**](https://github.com/IvanHunters) in #1485).
|
||||
|
||||
### UI/Icons
|
||||
|
||||
* New **VM-Disk** SVG icon ([**@kvapsova**](https://github.com/kvapsova) in #1435).
|
||||
|
||||
---
|
||||
|
||||
## Improvements (minor)
|
||||
|
||||
* Make the **Info** app deploy irrespective of OIDC settings ([**klinch0**](https://github.com/klinch0) in #1474).
|
||||
* Move SA token Secret creation to **Info** app ([**@lllamnyp**](https://github.com/lllamnyp) in #1446).
|
||||
* Explicitly set lineage labels for VictoriaMetrics resources ([**@lllamnyp**](https://github.com/lllamnyp) in #1452).
|
||||
|
||||
---
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* **Kubernetes**: fix MachineDeployment `spec.selector` mismatch to ensure proper targeting ([**@kvaps**](https://github.com/kvaps) in #1502).
|
||||
* **Old dashboard**: FerretDB spec typo prevented deploy/display ([**@lllamnyp**](https://github.com/lllamnyp) in #1440).
|
||||
* **SeaweedFS**: fix per-zone size fallback for multi-DC volumes; make migrations more robust ([**@kvaps**](https://github.com/kvaps) in #1476, #1430).
|
||||
* **CoreDNS**: pin tag to v1.12.4 ([**@kvaps**](https://github.com/kvaps) in #1469).
|
||||
* **OIDC**: avoid creating KeycloakRealmGroup before operator API is available ([**@lllamnyp**](https://github.com/lllamnyp) in #1495).
|
||||
* **Kafka**: disable noisy alerts when Kafka isn’t deployed ([**@lllamnyp**](https://github.com/lllamnyp) in #1488).
|
||||
|
||||
---
|
||||
|
||||
## Dependency & version updates
|
||||
|
||||
* **Velero → v1.17.0**; Helm chart v11; node agent default-on ([**@kvaps**](https://github.com/kvaps) in #1484).
|
||||
* **Cilium → v1.17.8** ([**@kvaps**](https://github.com/kvaps) in #1473).
|
||||
* **Flux Operator → v0.29.0** (Kingdon Barrett in #1466).
|
||||
|
||||
---
|
||||
|
||||
## Refactors & chores
|
||||
|
||||
* Remove legacy `versions_map`; unify packaging targets; tighten HelmRelease defaults; replace many chart versions with build-time placeholders ([**@kvaps**](https://github.com/kvaps) in #1453).
|
||||
* Pin CoreDNS image and refresh numerous images ([**@kvaps**](https://github.com/kvaps) in #1469; related image refreshes across #1448 work).
|
||||
|
||||
---
|
||||
|
||||
## Documentation & governance
|
||||
|
||||
* **Contributor Ladder** created and later updated (Timur Tukaev in #1224; Andrei Kvapil & Timur Tukaev in #1492).
|
||||
* **Code of Conduct** updated with a Vendor Neutrality Manifesto (Timur Tukaev in #1493).
|
||||
* **Adopters**: add Hidora (Matthieu Robin in #1429).
|
||||
* **MAINTAINERS**: add/remove entries (Nikita Bykov in #1487; Timur Tukaev in #1491).
|
||||
* **Issue templates**: new bug-report template and tweaks (Moriarti).
|
||||
* **README**: updated dark-theme screenshot ([**@kvaps**](https://github.com/kvaps) in #1459).
|
||||
|
||||
---
|
||||
|
||||
## Breaking changes & upgrade notes
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Security & stability
|
||||
|
||||
44
hack/e2e-apps/ferretdb.bats
Normal file
44
hack/e2e-apps/ferretdb.bats
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "Create DB FerretDB" {
|
||||
name='test'
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: apps.cozystack.io/v1alpha1
|
||||
kind: FerretDB
|
||||
metadata:
|
||||
name: $name
|
||||
namespace: tenant-test
|
||||
spec:
|
||||
backup:
|
||||
destinationPath: "s3://bucket/path/to/folder/"
|
||||
enabled: false
|
||||
endpointURL: "http://minio-gateway-service:9000"
|
||||
retentionPolicy: "30d"
|
||||
s3AccessKey: "<your-access-key>"
|
||||
s3SecretKey: "<your-secret-key>"
|
||||
schedule: "0 2 * * * *"
|
||||
bootstrap:
|
||||
enabled: false
|
||||
external: false
|
||||
quorum:
|
||||
maxSyncReplicas: 0
|
||||
minSyncReplicas: 0
|
||||
replicas: 2
|
||||
resources: {}
|
||||
resourcesPreset: "micro"
|
||||
size: "10Gi"
|
||||
users:
|
||||
testuser:
|
||||
password: xai7Wepo
|
||||
EOF
|
||||
sleep 5
|
||||
kubectl -n tenant-test wait hr ferretdb-$name --timeout=100s --for=condition=ready
|
||||
timeout 40 sh -ec "until kubectl -n tenant-test get svc ferretdb-$name-postgres-r -o jsonpath='{.spec.ports[0].port}' | grep -q '5432'; do sleep 10; done"
|
||||
timeout 40 sh -ec "until kubectl -n tenant-test get svc ferretdb-$name-postgres-ro -o jsonpath='{.spec.ports[0].port}' | grep -q '5432'; do sleep 10; done"
|
||||
timeout 40 sh -ec "until kubectl -n tenant-test get svc ferretdb-$name-postgres-rw -o jsonpath='{.spec.ports[0].port}' | grep -q '5432'; do sleep 10; done"
|
||||
timeout 120 sh -ec "until kubectl -n tenant-test get endpoints ferretdb-$name-postgres-r -o jsonpath='{.subsets[*].addresses[*].ip}' | grep -q '[0-9]'; do sleep 10; done"
|
||||
# for some reason it takes longer for the read-only endpoint to be ready
|
||||
#timeout 120 sh -ec "until kubectl -n tenant-test get endpoints ferretdb-$name-postgres-ro -o jsonpath='{.subsets[*].addresses[*].ip}' | grep -q '[0-9]'; do sleep 10; done"
|
||||
timeout 120 sh -ec "until kubectl -n tenant-test get endpoints ferretdb-$name-postgres-rw -o jsonpath='{.subsets[*].addresses[*].ip}' | grep -q '[0-9]'; do sleep 10; done"
|
||||
kubectl -n tenant-test delete ferretdb.apps.cozystack.io $name
|
||||
}
|
||||
121
hack/e2e-apps/foundationdb.bats
Normal file
121
hack/e2e-apps/foundationdb.bats
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "Create DB FoundationDB" {
|
||||
name='test'
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: apps.cozystack.io/v1alpha1
|
||||
kind: FoundationDB
|
||||
metadata:
|
||||
name: $name
|
||||
namespace: tenant-test
|
||||
spec:
|
||||
cluster:
|
||||
version: "7.3.63"
|
||||
processCounts:
|
||||
storage: 3
|
||||
stateless: -1
|
||||
cluster_controller: 1
|
||||
redundancyMode: "double"
|
||||
storageEngine: "ssd-2"
|
||||
faultDomain:
|
||||
key: "foundationdb.org/none"
|
||||
valueFrom: "\$FDB_ZONE_ID"
|
||||
storage:
|
||||
size: "1Gi"
|
||||
storageClass: ""
|
||||
resourcesPreset: "small"
|
||||
backup:
|
||||
enabled: false
|
||||
s3:
|
||||
bucket: ""
|
||||
endpoint: ""
|
||||
region: ""
|
||||
credentials:
|
||||
accessKeyId: ""
|
||||
secretAccessKey: ""
|
||||
retentionPolicy: "7d"
|
||||
monitoring:
|
||||
enabled: true
|
||||
customParameters:
|
||||
- "knob_disable_posix_kernel_aio=1"
|
||||
imageType: "unified"
|
||||
automaticReplacements: true
|
||||
EOF
|
||||
sleep 15
|
||||
|
||||
# Wait for HelmRelease to be ready
|
||||
kubectl -n tenant-test wait hr foundationdb-$name --timeout=300s --for=condition=ready
|
||||
|
||||
# Wait for FoundationDBCluster to be created (name has foundationdb- prefix)
|
||||
timeout 300 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name; do sleep 15; done"
|
||||
|
||||
# Wait for cluster to become available (initial reconciliation takes time - allow 5 minutes)
|
||||
timeout 300 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.databaseConfiguration.usable_regions}' | grep -q '1'; do sleep 30; done"
|
||||
|
||||
# Check that storage processes are running
|
||||
timeout 300 sh -ec "until [ \$(kubectl -n tenant-test get pods -l foundationdb.org/fdb-cluster-name=foundationdb-$name,foundationdb.org/fdb-process-class=storage --field-selector=status.phase=Running --no-headers | wc -l) -eq 3 ]; do sleep 15; done"
|
||||
|
||||
# Check that log processes are running (these are the stateless processes)
|
||||
timeout 300 sh -ec "until [ \$(kubectl -n tenant-test get pods -l foundationdb.org/fdb-cluster-name=foundationdb-$name,foundationdb.org/fdb-process-class=log --field-selector=status.phase=Running --no-headers | wc -l) -ge 1 ]; do sleep 15; done"
|
||||
|
||||
# Check that cluster controller is running
|
||||
timeout 300 sh -ec "until [ \$(kubectl -n tenant-test get pods -l foundationdb.org/fdb-cluster-name=foundationdb-$name,foundationdb.org/fdb-process-class=cluster_controller --field-selector=status.phase=Running --no-headers | wc -l) -eq 1 ]; do sleep 15; done"
|
||||
|
||||
# Check WorkloadMonitor is created and configured
|
||||
timeout 120 sh -ec "until kubectl -n tenant-test get workloadmonitor foundationdb-$name; do sleep 10; done"
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get workloadmonitor foundationdb-$name -o jsonpath='{.spec.replicas}' | grep -q '3'; do sleep 5; done"
|
||||
|
||||
# Check dashboard resource map is created
|
||||
kubectl -n tenant-test get configmap foundationdb-$name-resourcemap
|
||||
|
||||
# Verify cluster is healthy (check cluster status) - allow extra time for initial setup
|
||||
timeout 300 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.health.available}' | grep -q 'true'; do sleep 20; done"
|
||||
|
||||
# Validate status.configured field
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.configured}' | grep -q 'true'; do sleep 10; done"
|
||||
|
||||
# Validate status.connectionString field exists and contains expected format
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.connectionString}' | grep -q '@.*\.svc\.cozy\.local'; do sleep 10; done"
|
||||
|
||||
# Validate comprehensive status.databaseConfiguration fields
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.databaseConfiguration.logs}' | grep -q '3'; do sleep 10; done"
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.databaseConfiguration.proxies}' | grep -q '3'; do sleep 10; done"
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.databaseConfiguration.redundancy_mode}' | grep -q 'double'; do sleep 10; done"
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.databaseConfiguration.resolvers}' | grep -q '1'; do sleep 10; done"
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.databaseConfiguration.storage_engine}' | grep -q 'ssd-2'; do sleep 10; done"
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.databaseConfiguration.usable_regions}' | grep -q '1'; do sleep 10; done"
|
||||
|
||||
# Validate status.desiredProcessGroups field
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.desiredProcessGroups}' | grep -q '^[0-9][0-9]*$'; do sleep 10; done"
|
||||
|
||||
# Validate status.generations.reconciled field
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.generations.reconciled}' | grep -q '^[0-9][0-9]*$'; do sleep 10; done"
|
||||
|
||||
# Validate status.hasListenIPsForAllPods field
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.hasListenIPsForAllPods}' | grep -q 'true'; do sleep 10; done"
|
||||
|
||||
# Validate comprehensive status.health fields
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.health.fullReplication}' | grep -q 'true'; do sleep 10; done"
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.status.health.healthy}' | grep -q 'true'; do sleep 10; done"
|
||||
|
||||
# Verify security context is applied correctly (non-root user)
|
||||
storage_pod=$(kubectl -n tenant-test get pods -l foundationdb.org/fdb-cluster-name=foundationdb-$name,foundationdb.org/fdb-process-class=storage --no-headers | head -n1 | awk '{print $1}')
|
||||
kubectl -n tenant-test get pod "$storage_pod" -o jsonpath='{.spec.containers[0].securityContext.runAsUser}' | grep -q '4059'
|
||||
kubectl -n tenant-test get pod "$storage_pod" -o jsonpath='{.spec.containers[0].securityContext.runAsGroup}' | grep -q '4059'
|
||||
|
||||
# Verify volumeClaimTemplate is properly configured in FoundationDBCluster CRD
|
||||
timeout 60 sh -ec "until kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name -o jsonpath='{.spec.processes.general.volumeClaimTemplate.spec.resources.requests.storage}' | grep -q '1Gi'; do sleep 10; done"
|
||||
|
||||
# Verify PVCs are created with correct storage size (1Gi as specified in test)
|
||||
timeout 120 sh -ec "until [ \$(kubectl -n tenant-test get pvc -l foundationdb.org/fdb-cluster-name=foundationdb-$name --no-headers | wc -l) -ge 3 ]; do sleep 10; done"
|
||||
kubectl -n tenant-test get pvc -l foundationdb.org/fdb-cluster-name=foundationdb-$name -o jsonpath='{.items[*].spec.resources.requests.storage}' | grep -q '1Gi'
|
||||
|
||||
# Verify actual PVC storage capacity matches requested size
|
||||
kubectl -n tenant-test get pvc -l foundationdb.org/fdb-cluster-name=foundationdb-$name -o jsonpath='{.items[*].status.capacity.storage}' | grep -q '1Gi'
|
||||
|
||||
# Clean up
|
||||
kubectl -n tenant-test delete foundationdb $name
|
||||
|
||||
# Wait for cleanup to complete
|
||||
timeout 120 sh -ec "while kubectl -n tenant-test get foundationdbclusters.apps.foundationdb.org foundationdb-$name 2>/dev/null; do sleep 10; done"
|
||||
}
|
||||
@@ -87,14 +87,14 @@ EOF
|
||||
|
||||
|
||||
# Set up port forwarding to the Kubernetes API server for a 200 second timeout
|
||||
bash -c 'timeout 300s kubectl port-forward service/kubernetes-'"${test_name}"' -n tenant-test '"${port}"':6443 > /dev/null 2>&1 &'
|
||||
bash -c 'timeout 200s kubectl port-forward service/kubernetes-'"${test_name}"' -n tenant-test '"${port}"':6443 > /dev/null 2>&1 &'
|
||||
# Verify the Kubernetes version matches what we expect (retry for up to 20 seconds)
|
||||
timeout 20 sh -ec 'until kubectl --kubeconfig tenantkubeconfig version 2>/dev/null | grep -Fq "Server Version: ${k8s_version}"; do sleep 5; done'
|
||||
|
||||
# Wait for the nodes to be ready (timeout after 2 minutes)
|
||||
timeout 3m bash -c '
|
||||
timeout 2m bash -c '
|
||||
until [ "$(kubectl --kubeconfig tenantkubeconfig get nodes -o jsonpath="{.items[*].metadata.name}" | wc -w)" -eq 2 ]; do
|
||||
sleep 2
|
||||
sleep 3
|
||||
done
|
||||
'
|
||||
# Verify the nodes are ready
|
||||
|
||||
@@ -118,7 +118,7 @@ EOF
|
||||
}
|
||||
|
||||
@test "Check Cozystack API service" {
|
||||
kubectl wait --for=condition=Available apiservices/v1alpha1.apps.cozystack.io apiservices/v1alpha1.core.cozystack.io --timeout=2m
|
||||
kubectl wait --for=condition=Available apiservices/v1alpha1.apps.cozystack.io --timeout=2m
|
||||
}
|
||||
|
||||
@test "Configure Tenant and wait for applications" {
|
||||
|
||||
@@ -132,6 +132,7 @@ machine:
|
||||
- usermode_helper=disabled
|
||||
- name: zfs
|
||||
- name: spl
|
||||
- name: lldpd
|
||||
registries:
|
||||
mirrors:
|
||||
docker.io:
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
@test "Test OpenAPI v3 endpoint" {
|
||||
kubectl get -v7 --raw '/openapi/v3/apis/apps.cozystack.io/v1alpha1' > /dev/null
|
||||
kubectl get -v7 --raw '/openapi/v3/apis/core.cozystack.io/v1alpha1' > /dev/null
|
||||
}
|
||||
|
||||
@test "Test OpenAPI v2 endpoint (protobuf)" {
|
||||
|
||||
@@ -58,8 +58,8 @@ func (m *Manager) ensureBreadcrumb(ctx context.Context, crd *cozyv1alpha1.Cozyst
|
||||
"breadcrumbItems": items,
|
||||
}
|
||||
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.Client, obj, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.Scheme); err != nil {
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.client, obj, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
// Add dashboard labels to dynamic resources
|
||||
|
||||
@@ -30,6 +30,10 @@ func (m *Manager) ensureCustomColumnsOverride(ctx context.Context, crd *cozyv1al
|
||||
name := fmt.Sprintf("stock-namespace-%s.%s.%s", g, v, plural)
|
||||
id := fmt.Sprintf("stock-namespace-/%s/%s/%s", g, v, plural)
|
||||
|
||||
// Badge content & color derived from kind
|
||||
badgeText := initialsFromKind(kind) // e.g., "VirtualMachine" -> "VM", "Bucket" -> "B"
|
||||
badgeColor := hexColorForKind(kind) // deterministic, dark enough for white text
|
||||
|
||||
obj := &dashv1alpha1.CustomColumnsOverride{}
|
||||
obj.SetName(name)
|
||||
|
||||
@@ -58,11 +62,25 @@ func (m *Manager) ensureCustomColumnsOverride(ctx context.Context, crd *cozyv1al
|
||||
},
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"type": "antdText",
|
||||
"data": map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": kind,
|
||||
// abbreviation auto-generated by ResourceBadge from value
|
||||
"text": badgeText,
|
||||
"title": strings.ToLower(kind), // optional tooltip
|
||||
"style": map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
"borderRadius": "20px",
|
||||
"color": "#fff",
|
||||
"display": "inline-block",
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": "15px",
|
||||
"fontWeight": 400,
|
||||
"lineHeight": "24px",
|
||||
"minWidth": 24,
|
||||
"padding": "0 9px",
|
||||
"textAlign": "center",
|
||||
"whiteSpace": "nowrap",
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]any{
|
||||
@@ -127,8 +145,8 @@ func (m *Manager) ensureCustomColumnsOverride(ctx context.Context, crd *cozyv1al
|
||||
},
|
||||
}
|
||||
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.Client, obj, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.Scheme); err != nil {
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.client, obj, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
// Add dashboard labels to dynamic resources
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
|
||||
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
// ensureCustomFormsOverride creates or updates a CustomFormsOverride resource for the given CRD
|
||||
@@ -46,25 +45,16 @@ func (m *Manager) ensureCustomFormsOverride(ctx context.Context, crd *cozyv1alph
|
||||
}
|
||||
}
|
||||
|
||||
// Build schema with multilineString for string fields without enum
|
||||
l := log.FromContext(ctx)
|
||||
schema, err := buildMultilineStringSchema(crd.Spec.Application.OpenAPISchema)
|
||||
if err != nil {
|
||||
// If schema parsing fails, log the error and use an empty schema
|
||||
l.Error(err, "failed to build multiline string schema, using empty schema", "crd", crd.Name)
|
||||
schema = map[string]any{}
|
||||
}
|
||||
|
||||
spec := map[string]any{
|
||||
"customizationId": customizationID,
|
||||
"hidden": hidden,
|
||||
"sort": sort,
|
||||
"schema": schema,
|
||||
"schema": map[string]any{}, // {}
|
||||
"strategy": "merge",
|
||||
}
|
||||
|
||||
_, err = controllerutil.CreateOrUpdate(ctx, m.Client, obj, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.Scheme); err != nil {
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.client, obj, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
// Add dashboard labels to dynamic resources
|
||||
@@ -83,112 +73,3 @@ func (m *Manager) ensureCustomFormsOverride(ctx context.Context, crd *cozyv1alph
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// buildMultilineStringSchema parses OpenAPI schema and creates schema with multilineString
|
||||
// for all string fields inside spec that don't have enum
|
||||
func buildMultilineStringSchema(openAPISchema string) (map[string]any, error) {
|
||||
if openAPISchema == "" {
|
||||
return map[string]any{}, nil
|
||||
}
|
||||
|
||||
var root map[string]any
|
||||
if err := json.Unmarshal([]byte(openAPISchema), &root); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse openAPISchema: %w", err)
|
||||
}
|
||||
|
||||
props, _ := root["properties"].(map[string]any)
|
||||
if props == nil {
|
||||
return map[string]any{}, nil
|
||||
}
|
||||
|
||||
schema := map[string]any{
|
||||
"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(specProps, specSchema["properties"].(map[string]any))
|
||||
|
||||
return schema, nil
|
||||
}
|
||||
|
||||
// processSpecProperties recursively processes spec properties and adds multilineString type
|
||||
// for string fields without enum
|
||||
func processSpecProperties(props map[string]any, schemaProps map[string]any) {
|
||||
for pname, raw := range props {
|
||||
sub, ok := raw.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
typ, _ := sub["type"].(string)
|
||||
|
||||
switch typ {
|
||||
case "string":
|
||||
// Check if this string field has enum
|
||||
if !hasEnum(sub) {
|
||||
// Add multilineString type for this field
|
||||
if schemaProps[pname] == nil {
|
||||
schemaProps[pname] = map[string]any{}
|
||||
}
|
||||
fieldSchema := schemaProps[pname].(map[string]any)
|
||||
fieldSchema["type"] = "multilineString"
|
||||
}
|
||||
case "object":
|
||||
// Recursively process nested objects
|
||||
if childProps, ok := sub["properties"].(map[string]any); ok {
|
||||
fieldSchema, ok := schemaProps[pname].(map[string]any)
|
||||
if !ok {
|
||||
fieldSchema = map[string]any{}
|
||||
schemaProps[pname] = fieldSchema
|
||||
}
|
||||
nestedSchemaProps, ok := fieldSchema["properties"].(map[string]any)
|
||||
if !ok {
|
||||
nestedSchemaProps = map[string]any{}
|
||||
fieldSchema["properties"] = nestedSchemaProps
|
||||
}
|
||||
processSpecProperties(childProps, nestedSchemaProps)
|
||||
}
|
||||
case "array":
|
||||
// Check if array items are objects with properties
|
||||
if items, ok := sub["items"].(map[string]any); ok {
|
||||
if itemProps, ok := items["properties"].(map[string]any); ok {
|
||||
// Create array item schema
|
||||
fieldSchema, ok := schemaProps[pname].(map[string]any)
|
||||
if !ok {
|
||||
fieldSchema = map[string]any{}
|
||||
schemaProps[pname] = fieldSchema
|
||||
}
|
||||
itemSchema, ok := fieldSchema["items"].(map[string]any)
|
||||
if !ok {
|
||||
itemSchema = map[string]any{}
|
||||
fieldSchema["items"] = itemSchema
|
||||
}
|
||||
itemSchemaProps, ok := itemSchema["properties"].(map[string]any)
|
||||
if !ok {
|
||||
itemSchemaProps = map[string]any{}
|
||||
itemSchema["properties"] = itemSchemaProps
|
||||
}
|
||||
processSpecProperties(itemProps, itemSchemaProps)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBuildMultilineStringSchema(t *testing.T) {
|
||||
// Test OpenAPI schema with various field types
|
||||
openAPISchema := `{
|
||||
"properties": {
|
||||
"spec": {
|
||||
"type": "object",
|
||||
"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": {
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
schema, err := buildMultilineStringSchema(openAPISchema)
|
||||
if err != nil {
|
||||
t.Fatalf("buildMultilineStringSchema failed: %v", err)
|
||||
}
|
||||
|
||||
// Marshal to JSON for easier inspection
|
||||
schemaJSON, err := json.MarshalIndent(schema, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to marshal schema: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("Generated schema:\n%s", schemaJSON)
|
||||
|
||||
// Verify that simpleString has multilineString type
|
||||
props, ok := schema["properties"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatal("schema.properties is not a map")
|
||||
}
|
||||
|
||||
// Check spec property exists
|
||||
spec, ok := props["spec"].(map[string]any)
|
||||
if !ok {
|
||||
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 := 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 := specProps["numberField"].(map[string]any); ok {
|
||||
if numberField["type"] != nil {
|
||||
t.Error("numberField should not have any type override")
|
||||
}
|
||||
}
|
||||
|
||||
// Check nested object
|
||||
nestedObject, ok := specProps["nestedObject"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatal("nestedObject not found in spec.properties")
|
||||
}
|
||||
nestedProps, ok := nestedObject["properties"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatal("nestedObject.properties is not a map")
|
||||
}
|
||||
|
||||
// Check nestedString
|
||||
nestedString, ok := nestedProps["nestedString"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatal("nestedString not found in nestedObject.properties")
|
||||
}
|
||||
if nestedString["type"] != "multilineString" {
|
||||
t.Errorf("nestedString should have type multilineString, got %v", nestedString["type"])
|
||||
}
|
||||
|
||||
// Check array of objects
|
||||
arrayOfObjects, ok := specProps["arrayOfObjects"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatal("arrayOfObjects not found in spec.properties")
|
||||
}
|
||||
items, ok := arrayOfObjects["items"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatal("arrayOfObjects.items is not a map")
|
||||
}
|
||||
itemProps, ok := items["properties"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatal("arrayOfObjects.items.properties is not a map")
|
||||
}
|
||||
itemString, ok := itemProps["itemString"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatal("itemString not found in arrayOfObjects.items.properties")
|
||||
}
|
||||
if itemString["type"] != "multilineString" {
|
||||
t.Errorf("itemString should have type multilineString, got %v", itemString["type"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildMultilineStringSchemaEmpty(t *testing.T) {
|
||||
schema, err := buildMultilineStringSchema("")
|
||||
if err != nil {
|
||||
t.Fatalf("buildMultilineStringSchema failed on empty string: %v", err)
|
||||
}
|
||||
if len(schema) != 0 {
|
||||
t.Errorf("Expected empty schema for empty input, got %v", schema)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildMultilineStringSchemaInvalidJSON(t *testing.T) {
|
||||
schema, err := buildMultilineStringSchema("{invalid json")
|
||||
if err == nil {
|
||||
t.Error("Expected error for invalid JSON")
|
||||
}
|
||||
if schema != nil {
|
||||
t.Errorf("Expected nil schema for invalid JSON, got %v", schema)
|
||||
}
|
||||
}
|
||||
@@ -56,8 +56,8 @@ func (m *Manager) ensureCustomFormsPrefill(ctx context.Context, crd *cozyv1alpha
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
_, err = controllerutil.CreateOrUpdate(ctx, m.Client, cfp, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, cfp, m.Scheme); err != nil {
|
||||
_, err = controllerutil.CreateOrUpdate(ctx, m.client, cfp, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, cfp, m.scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
// Add dashboard labels to dynamic resources
|
||||
|
||||
@@ -53,6 +53,7 @@ func (m *Manager) ensureFactory(ctx context.Context, crd *cozyv1alpha1.Cozystack
|
||||
Kind: kind,
|
||||
Plural: plural,
|
||||
Title: strings.ToLower(plural),
|
||||
Size: BadgeSizeLarge,
|
||||
}
|
||||
|
||||
spec := createUnifiedFactory(config, tabs, []any{resourceFetch})
|
||||
@@ -60,8 +61,8 @@ func (m *Manager) ensureFactory(ctx context.Context, crd *cozyv1alpha1.Cozystack
|
||||
obj := &dashv1alpha1.Factory{}
|
||||
obj.SetName(factoryName)
|
||||
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.Client, obj, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.Scheme); err != nil {
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.client, obj, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
// Add dashboard labels to dynamic resources
|
||||
@@ -114,7 +115,7 @@ func detailsTab(kind, endpoint, schemaJSON string, keysOrder [][]string) map[str
|
||||
"gap": float64(6),
|
||||
},
|
||||
"children": []any{
|
||||
createUnifiedBadgeFromKind("ns-badge", "Namespace"),
|
||||
createUnifiedBadgeFromKind("ns-badge", "Namespace", "namespace", BadgeSizeMedium),
|
||||
antdLink("namespace-link",
|
||||
"{reqsJsonPath[0]['.metadata.namespace']['-']}",
|
||||
"/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace",
|
||||
@@ -221,7 +222,7 @@ func workloadsTab(kind string) map[string]any {
|
||||
"baseprefix": "/openapi-ui",
|
||||
"customizationId": "factory-details-v1alpha1.cozystack.io.workloadmonitors",
|
||||
"pathToItems": []any{"items"},
|
||||
"labelSelector": map[string]any{
|
||||
"labelsSelector": map[string]any{
|
||||
"apps.cozystack.io/application.group": "apps.cozystack.io",
|
||||
"apps.cozystack.io/application.kind": kind,
|
||||
"apps.cozystack.io/application.name": "{reqs[0]['metadata','name']}",
|
||||
@@ -246,7 +247,7 @@ func servicesTab(kind string) map[string]any {
|
||||
"baseprefix": "/openapi-ui",
|
||||
"customizationId": "factory-details-v1.services",
|
||||
"pathToItems": []any{"items"},
|
||||
"labelSelector": map[string]any{
|
||||
"labelsSelector": map[string]any{
|
||||
"apps.cozystack.io/application.group": "apps.cozystack.io",
|
||||
"apps.cozystack.io/application.kind": kind,
|
||||
"apps.cozystack.io/application.name": "{reqs[0]['metadata','name']}",
|
||||
@@ -272,7 +273,7 @@ func ingressesTab(kind string) map[string]any {
|
||||
"baseprefix": "/openapi-ui",
|
||||
"customizationId": "factory-details-networking.k8s.io.v1.ingresses",
|
||||
"pathToItems": []any{"items"},
|
||||
"labelSelector": map[string]any{
|
||||
"labelsSelector": map[string]any{
|
||||
"apps.cozystack.io/application.group": "apps.cozystack.io",
|
||||
"apps.cozystack.io/application.kind": kind,
|
||||
"apps.cozystack.io/application.name": "{reqs[0]['metadata','name']}",
|
||||
@@ -293,12 +294,12 @@ func secretsTab(kind string) map[string]any {
|
||||
"type": "EnrichedTable",
|
||||
"data": map[string]any{
|
||||
"id": "secrets-table",
|
||||
"fetchUrl": "/api/clusters/{2}/k8s/apis/core.cozystack.io/v1alpha1/namespaces/{3}/tenantsecrets",
|
||||
"fetchUrl": "/api/clusters/{2}/k8s/apis/core.cozystack.io/v1alpha1/namespaces/{3}/tenantsecretstables",
|
||||
"clusterNamePartOfUrl": "{2}",
|
||||
"baseprefix": "/openapi-ui",
|
||||
"customizationId": "factory-details-v1alpha1.core.cozystack.io.tenantsecrets",
|
||||
"customizationId": "factory-details-v1alpha1.core.cozystack.io.tenantsecretstables",
|
||||
"pathToItems": []any{"items"},
|
||||
"labelSelector": map[string]any{
|
||||
"labelsSelector": map[string]any{
|
||||
"apps.cozystack.io/application.group": "apps.cozystack.io",
|
||||
"apps.cozystack.io/application.kind": kind,
|
||||
"apps.cozystack.io/application.name": "{reqs[0]['metadata','name']}",
|
||||
@@ -323,7 +324,6 @@ func yamlTab(plural string) map[string]any {
|
||||
"type": "builtin",
|
||||
"typeName": plural,
|
||||
"prefillValuesRequestIndex": float64(0),
|
||||
"readOnly": true,
|
||||
"substractHeight": float64(400),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -54,6 +57,97 @@ func pickPlural(kind string, crd *cozyv1alpha1.CozystackResourceDefinition) stri
|
||||
return k + "s"
|
||||
}
|
||||
|
||||
// initialsFromKind splits CamelCase and returns the first letters in upper case.
|
||||
// "VirtualMachine" -> "VM"; "Bucket" -> "B".
|
||||
func initialsFromKind(kind string) string {
|
||||
parts := splitCamel(kind)
|
||||
if len(parts) == 0 {
|
||||
return strings.ToUpper(kind)
|
||||
}
|
||||
var b strings.Builder
|
||||
for _, p := range parts {
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
b.WriteString(strings.ToUpper(string(p[0])))
|
||||
// Limit to 3 chars to keep the badge compact (VM, PVC, etc.)
|
||||
if b.Len() >= 3 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// hexColorForKind returns a dark, saturated color (hex) derived from a stable hash of the kind.
|
||||
// We map the hash to an HSL hue; fix S/L for consistent readability with white text.
|
||||
func hexColorForKind(kind string) string {
|
||||
// Stable short hash (sha1 → bytes → hue)
|
||||
sum := sha1.Sum([]byte(kind))
|
||||
// Use first two bytes for hue [0..359]
|
||||
hue := int(sum[0])<<8 | int(sum[1])
|
||||
hue = hue % 360
|
||||
|
||||
// Fixed S/L chosen to contrast with white text:
|
||||
// S = 80%, L = 35% (dark enough so #fff is readable)
|
||||
r, g, b := hslToRGB(float64(hue), 0.80, 0.35)
|
||||
|
||||
return fmt.Sprintf("#%02x%02x%02x", r, g, b)
|
||||
}
|
||||
|
||||
// hslToRGB converts HSL (0..360, 0..1, 0..1) to sRGB (0..255).
|
||||
func hslToRGB(h float64, s float64, l float64) (uint8, uint8, uint8) {
|
||||
c := (1 - absFloat(2*l-1)) * s
|
||||
hp := h / 60.0
|
||||
x := c * (1 - absFloat(modFloat(hp, 2)-1))
|
||||
var r1, g1, b1 float64
|
||||
switch {
|
||||
case 0 <= hp && hp < 1:
|
||||
r1, g1, b1 = c, x, 0
|
||||
case 1 <= hp && hp < 2:
|
||||
r1, g1, b1 = x, c, 0
|
||||
case 2 <= hp && hp < 3:
|
||||
r1, g1, b1 = 0, c, x
|
||||
case 3 <= hp && hp < 4:
|
||||
r1, g1, b1 = 0, x, c
|
||||
case 4 <= hp && hp < 5:
|
||||
r1, g1, b1 = x, 0, c
|
||||
default:
|
||||
r1, g1, b1 = c, 0, x
|
||||
}
|
||||
m := l - c/2
|
||||
r := uint8(clamp01(r1+m) * 255.0)
|
||||
g := uint8(clamp01(g1+m) * 255.0)
|
||||
b := uint8(clamp01(b1+m) * 255.0)
|
||||
return r, g, b
|
||||
}
|
||||
|
||||
func absFloat(v float64) float64 {
|
||||
if v < 0 {
|
||||
return -v
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func modFloat(a, b float64) float64 {
|
||||
return a - b*float64(int(a/b))
|
||||
}
|
||||
|
||||
func clamp01(v float64) float64 {
|
||||
if v < 0 {
|
||||
return 0
|
||||
}
|
||||
if v > 1 {
|
||||
return 1
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// optional: tiny helper to expose the compact color hash (useful for debugging)
|
||||
func shortHashHex(s string) string {
|
||||
sum := sha1.Sum([]byte(s))
|
||||
return hex.EncodeToString(sum[:4])
|
||||
}
|
||||
|
||||
// ----------------------- Helpers (OpenAPI → values) -----------------------
|
||||
|
||||
// defaultOrZero returns the schema default if present; otherwise a reasonable zero value.
|
||||
@@ -201,6 +295,12 @@ func normalizeJSON(v any) any {
|
||||
}
|
||||
}
|
||||
|
||||
var camelSplitter = regexp.MustCompile(`(?m)([A-Z]+[a-z0-9]*|[a-z0-9]+)`)
|
||||
|
||||
func splitCamel(s string) []string {
|
||||
return camelSplitter.FindAllString(s, -1)
|
||||
}
|
||||
|
||||
// --- helpers for schema inspection ---
|
||||
|
||||
func isScalarType(n map[string]any) bool {
|
||||
|
||||
@@ -10,12 +10,9 @@ import (
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
managerpkg "sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
)
|
||||
|
||||
@@ -43,51 +40,28 @@ func AddToScheme(s *runtime.Scheme) error {
|
||||
// Manager owns logic for creating/updating dashboard resources derived from CRDs.
|
||||
// It’s easy to extend: add new ensure* methods and wire them into EnsureForCRD.
|
||||
type Manager struct {
|
||||
client.Client
|
||||
Scheme *runtime.Scheme
|
||||
client client.Client
|
||||
scheme *runtime.Scheme
|
||||
crdListFn func(context.Context) ([]cozyv1alpha1.CozystackResourceDefinition, error)
|
||||
}
|
||||
|
||||
// Option pattern so callers can inject a custom lister.
|
||||
type Option func(*Manager)
|
||||
|
||||
// WithCRDListFunc overrides how Manager lists all CozystackResourceDefinitions.
|
||||
func WithCRDListFunc(fn func(context.Context) ([]cozyv1alpha1.CozystackResourceDefinition, error)) Option {
|
||||
return func(m *Manager) { m.crdListFn = fn }
|
||||
}
|
||||
|
||||
// NewManager constructs a dashboard Manager.
|
||||
func NewManager(c client.Client, scheme *runtime.Scheme) *Manager {
|
||||
m := &Manager{Client: c, Scheme: scheme}
|
||||
func NewManager(c client.Client, scheme *runtime.Scheme, opts ...Option) *Manager {
|
||||
m := &Manager{client: c, scheme: scheme}
|
||||
for _, o := range opts {
|
||||
o(m)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Manager) SetupWithManager(mgr ctrl.Manager) error {
|
||||
if err := ctrl.NewControllerManagedBy(mgr).
|
||||
Named("dashboard-reconciler").
|
||||
For(&cozyv1alpha1.CozystackResourceDefinition{}).
|
||||
Complete(m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mgr.Add(managerpkg.RunnableFunc(func(ctx context.Context) error {
|
||||
if !mgr.GetCache().WaitForCacheSync(ctx) {
|
||||
return fmt.Errorf("dashboard static resources cache sync failed")
|
||||
}
|
||||
return m.ensureStaticResources(ctx)
|
||||
}))
|
||||
}
|
||||
|
||||
func (m *Manager) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
l := log.FromContext(ctx)
|
||||
|
||||
crd := &cozyv1alpha1.CozystackResourceDefinition{}
|
||||
|
||||
err := m.Get(ctx, types.NamespacedName{Name: req.Name}, crd)
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
if err := m.CleanupOrphanedResources(ctx); err != nil {
|
||||
l.Error(err, "Failed to cleanup orphaned dashboard resources")
|
||||
}
|
||||
return ctrl.Result{}, nil // no point in requeuing here
|
||||
}
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
return m.EnsureForCRD(ctx, crd)
|
||||
}
|
||||
|
||||
// EnsureForCRD is the single entry-point used by the controller.
|
||||
// Add more ensure* calls here as you implement support for other resources:
|
||||
//
|
||||
@@ -197,11 +171,21 @@ func (m *Manager) getStaticResourceSelector() client.MatchingLabels {
|
||||
// CleanupOrphanedResources removes dashboard resources that are no longer needed
|
||||
// This should be called after cache warming to ensure all current resources are known
|
||||
func (m *Manager) CleanupOrphanedResources(ctx context.Context) error {
|
||||
var crdList cozyv1alpha1.CozystackResourceDefinitionList
|
||||
if err := m.List(ctx, &crdList, &client.ListOptions{}); err != nil {
|
||||
return err
|
||||
// Get all current CRDs to determine which resources should exist
|
||||
var allCRDs []cozyv1alpha1.CozystackResourceDefinition
|
||||
if m.crdListFn != nil {
|
||||
s, err := m.crdListFn(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
allCRDs = s
|
||||
} else {
|
||||
var crdList cozyv1alpha1.CozystackResourceDefinitionList
|
||||
if err := m.client.List(ctx, &crdList, &client.ListOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
allCRDs = crdList.Items
|
||||
}
|
||||
allCRDs := crdList.Items
|
||||
|
||||
// Build a set of expected resource names for each type
|
||||
expectedResources := m.buildExpectedResourceSet(allCRDs)
|
||||
@@ -365,7 +349,7 @@ func (m *Manager) cleanupResourceType(ctx context.Context, resourceType client.O
|
||||
}
|
||||
|
||||
// List with dashboard labels
|
||||
if err := m.List(ctx, list, m.getDashboardResourceSelector()); err != nil {
|
||||
if err := m.client.List(ctx, list, m.getDashboardResourceSelector()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -374,7 +358,7 @@ func (m *Manager) cleanupResourceType(ctx context.Context, resourceType client.O
|
||||
case *dashv1alpha1.CustomColumnsOverrideList:
|
||||
for _, item := range l.Items {
|
||||
if !expected[item.Name] {
|
||||
if err := m.Delete(ctx, &item); err != nil {
|
||||
if err := m.client.Delete(ctx, &item); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
@@ -385,7 +369,7 @@ func (m *Manager) cleanupResourceType(ctx context.Context, resourceType client.O
|
||||
case *dashv1alpha1.CustomFormsOverrideList:
|
||||
for _, item := range l.Items {
|
||||
if !expected[item.Name] {
|
||||
if err := m.Delete(ctx, &item); err != nil {
|
||||
if err := m.client.Delete(ctx, &item); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
@@ -396,7 +380,7 @@ func (m *Manager) cleanupResourceType(ctx context.Context, resourceType client.O
|
||||
case *dashv1alpha1.CustomFormsPrefillList:
|
||||
for _, item := range l.Items {
|
||||
if !expected[item.Name] {
|
||||
if err := m.Delete(ctx, &item); err != nil {
|
||||
if err := m.client.Delete(ctx, &item); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
@@ -407,7 +391,7 @@ func (m *Manager) cleanupResourceType(ctx context.Context, resourceType client.O
|
||||
case *dashv1alpha1.MarketplacePanelList:
|
||||
for _, item := range l.Items {
|
||||
if !expected[item.Name] {
|
||||
if err := m.Delete(ctx, &item); err != nil {
|
||||
if err := m.client.Delete(ctx, &item); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
@@ -418,7 +402,7 @@ func (m *Manager) cleanupResourceType(ctx context.Context, resourceType client.O
|
||||
case *dashv1alpha1.SidebarList:
|
||||
for _, item := range l.Items {
|
||||
if !expected[item.Name] {
|
||||
if err := m.Delete(ctx, &item); err != nil {
|
||||
if err := m.client.Delete(ctx, &item); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
@@ -429,7 +413,7 @@ func (m *Manager) cleanupResourceType(ctx context.Context, resourceType client.O
|
||||
case *dashv1alpha1.TableUriMappingList:
|
||||
for _, item := range l.Items {
|
||||
if !expected[item.Name] {
|
||||
if err := m.Delete(ctx, &item); err != nil {
|
||||
if err := m.client.Delete(ctx, &item); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
@@ -442,7 +426,7 @@ func (m *Manager) cleanupResourceType(ctx context.Context, resourceType client.O
|
||||
if !expected[item.Name] {
|
||||
logger := log.FromContext(ctx)
|
||||
logger.Info("Deleting orphaned Breadcrumb resource", "name", item.Name)
|
||||
if err := m.Delete(ctx, &item); err != nil {
|
||||
if err := m.client.Delete(ctx, &item); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
@@ -454,7 +438,7 @@ func (m *Manager) cleanupResourceType(ctx context.Context, resourceType client.O
|
||||
if !expected[item.Name] {
|
||||
logger := log.FromContext(ctx)
|
||||
logger.Info("Deleting orphaned Factory resource", "name", item.Name)
|
||||
if err := m.Delete(ctx, &item); err != nil {
|
||||
if err := m.client.Delete(ctx, &item); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ func (m *Manager) ensureMarketplacePanel(ctx context.Context, crd *cozyv1alpha1.
|
||||
|
||||
// If dashboard is not set, delete the panel if it exists.
|
||||
if crd.Spec.Dashboard == nil {
|
||||
err := m.Get(ctx, client.ObjectKey{Name: mp.Name}, mp)
|
||||
err := m.client.Get(ctx, client.ObjectKey{Name: mp.Name}, mp)
|
||||
if apierrors.IsNotFound(err) {
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
if err := m.Delete(ctx, mp); err != nil && !apierrors.IsNotFound(err) {
|
||||
if err := m.client.Delete(ctx, mp); err != nil && !apierrors.IsNotFound(err) {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
logger.Info("Deleted MarketplacePanel because dashboard is not set", "name", mp.Name)
|
||||
@@ -40,14 +40,14 @@ func (m *Manager) ensureMarketplacePanel(ctx context.Context, crd *cozyv1alpha1.
|
||||
|
||||
// Skip module and tenant resources (they don't need MarketplacePanel)
|
||||
if crd.Spec.Dashboard.Module || crd.Spec.Application.Kind == "Tenant" {
|
||||
err := m.Get(ctx, client.ObjectKey{Name: mp.Name}, mp)
|
||||
err := m.client.Get(ctx, client.ObjectKey{Name: mp.Name}, mp)
|
||||
if apierrors.IsNotFound(err) {
|
||||
return reconcile.Result{}, nil
|
||||
}
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
if err := m.Delete(ctx, mp); err != nil && !apierrors.IsNotFound(err) {
|
||||
if err := m.client.Delete(ctx, mp); err != nil && !apierrors.IsNotFound(err) {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
logger.Info("Deleted MarketplacePanel because resource is a module", "name", mp.Name)
|
||||
@@ -86,8 +86,8 @@ func (m *Manager) ensureMarketplacePanel(ctx context.Context, crd *cozyv1alpha1.
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
_, err = controllerutil.CreateOrUpdate(ctx, m.Client, mp, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, mp, m.Scheme); err != nil {
|
||||
_, err = controllerutil.CreateOrUpdate(ctx, m.client, mp, func() error {
|
||||
if err := controllerutil.SetOwnerReference(crd, mp, m.scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
// Add dashboard labels to dynamic resources
|
||||
|
||||
@@ -33,11 +33,19 @@ func (m *Manager) ensureSidebar(ctx context.Context, crd *cozyv1alpha1.Cozystack
|
||||
|
||||
// 1) Fetch all CRDs
|
||||
var all []cozyv1alpha1.CozystackResourceDefinition
|
||||
var crdList cozyv1alpha1.CozystackResourceDefinitionList
|
||||
if err := m.List(ctx, &crdList, &client.ListOptions{}); err != nil {
|
||||
return err
|
||||
if m.crdListFn != nil {
|
||||
s, err := m.crdListFn(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
all = s
|
||||
} else {
|
||||
var crdList cozyv1alpha1.CozystackResourceDefinitionList
|
||||
if err := m.client.List(ctx, &crdList, &client.ListOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
all = crdList.Items
|
||||
}
|
||||
all = crdList.Items
|
||||
|
||||
// 2) Build category -> []item map (only for CRDs with spec.dashboard != nil)
|
||||
type item struct {
|
||||
@@ -243,7 +251,7 @@ func (m *Manager) upsertMultipleSidebars(
|
||||
obj := &dashv1alpha1.Sidebar{}
|
||||
obj.SetName(id)
|
||||
|
||||
if _, err := controllerutil.CreateOrUpdate(ctx, m.Client, obj, func() error {
|
||||
if _, err := controllerutil.CreateOrUpdate(ctx, m.client, obj, func() error {
|
||||
// Only set owner reference for dynamic sidebars (stock-project-factory-{kind}-details)
|
||||
// Static sidebars (stock-instance-*, stock-project-*) should not have owner references
|
||||
if strings.HasPrefix(id, "stock-project-factory-") && strings.HasSuffix(id, "-details") {
|
||||
@@ -252,7 +260,7 @@ func (m *Manager) upsertMultipleSidebars(
|
||||
lowerKind := strings.ToLower(kind)
|
||||
expectedID := fmt.Sprintf("stock-project-factory-%s-details", lowerKind)
|
||||
if id == expectedID {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.Scheme); err != nil {
|
||||
if err := controllerutil.SetOwnerReference(crd, obj, m.scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
// Add dashboard labels to dynamic resources
|
||||
|
||||
@@ -122,7 +122,7 @@ func createCustomColumnsOverride(id string, additionalPrinterColumns []any) *das
|
||||
}
|
||||
}
|
||||
|
||||
if name == "factory-details-v1alpha1.core.cozystack.io.tenantsecrets" {
|
||||
if name == "factory-details-v1alpha1.core.cozystack.io.tenantsecretstables" {
|
||||
data["additionalPrinterColumnsTrimLengths"] = []any{
|
||||
map[string]any{
|
||||
"key": "Name",
|
||||
@@ -531,6 +531,7 @@ func createBreadcrumbItem(key, label string, link ...string) map[string]any {
|
||||
|
||||
// createCustomColumn creates a custom column with factory type and badge
|
||||
func createCustomColumn(name, kind, plural, href string) map[string]any {
|
||||
badge := createUnifiedBadgeFromKind("header-badge", kind, plural, BadgeSizeMedium)
|
||||
link := antdLink("name-link", "{reqsJsonPath[0]['.metadata.name']['-']}", href)
|
||||
|
||||
return map[string]any{
|
||||
@@ -540,18 +541,8 @@ func createCustomColumn(name, kind, plural, href string) map[string]any {
|
||||
"disableEventBubbling": true,
|
||||
"items": []any{
|
||||
map[string]any{
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": kind,
|
||||
// abbreviation auto-generated by ResourceBadge from value
|
||||
},
|
||||
},
|
||||
link,
|
||||
},
|
||||
"type": "antdFlex",
|
||||
"children": []any{badge, link},
|
||||
"type": "antdFlex",
|
||||
"data": map[string]any{
|
||||
"align": "center",
|
||||
"gap": float64(6),
|
||||
@@ -563,15 +554,15 @@ func createCustomColumn(name, kind, plural, href string) map[string]any {
|
||||
}
|
||||
|
||||
// createCustomColumnWithBadge creates a custom column with a specific badge
|
||||
// badgeValue should be the kind in PascalCase (e.g., "Service", "Pod")
|
||||
// abbreviation is auto-generated by ResourceBadge from badgeValue
|
||||
func createCustomColumnWithBadge(name, badgeValue, href string) map[string]any {
|
||||
link := antdLink("name-link", "{reqsJsonPath[0]['.metadata.name']['-']}", href)
|
||||
|
||||
badgeData := map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": badgeValue,
|
||||
func createCustomColumnWithBadge(name, badgeText, badgeColor, title, href string) map[string]any {
|
||||
config := BadgeConfig{
|
||||
Text: badgeText,
|
||||
Color: badgeColor,
|
||||
Title: title,
|
||||
Size: BadgeSizeMedium,
|
||||
}
|
||||
badge := createUnifiedBadge("header-badge", config)
|
||||
link := antdLink("name-link", "{reqsJsonPath[0]['.metadata.name']['-']}", href)
|
||||
|
||||
return map[string]any{
|
||||
"name": name,
|
||||
@@ -580,14 +571,8 @@ func createCustomColumnWithBadge(name, badgeValue, href string) map[string]any {
|
||||
"disableEventBubbling": true,
|
||||
"items": []any{
|
||||
map[string]any{
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": badgeData,
|
||||
},
|
||||
link,
|
||||
},
|
||||
"type": "antdFlex",
|
||||
"children": []any{badge, link},
|
||||
"type": "antdFlex",
|
||||
"data": map[string]any{
|
||||
"align": "center",
|
||||
"gap": float64(6),
|
||||
@@ -598,22 +583,17 @@ func createCustomColumnWithBadge(name, badgeValue, href string) map[string]any {
|
||||
}
|
||||
}
|
||||
|
||||
// createCustomColumnWithSpecificColor creates a custom column with a specific kind and optional color
|
||||
// badgeValue should be the kind in PascalCase (e.g., "Service", "Pod")
|
||||
func createCustomColumnWithSpecificColor(name, kind, color, href string) map[string]any {
|
||||
// createCustomColumnWithSpecificColor creates a custom column with a specific color
|
||||
func createCustomColumnWithSpecificColor(name, kind, title, color, href string) map[string]any {
|
||||
config := BadgeConfig{
|
||||
Text: initialsFromKind(kind),
|
||||
Color: color,
|
||||
Title: title,
|
||||
Size: BadgeSizeMedium,
|
||||
}
|
||||
badge := createUnifiedBadge("header-badge", config)
|
||||
link := antdLink("name-link", "{reqsJsonPath[0]['.metadata.name']['-']}", href)
|
||||
|
||||
badgeData := map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": kind,
|
||||
}
|
||||
// Add custom color if specified
|
||||
if color != "" {
|
||||
badgeData["style"] = map[string]any{
|
||||
"backgroundColor": color,
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"name": name,
|
||||
"type": "factory",
|
||||
@@ -622,14 +602,8 @@ func createCustomColumnWithSpecificColor(name, kind, color, href string) map[str
|
||||
"disableEventBubbling": true,
|
||||
"items": []any{
|
||||
map[string]any{
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": badgeData,
|
||||
},
|
||||
link,
|
||||
},
|
||||
"type": "antdFlex",
|
||||
"children": []any{badge, link},
|
||||
"type": "antdFlex",
|
||||
"data": map[string]any{
|
||||
"align": "center",
|
||||
"gap": float64(6),
|
||||
@@ -694,7 +668,7 @@ func createTimestampColumn(name, jsonPath string) map[string]any {
|
||||
// createFactoryHeader creates a header for factory resources
|
||||
func createFactoryHeader(kind, plural string) map[string]any {
|
||||
lowerKind := strings.ToLower(kind)
|
||||
badge := createUnifiedBadgeFromKind("badge-"+lowerKind, kind)
|
||||
badge := createUnifiedBadgeFromKind("badge-"+lowerKind, kind, plural, BadgeSizeLarge)
|
||||
nameText := parsedText(lowerKind+"-name", "{reqsJsonPath[0]['.metadata.name']['-']}", map[string]any{
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": float64(20),
|
||||
@@ -744,26 +718,13 @@ func createFactorySpec(key string, sidebarTags []any, urlsToFetch []any, header
|
||||
}
|
||||
|
||||
// createCustomColumnWithJsonPath creates a column with a custom badge and link using jsonPath
|
||||
// badgeValue should be the kind in PascalCase (e.g., "Service", "VirtualMachine")
|
||||
// abbreviation is auto-generated by ResourceBadge from badgeValue
|
||||
func createCustomColumnWithJsonPath(name, jsonPath, badgeValue, badgeColor, linkHref string) map[string]any {
|
||||
func createCustomColumnWithJsonPath(name, jsonPath, badgeText, badgeTitle, badgeColor, linkHref string) map[string]any {
|
||||
// Determine link ID based on jsonPath
|
||||
linkId := "name-link"
|
||||
if jsonPath == ".metadata.namespace" {
|
||||
linkId = "namespace-link"
|
||||
}
|
||||
|
||||
badgeData := map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": badgeValue,
|
||||
}
|
||||
// Add custom color if specified
|
||||
if badgeColor != "" {
|
||||
badgeData["style"] = map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"name": name,
|
||||
"type": "factory",
|
||||
@@ -780,8 +741,26 @@ func createCustomColumnWithJsonPath(name, jsonPath, badgeValue, badgeColor, link
|
||||
},
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": badgeData,
|
||||
"type": "antdText",
|
||||
"data": map[string]any{
|
||||
"id": "header-badge",
|
||||
"text": badgeText,
|
||||
"title": badgeTitle,
|
||||
"style": map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
"borderRadius": "20px",
|
||||
"color": "#fff",
|
||||
"display": "inline-block",
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": "15px",
|
||||
"fontWeight": 400,
|
||||
"lineHeight": "24px",
|
||||
"minWidth": 24,
|
||||
"padding": "0 9px",
|
||||
"textAlign": "center",
|
||||
"whiteSpace": "nowrap",
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]any{
|
||||
"type": "antdLink",
|
||||
@@ -799,20 +778,7 @@ func createCustomColumnWithJsonPath(name, jsonPath, badgeValue, badgeColor, link
|
||||
}
|
||||
|
||||
// createCustomColumnWithoutJsonPath creates a column with a custom badge and link without jsonPath
|
||||
// badgeValue should be the kind in PascalCase (e.g., "Node", "Pod")
|
||||
// abbreviation is auto-generated by ResourceBadge from badgeValue
|
||||
func createCustomColumnWithoutJsonPath(name, badgeValue, badgeColor, linkHref string) map[string]any {
|
||||
badgeData := map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": badgeValue,
|
||||
}
|
||||
// Add custom color if specified
|
||||
if badgeColor != "" {
|
||||
badgeData["style"] = map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
}
|
||||
}
|
||||
|
||||
func createCustomColumnWithoutJsonPath(name, badgeText, badgeTitle, badgeColor, linkHref string) map[string]any {
|
||||
return map[string]any{
|
||||
"name": name,
|
||||
"type": "factory",
|
||||
@@ -828,8 +794,26 @@ func createCustomColumnWithoutJsonPath(name, badgeValue, badgeColor, linkHref st
|
||||
},
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": badgeData,
|
||||
"type": "antdText",
|
||||
"data": map[string]any{
|
||||
"id": "header-badge",
|
||||
"text": badgeText,
|
||||
"title": badgeTitle,
|
||||
"style": map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
"borderRadius": "20px",
|
||||
"color": "#fff",
|
||||
"display": "inline-block",
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": "15px",
|
||||
"fontWeight": 400,
|
||||
"lineHeight": "24px",
|
||||
"minWidth": 24,
|
||||
"padding": "0 9px",
|
||||
"textAlign": "center",
|
||||
"whiteSpace": "nowrap",
|
||||
},
|
||||
},
|
||||
},
|
||||
map[string]any{
|
||||
"type": "antdLink",
|
||||
@@ -1046,15 +1030,6 @@ func createConverterBytesColumn(name, jsonPath string) map[string]any {
|
||||
}
|
||||
}
|
||||
|
||||
// createFlatMapColumn creates a flatMap column that expands a map into separate rows
|
||||
func createFlatMapColumn(name, jsonPath string) map[string]any {
|
||||
return map[string]any{
|
||||
"name": name,
|
||||
"type": "flatMap",
|
||||
"jsonPath": jsonPath,
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------- Factory UI helper functions ----------------
|
||||
|
||||
// labelsEditor creates a Labels editor component
|
||||
|
||||
@@ -32,7 +32,7 @@ func (m *Manager) ensureStaticResource(ctx context.Context, obj client.Object) e
|
||||
// Add dashboard labels to static resources
|
||||
m.addDashboardLabels(resource, nil, ResourceTypeStatic)
|
||||
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.Client, resource, func() error {
|
||||
_, err := controllerutil.CreateOrUpdate(ctx, m.client, resource, func() error {
|
||||
// For static resources, we don't need to set owner references
|
||||
// as they are meant to be persistent across CRD changes
|
||||
// Copy Spec from the original object to the live object
|
||||
|
||||
@@ -132,7 +132,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
return []*dashboardv1alpha1.CustomColumnsOverride{
|
||||
// Factory details v1 services
|
||||
createCustomColumnsOverride("factory-details-v1.services", []any{
|
||||
createCustomColumnWithSpecificColor("Name", "Service", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithSpecificColor("Name", "Service", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("ClusterIP", ".spec.clusterIP"),
|
||||
createStringColumn("LoadbalancerIP", ".spec.loadBalancerIP"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
@@ -140,7 +140,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock namespace v1 services
|
||||
createCustomColumnsOverride("stock-namespace-/v1/services", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Service", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("ClusterIP", ".spec.clusterIP"),
|
||||
createStringColumn("LoadbalancerIP", ".status.loadBalancer.ingress[0].ip"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
@@ -148,7 +148,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock namespace core cozystack io v1alpha1 tenantmodules
|
||||
createCustomColumnsOverride("stock-namespace-/core.cozystack.io/v1alpha1/tenantmodules", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Module", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/{reqsJsonPath[0]['.metadata.name']['-']}-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "M", "module", getColorForType("module"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/{reqsJsonPath[0]['.metadata.name']['-']}-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createReadyColumn(),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
createStringColumn("Version", ".status.version"),
|
||||
@@ -164,7 +164,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Factory details v1alpha1 cozystack io workloadmonitors
|
||||
createCustomColumnsOverride("factory-details-v1alpha1.cozystack.io.workloadmonitors", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "WorkloadMonitor", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/workloadmonitor-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "W", "workloadmonitor", getColorForType("workloadmonitor"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/workloadmonitor-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("TYPE", ".spec.type"),
|
||||
createStringColumn("VERSION", ".spec.version"),
|
||||
createStringColumn("REPLICAS", ".spec.replicas"),
|
||||
@@ -173,19 +173,18 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
createStringColumn("OBSERVED", ".status.observedReplicas"),
|
||||
}),
|
||||
|
||||
// Factory details v1alpha1 core cozystack io tenantsecrets
|
||||
createCustomColumnsOverride("factory-details-v1alpha1.core.cozystack.io.tenantsecrets", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Secret", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createFlatMapColumn("Data", ".data"),
|
||||
createStringColumn("Key", "_flatMapData_Key"),
|
||||
createSecretBase64Column("Value", "._flatMapData_Value"),
|
||||
// Factory details v1alpha1 core cozystack io tenantsecretstables
|
||||
createCustomColumnsOverride("factory-details-v1alpha1.core.cozystack.io.tenantsecretstables", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "secret", getColorForType("secret"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("Key", ".data.key"),
|
||||
createSecretBase64Column("Value", ".data.value"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Factory ingress details rules
|
||||
createCustomColumnsOverride("factory-kube-ingress-details-rules", []any{
|
||||
createStringColumn("Host", ".host"),
|
||||
createCustomColumnWithJsonPath("Service", ".http.paths[0].backend.service.name", "Service", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.http.paths[0].backend.service.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Service", ".http.paths[0].backend.service.name", "S", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.http.paths[0].backend.service.name']['-']}"),
|
||||
createStringColumn("Port", ".http.paths[0].backend.service.port.number"),
|
||||
createStringColumn("Path", ".http.paths[0].path"),
|
||||
}),
|
||||
@@ -251,7 +250,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Factory details networking k8s io v1 ingresses
|
||||
createCustomColumnsOverride("factory-details-networking.k8s.io.v1.ingresses", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Ingress", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "I", "ingress", getColorForType("ingress"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("Hosts", ".spec.rules[*].host"),
|
||||
createStringColumn("Address", ".status.loadBalancer.ingress[0].ip"),
|
||||
createStringColumn("Port", ".spec.defaultBackend.service.port.number"),
|
||||
@@ -260,7 +259,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock namespace networking k8s io v1 ingresses
|
||||
createCustomColumnsOverride("stock-namespace-/networking.k8s.io/v1/ingresses", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Ingress", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "I", "ingress", getColorForType("ingress"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("Hosts", ".spec.rules[*].host"),
|
||||
createStringColumn("Address", ".status.loadBalancer.ingress[0].ip"),
|
||||
createStringColumn("Port", ".spec.defaultBackend.service.port.number"),
|
||||
@@ -269,34 +268,34 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock cluster v1 configmaps
|
||||
createCustomColumnsOverride("stock-cluster-/v1/configmaps", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "ConfigMap", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "CM", "configmap", getColorForType("configmap"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", getColorForType("namespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Stock namespace v1 configmaps
|
||||
createCustomColumnsOverride("stock-namespace-/v1/configmaps", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "ConfigMap", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "CM", "configmap", getColorForType("configmap"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Cluster v1 configmaps
|
||||
createCustomColumnsOverride("cluster-/v1/configmaps", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "ConfigMap", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "CM", "configmap", getColorForType("configmap"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", getColorForType("namespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Stock cluster v1 nodes
|
||||
createCustomColumnsOverride("stock-cluster-/v1/nodes", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Node", "", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "N", "node", getColorForType("node"), "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createSimpleStatusColumn("Status", "node-status"),
|
||||
}),
|
||||
|
||||
// Factory node details v1 pods
|
||||
createCustomColumnsOverride("factory-node-details-v1.pods", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Pod", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", getColorForType("pod"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", getColorForType("namespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createStringColumn("Restart Policy", ".spec.restartPolicy"),
|
||||
createStringColumn("Pod IP", ".status.podIP"),
|
||||
createStringColumn("QOS", ".status.qosClass"),
|
||||
@@ -305,8 +304,8 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Factory v1 pods
|
||||
createCustomColumnsOverride("factory-v1.pods", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Pod", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithoutJsonPath("Node", "Node", "", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", getColorForType("pod"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithoutJsonPath("Node", "N", "node", getColorForType("node"), "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createStringColumn("Restart Policy", ".spec.restartPolicy"),
|
||||
createStringColumn("Pod IP", ".status.podIP"),
|
||||
createStringColumn("QOS", ".status.qosClass"),
|
||||
@@ -315,9 +314,9 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock cluster v1 pods
|
||||
createCustomColumnsOverride("stock-cluster-/v1/pods", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
|
||||
createCustomColumnWithJsonPath("Node", ".spec.nodeName", "Node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
|
||||
createCustomColumnWithJsonPath("Node", ".spec.nodeName", "N", "node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createStringColumn("Restart Policy", ".spec.restartPolicy"),
|
||||
createStringColumn("Pod IP", ".status.podIP"),
|
||||
createStringColumn("QOS", ".status.qosClass"),
|
||||
@@ -326,8 +325,8 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock namespace v1 pods
|
||||
createCustomColumnsOverride("stock-namespace-/v1/pods", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithoutJsonPath("Node", "Node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithoutJsonPath("Node", "N", "node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createStringColumn("Restart Policy", ".spec.restartPolicy"),
|
||||
createStringColumn("Pod IP", ".status.podIP"),
|
||||
createStringColumn("QOS", ".status.qosClass"),
|
||||
@@ -336,15 +335,15 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock cluster v1 secrets
|
||||
createCustomColumnsOverride("stock-cluster-/v1/secrets", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
|
||||
createStringColumn("Type", ".type"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Stock namespace v1 secrets
|
||||
createCustomColumnsOverride("stock-namespace-/v1/secrets", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("Type", ".type"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
@@ -361,7 +360,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock cluster core cozystack io v1alpha1 tenantnamespaces
|
||||
createCustomColumnsOverride("stock-cluster-/core.cozystack.io/v1alpha1/tenantnamespaces", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "TenantNamespace", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.name']['-']}/factory/marketplace"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "TN", "tenantnamespace", getColorForType("tenantnamespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.name']['-']}/factory/marketplace"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
}
|
||||
@@ -497,6 +496,7 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
|
||||
Kind: "Namespace",
|
||||
Plural: "namespaces",
|
||||
Title: "namespace",
|
||||
Size: BadgeSizeLarge,
|
||||
}
|
||||
namespaceSpec := createUnifiedFactory(namespaceConfig, nil, []any{"/api/clusters/{2}/k8s/api/v1/namespaces/{5}"})
|
||||
|
||||
@@ -796,7 +796,6 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
|
||||
"substractHeight": float64(400),
|
||||
"type": "builtin",
|
||||
"typeName": "secrets",
|
||||
"readOnly": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1056,7 +1055,7 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
|
||||
"clusterNamePartOfUrl": "{2}",
|
||||
"customizationId": "factory-kube-service-details-endpointslice",
|
||||
"fetchUrl": "/api/clusters/{2}/k8s/apis/discovery.k8s.io/v1/namespaces/{3}/endpointslices",
|
||||
"labelSelector": map[string]any{
|
||||
"labelsSelector": map[string]any{
|
||||
"kubernetes.io/service-name": "{reqsJsonPath[0]['.metadata.name']['-']}",
|
||||
},
|
||||
"pathToItems": ".items[*].endpoints",
|
||||
@@ -1202,7 +1201,7 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
|
||||
"gap": 6,
|
||||
},
|
||||
"children": []any{
|
||||
createUnifiedBadgeFromKind("ns-badge", "Namespace"),
|
||||
createUnifiedBadgeFromKind("ns-badge", "Namespace", "namespace", BadgeSizeMedium),
|
||||
antdLink("namespace-link",
|
||||
"{reqsJsonPath[0]['.metadata.namespace']['-']}",
|
||||
"/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace",
|
||||
@@ -1397,7 +1396,7 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
|
||||
"clusterNamePartOfUrl": "{2}",
|
||||
"customizationId": "factory-details-v1alpha1.cozystack.io.workloads",
|
||||
"fetchUrl": "/api/clusters/{2}/k8s/apis/cozystack.io/v1alpha1/namespaces/{3}/workloads",
|
||||
"labelSelector": map[string]any{
|
||||
"labelsSelector": map[string]any{
|
||||
"workloads.cozystack.io/monitor": "{reqs[0]['metadata','name']}",
|
||||
},
|
||||
"pathToItems": []any{"items"},
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package dashboard
|
||||
|
||||
import "strings"
|
||||
|
||||
// ---------------- UI helpers (use float64 for numeric fields) ----------------
|
||||
|
||||
func contentCard(id string, style map[string]any, children []any) map[string]any {
|
||||
@@ -198,10 +200,10 @@ func createBadge(id, text, color, title string) map[string]any {
|
||||
|
||||
// createBadgeFromKind creates a badge using the existing badge generation functions
|
||||
func createBadgeFromKind(id, kind, title string) map[string]any {
|
||||
return createUnifiedBadgeFromKind(id, kind)
|
||||
return createUnifiedBadgeFromKind(id, kind, title, BadgeSizeMedium)
|
||||
}
|
||||
|
||||
// createHeaderBadge creates a badge specifically for headers with consistent styling
|
||||
func createHeaderBadge(id, kind, plural string) map[string]any {
|
||||
return createUnifiedBadgeFromKind(id, kind)
|
||||
return createUnifiedBadgeFromKind(id, kind, strings.ToLower(plural), BadgeSizeLarge)
|
||||
}
|
||||
|
||||
@@ -81,49 +81,88 @@ func isAlphanumeric(c byte) bool {
|
||||
|
||||
// BadgeConfig holds configuration for badge generation
|
||||
type BadgeConfig struct {
|
||||
Kind string // Resource kind in PascalCase (e.g., "VirtualMachine") - used for value and auto-generation
|
||||
Text string // Optional abbreviation override (if empty, ResourceBadge auto-generates from Kind)
|
||||
Color string // Optional custom backgroundColor override
|
||||
Text string
|
||||
Color string
|
||||
Title string
|
||||
Size BadgeSize
|
||||
}
|
||||
|
||||
// createUnifiedBadge creates a badge using the unified BadgeConfig with ResourceBadge component
|
||||
// BadgeSize represents the size of the badge
|
||||
type BadgeSize int
|
||||
|
||||
const (
|
||||
BadgeSizeSmall BadgeSize = iota
|
||||
BadgeSizeMedium
|
||||
BadgeSizeLarge
|
||||
)
|
||||
|
||||
// generateBadgeConfig creates a BadgeConfig from kind and optional custom values
|
||||
func generateBadgeConfig(kind string, customText, customColor, customTitle string) BadgeConfig {
|
||||
config := BadgeConfig{
|
||||
Text: initialsFromKind(kind),
|
||||
Color: hexColorForKind(kind),
|
||||
Title: strings.ToLower(kind),
|
||||
Size: BadgeSizeMedium,
|
||||
}
|
||||
|
||||
// Override with custom values if provided
|
||||
if customText != "" {
|
||||
config.Text = customText
|
||||
}
|
||||
if customColor != "" {
|
||||
config.Color = customColor
|
||||
}
|
||||
if customTitle != "" {
|
||||
config.Title = customTitle
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// createUnifiedBadge creates a badge using the unified BadgeConfig
|
||||
func createUnifiedBadge(id string, config BadgeConfig) map[string]any {
|
||||
data := map[string]any{
|
||||
"id": id,
|
||||
"value": config.Kind,
|
||||
}
|
||||
|
||||
// Add abbreviation override if specified (otherwise ResourceBadge auto-generates from Kind)
|
||||
if config.Text != "" {
|
||||
data["abbreviation"] = config.Text
|
||||
}
|
||||
|
||||
// Add custom color if specified
|
||||
if config.Color != "" {
|
||||
data["style"] = map[string]any{
|
||||
"backgroundColor": config.Color,
|
||||
}
|
||||
fontSize := "15px"
|
||||
if config.Size == BadgeSizeLarge {
|
||||
fontSize = "20px"
|
||||
} else if config.Size == BadgeSizeSmall {
|
||||
fontSize = "12px"
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": data,
|
||||
}
|
||||
}
|
||||
|
||||
// createUnifiedBadgeFromKind creates a badge from kind with ResourceBadge component
|
||||
// Abbreviation is auto-generated by ResourceBadge from kind, but can be customized if needed
|
||||
func createUnifiedBadgeFromKind(id, kind string) map[string]any {
|
||||
return map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"type": "antdText",
|
||||
"data": map[string]any{
|
||||
"id": id,
|
||||
"value": kind,
|
||||
// abbreviation is optional - ResourceBadge auto-generates from value
|
||||
"text": config.Text,
|
||||
"title": config.Title,
|
||||
"style": map[string]any{
|
||||
"backgroundColor": config.Color,
|
||||
"borderRadius": "20px",
|
||||
"color": "#fff",
|
||||
"display": "inline-block",
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": fontSize,
|
||||
"fontWeight": float64(400),
|
||||
"lineHeight": "24px",
|
||||
"minWidth": float64(24),
|
||||
"padding": "0 9px",
|
||||
"textAlign": "center",
|
||||
"whiteSpace": "nowrap",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// createUnifiedBadgeFromKind creates a badge from kind with automatic color generation
|
||||
func createUnifiedBadgeFromKind(id, kind, title string, size BadgeSize) map[string]any {
|
||||
config := BadgeConfig{
|
||||
Text: initialsFromKind(kind),
|
||||
Color: hexColorForKind(kind),
|
||||
Title: title,
|
||||
Size: size,
|
||||
}
|
||||
return createUnifiedBadge(id, config)
|
||||
}
|
||||
|
||||
// ---------------- Resource creation helpers with unified approach ----------------
|
||||
|
||||
// ResourceConfig holds configuration for resource creation
|
||||
@@ -144,9 +183,7 @@ func createResourceConfig(components []string, kind, title string) ResourceConfi
|
||||
metadataName := generateMetadataName(specID)
|
||||
|
||||
// Generate badge config
|
||||
badgeConfig := BadgeConfig{
|
||||
Kind: kind,
|
||||
}
|
||||
badgeConfig := generateBadgeConfig(kind, "", "", title)
|
||||
|
||||
return ResourceConfig{
|
||||
SpecID: specID,
|
||||
@@ -159,6 +196,35 @@ func createResourceConfig(components []string, kind, title string) ResourceConfi
|
||||
|
||||
// ---------------- Enhanced color generation ----------------
|
||||
|
||||
// getColorForKind returns a color for a specific kind with improved distribution
|
||||
func getColorForKind(kind string) string {
|
||||
// Use existing hexColorForKind function
|
||||
return hexColorForKind(kind)
|
||||
}
|
||||
|
||||
// getColorForType returns a color for a specific type (like "namespace", "service", etc.)
|
||||
func getColorForType(typeName string) string {
|
||||
// Map common types to specific colors for consistency
|
||||
colorMap := map[string]string{
|
||||
"namespace": "#a25792ff",
|
||||
"service": "#6ca100",
|
||||
"pod": "#009596",
|
||||
"node": "#8476d1",
|
||||
"secret": "#c46100",
|
||||
"configmap": "#b48c78ff",
|
||||
"ingress": "#2e7dff",
|
||||
"workloadmonitor": "#c46100",
|
||||
"module": "#8b5cf6",
|
||||
}
|
||||
|
||||
if color, exists := colorMap[strings.ToLower(typeName)]; exists {
|
||||
return color
|
||||
}
|
||||
|
||||
// Fall back to hash-based color generation
|
||||
return hexColorForKind(typeName)
|
||||
}
|
||||
|
||||
// ---------------- Automatic ID generation for UI elements ----------------
|
||||
|
||||
// generateElementID creates an ID for UI elements based on context and type
|
||||
@@ -216,6 +282,7 @@ type UnifiedResourceConfig struct {
|
||||
Title string
|
||||
Color string
|
||||
BadgeText string
|
||||
Size BadgeSize
|
||||
}
|
||||
|
||||
// createUnifiedFactory creates a factory using unified approach
|
||||
@@ -225,9 +292,16 @@ func createUnifiedFactory(config UnifiedResourceConfig, tabs []any, urlsToFetch
|
||||
|
||||
// Create header with unified badge
|
||||
badgeConfig := BadgeConfig{
|
||||
Kind: config.Kind,
|
||||
Text: config.BadgeText,
|
||||
Color: config.Color,
|
||||
Title: config.Title,
|
||||
Size: config.Size,
|
||||
}
|
||||
if badgeConfig.Text == "" {
|
||||
badgeConfig.Text = initialsFromKind(config.Kind)
|
||||
}
|
||||
if badgeConfig.Color == "" {
|
||||
badgeConfig.Color = getColorForKind(config.Kind)
|
||||
}
|
||||
|
||||
badge := createUnifiedBadge(generateBadgeID("header", config.Kind), badgeConfig)
|
||||
@@ -274,9 +348,7 @@ func createUnifiedFactory(config UnifiedResourceConfig, tabs []any, urlsToFetch
|
||||
|
||||
// createUnifiedCustomColumn creates a custom column using unified approach
|
||||
func createUnifiedCustomColumn(name, jsonPath, kind, title, href string) map[string]any {
|
||||
badgeConfig := BadgeConfig{
|
||||
Kind: kind,
|
||||
}
|
||||
badgeConfig := generateBadgeConfig(kind, "", "", title)
|
||||
badge := createUnifiedBadge(generateBadgeID("column", kind), badgeConfig)
|
||||
|
||||
linkID := generateLinkID("column", "name")
|
||||
|
||||
@@ -23,53 +23,53 @@ For more details, read [Restic: Effective Backup from Stdin](https://blog.aenix.
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `replicas` | Number of Clickhouse replicas | `int` | `2` |
|
||||
| `shards` | Number of Clickhouse shards | `int` | `1` |
|
||||
| `resources` | Explicit CPU and memory configuration for each Clickhouse replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `small` |
|
||||
| `size` | Persistent Volume Claim size, available for application data | `quantity` | `10Gi` |
|
||||
| `storageClass` | StorageClass used to store the data | `string` | `""` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | ---------- | ------- |
|
||||
| `replicas` | Number of ClickHouse replicas. | `int` | `2` |
|
||||
| `shards` | Number of ClickHouse shards. | `int` | `1` |
|
||||
| `resources` | Explicit CPU and memory configuration for each ClickHouse replica. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `small` |
|
||||
| `size` | Persistent Volume Claim size available for application data. | `quantity` | `10Gi` |
|
||||
| `storageClass` | StorageClass used to store the data. | `string` | `""` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------- | ------------------------------------------------------------ | ------------------- | ------- |
|
||||
| `logStorageSize` | Size of Persistent Volume for logs | `quantity` | `2Gi` |
|
||||
| `logTTL` | TTL (expiration time) for `query_log` and `query_thread_log` | `int` | `15` |
|
||||
| `users` | Users configuration | `map[string]object` | `{...}` |
|
||||
| `users[name].password` | Password for the user | `*string` | `null` |
|
||||
| `users[name].readonly` | User is `readonly`, default is `false`. | `*bool` | `null` |
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------- | ------------------------------------------------------------- | ------------------- | ------- |
|
||||
| `logStorageSize` | Size of Persistent Volume for logs. | `quantity` | `2Gi` |
|
||||
| `logTTL` | TTL (expiration time) for `query_log` and `query_thread_log`. | `int` | `15` |
|
||||
| `users` | Users configuration map. | `map[string]object` | `{}` |
|
||||
| `users[name].password` | Password for the user. | `string` | `""` |
|
||||
| `users[name].readonly` | User is readonly (default: false). | `bool` | `false` |
|
||||
|
||||
|
||||
### Backup parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ---------------------------------------------- | -------- | ------------------------------------------------------ |
|
||||
| `backup` | Backup configuration | `object` | `{}` |
|
||||
| `backup.enabled` | Enable regular backups, default is `false` | `bool` | `false` |
|
||||
| `backup.s3Region` | AWS S3 region where backups are stored | `string` | `us-east-1` |
|
||||
| `backup.s3Bucket` | S3 bucket used for storing backups | `string` | `s3.example.org/clickhouse-backups` |
|
||||
| `backup.schedule` | Cron schedule for automated backups | `string` | `0 2 * * *` |
|
||||
| `backup.cleanupStrategy` | Retention strategy for cleaning up old backups | `string` | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
||||
| `backup.s3AccessKey` | Access key for S3, used for authentication | `string` | `<your-access-key>` |
|
||||
| `backup.s3SecretKey` | Secret key for S3, used for authentication | `string` | `<your-secret-key>` |
|
||||
| `backup.resticPassword` | Password for Restic backup encryption | `string` | `<password>` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ----------------------------------------------- | -------- | ------------------------------------------------------ |
|
||||
| `backup` | Backup configuration. | `object` | `{}` |
|
||||
| `backup.enabled` | Enable regular backups (default: false). | `bool` | `false` |
|
||||
| `backup.s3Region` | AWS S3 region where backups are stored. | `string` | `us-east-1` |
|
||||
| `backup.s3Bucket` | S3 bucket used for storing backups. | `string` | `s3.example.org/clickhouse-backups` |
|
||||
| `backup.schedule` | Cron schedule for automated backups. | `string` | `0 2 * * *` |
|
||||
| `backup.cleanupStrategy` | Retention strategy for cleaning up old backups. | `string` | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
||||
| `backup.s3AccessKey` | Access key for S3 authentication. | `string` | `<your-access-key>` |
|
||||
| `backup.s3SecretKey` | Secret key for S3 authentication. | `string` | `<your-secret-key>` |
|
||||
| `backup.resticPassword` | Password for Restic backup encryption. | `string` | `<password>` |
|
||||
|
||||
|
||||
### Clickhouse Keeper parameters
|
||||
### ClickHouse Keeper parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `clickhouseKeeper` | Clickhouse Keeper configuration | `*object` | `null` |
|
||||
| `clickhouseKeeper.enabled` | Deploy ClickHouse Keeper for cluster coordination | `*bool` | `true` |
|
||||
| `clickhouseKeeper.size` | Persistent Volume Claim size, available for application data | `*quantity` | `1Gi` |
|
||||
| `clickhouseKeeper.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `micro` |
|
||||
| `clickhouseKeeper.replicas` | Number of Keeper replicas | `*int` | `3` |
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------------------- | ------------------------------------------------------------ | ---------- | ------- |
|
||||
| `clickhouseKeeper` | ClickHouse Keeper configuration. | `object` | `{}` |
|
||||
| `clickhouseKeeper.enabled` | Deploy ClickHouse Keeper for cluster coordination. | `bool` | `true` |
|
||||
| `clickhouseKeeper.size` | Persistent Volume Claim size available for application data. | `quantity` | `1Gi` |
|
||||
| `clickhouseKeeper.resourcesPreset` | Default sizing preset. | `string` | `micro` |
|
||||
| `clickhouseKeeper.replicas` | Number of Keeper replicas. | `int` | `3` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backup": {
|
||||
"description": "Backup configuration",
|
||||
"description": "Backup configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -18,67 +18,64 @@
|
||||
],
|
||||
"properties": {
|
||||
"cleanupStrategy": {
|
||||
"description": "Retention strategy for cleaning up old backups",
|
||||
"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 is `false`",
|
||||
"description": "Enable regular backups (default: false).",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"resticPassword": {
|
||||
"description": "Password for Restic backup encryption",
|
||||
"description": "Password for Restic backup encryption.",
|
||||
"type": "string",
|
||||
"default": "\u003cpassword\u003e"
|
||||
},
|
||||
"s3AccessKey": {
|
||||
"description": "Access key for S3, used for authentication",
|
||||
"description": "Access key for S3 authentication.",
|
||||
"type": "string",
|
||||
"default": "\u003cyour-access-key\u003e"
|
||||
},
|
||||
"s3Bucket": {
|
||||
"description": "S3 bucket used for storing backups",
|
||||
"description": "S3 bucket used for storing backups.",
|
||||
"type": "string",
|
||||
"default": "s3.example.org/clickhouse-backups"
|
||||
},
|
||||
"s3Region": {
|
||||
"description": "AWS S3 region where backups are stored",
|
||||
"description": "AWS S3 region where backups are stored.",
|
||||
"type": "string",
|
||||
"default": "us-east-1"
|
||||
},
|
||||
"s3SecretKey": {
|
||||
"description": "Secret key for S3, used for authentication",
|
||||
"description": "Secret key for S3 authentication.",
|
||||
"type": "string",
|
||||
"default": "\u003cyour-secret-key\u003e"
|
||||
},
|
||||
"schedule": {
|
||||
"description": "Cron schedule for automated backups",
|
||||
"description": "Cron schedule for automated backups.",
|
||||
"type": "string",
|
||||
"default": "0 2 * * *"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clickhouseKeeper": {
|
||||
"description": "Clickhouse Keeper configuration",
|
||||
"description": "ClickHouse Keeper configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"resourcesPreset"
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Deploy ClickHouse Keeper for cluster coordination",
|
||||
"description": "Deploy ClickHouse Keeper for cluster coordination.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of Keeper replicas",
|
||||
"description": "Number of Keeper replicas.",
|
||||
"type": "integer",
|
||||
"default": 3
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset.",
|
||||
"type": "string",
|
||||
"default": "micro",
|
||||
"enum": [
|
||||
@@ -92,7 +89,7 @@
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume Claim size, available for application data",
|
||||
"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": [
|
||||
@@ -108,7 +105,7 @@
|
||||
}
|
||||
},
|
||||
"logStorageSize": {
|
||||
"description": "Size of Persistent Volume for logs",
|
||||
"description": "Size of Persistent Volume for logs.",
|
||||
"default": "2Gi",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
@@ -122,22 +119,22 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"logTTL": {
|
||||
"description": "TTL (expiration time) for `query_log` and `query_thread_log`",
|
||||
"description": "TTL (expiration time) for `query_log` and `query_thread_log`.",
|
||||
"type": "integer",
|
||||
"default": 15
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of Clickhouse replicas",
|
||||
"description": "Number of ClickHouse replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each Clickhouse replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "Explicit CPU and memory configuration for each ClickHouse replica. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each replica",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -150,7 +147,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -165,7 +162,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "small",
|
||||
"enum": [
|
||||
@@ -179,12 +176,12 @@
|
||||
]
|
||||
},
|
||||
"shards": {
|
||||
"description": "Number of Clickhouse shards",
|
||||
"description": "Number of ClickHouse shards.",
|
||||
"type": "integer",
|
||||
"default": 1
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume Claim size, available for application data",
|
||||
"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": [
|
||||
@@ -198,22 +195,23 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"users": {
|
||||
"description": "Users configuration",
|
||||
"description": "Users configuration map.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"password": {
|
||||
"description": "Password for the user",
|
||||
"description": "Password for the user.",
|
||||
"type": "string"
|
||||
},
|
||||
"readonly": {
|
||||
"description": "User is `readonly`, default is `false`.",
|
||||
"description": "User is readonly (default: false).",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,54 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param replicas {int} Number of Clickhouse replicas
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each ClickHouse replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @param {int} replicas - Number of ClickHouse replicas.
|
||||
replicas: 2
|
||||
## @param shards {int} Number of Clickhouse shards
|
||||
|
||||
## @param {int} shards - Number of ClickHouse shards.
|
||||
shards: 1
|
||||
## @param resources {*resources} Explicit CPU and memory configuration for each Clickhouse replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
|
||||
## @param {Resources} [resources] - Explicit CPU and memory configuration for each ClickHouse replica. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
resources: {}
|
||||
|
||||
|
||||
|
||||
## @param resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
## @param {ResourcesPreset} resourcesPreset="small" - Default sizing preset used when `resources` is omitted.
|
||||
resourcesPreset: "small"
|
||||
## @param size {quantity} Persistent Volume Claim size, available for application data
|
||||
|
||||
## @param {quantity} size - Persistent Volume Claim size available for application data.
|
||||
size: 10Gi
|
||||
## @param storageClass {string} StorageClass used to store the data
|
||||
|
||||
## @param {string} storageClass - StorageClass used to store the data.
|
||||
storageClass: ""
|
||||
|
||||
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
## @param logStorageSize {quantity} Size of Persistent Volume for logs
|
||||
|
||||
## @param {quantity} logStorageSize - Size of Persistent Volume for logs.
|
||||
logStorageSize: 2Gi
|
||||
## @param logTTL {int} TTL (expiration time) for `query_log` and `query_thread_log`
|
||||
|
||||
## @param {int} logTTL - TTL (expiration time) for `query_log` and `query_thread_log`.
|
||||
logTTL: 15
|
||||
## @param users {map[string]user} Users configuration
|
||||
## @field user.password {*string} Password for the user
|
||||
## @field user.readonly {*bool} User is `readonly`, default is `false`.
|
||||
|
||||
## @typedef {struct} User - User configuration.
|
||||
## @field {string} [password] - Password for the user.
|
||||
## @field {bool} [readonly] - User is readonly (default: false).
|
||||
|
||||
## @param {map[string]User} users - Users configuration map.
|
||||
users: {}
|
||||
## Example:
|
||||
## users:
|
||||
## user1:
|
||||
@@ -39,20 +57,22 @@ logTTL: 15
|
||||
## readonly: true
|
||||
## password: hackme
|
||||
##
|
||||
users: {}
|
||||
|
||||
|
||||
##
|
||||
## @section Backup parameters
|
||||
##
|
||||
|
||||
## @param backup {backup} Backup configuration
|
||||
## @field backup.enabled {bool} Enable regular backups, default is `false`
|
||||
## @field backup.s3Region {string} AWS S3 region where backups are stored
|
||||
## @field backup.s3Bucket {string} S3 bucket used for storing backups
|
||||
## @field backup.schedule {string} Cron schedule for automated backups
|
||||
## @field backup.cleanupStrategy {string} Retention strategy for cleaning up old backups
|
||||
## @field backup.s3AccessKey {string} Access key for S3, used for authentication
|
||||
## @field backup.s3SecretKey {string} Secret key for S3, used for authentication
|
||||
## @field backup.resticPassword {string} Password for Restic backup encryption
|
||||
## @typedef {struct} Backup - Backup configuration.
|
||||
## @field {bool} enabled - Enable regular backups (default: false).
|
||||
## @field {string} s3Region - AWS S3 region where backups are stored.
|
||||
## @field {string} s3Bucket - S3 bucket used for storing backups.
|
||||
## @field {string} schedule - Cron schedule for automated backups.
|
||||
## @field {string} cleanupStrategy - Retention strategy for cleaning up old backups.
|
||||
## @field {string} s3AccessKey - Access key for S3 authentication.
|
||||
## @field {string} s3SecretKey - Secret key for S3 authentication.
|
||||
## @field {string} resticPassword - Password for Restic backup encryption.
|
||||
|
||||
## @param {Backup} backup - Backup configuration.
|
||||
backup:
|
||||
enabled: false
|
||||
s3Region: us-east-1
|
||||
@@ -63,13 +83,17 @@ backup:
|
||||
s3SecretKey: "<your-secret-key>"
|
||||
resticPassword: "<password>"
|
||||
|
||||
##
|
||||
## @section ClickHouse Keeper parameters
|
||||
##
|
||||
|
||||
## @section Clickhouse Keeper parameters
|
||||
## @param clickhouseKeeper {*clickhouseKeeper} Clickhouse Keeper configuration
|
||||
## @field clickhouseKeeper.enabled {*bool} Deploy ClickHouse Keeper for cluster coordination
|
||||
## @field clickhouseKeeper.size {*quantity} Persistent Volume Claim size, available for application data
|
||||
## @field clickhouseKeeper.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
## @field clickhouseKeeper.replicas {*int} Number of Keeper replicas
|
||||
## @typedef {struct} ClickHouseKeeper - ClickHouse Keeper configuration.
|
||||
## @field {bool} [enabled] - Deploy ClickHouse Keeper for cluster coordination.
|
||||
## @field {quantity} [size] - Persistent Volume Claim size available for application data.
|
||||
## @field {ResourcesPreset} [resourcesPreset] - Default sizing preset.
|
||||
## @field {int} [replicas] - Number of Keeper replicas.
|
||||
|
||||
## @param {ClickHouseKeeper} clickhouseKeeper - ClickHouse Keeper configuration.
|
||||
clickhouseKeeper:
|
||||
enabled: true
|
||||
size: 1Gi
|
||||
|
||||
@@ -8,51 +8,51 @@ Internally, FerretDB service is backed by Postgres.
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `replicas` | Number of replicas | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each FerretDB replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `micro` |
|
||||
| `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` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------- |
|
||||
| `replicas` | Number of replicas. | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each FerretDB replica. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `micro` |
|
||||
| `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` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------- | ------------------- | ------- |
|
||||
| `quorum` | Configuration for the quorum-based synchronous replication | `object` | `{}` |
|
||||
| `quorum.minSyncReplicas` | Minimum number of synchronous replicas that must acknowledge a transaction before it is considered committed | `int` | `0` |
|
||||
| `quorum.maxSyncReplicas` | Maximum number of synchronous replicas that can acknowledge a transaction (must be lower than the total number of replicas) | `int` | `0` |
|
||||
| `users` | Users configuration | `map[string]object` | `{...}` |
|
||||
| `users[name].password` | Password for the user | `*string` | `null` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ---------------------------------------------------------------------------------- | ------------------- | ----- |
|
||||
| `quorum` | Configuration for quorum-based synchronous replication. | `object` | `{}` |
|
||||
| `quorum.minSyncReplicas` | Minimum number of synchronous replicas required for commit. | `int` | `0` |
|
||||
| `quorum.maxSyncReplicas` | Maximum number of synchronous replicas allowed (must be less than total replicas). | `int` | `0` |
|
||||
| `users` | Users configuration map. | `map[string]object` | `{}` |
|
||||
| `users[name].password` | Password for the user. | `string` | `""` |
|
||||
|
||||
|
||||
### Backup parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ---------------------------------------------------------- | -------- | ----------------------------------- |
|
||||
| `backup` | Backup configuration | `object` | `{}` |
|
||||
| `backup.enabled` | Enable regular backups, default is `false`. | `bool` | `false` |
|
||||
| `backup.schedule` | Cron schedule for automated backups | `string` | `0 2 * * * *` |
|
||||
| `backup.retentionPolicy` | Retention policy | `string` | `30d` |
|
||||
| `backup.endpointURL` | S3 Endpoint used to upload data to the cloud | `string` | `http://minio-gateway-service:9000` |
|
||||
| `backup.destinationPath` | Path to store the backup (i.e. s3://bucket/path/to/folder) | `string` | `s3://bucket/path/to/folder/` |
|
||||
| `backup.s3AccessKey` | Access key for S3, used for authentication | `string` | `<your-access-key>` |
|
||||
| `backup.s3SecretKey` | Secret key for S3, used for authentication | `string` | `<your-secret-key>` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ------------------------------------------------------------ | -------- | ----------------------------------- |
|
||||
| `backup` | Backup configuration. | `object` | `{}` |
|
||||
| `backup.enabled` | Enable regular backups (default: false). | `bool` | `false` |
|
||||
| `backup.schedule` | Cron schedule for automated backups. | `string` | `0 2 * * * *` |
|
||||
| `backup.retentionPolicy` | Retention policy. | `string` | `30d` |
|
||||
| `backup.endpointURL` | S3 endpoint URL for uploads. | `string` | `http://minio-gateway-service:9000` |
|
||||
| `backup.destinationPath` | Path to store the backup (e.g. s3://bucket/path/to/folder/). | `string` | `s3://bucket/path/to/folder/` |
|
||||
| `backup.s3AccessKey` | Access key for S3 authentication. | `string` | `<your-access-key>` |
|
||||
| `backup.s3SecretKey` | Secret key for S3 authentication. | `string` | `<your-secret-key>` |
|
||||
|
||||
|
||||
### Bootstrap (recovery) parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------- | --------- | ------- |
|
||||
| `bootstrap` | Bootstrap (recovery) configuration | `object` | `{}` |
|
||||
| `bootstrap.enabled` | Restore database cluster from a backup | `*bool` | `false` |
|
||||
| `bootstrap.recoveryTime` | Timestamp (PITR) up to which recovery will proceed, expressed in RFC 3339 format. If left empty, will restore latest. | `*string` | `""` |
|
||||
| `bootstrap.oldName` | Name of database cluster before deleting | `*string` | `""` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ------------------------------------------------------------------- | -------- | ------- |
|
||||
| `bootstrap` | Bootstrap configuration. | `object` | `{}` |
|
||||
| `bootstrap.enabled` | Restore database cluster from a backup. | `bool` | `false` |
|
||||
| `bootstrap.recoveryTime` | Timestamp (RFC3339) for point-in-time recovery; empty means latest. | `string` | `""` |
|
||||
| `bootstrap.oldName` | Name of database cluster before deletion. | `string` | `""` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backup": {
|
||||
"description": "Backup configuration",
|
||||
"description": "Backup configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -17,69 +17,71 @@
|
||||
],
|
||||
"properties": {
|
||||
"destinationPath": {
|
||||
"description": "Path to store the backup (i.e. s3://bucket/path/to/folder)",
|
||||
"description": "Path to store the backup (e.g. s3://bucket/path/to/folder/).",
|
||||
"type": "string",
|
||||
"default": "s3://bucket/path/to/folder/"
|
||||
},
|
||||
"enabled": {
|
||||
"description": "Enable regular backups, default is `false`.",
|
||||
"description": "Enable regular backups (default: false).",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"endpointURL": {
|
||||
"description": "S3 Endpoint used to upload data to the cloud",
|
||||
"description": "S3 endpoint URL for uploads.",
|
||||
"type": "string",
|
||||
"default": "http://minio-gateway-service:9000"
|
||||
},
|
||||
"retentionPolicy": {
|
||||
"description": "Retention policy",
|
||||
"description": "Retention policy.",
|
||||
"type": "string",
|
||||
"default": "30d"
|
||||
},
|
||||
"s3AccessKey": {
|
||||
"description": "Access key for S3, used for authentication",
|
||||
"description": "Access key for S3 authentication.",
|
||||
"type": "string",
|
||||
"default": "\u003cyour-access-key\u003e"
|
||||
},
|
||||
"s3SecretKey": {
|
||||
"description": "Secret key for S3, used for authentication",
|
||||
"description": "Secret key for S3 authentication.",
|
||||
"type": "string",
|
||||
"default": "\u003cyour-secret-key\u003e"
|
||||
},
|
||||
"schedule": {
|
||||
"description": "Cron schedule for automated backups",
|
||||
"description": "Cron schedule for automated backups.",
|
||||
"type": "string",
|
||||
"default": "0 2 * * * *"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bootstrap": {
|
||||
"description": "Bootstrap (recovery) configuration",
|
||||
"description": "Bootstrap configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Restore database cluster from a backup",
|
||||
"description": "Restore database cluster from a backup.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"oldName": {
|
||||
"description": "Name of database cluster before deleting",
|
||||
"type": "string"
|
||||
"description": "Name of database cluster before deletion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"recoveryTime": {
|
||||
"description": "Timestamp (PITR) up to which recovery will proceed, expressed in RFC 3339 format. If left empty, will restore latest.",
|
||||
"type": "string"
|
||||
"description": "Timestamp (RFC3339) for point-in-time recovery; empty means latest.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"external": {
|
||||
"description": "Enable external access from outside the cluster",
|
||||
"description": "Enable external access from outside the cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"quorum": {
|
||||
"description": "Configuration for the quorum-based synchronous replication",
|
||||
"description": "Configuration for quorum-based synchronous replication.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -88,29 +90,29 @@
|
||||
],
|
||||
"properties": {
|
||||
"maxSyncReplicas": {
|
||||
"description": "Maximum number of synchronous replicas that can acknowledge a transaction (must be lower than the total number of replicas)",
|
||||
"description": "Maximum number of synchronous replicas allowed (must be less than total replicas).",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"minSyncReplicas": {
|
||||
"description": "Minimum number of synchronous replicas that must acknowledge a transaction before it is considered committed",
|
||||
"description": "Minimum number of synchronous replicas required for commit.",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of replicas",
|
||||
"description": "Number of replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each FerretDB replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "Explicit CPU and memory configuration for each FerretDB replica. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each replica",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -123,7 +125,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -138,7 +140,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "micro",
|
||||
"enum": [
|
||||
@@ -152,7 +154,7 @@
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume Claim size, available for application data",
|
||||
"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": [
|
||||
@@ -166,18 +168,19 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"users": {
|
||||
"description": "Users configuration",
|
||||
"description": "Users configuration map.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"password": {
|
||||
"description": "Password for the user",
|
||||
"description": "Password for the user.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,56 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param replicas {int} Number of replicas
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each FerretDB replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @param {int} replicas - Number of replicas.
|
||||
replicas: 2
|
||||
## @param resources {*resources} Explicit CPU and memory configuration for each FerretDB replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
|
||||
## @param {Resources} [resources] - Explicit CPU and memory configuration for each FerretDB replica. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
resources: {}
|
||||
|
||||
## @param resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
## @param {ResourcesPreset} resourcesPreset="micro" - Default sizing preset used when `resources` is omitted.
|
||||
resourcesPreset: "micro"
|
||||
## @param size {quantity} Persistent Volume Claim size, available for application data
|
||||
|
||||
## @param {quantity} size - Persistent Volume Claim size available for application data.
|
||||
size: 10Gi
|
||||
## @param storageClass {string} StorageClass used to store the data
|
||||
|
||||
## @param {string} storageClass - StorageClass used to store the data.
|
||||
storageClass: ""
|
||||
## @param external {bool} Enable external access from outside the cluster
|
||||
|
||||
## @param {bool} external - Enable external access from outside the cluster.
|
||||
external: false
|
||||
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
## @param quorum {quorum} Configuration for the quorum-based synchronous replication
|
||||
## @field quorum.minSyncReplicas {int} Minimum number of synchronous replicas that must acknowledge a transaction before it is considered committed
|
||||
## @field quorum.maxSyncReplicas {int} Maximum number of synchronous replicas that can acknowledge a transaction (must be lower than the total number of replicas)
|
||||
|
||||
## @typedef {struct} Quorum - Configuration for quorum-based synchronous replication.
|
||||
## @field {int} minSyncReplicas - Minimum number of synchronous replicas required for commit.
|
||||
## @field {int} maxSyncReplicas - Maximum number of synchronous replicas allowed (must be less than total replicas).
|
||||
|
||||
## @param {Quorum} quorum - Configuration for quorum-based synchronous replication.
|
||||
quorum:
|
||||
minSyncReplicas: 0
|
||||
maxSyncReplicas: 0
|
||||
|
||||
## @param users {map[string]user} Users configuration
|
||||
## @field user.password {*string} Password for the user
|
||||
## @typedef {struct} User - User configuration.
|
||||
## @field {string} [password] - Password for the user.
|
||||
|
||||
## @param {map[string]User} users - Users configuration map.
|
||||
users: {}
|
||||
## Example:
|
||||
## users:
|
||||
## user1:
|
||||
@@ -37,21 +58,21 @@ quorum:
|
||||
## user2:
|
||||
## password: hackme
|
||||
##
|
||||
users: {}
|
||||
|
||||
|
||||
|
||||
##
|
||||
## @section Backup parameters
|
||||
##
|
||||
|
||||
## @param backup {backup} Backup configuration
|
||||
## @field backup.enabled {bool} Enable regular backups, default is `false`.
|
||||
## @field backup.schedule {string} Cron schedule for automated backups
|
||||
## @field backup.retentionPolicy {string} Retention policy
|
||||
## @field backup.endpointURL {string} S3 Endpoint used to upload data to the cloud
|
||||
## @field backup.destinationPath {string} Path to store the backup (i.e. s3://bucket/path/to/folder)
|
||||
## @field backup.s3AccessKey {string} Access key for S3, used for authentication
|
||||
## @field backup.s3SecretKey {string} Secret key for S3, used for authentication
|
||||
## @typedef {struct} Backup - Backup configuration.
|
||||
## @field {bool} enabled - Enable regular backups (default: false).
|
||||
## @field {string} schedule - Cron schedule for automated backups.
|
||||
## @field {string} retentionPolicy - Retention policy.
|
||||
## @field {string} endpointURL - S3 endpoint URL for uploads.
|
||||
## @field {string} destinationPath - Path to store the backup (e.g. s3://bucket/path/to/folder/).
|
||||
## @field {string} s3AccessKey - Access key for S3 authentication.
|
||||
## @field {string} s3SecretKey - Secret key for S3 authentication.
|
||||
|
||||
## @param {Backup} backup - Backup configuration.
|
||||
backup:
|
||||
enabled: false
|
||||
schedule: "0 2 * * * *"
|
||||
@@ -61,18 +82,17 @@ backup:
|
||||
s3AccessKey: "<your-access-key>"
|
||||
s3SecretKey: "<your-secret-key>"
|
||||
|
||||
|
||||
##
|
||||
## @section Bootstrap (recovery) parameters
|
||||
##
|
||||
## @param bootstrap {bootstrap} Bootstrap (recovery) configuration
|
||||
## @field bootstrap.enabled {*bool} Restore database cluster from a backup
|
||||
## @field bootstrap.recoveryTime {*string} Timestamp (PITR) up to which recovery will proceed, expressed in RFC 3339 format. If left empty, will restore latest.
|
||||
## @field bootstrap.oldName {*string} Name of database cluster before deleting
|
||||
##
|
||||
|
||||
## @typedef {struct} Bootstrap - Bootstrap configuration for restoring a database cluster from a backup.
|
||||
## @field {bool} [enabled] - Restore database cluster from a backup.
|
||||
## @field {string} [recoveryTime] - Timestamp (RFC3339) for point-in-time recovery; empty means latest.
|
||||
## @field {string} [oldName] - Name of database cluster before deletion.
|
||||
|
||||
## @param {Bootstrap} bootstrap - Bootstrap configuration.
|
||||
bootstrap:
|
||||
enabled: false
|
||||
# example: 2020-11-26 15:22:00.00000+00
|
||||
recoveryTime: ""
|
||||
oldName: ""
|
||||
|
||||
|
||||
|
||||
1
packages/apps/foundationdb/.helmignore
Normal file
1
packages/apps/foundationdb/.helmignore
Normal file
@@ -0,0 +1 @@
|
||||
Makefile
|
||||
25
packages/apps/foundationdb/Chart.yaml
Normal file
25
packages/apps/foundationdb/Chart.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: v2
|
||||
name: foundationdb
|
||||
description: Managed FoundationDB service
|
||||
icon: /logos/foundationdb.svg
|
||||
|
||||
# A chart can be either an 'application' or a 'library' chart.
|
||||
#
|
||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
||||
# to be deployed.
|
||||
#
|
||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
||||
type: application
|
||||
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 0.1.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "7.3.63"
|
||||
4
packages/apps/foundationdb/Makefile
Normal file
4
packages/apps/foundationdb/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
include ../../../scripts/package.mk
|
||||
|
||||
generate:
|
||||
cozyvalues-gen -v values.yaml -s values.schema.json -r README.md
|
||||
195
packages/apps/foundationdb/README.md
Normal file
195
packages/apps/foundationdb/README.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# FoundationDB
|
||||
|
||||
A managed FoundationDB service for Cozystack.
|
||||
|
||||
## Overview
|
||||
|
||||
FoundationDB is a distributed database designed to handle large volumes of structured data across clusters of commodity servers. It organizes data as an ordered key-value store and employs ACID transactions for all operations.
|
||||
|
||||
This package provides a managed FoundationDB cluster deployment using the FoundationDB Kubernetes Operator.
|
||||
|
||||
## Features
|
||||
|
||||
- **High Availability**: Multi-instance deployment with automatic failover
|
||||
- **ACID Transactions**: Full ACID transaction support across the cluster
|
||||
- **Scalable**: Easily scale storage and compute resources
|
||||
- **Backup Integration**: Optional S3-compatible backup storage
|
||||
- **Monitoring**: Built-in monitoring and alerting through WorkloadMonitor
|
||||
- **Flexible Configuration**: Support for custom FoundationDB parameters
|
||||
|
||||
## Configuration
|
||||
|
||||
### Basic Configuration
|
||||
|
||||
```yaml
|
||||
# Cluster process configuration
|
||||
cluster:
|
||||
version: "7.3.63"
|
||||
processCounts:
|
||||
storage: 3 # Number of storage processes (determines cluster size)
|
||||
stateless: -1 # Automatically calculated
|
||||
cluster_controller: 1
|
||||
faultDomain:
|
||||
key: "kubernetes.io/hostname"
|
||||
valueFrom: "spec.nodeName"
|
||||
```
|
||||
|
||||
### Storage
|
||||
|
||||
```yaml
|
||||
storage:
|
||||
size: "16Gi" # Storage size per instance
|
||||
storageClass: "" # Storage class (optional)
|
||||
```
|
||||
|
||||
### Resources
|
||||
|
||||
```yaml
|
||||
# Use preset sizing
|
||||
resourcesPreset: "medium" # small, medium, large, xlarge, 2xlarge
|
||||
|
||||
# Or custom resource configuration
|
||||
resources:
|
||||
cpu: "2000m"
|
||||
memory: "4Gi"
|
||||
```
|
||||
|
||||
### Backup (Optional)
|
||||
|
||||
```yaml
|
||||
backup:
|
||||
enabled: true
|
||||
s3:
|
||||
bucket: "my-fdb-backups"
|
||||
endpoint: "https://s3.amazonaws.com"
|
||||
region: "us-east-1"
|
||||
credentials:
|
||||
accessKeyId: "AKIA..."
|
||||
secretAccessKey: "..."
|
||||
retentionPolicy: "7d"
|
||||
```
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
```yaml
|
||||
# Custom FoundationDB parameters
|
||||
customParameters:
|
||||
- "knob_disable_posix_kernel_aio=1"
|
||||
|
||||
# Image type (unified is default and recommended for new deployments)
|
||||
imageType: "unified"
|
||||
|
||||
# Enable automatic pod replacements
|
||||
automaticReplacements: true
|
||||
|
||||
# Security context configuration
|
||||
securityContext:
|
||||
runAsUser: 4059
|
||||
runAsGroup: 4059
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- FoundationDB Operator must be installed in the cluster
|
||||
- Sufficient storage and compute resources
|
||||
- For backups: S3-compatible storage credentials
|
||||
|
||||
## Deployment
|
||||
|
||||
1. Install the FoundationDB operator (system package)
|
||||
2. Deploy this application package with your desired configuration
|
||||
3. The cluster will be automatically provisioned and configured
|
||||
|
||||
## Monitoring
|
||||
|
||||
This package includes WorkloadMonitor integration for cluster health monitoring and resource tracking. Monitoring can be disabled by setting:
|
||||
|
||||
```yaml
|
||||
monitoring:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
- All containers run with restricted security contexts
|
||||
- No privilege escalation allowed
|
||||
- Read-only root filesystem where possible
|
||||
- Custom security context configurations supported
|
||||
|
||||
## Fault Tolerance
|
||||
|
||||
FoundationDB is designed for high availability:
|
||||
- Automatic failure detection and recovery
|
||||
- Data replication across instances
|
||||
- Configurable fault domains for rack/zone awareness
|
||||
- Transaction log redundancy
|
||||
|
||||
The included `WorkloadMonitor` is automatically configured based on the `cluster.redundancyMode` value. It sets the `minReplicas` property on the `WorkloadMonitor` resource to ensure the cluster's health status accurately reflects its fault tolerance level. The number of tolerated failures is as follows:
|
||||
- `single`: 0 failures
|
||||
- `double`: 1 failure
|
||||
- `triple` and datacenter-aware modes: 2 failures
|
||||
|
||||
For example, with the default configuration (`redundancyMode: double` and 3 storage pods), `minReplicas` will be set to 2.
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- Use SSD storage for better performance
|
||||
- Consider dedicating nodes for storage processes
|
||||
- Monitor cluster metrics for optimization opportunities
|
||||
- Scale storage and stateless processes based on workload
|
||||
|
||||
## Support
|
||||
|
||||
For issues related to FoundationDB itself, refer to the [FoundationDB documentation](https://apple.github.io/foundationdb/).
|
||||
|
||||
For Cozystack-specific issues, consult the Cozystack documentation or support channels.
|
||||
|
||||
## Parameters
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------------------ |
|
||||
| `cluster` | Cluster configuration. | `object` | `{}` |
|
||||
| `cluster.processCounts` | Process counts for different roles. | `object` | `{}` |
|
||||
| `cluster.processCounts.stateless` | Number of stateless processes (-1 for automatic). | `int` | `-1` |
|
||||
| `cluster.processCounts.storage` | Number of storage processes (determines cluster size). | `int` | `3` |
|
||||
| `cluster.processCounts.cluster_controller` | Number of cluster controller processes. | `int` | `1` |
|
||||
| `cluster.version` | Version of FoundationDB to use. | `string` | `7.3.63` |
|
||||
| `cluster.redundancyMode` | Database redundancy mode (single, double, triple, three_datacenter, three_datacenter_fallback). | `string` | `double` |
|
||||
| `cluster.storageEngine` | Storage engine (ssd-2, ssd-redwood-v1, ssd-rocksdb-v1, memory). | `string` | `ssd-2` |
|
||||
| `cluster.faultDomain` | Fault domain configuration. | `object` | `{}` |
|
||||
| `cluster.faultDomain.key` | Fault domain key. | `string` | `kubernetes.io/hostname` |
|
||||
| `cluster.faultDomain.valueFrom` | Fault domain value source. | `string` | `spec.nodeName` |
|
||||
| `storage` | Storage configuration. | `object` | `{}` |
|
||||
| `storage.size` | Size of persistent volumes for each instance. | `quantity` | `16Gi` |
|
||||
| `storage.storageClass` | Storage class (if not set, uses cluster default). | `string` | `""` |
|
||||
| `resources` | Explicit CPU and memory configuration for each FoundationDB instance. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `resources.cpu` | CPU available to each instance. | `quantity` | `""` |
|
||||
| `resources.memory` | Memory (RAM) available to each instance. | `quantity` | `""` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `medium` |
|
||||
| `backup` | Backup configuration. | `object` | `{}` |
|
||||
| `backup.enabled` | Enable backups. | `bool` | `false` |
|
||||
| `backup.s3` | S3 configuration for backups. | `object` | `{}` |
|
||||
| `backup.s3.bucket` | S3 bucket name. | `string` | `""` |
|
||||
| `backup.s3.endpoint` | S3 endpoint URL. | `string` | `""` |
|
||||
| `backup.s3.region` | S3 region. | `string` | `us-east-1` |
|
||||
| `backup.s3.credentials` | S3 credentials. | `object` | `{}` |
|
||||
| `backup.s3.credentials.accessKeyId` | S3 access key ID. | `string` | `""` |
|
||||
| `backup.s3.credentials.secretAccessKey` | S3 secret access key. | `string` | `""` |
|
||||
| `backup.retentionPolicy` | Retention policy for backups. | `string` | `7d` |
|
||||
| `monitoring` | Monitoring configuration. | `object` | `{}` |
|
||||
| `monitoring.enabled` | Enable WorkloadMonitor integration. | `bool` | `true` |
|
||||
|
||||
|
||||
### FoundationDB configuration
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------------- | ------------------------------------------ | ---------- | --------- |
|
||||
| `customParameters` | Custom parameters to pass to FoundationDB. | `[]string` | `[]` |
|
||||
| `imageType` | Container image deployment type. | `string` | `unified` |
|
||||
| `securityContext` | Security context for containers. | `object` | `{}` |
|
||||
| `securityContext.runAsUser` | User ID to run the container. | `int` | `4059` |
|
||||
| `securityContext.runAsGroup` | Group ID to run the container. | `int` | `4059` |
|
||||
| `automaticReplacements` | Enable automatic pod replacements. | `bool` | `true` |
|
||||
|
||||
1
packages/apps/foundationdb/charts/cozy-lib
Symbolic link
1
packages/apps/foundationdb/charts/cozy-lib
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../library/cozy-lib
|
||||
106
packages/apps/foundationdb/logos/foundationdb.svg
Normal file
106
packages/apps/foundationdb/logos/foundationdb.svg
Normal file
@@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="144"
|
||||
height="144"
|
||||
viewBox="0 0 144 144"
|
||||
fill="none"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="foundationdb.svg"
|
||||
inkscape:version="1.4.2 (unknown)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview4"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="6.0902778"
|
||||
inkscape:cx="72"
|
||||
inkscape:cy="72.492588"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1128"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<rect
|
||||
width="144"
|
||||
height="144"
|
||||
rx="24"
|
||||
fill="url(#paint0_linear_fdb)"
|
||||
id="rect1"
|
||||
style="fill:#ffffff" />
|
||||
<!-- FoundationDB Icon (scaled and positioned) -->
|
||||
<!-- FoundationDB Text -->
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="paint0_linear_fdb"
|
||||
x1="140"
|
||||
y1="130.5"
|
||||
x2="4"
|
||||
y2="9.49999"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#047BFE"
|
||||
id="stop3" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#3F9AFB"
|
||||
id="stop4" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
id="g1134"
|
||||
transform="matrix(3.132791,0,0,3.132791,-115.98385,6.9294227)">
|
||||
<g
|
||||
transform="matrix(0.08541251,0,0,0.08541251,8.7615159,9.5962543)"
|
||||
id="g10">
|
||||
<polygon
|
||||
style="fill:#3f9afb"
|
||||
class="st0"
|
||||
points="457.2,150.5 457.2,98.6 561.4,124 561.6,164.8 666.6,150.9 666.3,98.7 845.8,143 846.4,189.9 667.4,165.8 560.6,177.3 457.1,165.4 354.2,177.6 354.1,165.7 "
|
||||
id="polygon4" />
|
||||
|
||||
<path
|
||||
style="fill:#0b70e0"
|
||||
inkscape:connector-curvature="0"
|
||||
class="st1"
|
||||
d="m 666.6,183.2 179.6,18.6 v 46 H 353.8 l -0.5,-12.2 h 103.5 c 0,0 0,-34.2 0,-52.3 34.8,3.4 103.8,10.2 103.8,10.2 v 40.9 h 106 z"
|
||||
id="path6" />
|
||||
|
||||
<path
|
||||
style="fill:#9eccfd"
|
||||
inkscape:connector-curvature="0"
|
||||
class="st2"
|
||||
d="m 561.4,109.1 -0.3,-12.6 c 0,0 68.1,-20.4 103.3,-30.8 0,-16.9 0,-33.2 0,-52.9 61.8,24.8 121.2,48.8 181.2,72.9 0,15 0,29.4 0,45.4 -61.5,-16.9 -121.7,-33.5 -180.2,-49.6 -35.6,9.5 -104,27.6 -104,27.6 z"
|
||||
id="path8" />
|
||||
|
||||
</g>
|
||||
<polygon
|
||||
transform="matrix(0.08541251,0,0,0.08541251,8.7795597,9.6869671)"
|
||||
style="fill:#3f9afb"
|
||||
class="st0"
|
||||
points="666.6,150.9 666.3,98.7 845.8,143 846.4,189.9 667.4,165.8 560.6,177.3 457.1,165.4 354.2,177.6 354.1,165.7 457.2,150.5 457.2,98.6 561.4,124 561.6,164.8 "
|
||||
id="polygon856" />
|
||||
<path
|
||||
style="fill:#0b70e0;stroke-width:0.0854125"
|
||||
inkscape:connector-curvature="0"
|
||||
class="st1"
|
||||
d="m 65.715539,25.334539 15.340087,1.588673 v 3.928975 h -42.05712 l -0.04271,-1.042033 h 8.840195 c 0,0 0,-2.921107 0,-4.467074 2.972356,0.290403 8.865819,0.871208 8.865819,0.871208 v 3.493371 h 9.053726 z"
|
||||
id="path858" />
|
||||
<path
|
||||
style="fill:#9eccfd;stroke-width:0.0854125"
|
||||
inkscape:connector-curvature="0"
|
||||
class="st2"
|
||||
d="m 56.730143,19.005472 -0.02562,-1.076198 c 0,0 5.816592,-1.742415 8.823112,-2.630705 0,-1.443471 0,-2.835695 0,-4.518322 5.278493,2.11823 10.351997,4.168131 15.476747,6.226572 0,1.281188 0,2.511128 0,3.877728 -5.252869,-1.443471 -10.394702,-2.861319 -15.391334,-4.23646 -3.040686,0.811419 -8.882901,2.357385 -8.882901,2.357385 z"
|
||||
id="path860" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
47
packages/apps/foundationdb/templates/_resources.tpl
Normal file
47
packages/apps/foundationdb/templates/_resources.tpl
Normal file
@@ -0,0 +1,47 @@
|
||||
{{/*
|
||||
Common resource definitions
|
||||
*/}}
|
||||
{{- define "foundationdb.resources" -}}
|
||||
{{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resources.preset .Values.resources $) }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "foundationdb.labels" -}}
|
||||
helm.sh/chart: {{ include "foundationdb.chart" . }}
|
||||
{{ include "foundationdb.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "foundationdb.selectorLabels" -}}
|
||||
app.kubernetes.io/name: foundationdb
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Chart name and version
|
||||
*/}}
|
||||
{{- define "foundationdb.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Calculate minReplicas for WorkloadMonitor based on redundancyMode
|
||||
*/}}
|
||||
{{- define "foundationdb.minReplicas" -}}
|
||||
{{- $replicas := .Values.cluster.processCounts.storage -}}
|
||||
{{- if or (eq .Values.cluster.redundancyMode "triple") (eq .Values.cluster.redundancyMode "three_data_hall") (eq .Values.cluster.redundancyMode "three_datacenter") (eq .Values.cluster.redundancyMode "three_datacenter_fallback") (eq .Values.cluster.redundancyMode "three_data_hall_fallback") }}
|
||||
{{- print (max 1 (sub $replicas 2)) -}}
|
||||
{{- else if eq .Values.cluster.redundancyMode "double" }}
|
||||
{{- print (max 1 (sub $replicas 1)) -}}
|
||||
{{- else }}
|
||||
{{- print $replicas -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
65
packages/apps/foundationdb/templates/backup.yaml
Normal file
65
packages/apps/foundationdb/templates/backup.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
{{- if .Values.backup.enabled }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-s3-creds
|
||||
labels:
|
||||
app.kubernetes.io/name: foundationdb
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
type: Opaque
|
||||
data:
|
||||
AWS_ACCESS_KEY_ID: {{ .Values.backup.s3.credentials.accessKeyId | b64enc }}
|
||||
AWS_SECRET_ACCESS_KEY: {{ .Values.backup.s3.credentials.secretAccessKey | b64enc }}
|
||||
|
||||
---
|
||||
apiVersion: apps.foundationdb.org/v1beta2
|
||||
kind: FoundationDBBackup
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-backup
|
||||
labels:
|
||||
app.kubernetes.io/name: foundationdb
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
spec:
|
||||
clusterName: {{ .Release.Name }}
|
||||
|
||||
backupState: Running
|
||||
|
||||
backupDeploymentSpec:
|
||||
podTemplateSpec:
|
||||
spec:
|
||||
containers:
|
||||
- name: foundationdb
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
|
||||
customParameters:
|
||||
- backup_agent_snapshot_mode=0
|
||||
|
||||
snapshotPeriodSeconds: 3600
|
||||
|
||||
blobStoreConfiguration:
|
||||
accountName: {{ .Values.backup.s3.bucket }}
|
||||
bucket: {{ .Values.backup.s3.bucket }}
|
||||
{{- if .Values.backup.s3.endpoint }}
|
||||
endpoint: {{ .Values.backup.s3.endpoint }}
|
||||
{{- end }}
|
||||
credentials:
|
||||
AWS_ACCESS_KEY_ID:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-s3-creds
|
||||
key: AWS_ACCESS_KEY_ID
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-s3-creds
|
||||
key: AWS_SECRET_ACCESS_KEY
|
||||
{{- end }}
|
||||
98
packages/apps/foundationdb/templates/cluster.yaml
Normal file
98
packages/apps/foundationdb/templates/cluster.yaml
Normal file
@@ -0,0 +1,98 @@
|
||||
{{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" | default (dict "data" (dict)) }}
|
||||
{{- $clusterDomain := index $cozyConfig.data "cluster-domain" | default "cozy.local" }}
|
||||
---
|
||||
apiVersion: apps.foundationdb.org/v1beta2
|
||||
kind: FoundationDBCluster
|
||||
metadata:
|
||||
name: {{ .Release.Name }}
|
||||
labels:
|
||||
app.kubernetes.io/name: foundationdb
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
spec:
|
||||
version: {{ .Values.cluster.version | quote }}
|
||||
|
||||
databaseConfiguration:
|
||||
redundancy_mode: {{ .Values.cluster.redundancyMode }}
|
||||
storage_engine: {{ .Values.cluster.storageEngine }}
|
||||
|
||||
processCounts:
|
||||
{{- toYaml .Values.cluster.processCounts | nindent 4 }}
|
||||
|
||||
automationOptions:
|
||||
replacements:
|
||||
enabled: {{ .Values.automaticReplacements }}
|
||||
faultDomain:
|
||||
key: {{ .Values.cluster.faultDomain.key }}
|
||||
{{- if .Values.cluster.faultDomain.valueFrom }}
|
||||
valueFrom: {{ .Values.cluster.faultDomain.valueFrom }}
|
||||
{{- end }}
|
||||
imageType: {{ .Values.imageType }}
|
||||
labels:
|
||||
filterOnOwnerReference: false
|
||||
matchLabels:
|
||||
foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
|
||||
processClassLabels:
|
||||
- foundationdb.org/fdb-process-class
|
||||
processGroupIDLabels:
|
||||
- foundationdb.org/fdb-process-group-id
|
||||
minimumUptimeSecondsForBounce: 60
|
||||
|
||||
processes:
|
||||
general:
|
||||
{{- if .Values.customParameters }}
|
||||
customParameters:
|
||||
{{- range .Values.customParameters }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
podTemplate:
|
||||
metadata:
|
||||
labels:
|
||||
policy.cozystack.io/allow-to-apiserver: "true"
|
||||
spec:
|
||||
serviceAccountName: {{ .Release.Name }}-foundationdb
|
||||
securityContext:
|
||||
fsGroup: {{ .Values.securityContext.runAsGroup }}
|
||||
containers:
|
||||
- name: foundationdb
|
||||
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 16 }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 16 }}
|
||||
- name: foundationdb-kubernetes-sidecar
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 16 }}
|
||||
initContainers:
|
||||
- name: foundationdb-kubernetes-init
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 16 }}
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
{{- if .Values.storage.storageClass }}
|
||||
storageClassName: {{ .Values.storage.storageClass }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.storage.size }}
|
||||
|
||||
routing:
|
||||
dnsDomain: {{ $clusterDomain }}
|
||||
defineDNSLocalityFields: true
|
||||
|
||||
sidecarContainer:
|
||||
enableLivenessProbe: true
|
||||
enableReadinessProbe: true
|
||||
@@ -0,0 +1,22 @@
|
||||
{{- if .Values.monitoring.enabled }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-resourcemap
|
||||
labels:
|
||||
app.kubernetes.io/name: foundationdb
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.cozystack.io/type: dashboard-resourcemap
|
||||
data:
|
||||
resources: |
|
||||
- apiVersion: apps.foundationdb.org/v1beta2
|
||||
kind: FoundationDBCluster
|
||||
name: {{ .Release.Name }}
|
||||
{{- if .Values.backup.enabled }}
|
||||
- apiVersion: apps.foundationdb.org/v1beta2
|
||||
kind: FoundationDBBackup
|
||||
name: {{ .Release.Name }}-backup
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
22
packages/apps/foundationdb/templates/role.yaml
Normal file
22
packages/apps/foundationdb/templates/role.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-foundationdb
|
||||
labels:
|
||||
app.kubernetes.io/name: foundationdb
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
17
packages/apps/foundationdb/templates/rolebinding.yaml
Normal file
17
packages/apps/foundationdb/templates/rolebinding.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-foundationdb
|
||||
labels:
|
||||
app.kubernetes.io/name: foundationdb
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ .Release.Name }}-foundationdb
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Release.Name }}-foundationdb
|
||||
namespace: {{ .Release.Namespace }}
|
||||
9
packages/apps/foundationdb/templates/serviceaccount.yaml
Normal file
9
packages/apps/foundationdb/templates/serviceaccount.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-foundationdb
|
||||
labels:
|
||||
app.kubernetes.io/name: foundationdb
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
20
packages/apps/foundationdb/templates/workloadmonitor.yaml
Normal file
20
packages/apps/foundationdb/templates/workloadmonitor.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
{{- if .Values.monitoring.enabled }}
|
||||
---
|
||||
apiVersion: cozystack.io/v1alpha1
|
||||
kind: WorkloadMonitor
|
||||
metadata:
|
||||
name: {{ .Release.Name }}
|
||||
labels:
|
||||
app.kubernetes.io/name: foundationdb
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
spec:
|
||||
replicas: {{ .Values.cluster.processCounts.storage }}
|
||||
minReplicas: {{ include "foundationdb.minReplicas" . }}
|
||||
kind: foundationdb
|
||||
type: foundationdb
|
||||
selector:
|
||||
foundationdb.org/fdb-cluster-name: {{ .Release.Name }}
|
||||
foundationdb.org/fdb-process-class: storage
|
||||
version: {{ .Chart.Version }}
|
||||
{{- end }}
|
||||
287
packages/apps/foundationdb/values.schema.json
Normal file
287
packages/apps/foundationdb/values.schema.json
Normal file
@@ -0,0 +1,287 @@
|
||||
{
|
||||
"title": "Chart Values",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"automaticReplacements": {
|
||||
"description": "Enable automatic pod replacements.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"backup": {
|
||||
"description": "Backup configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"enabled",
|
||||
"retentionPolicy",
|
||||
"s3"
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable backups.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"retentionPolicy": {
|
||||
"description": "Retention policy for backups.",
|
||||
"type": "string",
|
||||
"default": "7d"
|
||||
},
|
||||
"s3": {
|
||||
"description": "S3 configuration for backups.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"bucket",
|
||||
"credentials",
|
||||
"endpoint",
|
||||
"region"
|
||||
],
|
||||
"properties": {
|
||||
"bucket": {
|
||||
"description": "S3 bucket name.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"credentials": {
|
||||
"description": "S3 credentials.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"accessKeyId",
|
||||
"secretAccessKey"
|
||||
],
|
||||
"properties": {
|
||||
"accessKeyId": {
|
||||
"description": "S3 access key ID.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"secretAccessKey": {
|
||||
"description": "S3 secret access key.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"endpoint": {
|
||||
"description": "S3 endpoint URL.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"region": {
|
||||
"description": "S3 region.",
|
||||
"type": "string",
|
||||
"default": "us-east-1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cluster": {
|
||||
"description": "Cluster configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"faultDomain",
|
||||
"processCounts",
|
||||
"redundancyMode",
|
||||
"storageEngine",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"faultDomain": {
|
||||
"description": "Fault domain configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"key",
|
||||
"valueFrom"
|
||||
],
|
||||
"properties": {
|
||||
"key": {
|
||||
"description": "Fault domain key.",
|
||||
"type": "string",
|
||||
"default": "kubernetes.io/hostname"
|
||||
},
|
||||
"valueFrom": {
|
||||
"description": "Fault domain value source.",
|
||||
"type": "string",
|
||||
"default": "spec.nodeName"
|
||||
}
|
||||
}
|
||||
},
|
||||
"processCounts": {
|
||||
"description": "Process counts for different roles.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"cluster_controller",
|
||||
"stateless",
|
||||
"storage"
|
||||
],
|
||||
"properties": {
|
||||
"cluster_controller": {
|
||||
"description": "Number of cluster controller processes.",
|
||||
"type": "integer",
|
||||
"default": 1
|
||||
},
|
||||
"stateless": {
|
||||
"description": "Number of stateless processes (-1 for automatic).",
|
||||
"type": "integer",
|
||||
"default": -1
|
||||
},
|
||||
"storage": {
|
||||
"description": "Number of storage processes (determines cluster size).",
|
||||
"type": "integer",
|
||||
"default": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
"redundancyMode": {
|
||||
"description": "Database redundancy mode (single, double, triple, three_datacenter, three_datacenter_fallback).",
|
||||
"type": "string",
|
||||
"default": "double"
|
||||
},
|
||||
"storageEngine": {
|
||||
"description": "Storage engine (ssd-2, ssd-redwood-v1, ssd-rocksdb-v1, memory).",
|
||||
"type": "string",
|
||||
"default": "ssd-2"
|
||||
},
|
||||
"version": {
|
||||
"description": "Version of FoundationDB to use.",
|
||||
"type": "string",
|
||||
"default": "7.3.63"
|
||||
}
|
||||
}
|
||||
},
|
||||
"customParameters": {
|
||||
"description": "Custom parameters to pass to FoundationDB.",
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"imageType": {
|
||||
"description": "Container image deployment type.",
|
||||
"type": "string",
|
||||
"default": "unified",
|
||||
"enum": [
|
||||
"unified",
|
||||
"split"
|
||||
]
|
||||
},
|
||||
"monitoring": {
|
||||
"description": "Monitoring configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"enabled"
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable WorkloadMonitor integration.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each FoundationDB instance. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each instance.",
|
||||
"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 instance.",
|
||||
"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": "medium",
|
||||
"enum": [
|
||||
"small",
|
||||
"medium",
|
||||
"large",
|
||||
"xlarge",
|
||||
"2xlarge"
|
||||
]
|
||||
},
|
||||
"securityContext": {
|
||||
"description": "Security context for containers.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"runAsGroup",
|
||||
"runAsUser"
|
||||
],
|
||||
"properties": {
|
||||
"runAsGroup": {
|
||||
"description": "Group ID to run the container.",
|
||||
"type": "integer",
|
||||
"default": 4059
|
||||
},
|
||||
"runAsUser": {
|
||||
"description": "User ID to run the container.",
|
||||
"type": "integer",
|
||||
"default": 4059
|
||||
}
|
||||
}
|
||||
},
|
||||
"storage": {
|
||||
"description": "Storage configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"size",
|
||||
"storageClass"
|
||||
],
|
||||
"properties": {
|
||||
"size": {
|
||||
"description": "Size of persistent volumes for each instance.",
|
||||
"default": "16Gi",
|
||||
"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": "Storage class (if not set, uses cluster default).",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
packages/apps/foundationdb/values.yaml
Normal file
120
packages/apps/foundationdb/values.yaml
Normal file
@@ -0,0 +1,120 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
|
||||
## @typedef {struct} ClusterProcessCounts - Process counts for different roles.
|
||||
## @field {int} stateless - Number of stateless processes (-1 for automatic).
|
||||
## @field {int} storage - Number of storage processes (determines cluster size).
|
||||
## @field {int} cluster_controller - Number of cluster controller processes.
|
||||
|
||||
## @typedef {struct} ClusterFaultDomain - Fault domain configuration.
|
||||
## @field {string} key - Fault domain key.
|
||||
## @field {string} valueFrom - Fault domain value source.
|
||||
|
||||
## @typedef {struct} Cluster - Cluster configuration.
|
||||
## @field {ClusterProcessCounts} processCounts - Process counts for different roles.
|
||||
## @field {string} version - Version of FoundationDB to use.
|
||||
## @field {string} redundancyMode - Database redundancy mode (single, double, triple, three_datacenter, three_datacenter_fallback).
|
||||
## @field {string} storageEngine - Storage engine (ssd-2, ssd-redwood-v1, ssd-rocksdb-v1, memory).
|
||||
## @field {ClusterFaultDomain} faultDomain - Fault domain configuration.
|
||||
|
||||
## @param {Cluster} cluster - Cluster configuration.
|
||||
cluster:
|
||||
processCounts:
|
||||
stateless: -1
|
||||
storage: 3
|
||||
cluster_controller: 1
|
||||
|
||||
version: "7.3.63"
|
||||
redundancyMode: "double"
|
||||
storageEngine: "ssd-2"
|
||||
|
||||
faultDomain:
|
||||
key: "kubernetes.io/hostname"
|
||||
valueFrom: "spec.nodeName"
|
||||
|
||||
## @typedef {struct} Storage - Storage configuration.
|
||||
## @field {quantity} size - Size of persistent volumes for each instance.
|
||||
## @field {string} storageClass - Storage class (if not set, uses cluster default).
|
||||
|
||||
## @param {Storage} storage - Storage configuration.
|
||||
storage:
|
||||
size: "16Gi"
|
||||
storageClass: ""
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each FoundationDB instance.
|
||||
## @field {quantity} [cpu] - CPU available to each instance.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each instance.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @param {Resources} [resources] - Explicit CPU and memory configuration for each FoundationDB instance. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
resources: {}
|
||||
|
||||
## @param {ResourcesPreset} resourcesPreset="medium" - Default sizing preset used when `resources` is omitted.
|
||||
resourcesPreset: "medium"
|
||||
|
||||
## @typedef {struct} BackupS3Credentials - S3 credentials.
|
||||
## @field {string} accessKeyId - S3 access key ID.
|
||||
## @field {string} secretAccessKey - S3 secret access key.
|
||||
|
||||
## @typedef {struct} BackupS3 - S3 configuration for backups.
|
||||
## @field {string} bucket - S3 bucket name.
|
||||
## @field {string} endpoint - S3 endpoint URL.
|
||||
## @field {string} region - S3 region.
|
||||
## @field {BackupS3Credentials} credentials - S3 credentials.
|
||||
|
||||
## @typedef {struct} Backup - Backup configuration.
|
||||
## @field {bool} enabled - Enable backups.
|
||||
## @field {BackupS3} s3 - S3 configuration for backups.
|
||||
## @field {string} retentionPolicy - Retention policy for backups.
|
||||
|
||||
## @param {Backup} backup - Backup configuration.
|
||||
backup:
|
||||
enabled: false
|
||||
s3:
|
||||
bucket: ""
|
||||
endpoint: ""
|
||||
region: "us-east-1"
|
||||
credentials:
|
||||
accessKeyId: ""
|
||||
secretAccessKey: ""
|
||||
retentionPolicy: "7d"
|
||||
|
||||
## @typedef {struct} Monitoring - Monitoring configuration.
|
||||
## @field {bool} enabled - Enable WorkloadMonitor integration.
|
||||
|
||||
## @param {Monitoring} monitoring - Monitoring configuration.
|
||||
monitoring:
|
||||
enabled: true
|
||||
|
||||
##
|
||||
## @section FoundationDB configuration
|
||||
##
|
||||
|
||||
## @param {[]string} customParameters - Custom parameters to pass to FoundationDB.
|
||||
customParameters: []
|
||||
|
||||
## @enum {string} ImageType - Container image deployment type.
|
||||
## @value unified
|
||||
## @value split
|
||||
|
||||
## @param {ImageType} imageType="unified" - Container image deployment type.
|
||||
imageType: "unified"
|
||||
|
||||
## @typedef {struct} SecurityContext - Security context for containers.
|
||||
## @field {int} runAsUser - User ID to run the container.
|
||||
## @field {int} runAsGroup - Group ID to run the container.
|
||||
|
||||
## @param {SecurityContext} securityContext - Security context for containers.
|
||||
securityContext:
|
||||
runAsUser: 4059
|
||||
runAsGroup: 4059
|
||||
|
||||
## @param {bool} automaticReplacements - Enable automatic pod replacements.
|
||||
automaticReplacements: true
|
||||
@@ -62,40 +62,40 @@ The deployment architecture is illustrated in the diagram below:
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| -------------- | ------------------------------------------------------------ | ---------- | ------- |
|
||||
| `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` |
|
||||
| `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` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ----------- | ----------------------------------------------- | ---------- | ----- |
|
||||
| `endpoints` | Endpoints configuration, as a list of <ip:port> | `[]string` | `[]` |
|
||||
| Name | Description | Type | Value |
|
||||
| ----------- | ------------------------------------------------ | ---------- | ----- |
|
||||
| `endpoints` | Endpoints configuration, as a list of <ip:port>. | `[]string` | `[]` |
|
||||
|
||||
|
||||
### HAProxy parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------ |
|
||||
| `haproxy` | HAProxy configuration | `object` | `{}` |
|
||||
| `haproxy.replicas` | Number of HAProxy replicas | `int` | `2` |
|
||||
| `haproxy.resources` | Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `haproxy.resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `haproxy.resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `haproxy.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `nano` |
|
||||
| Name | Description | Type | Value |
|
||||
| -------------------------- | -------------------------------------------------------------------------------------------------------- | ---------- | ------ |
|
||||
| `haproxy` | HAProxy configuration. | `object` | `{}` |
|
||||
| `haproxy.replicas` | Number of HAProxy replicas. | `int` | `2` |
|
||||
| `haproxy.resources` | Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `haproxy.resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `haproxy.resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `haproxy.resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `nano` |
|
||||
|
||||
|
||||
### Nginx parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------ |
|
||||
| `nginx` | Nginx configuration | `object` | `{}` |
|
||||
| `nginx.replicas` | Number of Nginx replicas | `int` | `2` |
|
||||
| `nginx.resources` | Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `nginx.resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `nginx.resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `nginx.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `nano` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | -------------------------------------------------------------------------------------------------------- | ---------- | ------ |
|
||||
| `nginx` | Nginx configuration. | `object` | `{}` |
|
||||
| `nginx.replicas` | Number of Nginx replicas. | `int` | `2` |
|
||||
| `nginx.resources` | Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `nginx.resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `nginx.resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `nginx.resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `nano` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"endpoints": {
|
||||
"description": "Endpoints configuration, as a list of \u003cip:port\u003e",
|
||||
"description": "Endpoints configuration, as a list of \u003cip:port\u003e.",
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
@@ -11,32 +11,31 @@
|
||||
}
|
||||
},
|
||||
"external": {
|
||||
"description": "Enable external access from outside the cluster",
|
||||
"description": "Enable external access from outside the cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"haproxy": {
|
||||
"description": "HAProxy configuration",
|
||||
"description": "HAProxy configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"replicas",
|
||||
"resources",
|
||||
"resourcesPreset"
|
||||
],
|
||||
"properties": {
|
||||
"replicas": {
|
||||
"description": "Number of HAProxy replicas",
|
||||
"description": "Number of HAProxy replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each replica",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -49,7 +48,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -64,7 +63,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "nano",
|
||||
"enum": [
|
||||
@@ -80,7 +79,7 @@
|
||||
}
|
||||
},
|
||||
"nginx": {
|
||||
"description": "Nginx configuration",
|
||||
"description": "Nginx configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -89,17 +88,17 @@
|
||||
],
|
||||
"properties": {
|
||||
"replicas": {
|
||||
"description": "Number of Nginx replicas",
|
||||
"description": "Number of Nginx replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each replica",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -112,7 +111,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -127,7 +126,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "nano",
|
||||
"enum": [
|
||||
@@ -143,7 +142,7 @@
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume Claim size, available for application data",
|
||||
"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": [
|
||||
@@ -157,8 +156,9 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,22 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param size {quantity} Persistent Volume Claim size, available for application data
|
||||
size: 10Gi
|
||||
## @param storageClass {string} StorageClass used to store the data
|
||||
storageClass: ""
|
||||
## @param external {bool} Enable external access from outside the cluster
|
||||
external: false
|
||||
## @section Application-specific parameters
|
||||
|
||||
## @param endpoints {[]string} Endpoints configuration, as a list of <ip:port>
|
||||
## @param {quantity} size - Persistent Volume Claim size available for application data.
|
||||
size: 10Gi
|
||||
|
||||
## @param {string} storageClass - StorageClass used to store the data.
|
||||
storageClass: ""
|
||||
|
||||
## @param {bool} external - Enable external access from outside the cluster.
|
||||
external: false
|
||||
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
|
||||
## @param {[]string} endpoints - Endpoints configuration, as a list of <ip:port>.
|
||||
endpoints: []
|
||||
## Example:
|
||||
## endpoints:
|
||||
## - 10.100.3.1:80
|
||||
@@ -17,37 +25,46 @@ external: false
|
||||
## - 10.100.3.12:80
|
||||
## - 10.100.3.3:80
|
||||
## - 10.100.3.13:80
|
||||
|
||||
##
|
||||
endpoints: []
|
||||
|
||||
|
||||
## @section HAProxy parameters
|
||||
##
|
||||
## @param haproxy {haproxy} HAProxy configuration
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @typedef {struct} HAProxy - HAProxy configuration.
|
||||
## @field {int} replicas - Number of HAProxy replicas.
|
||||
## @field {Resources} [resources] - Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
## @field {ResourcesPreset} resourcesPreset - Default sizing preset used when `resources` is omitted.
|
||||
|
||||
## @param {HAProxy} haproxy - HAProxy configuration.
|
||||
haproxy:
|
||||
## @field haproxy.replicas {int} Number of HAProxy replicas
|
||||
replicas: 2
|
||||
## @field haproxy.resources {resources} Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
resources: {}
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
## @field haproxy.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
resourcesPreset: "nano"
|
||||
|
||||
##
|
||||
## @section Nginx parameters
|
||||
##
|
||||
## @param nginx {nginx} Nginx configuration
|
||||
nginx:
|
||||
## @field nginx.replicas {int} Number of Nginx replicas
|
||||
replicas: 2
|
||||
## @field nginx.resources {*resources} Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
resources: {}
|
||||
|
||||
## @field nginx.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
## @typedef {struct} Nginx - Nginx configuration.
|
||||
## @field {int} replicas - Number of Nginx replicas.
|
||||
## @field {Resources} [resources] - Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
## @field {ResourcesPreset} resourcesPreset - Default sizing preset used when `resources` is omitted.
|
||||
|
||||
## @param {Nginx} nginx - Nginx configuration.
|
||||
nginx:
|
||||
replicas: 2
|
||||
resources: {}
|
||||
resourcesPreset: "nano"
|
||||
|
||||
@@ -4,48 +4,48 @@
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ---------- | ----------------------------------------------- | ------ | ------- |
|
||||
| `external` | Enable external access from outside the cluster | `bool` | `false` |
|
||||
| Name | Description | Type | Value |
|
||||
| ---------- | ------------------------------------------------ | ------ | ------- |
|
||||
| `external` | Enable external access from outside the cluster. | `bool` | `false` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------- | -------------------- | ---------- | ----- |
|
||||
| `topics` | Topics configuration | `[]object` | `[]` |
|
||||
| `topics[i].name` | Topic name | `string` | `""` |
|
||||
| `topics[i].partitions` | Number of partitions | `int` | `0` |
|
||||
| `topics[i].replicas` | Number of replicas | `int` | `0` |
|
||||
| `topics[i].config` | Topic configuration | `object` | `{}` |
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------- | --------------------- | ---------- | ----- |
|
||||
| `topics` | Topics configuration. | `[]object` | `[]` |
|
||||
| `topics[i].name` | Topic name. | `string` | `""` |
|
||||
| `topics[i].partitions` | Number of partitions. | `int` | `0` |
|
||||
| `topics[i].replicas` | Number of replicas. | `int` | `0` |
|
||||
| `topics[i].config` | Topic configuration. | `object` | `{}` |
|
||||
|
||||
|
||||
### Kafka configuration
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `kafka` | Kafka configuration | `object` | `{}` |
|
||||
| `kafka.replicas` | Number of Kafka replicas | `int` | `3` |
|
||||
| `kafka.resources` | Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `kafka.resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `kafka.resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `kafka.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `small` |
|
||||
| `kafka.size` | Persistent Volume size for Kafka | `quantity` | `10Gi` |
|
||||
| `kafka.storageClass` | StorageClass used to store the Kafka data | `string` | `""` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | -------------------------------------------------------------------------------------------------------- | ---------- | ------- |
|
||||
| `kafka` | Kafka configuration. | `object` | `{}` |
|
||||
| `kafka.replicas` | Number of Kafka replicas. | `int` | `3` |
|
||||
| `kafka.resources` | Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `kafka.resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `kafka.resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `kafka.resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `small` |
|
||||
| `kafka.size` | Persistent Volume size for Kafka. | `quantity` | `10Gi` |
|
||||
| `kafka.storageClass` | StorageClass used to store the Kafka data. | `string` | `""` |
|
||||
|
||||
|
||||
### Zookeeper configuration
|
||||
### ZooKeeper configuration
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `zookeeper` | Zookeeper configuration | `object` | `{}` |
|
||||
| `zookeeper.replicas` | Number of ZooKeeper replicas | `int` | `3` |
|
||||
| `zookeeper.resources` | Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `zookeeper.resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `zookeeper.resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `zookeeper.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `small` |
|
||||
| `zookeeper.size` | Persistent Volume size for ZooKeeper | `quantity` | `5Gi` |
|
||||
| `zookeeper.storageClass` | StorageClass used to store the ZooKeeper data | `string` | `""` |
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------------------------------- | ---------- | ------- |
|
||||
| `zookeeper` | ZooKeeper configuration. | `object` | `{}` |
|
||||
| `zookeeper.replicas` | Number of ZooKeeper replicas. | `int` | `3` |
|
||||
| `zookeeper.resources` | Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `zookeeper.resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `zookeeper.resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `zookeeper.resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `small` |
|
||||
| `zookeeper.size` | Persistent Volume size for ZooKeeper. | `quantity` | `5Gi` |
|
||||
| `zookeeper.storageClass` | StorageClass used to store the ZooKeeper data. | `string` | `""` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"external": {
|
||||
"description": "Enable external access from outside the cluster",
|
||||
"description": "Enable external access from outside the cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"kafka": {
|
||||
"description": "Kafka configuration",
|
||||
"description": "Kafka configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -19,17 +19,17 @@
|
||||
],
|
||||
"properties": {
|
||||
"replicas": {
|
||||
"description": "Number of Kafka replicas",
|
||||
"description": "Number of Kafka replicas.",
|
||||
"type": "integer",
|
||||
"default": 3
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each replica",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -42,7 +42,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -57,7 +57,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "small",
|
||||
"enum": [
|
||||
@@ -71,7 +71,7 @@
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume size for Kafka",
|
||||
"description": "Persistent Volume size for Kafka.",
|
||||
"default": "10Gi",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
@@ -85,13 +85,14 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the Kafka data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the Kafka data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"topics": {
|
||||
"description": "Topics configuration",
|
||||
"description": "Topics configuration.",
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
@@ -104,27 +105,27 @@
|
||||
],
|
||||
"properties": {
|
||||
"config": {
|
||||
"description": "Topic configuration",
|
||||
"description": "Topic configuration.",
|
||||
"type": "object",
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
},
|
||||
"name": {
|
||||
"description": "Topic name",
|
||||
"description": "Topic name.",
|
||||
"type": "string"
|
||||
},
|
||||
"partitions": {
|
||||
"description": "Number of partitions",
|
||||
"description": "Number of partitions.",
|
||||
"type": "integer"
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of replicas",
|
||||
"description": "Number of replicas.",
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"zookeeper": {
|
||||
"description": "Zookeeper configuration",
|
||||
"description": "ZooKeeper configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -135,17 +136,17 @@
|
||||
],
|
||||
"properties": {
|
||||
"replicas": {
|
||||
"description": "Number of ZooKeeper replicas",
|
||||
"description": "Number of ZooKeeper replicas.",
|
||||
"type": "integer",
|
||||
"default": 3
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each replica",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -158,7 +159,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -173,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "small",
|
||||
"enum": [
|
||||
@@ -187,7 +188,7 @@
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume size for ZooKeeper",
|
||||
"description": "Persistent Volume size for ZooKeeper.",
|
||||
"default": "5Gi",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
@@ -201,8 +202,9 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the ZooKeeper data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the ZooKeeper data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param external {bool} Enable external access from outside the cluster
|
||||
|
||||
## @param {bool} external - Enable external access from outside the cluster.
|
||||
external: false
|
||||
|
||||
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
## @param topics {[]topic} Topics configuration
|
||||
## @field topic {topic} Topic
|
||||
## @field topic.name {string} Topic name
|
||||
## @field topic.partitions {int} Number of partitions
|
||||
## @field topic.replicas {int} Number of replicas
|
||||
## @field topic.config {object} Topic configuration
|
||||
|
||||
## @typedef {struct} Topic - Topic configuration.
|
||||
## @field {string} name - Topic name.
|
||||
## @field {int} partitions - Number of partitions.
|
||||
## @field {int} replicas - Number of replicas.
|
||||
## @field {object} config - Topic configuration.
|
||||
|
||||
## @param {[]Topic} topics - Topics configuration.
|
||||
topics: []
|
||||
## Example:
|
||||
## topics:
|
||||
## - name: Results
|
||||
@@ -27,46 +32,54 @@ external: false
|
||||
## min.insync.replicas: 2
|
||||
## partitions: 1
|
||||
## replicas: 3
|
||||
##
|
||||
topics: []
|
||||
|
||||
##
|
||||
## @section Kafka configuration
|
||||
##
|
||||
## @param kafka {kafka} Kafka configuration
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @typedef {struct} Kafka - Kafka configuration.
|
||||
## @field {int} replicas - Number of Kafka replicas.
|
||||
## @field {Resources} [resources] - Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
## @field {ResourcesPreset} resourcesPreset - Default sizing preset used when `resources` is omitted.
|
||||
## @field {quantity} size - Persistent Volume size for Kafka.
|
||||
## @field {string} storageClass - StorageClass used to store the Kafka data.
|
||||
|
||||
## @param {Kafka} kafka - Kafka configuration.
|
||||
kafka:
|
||||
## @field kafka.replicas {int} Number of Kafka replicas
|
||||
replicas: 3
|
||||
## @field kafka.resources {*resources} Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
resources: {}
|
||||
## @field kafka.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
resourcesPreset: "small"
|
||||
## @field kafka.size {quantity} Persistent Volume size for Kafka
|
||||
size: 10Gi
|
||||
## @field kafka.storageClass {string} StorageClass used to store the Kafka data
|
||||
storageClass: ""
|
||||
|
||||
|
||||
## @section Zookeeper configuration
|
||||
##
|
||||
## @param zookeeper {zookeeper} Zookeeper configuration
|
||||
## @section ZooKeeper configuration
|
||||
##
|
||||
|
||||
## @typedef {struct} ZooKeeper - ZooKeeper configuration.
|
||||
## @field {int} replicas - Number of ZooKeeper replicas.
|
||||
## @field {Resources} [resources] - Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
## @field {ResourcesPreset} resourcesPreset - Default sizing preset used when `resources` is omitted.
|
||||
## @field {quantity} size - Persistent Volume size for ZooKeeper.
|
||||
## @field {string} storageClass - StorageClass used to store the ZooKeeper data.
|
||||
|
||||
## @param {ZooKeeper} zookeeper - ZooKeeper configuration.
|
||||
zookeeper:
|
||||
## @field zookeeper.replicas {int} Number of ZooKeeper replicas
|
||||
replicas: 3
|
||||
## @field zookeeper.resources {*resources} Explicit CPU and memory configuration for each replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
resources: {}
|
||||
|
||||
## @field zookeeper.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
resourcesPreset: "small"
|
||||
## @field zookeeper.size {quantity} Persistent Volume size for ZooKeeper
|
||||
size: 5Gi
|
||||
## @field zookeeper.storageClass {string} StorageClass used to store the ZooKeeper data
|
||||
storageClass: ""
|
||||
|
||||
|
||||
@@ -84,92 +84,92 @@ See the reference for components utilized in this service:
|
||||
|
||||
### Common Parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| -------------- | ----------------------------------- | -------- | ------------ |
|
||||
| `storageClass` | StorageClass used to store the data | `string` | `replicated` |
|
||||
| Name | Description | Type | Value |
|
||||
| -------------- | ------------------------------------ | -------- | ------------ |
|
||||
| `storageClass` | StorageClass used to store the data. | `string` | `replicated` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
### Application-specific Parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------- | ----------- |
|
||||
| `version` | Kubernetes version given as vMAJOR.MINOR. Available are versions from 1.28 to 1.33. | `string` | `v1.33` |
|
||||
| `host` | Hostname used to access the Kubernetes cluster externally. Defaults to `<cluster-name>.<tenant-host>` when empty. | `string` | `""` |
|
||||
| `nodeGroups` | Worker nodes configuration | `map[string]object` | `{...}` |
|
||||
| `nodeGroups[name].minReplicas` | Minimum amount of replicas | `int` | `0` |
|
||||
| `nodeGroups[name].maxReplicas` | Maximum amount of replicas | `int` | `10` |
|
||||
| `nodeGroups[name].instanceType` | Virtual machine instance type | `string` | `u1.medium` |
|
||||
| `nodeGroups[name].ephemeralStorage` | Ephemeral storage size | `quantity` | `20Gi` |
|
||||
| `nodeGroups[name].roles` | List of node's roles | `[]string` | `[]` |
|
||||
| `nodeGroups[name].resources` | Resources available to each worker node | `object` | `{}` |
|
||||
| `nodeGroups[name].resources.cpu` | CPU available to each worker node | `*quantity` | `null` |
|
||||
| `nodeGroups[name].resources.memory` | Memory (RAM) available to each worker node | `*quantity` | `null` |
|
||||
| `nodeGroups[name].gpus` | List of GPUs to attach (WARN: NVIDIA driver requires at least 4 GiB of RAM) | `[]object` | `{}` |
|
||||
| `nodeGroups[name].gpus[i].name` | Name of GPU, such as "nvidia.com/AD102GL_L40S" | `string` | `""` |
|
||||
| Name | Description | Type | Value |
|
||||
| ----------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------- | ----------- |
|
||||
| `nodeGroups` | Worker nodes configuration map. | `map[string]object` | `{...}` |
|
||||
| `nodeGroups[name].minReplicas` | Minimum number of replicas. | `int` | `0` |
|
||||
| `nodeGroups[name].maxReplicas` | Maximum number of replicas. | `int` | `10` |
|
||||
| `nodeGroups[name].instanceType` | Virtual machine instance type. | `string` | `u1.medium` |
|
||||
| `nodeGroups[name].ephemeralStorage` | Ephemeral storage size. | `quantity` | `20Gi` |
|
||||
| `nodeGroups[name].roles` | List of node roles. | `[]string` | `[]` |
|
||||
| `nodeGroups[name].resources` | CPU and memory resources for each worker node. | `object` | `{}` |
|
||||
| `nodeGroups[name].resources.cpu` | CPU available. | `quantity` | `""` |
|
||||
| `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` |
|
||||
| `host` | External hostname for Kubernetes cluster. Defaults to `<cluster-name>.<tenant-host>` if empty. | `string` | `""` |
|
||||
|
||||
|
||||
### Cluster Addons
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | --------- |
|
||||
| `addons` | Cluster addons configuration | `object` | `{}` |
|
||||
| `addons.certManager` | Cert-manager: automatically creates and manages SSL/TLS certificate | `object` | `{}` |
|
||||
| `addons.certManager.enabled` | Enable cert-manager, which automatically creates and manages SSL/TLS certificates. | `bool` | `false` |
|
||||
| `addons.certManager.valuesOverride` | Custom values to override | `object` | `{}` |
|
||||
| `addons.cilium` | Cilium CNI plugin | `object` | `{}` |
|
||||
| `addons.cilium.valuesOverride` | Custom values to override | `object` | `{}` |
|
||||
| `addons.gatewayAPI` | Gateway API | `object` | `{}` |
|
||||
| `addons.gatewayAPI.enabled` | Enable the Gateway API | `bool` | `false` |
|
||||
| `addons.ingressNginx` | Ingress-NGINX Controller | `object` | `{}` |
|
||||
| `addons.ingressNginx.enabled` | Enable the Ingress-NGINX controller (requires nodes labeled with the 'ingress-nginx' role). | `bool` | `false` |
|
||||
| `addons.ingressNginx.exposeMethod` | Method to expose the Ingress-NGINX controller. Allowed values: `Proxied`, `LoadBalancer`. | `string` | `Proxied` |
|
||||
| `addons.ingressNginx.hosts` | List of domain names that the parent cluster should route to this tenant cluster. Taken into account only when `exposeMethod` is set to `Proxied`. | `[]string` | `[]` |
|
||||
| `addons.ingressNginx.valuesOverride` | Custom values to override | `object` | `{}` |
|
||||
| `addons.gpuOperator` | GPU-operator: NVIDIA GPU Operator | `object` | `{}` |
|
||||
| `addons.gpuOperator.enabled` | Enable the GPU-operator | `bool` | `false` |
|
||||
| `addons.gpuOperator.valuesOverride` | Custom values to override | `object` | `{}` |
|
||||
| `addons.fluxcd` | Flux CD | `object` | `{}` |
|
||||
| `addons.fluxcd.enabled` | Enable FluxCD | `bool` | `false` |
|
||||
| `addons.fluxcd.valuesOverride` | Custom values to override | `object` | `{}` |
|
||||
| `addons.monitoringAgents` | MonitoringAgents | `object` | `{}` |
|
||||
| `addons.monitoringAgents.enabled` | Enable monitoring agents (Fluent Bit and VMAgents) to send logs and metrics. If tenant monitoring is enabled, data is sent to tenant storage; otherwise, it goes to root storage. | `bool` | `false` |
|
||||
| `addons.monitoringAgents.valuesOverride` | Custom values to override | `object` | `{}` |
|
||||
| `addons.verticalPodAutoscaler` | VerticalPodAutoscaler | `object` | `{}` |
|
||||
| `addons.verticalPodAutoscaler.valuesOverride` | Custom values to override | `object` | `{}` |
|
||||
| `addons.velero` | Velero | `object` | `{}` |
|
||||
| `addons.velero.enabled` | Enable Velero for backup and recovery of a tenant Kubernetes cluster. | `bool` | `false` |
|
||||
| `addons.velero.valuesOverride` | Custom values to override | `object` | `{}` |
|
||||
| `addons.coredns` | Coredns | `object` | `{}` |
|
||||
| `addons.coredns.valuesOverride` | Custom values to override | `object` | `{}` |
|
||||
| Name | Description | Type | Value |
|
||||
| --------------------------------------------- | --------------------------------------------------------------------------- | ---------- | --------- |
|
||||
| `addons` | Cluster addons configuration. | `object` | `{}` |
|
||||
| `addons.certManager` | Cert-manager addon. | `object` | `{}` |
|
||||
| `addons.certManager.enabled` | Enable cert-manager. | `bool` | `false` |
|
||||
| `addons.certManager.valuesOverride` | Custom Helm values overrides. | `object` | `{}` |
|
||||
| `addons.cilium` | Cilium CNI plugin. | `object` | `{}` |
|
||||
| `addons.cilium.valuesOverride` | Custom Helm values overrides. | `object` | `{}` |
|
||||
| `addons.gatewayAPI` | Gateway API addon. | `object` | `{}` |
|
||||
| `addons.gatewayAPI.enabled` | Enable Gateway API. | `bool` | `false` |
|
||||
| `addons.ingressNginx` | Ingress-NGINX controller. | `object` | `{}` |
|
||||
| `addons.ingressNginx.enabled` | Enable the controller (requires nodes labeled `ingress-nginx`). | `bool` | `false` |
|
||||
| `addons.ingressNginx.exposeMethod` | Method to expose the controller. Allowed values: `Proxied`, `LoadBalancer`. | `string` | `Proxied` |
|
||||
| `addons.ingressNginx.hosts` | Domains routed to this tenant cluster when `exposeMethod` is `Proxied`. | `[]string` | `[]` |
|
||||
| `addons.ingressNginx.valuesOverride` | Custom Helm values overrides. | `object` | `{}` |
|
||||
| `addons.gpuOperator` | NVIDIA GPU Operator. | `object` | `{}` |
|
||||
| `addons.gpuOperator.enabled` | Enable GPU Operator. | `bool` | `false` |
|
||||
| `addons.gpuOperator.valuesOverride` | Custom Helm values overrides. | `object` | `{}` |
|
||||
| `addons.fluxcd` | FluxCD GitOps operator. | `object` | `{}` |
|
||||
| `addons.fluxcd.enabled` | Enable FluxCD. | `bool` | `false` |
|
||||
| `addons.fluxcd.valuesOverride` | Custom Helm values overrides. | `object` | `{}` |
|
||||
| `addons.monitoringAgents` | Monitoring agents. | `object` | `{}` |
|
||||
| `addons.monitoringAgents.enabled` | Enable monitoring agents. | `bool` | `false` |
|
||||
| `addons.monitoringAgents.valuesOverride` | Custom Helm values overrides. | `object` | `{}` |
|
||||
| `addons.verticalPodAutoscaler` | Vertical Pod Autoscaler. | `object` | `{}` |
|
||||
| `addons.verticalPodAutoscaler.valuesOverride` | Custom Helm values overrides. | `object` | `{}` |
|
||||
| `addons.velero` | Velero backup/restore addon. | `object` | `{}` |
|
||||
| `addons.velero.enabled` | Enable Velero. | `bool` | `false` |
|
||||
| `addons.velero.valuesOverride` | Custom Helm values overrides. | `object` | `{}` |
|
||||
| `addons.coredns` | CoreDNS addon. | `object` | `{}` |
|
||||
| `addons.coredns.valuesOverride` | Custom Helm values overrides. | `object` | `{}` |
|
||||
|
||||
|
||||
### Kubernetes Control Plane Configuration
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -------- |
|
||||
| `controlPlane` | Control Plane Configuration | `object` | `{}` |
|
||||
| `controlPlane.replicas` | Number of replicas for Kubernetes control plane components. | `int` | `2` |
|
||||
| `controlPlane.apiServer` | Control plane API server configuration. | `object` | `{}` |
|
||||
| `controlPlane.apiServer.resources` | Explicit CPU and memory configuration for the API Server. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `controlPlane.apiServer.resources.cpu` | CPU available to each worker node | `*quantity` | `null` |
|
||||
| `controlPlane.apiServer.resources.memory` | Memory (RAM) available to each worker node | `*quantity` | `null` |
|
||||
| `controlPlane.apiServer.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `medium` |
|
||||
| `controlPlane.controllerManager` | Controller Manager configuration. | `object` | `{}` |
|
||||
| `controlPlane.controllerManager.resources` | Explicit CPU and memory configuration for the Controller Manager. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `controlPlane.controllerManager.resources.cpu` | CPU available to each worker node | `*quantity` | `null` |
|
||||
| `controlPlane.controllerManager.resources.memory` | Memory (RAM) available to each worker node | `*quantity` | `null` |
|
||||
| `controlPlane.controllerManager.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `micro` |
|
||||
| `controlPlane.scheduler` | Scheduler configuration. | `object` | `{}` |
|
||||
| `controlPlane.scheduler.resources` | Explicit CPU and memory configuration for the Scheduler. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `controlPlane.scheduler.resources.cpu` | CPU available to each worker node | `*quantity` | `null` |
|
||||
| `controlPlane.scheduler.resources.memory` | Memory (RAM) available to each worker node | `*quantity` | `null` |
|
||||
| `controlPlane.scheduler.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `micro` |
|
||||
| `controlPlane.konnectivity` | Konnectivity configuration. | `object` | `{}` |
|
||||
| `controlPlane.konnectivity.server` | Konnectivity server configuration. | `object` | `{}` |
|
||||
| `controlPlane.konnectivity.server.resources` | Explicit CPU and memory configuration for Konnectivity. When left empty, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `controlPlane.konnectivity.server.resources.cpu` | CPU available to each worker node | `*quantity` | `null` |
|
||||
| `controlPlane.konnectivity.server.resources.memory` | Memory (RAM) available to each worker node | `*quantity` | `null` |
|
||||
| `controlPlane.konnectivity.server.resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `micro` |
|
||||
| Name | Description | Type | Value |
|
||||
| --------------------------------------------------- | ------------------------------------------------ | ---------- | -------- |
|
||||
| `controlPlane` | Kubernetes control-plane configuration. | `object` | `{}` |
|
||||
| `controlPlane.replicas` | Number of control-plane replicas. | `int` | `2` |
|
||||
| `controlPlane.apiServer` | API Server configuration. | `object` | `{}` |
|
||||
| `controlPlane.apiServer.resources` | CPU and memory resources for API Server. | `object` | `{}` |
|
||||
| `controlPlane.apiServer.resources.cpu` | CPU available. | `quantity` | `""` |
|
||||
| `controlPlane.apiServer.resources.memory` | Memory (RAM) available. | `quantity` | `""` |
|
||||
| `controlPlane.apiServer.resourcesPreset` | Preset if `resources` omitted. | `string` | `medium` |
|
||||
| `controlPlane.controllerManager` | Controller Manager configuration. | `object` | `{}` |
|
||||
| `controlPlane.controllerManager.resources` | CPU and memory resources for Controller Manager. | `object` | `{}` |
|
||||
| `controlPlane.controllerManager.resources.cpu` | CPU available. | `quantity` | `""` |
|
||||
| `controlPlane.controllerManager.resources.memory` | Memory (RAM) available. | `quantity` | `""` |
|
||||
| `controlPlane.controllerManager.resourcesPreset` | Preset if `resources` omitted. | `string` | `micro` |
|
||||
| `controlPlane.scheduler` | Scheduler configuration. | `object` | `{}` |
|
||||
| `controlPlane.scheduler.resources` | CPU and memory resources for Scheduler. | `object` | `{}` |
|
||||
| `controlPlane.scheduler.resources.cpu` | CPU available. | `quantity` | `""` |
|
||||
| `controlPlane.scheduler.resources.memory` | Memory (RAM) available. | `quantity` | `""` |
|
||||
| `controlPlane.scheduler.resourcesPreset` | Preset if `resources` omitted. | `string` | `micro` |
|
||||
| `controlPlane.konnectivity` | Konnectivity configuration. | `object` | `{}` |
|
||||
| `controlPlane.konnectivity.server` | Konnectivity Server configuration. | `object` | `{}` |
|
||||
| `controlPlane.konnectivity.server.resources` | CPU and memory resources for Konnectivity. | `object` | `{}` |
|
||||
| `controlPlane.konnectivity.server.resources.cpu` | CPU available. | `quantity` | `""` |
|
||||
| `controlPlane.konnectivity.server.resources.memory` | Memory (RAM) available. | `quantity` | `""` |
|
||||
| `controlPlane.konnectivity.server.resourcesPreset` | Preset if `resources` omitted. | `string` | `micro` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -1 +1 @@
|
||||
ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:e1c0eb54d0ddadc8c7d72cee4f4282d56c957bf4ff0f62ef37db6b38dd0e8a01
|
||||
ghcr.io/cozystack/cozystack/cluster-autoscaler:0.0.0@sha256:2d39989846c3579dd020b9f6c77e6e314cc81aa344eaac0f6d633e723c17196d
|
||||
|
||||
@@ -1 +1 @@
|
||||
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:47396dac04a24f824f82892c90efa160539e1e0f8ac697f5dc8ecf397e1ac413
|
||||
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:c8b08084a86251cdd18e237de89b695bca0e4f7eb1f1f6ddc2b903b4d74ea5ff
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
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
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
policy.cozystack.io/allow-to-apiserver: "true"
|
||||
spec:
|
||||
serviceAccountName: {{ .Release.Name }}-cleanup
|
||||
restartPolicy: Never
|
||||
tolerations:
|
||||
- key: CriticalAddonsOnly
|
||||
operator: Exists
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
effect: "NoSchedule"
|
||||
containers:
|
||||
- name: kubectl
|
||||
image: docker.io/clastix/kubectl:v1.32
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
echo "Step 1: Suspending all HelmReleases with label cozystack.io/target-cluster-name={{ .Release.Name }}"
|
||||
for hr in $(kubectl -n {{ .Release.Namespace }} get helmreleases.helm.toolkit.fluxcd.io -l "cozystack.io/target-cluster-name={{ .Release.Name }}" -o name 2>/dev/null || true); do
|
||||
if [ -n "$hr" ]; then
|
||||
echo " Suspending $hr"
|
||||
kubectl -n {{ .Release.Namespace }} patch "$hr" \
|
||||
-p '{"spec": {"suspend": true}}' \
|
||||
--type=merge --field-manager=flux-client-side-apply
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Step 2: Deleting HelmReleases with label cozystack.io/target-cluster-name={{ .Release.Name }}"
|
||||
kubectl -n {{ .Release.Namespace }} delete helmreleases.helm.toolkit.fluxcd.io \
|
||||
-l "cozystack.io/target-cluster-name={{ .Release.Name }}" \
|
||||
--ignore-not-found=true --wait=true
|
||||
|
||||
echo "Step 3: Deleting KamajiControlPlane {{ .Release.Name }}"
|
||||
kubectl -n {{ .Release.Namespace }} delete kamajicontrolplanes.controlplane.cluster.x-k8s.io {{ .Release.Name }} \
|
||||
--ignore-not-found=true
|
||||
|
||||
echo "Step 4: Deleting TenantControlPlane {{ .Release.Name }}"
|
||||
kubectl -n {{ .Release.Namespace }} delete tenantcontrolplanes.kamaji.clastix.io {{ .Release.Name }} \
|
||||
--ignore-not-found=true
|
||||
|
||||
echo "Step 5: Cleaning up DataVolumes"
|
||||
kubectl -n {{ .Release.Namespace }} delete datavolumes \
|
||||
-l "cluster.x-k8s.io/cluster-name={{ .Release.Name }}" \
|
||||
--ignore-not-found=true
|
||||
|
||||
echo "Step 6: Cleaning up LoadBalancer Services"
|
||||
kubectl -n {{ .Release.Namespace }} delete services \
|
||||
-l "cluster.x-k8s.io/cluster-name={{ .Release.Name }}" \
|
||||
--field-selector spec.type=LoadBalancer \
|
||||
--ignore-not-found=true
|
||||
|
||||
echo "Cleanup completed successfully"
|
||||
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
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-weight: "0"
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
annotations:
|
||||
"helm.sh/hook": pre-delete
|
||||
"helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation,hook-failed
|
||||
"helm.sh/hook-weight": "5"
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "helm.toolkit.fluxcd.io"
|
||||
resources:
|
||||
- helmreleases
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- "controlplane.cluster.x-k8s.io"
|
||||
resources:
|
||||
- kamajicontrolplanes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- "kamaji.clastix.io"
|
||||
resources:
|
||||
- tenantcontrolplanes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- "cdi.kubevirt.io"
|
||||
resources:
|
||||
- datavolumes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- delete
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
annotations:
|
||||
"helm.sh/hook": pre-delete
|
||||
"helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation,hook-failed
|
||||
"helm.sh/hook-weight": "5"
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
namespace: {{ .Release.Namespace }}
|
||||
103
packages/apps/kubernetes/templates/helmreleases/delete.yaml
Normal file
103
packages/apps/kubernetes/templates/helmreleases/delete.yaml
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
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 }}-flux-teardown
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: {{ .Release.Name }}-flux-teardown
|
||||
restartPolicy: Never
|
||||
tolerations:
|
||||
- key: CriticalAddonsOnly
|
||||
operator: Exists
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
effect: "NoSchedule"
|
||||
containers:
|
||||
- name: kubectl
|
||||
image: docker.io/clastix/kubectl:v1.32
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
kubectl
|
||||
--namespace={{ .Release.Namespace }}
|
||||
patch
|
||||
helmrelease
|
||||
{{ .Release.Name }}-cilium
|
||||
{{ .Release.Name }}-gateway-api-crds
|
||||
{{ .Release.Name }}-csi
|
||||
{{ .Release.Name }}-cert-manager
|
||||
{{ .Release.Name }}-cert-manager-crds
|
||||
{{ .Release.Name }}-vertical-pod-autoscaler
|
||||
{{ .Release.Name }}-vertical-pod-autoscaler-crds
|
||||
{{ .Release.Name }}-ingress-nginx
|
||||
{{ .Release.Name }}-fluxcd-operator
|
||||
{{ .Release.Name }}-fluxcd
|
||||
{{ .Release.Name }}-gpu-operator
|
||||
{{ .Release.Name }}-velero
|
||||
{{ .Release.Name }}-coredns
|
||||
-p '{"spec": {"suspend": true}}'
|
||||
--type=merge --field-manager=flux-client-side-apply || true
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-flux-teardown
|
||||
annotations:
|
||||
helm.sh/hook: pre-delete
|
||||
helm.sh/hook-delete-policy: before-hook-creation,hook-failed
|
||||
helm.sh/hook-weight: "0"
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,post-install,pre-delete
|
||||
"helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation,hook-failed
|
||||
"helm.sh/hook-weight": "5"
|
||||
name: {{ .Release.Name }}-flux-teardown
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "helm.toolkit.fluxcd.io"
|
||||
resources:
|
||||
- helmreleases
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
resourceNames:
|
||||
- {{ .Release.Name }}-cilium
|
||||
- {{ .Release.Name }}-csi
|
||||
- {{ .Release.Name }}-cert-manager
|
||||
- {{ .Release.Name }}-cert-manager-crds
|
||||
- {{ .Release.Name }}-vertical-pod-autoscaler
|
||||
- {{ .Release.Name }}-vertical-pod-autoscaler-crds
|
||||
- {{ .Release.Name }}-ingress-nginx
|
||||
- {{ .Release.Name }}-fluxcd-operator
|
||||
- {{ .Release.Name }}-fluxcd
|
||||
- {{ .Release.Name }}-gpu-operator
|
||||
- {{ .Release.Name }}-velero
|
||||
- {{ .Release.Name }}-coredns
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
annotations:
|
||||
helm.sh/hook: pre-delete
|
||||
helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation,hook-failed
|
||||
helm.sh/hook-weight: "5"
|
||||
name: {{ .Release.Name }}-flux-teardown
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ .Release.Name }}-flux-teardown
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Release.Name }}-flux-teardown
|
||||
namespace: {{ .Release.Namespace }}
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"addons": {
|
||||
"description": "Cluster addons configuration",
|
||||
"description": "Cluster addons configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -20,7 +20,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"certManager": {
|
||||
"description": "Cert-manager: automatically creates and manages SSL/TLS certificate",
|
||||
"description": "Cert-manager addon.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -29,12 +29,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable cert-manager, which automatically creates and manages SSL/TLS certificates.",
|
||||
"description": "Enable cert-manager.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"valuesOverride": {
|
||||
"description": "Custom values to override",
|
||||
"description": "Custom Helm values overrides.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -42,7 +42,7 @@
|
||||
}
|
||||
},
|
||||
"cilium": {
|
||||
"description": "Cilium CNI plugin",
|
||||
"description": "Cilium CNI plugin.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -50,7 +50,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"valuesOverride": {
|
||||
"description": "Custom values to override",
|
||||
"description": "Custom Helm values overrides.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -58,7 +58,7 @@
|
||||
}
|
||||
},
|
||||
"coredns": {
|
||||
"description": "Coredns",
|
||||
"description": "CoreDNS addon.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -66,7 +66,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"valuesOverride": {
|
||||
"description": "Custom values to override",
|
||||
"description": "Custom Helm values overrides.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -74,7 +74,7 @@
|
||||
}
|
||||
},
|
||||
"fluxcd": {
|
||||
"description": "Flux CD",
|
||||
"description": "FluxCD GitOps operator.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -83,12 +83,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable FluxCD",
|
||||
"description": "Enable FluxCD.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"valuesOverride": {
|
||||
"description": "Custom values to override",
|
||||
"description": "Custom Helm values overrides.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -96,7 +96,7 @@
|
||||
}
|
||||
},
|
||||
"gatewayAPI": {
|
||||
"description": "Gateway API",
|
||||
"description": "Gateway API addon.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -104,14 +104,14 @@
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable the Gateway API",
|
||||
"description": "Enable Gateway API.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"gpuOperator": {
|
||||
"description": "GPU-operator: NVIDIA GPU Operator",
|
||||
"description": "NVIDIA GPU Operator.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -120,12 +120,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable the GPU-operator",
|
||||
"description": "Enable GPU Operator.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"valuesOverride": {
|
||||
"description": "Custom values to override",
|
||||
"description": "Custom Helm values overrides.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -133,7 +133,7 @@
|
||||
}
|
||||
},
|
||||
"ingressNginx": {
|
||||
"description": "Ingress-NGINX Controller",
|
||||
"description": "Ingress-NGINX controller.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -143,21 +143,17 @@
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable the Ingress-NGINX controller (requires nodes labeled with the 'ingress-nginx' role).",
|
||||
"description": "Enable the controller (requires nodes labeled `ingress-nginx`).",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"exposeMethod": {
|
||||
"description": "Method to expose the Ingress-NGINX controller. Allowed values: `Proxied`, `LoadBalancer`.",
|
||||
"description": "Method to expose the controller. Allowed values: `Proxied`, `LoadBalancer`.",
|
||||
"type": "string",
|
||||
"default": "Proxied",
|
||||
"enum": [
|
||||
"Proxied",
|
||||
"LoadBalancer"
|
||||
]
|
||||
"default": "Proxied"
|
||||
},
|
||||
"hosts": {
|
||||
"description": "List of domain names that the parent cluster should route to this tenant cluster. Taken into account only when `exposeMethod` is set to `Proxied`.",
|
||||
"description": "Domains routed to this tenant cluster when `exposeMethod` is `Proxied`.",
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
@@ -165,7 +161,7 @@
|
||||
}
|
||||
},
|
||||
"valuesOverride": {
|
||||
"description": "Custom values to override",
|
||||
"description": "Custom Helm values overrides.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -173,7 +169,7 @@
|
||||
}
|
||||
},
|
||||
"monitoringAgents": {
|
||||
"description": "MonitoringAgents",
|
||||
"description": "Monitoring agents.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -182,12 +178,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable monitoring agents (Fluent Bit and VMAgents) to send logs and metrics. If tenant monitoring is enabled, data is sent to tenant storage; otherwise, it goes to root storage.",
|
||||
"description": "Enable monitoring agents.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"valuesOverride": {
|
||||
"description": "Custom values to override",
|
||||
"description": "Custom Helm values overrides.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -195,7 +191,7 @@
|
||||
}
|
||||
},
|
||||
"velero": {
|
||||
"description": "Velero",
|
||||
"description": "Velero backup/restore addon.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -204,12 +200,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable Velero for backup and recovery of a tenant Kubernetes cluster.",
|
||||
"description": "Enable Velero.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"valuesOverride": {
|
||||
"description": "Custom values to override",
|
||||
"description": "Custom Helm values overrides.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -217,7 +213,7 @@
|
||||
}
|
||||
},
|
||||
"verticalPodAutoscaler": {
|
||||
"description": "VerticalPodAutoscaler",
|
||||
"description": "Vertical Pod Autoscaler.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -225,7 +221,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"valuesOverride": {
|
||||
"description": "Custom values to override",
|
||||
"description": "Custom Helm values overrides.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -235,7 +231,7 @@
|
||||
}
|
||||
},
|
||||
"controlPlane": {
|
||||
"description": "Control Plane Configuration",
|
||||
"description": "Kubernetes control-plane configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -247,7 +243,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"apiServer": {
|
||||
"description": "Control plane API server configuration.",
|
||||
"description": "API Server configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -256,12 +252,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for the API Server. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "CPU and memory resources for API Server.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each worker node",
|
||||
"description": "CPU available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -274,7 +270,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each worker node",
|
||||
"description": "Memory (RAM) available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -289,7 +285,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Preset if `resources` omitted.",
|
||||
"type": "string",
|
||||
"default": "medium",
|
||||
"enum": [
|
||||
@@ -314,12 +310,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for the Controller Manager. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "CPU and memory resources for Controller Manager.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each worker node",
|
||||
"description": "CPU available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -332,7 +328,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each worker node",
|
||||
"description": "Memory (RAM) available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -347,7 +343,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Preset if `resources` omitted.",
|
||||
"type": "string",
|
||||
"default": "micro",
|
||||
"enum": [
|
||||
@@ -371,7 +367,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"server": {
|
||||
"description": "Konnectivity server configuration.",
|
||||
"description": "Konnectivity Server configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -380,12 +376,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for Konnectivity. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "CPU and memory resources for Konnectivity.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each worker node",
|
||||
"description": "CPU available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -398,7 +394,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each worker node",
|
||||
"description": "Memory (RAM) available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -413,7 +409,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Preset if `resources` omitted.",
|
||||
"type": "string",
|
||||
"default": "micro",
|
||||
"enum": [
|
||||
@@ -431,7 +427,7 @@
|
||||
}
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of replicas for Kubernetes control plane components.",
|
||||
"description": "Number of control-plane replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
@@ -445,12 +441,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for the Scheduler. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "CPU and memory resources for Scheduler.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each worker node",
|
||||
"description": "CPU available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -463,7 +459,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each worker node",
|
||||
"description": "Memory (RAM) available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -478,7 +474,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Preset if `resources` omitted.",
|
||||
"type": "string",
|
||||
"default": "micro",
|
||||
"enum": [
|
||||
@@ -496,11 +492,12 @@
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"description": "Hostname used to access the Kubernetes cluster externally. Defaults to `<cluster-name>.<tenant-host>` when empty.",
|
||||
"type": "string"
|
||||
"description": "External hostname for Kubernetes cluster. Defaults to `<cluster-name>.<tenant-host>` if empty.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"nodeGroups": {
|
||||
"description": "Worker nodes configuration",
|
||||
"description": "Worker nodes configuration map.",
|
||||
"type": "object",
|
||||
"default": {
|
||||
"md0": {
|
||||
@@ -526,7 +523,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"ephemeralStorage": {
|
||||
"description": "Ephemeral storage size",
|
||||
"description": "Ephemeral storage size.",
|
||||
"default": "20Gi",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
@@ -540,9 +537,8 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"gpus": {
|
||||
"description": "List of GPUs to attach (WARN: NVIDIA driver requires at least 4 GiB of RAM)",
|
||||
"description": "List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).",
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -550,34 +546,33 @@
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "Name of GPU, such as \"nvidia.com/AD102GL_L40S\"",
|
||||
"description": "Name of GPU, such as \"nvidia.com/AD102GL_L40S\".",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"instanceType": {
|
||||
"description": "Virtual machine instance type",
|
||||
"description": "Virtual machine instance type.",
|
||||
"type": "string",
|
||||
"default": "u1.medium"
|
||||
},
|
||||
"maxReplicas": {
|
||||
"description": "Maximum amount of replicas",
|
||||
"description": "Maximum number of replicas.",
|
||||
"type": "integer",
|
||||
"default": 10
|
||||
},
|
||||
"minReplicas": {
|
||||
"description": "Minimum amount of replicas",
|
||||
"description": "Minimum number of replicas.",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"resources": {
|
||||
"description": "Resources available to each worker node",
|
||||
"description": "CPU and memory resources for each worker node.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each worker node",
|
||||
"description": "CPU available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -590,7 +585,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each worker node",
|
||||
"description": "Memory (RAM) available.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -605,7 +600,7 @@
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"description": "List of node's roles",
|
||||
"description": "List of node roles.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
@@ -615,12 +610,12 @@
|
||||
}
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the data",
|
||||
"description": "StorageClass used to store the data.",
|
||||
"type": "string",
|
||||
"default": "replicated"
|
||||
},
|
||||
"version": {
|
||||
"description": "Kubernetes version given as vMAJOR.MINOR. Available are versions from 1.28 to 1.33.",
|
||||
"description": "Kubernetes version (vMAJOR.MINOR). Supported: 1.28–1.33.",
|
||||
"type": "string",
|
||||
"default": "v1.33",
|
||||
"enum": [
|
||||
|
||||
@@ -1,27 +1,40 @@
|
||||
##
|
||||
## @section Common Parameters
|
||||
##
|
||||
|
||||
## @param storageClass {string} StorageClass used to store the data
|
||||
## @param {string} storageClass - StorageClass used to store the data.
|
||||
storageClass: replicated
|
||||
|
||||
## @section Application-specific parameters
|
||||
## @param version {string} Kubernetes version given as vMAJOR.MINOR. Available are versions from 1.28 to 1.33.
|
||||
version: "v1.33"
|
||||
## @param host {string} Hostname used to access the Kubernetes cluster externally. Defaults to `<cluster-name>.<tenant-host>` when empty.
|
||||
host: ""
|
||||
|
||||
## @param nodeGroups {map[string]nodeGroup} Worker nodes configuration
|
||||
## @field nodeGroup {nodeGroup} Node configuration
|
||||
## @field nodeGroup.minReplicas {int default=0} Minimum amount of replicas
|
||||
## @field nodeGroup.maxReplicas {int default=10} Maximum amount of replicas
|
||||
## @field nodeGroup.instanceType {string default="u1.medium"} Virtual machine instance type
|
||||
## @field nodeGroup.ephemeralStorage {quantity default="20Gi"} Ephemeral storage size
|
||||
## @field nodeGroup.roles {[]string default=[]} List of node's roles
|
||||
## @field nodeGroup.resources {resources default={}} Resources available to each worker node
|
||||
## @field resources.cpu {*quantity} CPU available to each worker node
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each worker node
|
||||
## @field nodeGroup.gpus {[]gpu default={}} List of GPUs to attach (WARN: NVIDIA driver requires at least 4 GiB of RAM)
|
||||
## @field gpu.name {string} Name of GPU, such as "nvidia.com/AD102GL_L40S"
|
||||
##
|
||||
## @section Application-specific Parameters
|
||||
##
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for a node or component.
|
||||
## @field {quantity} [cpu] - CPU available.
|
||||
## @field {quantity} [memory] - Memory (RAM) available.
|
||||
|
||||
## @typedef {struct} GPU - GPU configuration.
|
||||
## @field {string} name - Name of GPU, such as "nvidia.com/AD102GL_L40S".
|
||||
|
||||
## @typedef {struct} NodeGroup - Worker node group configuration.
|
||||
## @field {int} minReplicas=0 - Minimum number of replicas.
|
||||
## @field {int} maxReplicas=10 - Maximum number of replicas.
|
||||
## @field {string} instanceType="u1.medium" - Virtual machine instance type.
|
||||
## @field {quantity} ephemeralStorage="20Gi" - Ephemeral storage size.
|
||||
## @field {[]string} roles - List of node roles.
|
||||
## @field {Resources} resources - CPU and memory resources for each worker node.
|
||||
## @field {[]GPU} gpus - List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).
|
||||
|
||||
## @param {map[string]NodeGroup} nodeGroups - Worker nodes configuration map.
|
||||
nodeGroups:
|
||||
md0:
|
||||
minReplicas: 0
|
||||
@@ -31,141 +44,142 @@ nodeGroups:
|
||||
roles:
|
||||
- ingress-nginx
|
||||
resources: {}
|
||||
## List of GPUs to attach (WARN: NVIDIA driver requires at least 4 GiB of RAM)
|
||||
## e.g:
|
||||
## instanceType: "u1.xlarge"
|
||||
## gpus:
|
||||
## - name: nvidia.com/AD102GL_L40S
|
||||
gpus: []
|
||||
|
||||
## @param {string} version - Kubernetes version (vMAJOR.MINOR). Supported: 1.28–1.33.
|
||||
version: "v1.33"
|
||||
|
||||
## @param {string} host - External hostname for Kubernetes cluster. Defaults to `<cluster-name>.<tenant-host>` if empty.
|
||||
host: ""
|
||||
|
||||
##
|
||||
## @section Cluster Addons
|
||||
##
|
||||
## @param addons {addons} Cluster addons configuration
|
||||
|
||||
## @typedef {struct} CertManagerAddon - cert-manager addon.
|
||||
## @field {bool} enabled - Enable cert-manager.
|
||||
## @field {object} valuesOverride - Custom Helm values overrides.
|
||||
|
||||
## @typedef {struct} CiliumAddon - Cilium CNI plugin.
|
||||
## @field {object} valuesOverride - Custom Helm values overrides.
|
||||
|
||||
## @typedef {struct} GatewayAPIAddon - Gateway API addon.
|
||||
## @field {bool} enabled - Enable Gateway API.
|
||||
|
||||
## @typedef {struct} IngressNginxAddon - Ingress-NGINX controller.
|
||||
## @field {bool} enabled - Enable the controller (requires nodes labeled `ingress-nginx`).
|
||||
## @field {string} exposeMethod - Method to expose the controller. Allowed values: `Proxied`, `LoadBalancer`.
|
||||
## @field {[]string} hosts - Domains routed to this tenant cluster when `exposeMethod` is `Proxied`.
|
||||
## @field {object} valuesOverride - Custom Helm values overrides.
|
||||
|
||||
## @typedef {struct} GPUOperatorAddon - NVIDIA GPU Operator.
|
||||
## @field {bool} enabled - Enable GPU Operator.
|
||||
## @field {object} valuesOverride - Custom Helm values overrides.
|
||||
|
||||
## @typedef {struct} FluxCDAddon - FluxCD GitOps operator.
|
||||
## @field {bool} enabled - Enable FluxCD.
|
||||
## @field {object} valuesOverride - Custom Helm values overrides.
|
||||
|
||||
## @typedef {struct} MonitoringAgentsAddon - Monitoring agents (Fluent Bit, VMAgents).
|
||||
## @field {bool} enabled - Enable monitoring agents.
|
||||
## @field {object} valuesOverride - Custom Helm values overrides.
|
||||
|
||||
## @typedef {struct} VerticalPodAutoscalerAddon - Vertical Pod Autoscaler.
|
||||
## @field {object} valuesOverride - Custom Helm values overrides.
|
||||
|
||||
## @typedef {struct} VeleroAddon - Velero backup and recovery addon.
|
||||
## @field {bool} enabled - Enable Velero.
|
||||
## @field {object} valuesOverride - Custom Helm values overrides.
|
||||
|
||||
## @typedef {struct} CoreDNSAddon - CoreDNS addon.
|
||||
## @field {object} valuesOverride - Custom Helm values overrides.
|
||||
|
||||
## @typedef {struct} Addons - Cluster addons configuration.
|
||||
## @field {CertManagerAddon} certManager - Cert-manager addon.
|
||||
## @field {CiliumAddon} cilium - Cilium CNI plugin.
|
||||
## @field {GatewayAPIAddon} gatewayAPI - Gateway API addon.
|
||||
## @field {IngressNginxAddon} ingressNginx - Ingress-NGINX controller.
|
||||
## @field {GPUOperatorAddon} gpuOperator - NVIDIA GPU Operator.
|
||||
## @field {FluxCDAddon} fluxcd - FluxCD GitOps operator.
|
||||
## @field {MonitoringAgentsAddon} monitoringAgents - Monitoring agents.
|
||||
## @field {VerticalPodAutoscalerAddon} verticalPodAutoscaler - Vertical Pod Autoscaler.
|
||||
## @field {VeleroAddon} velero - Velero backup/restore addon.
|
||||
## @field {CoreDNSAddon} coredns - CoreDNS addon.
|
||||
|
||||
## @param {Addons} addons - Cluster addons configuration.
|
||||
addons:
|
||||
## @field addons.certManager {certManager} Cert-manager: automatically creates and manages SSL/TLS certificate
|
||||
##
|
||||
certManager:
|
||||
## @field certManager.enabled {bool} Enable cert-manager, which automatically creates and manages SSL/TLS certificates.
|
||||
enabled: false
|
||||
## @field certManager.valuesOverride {object} Custom values to override
|
||||
valuesOverride: {}
|
||||
|
||||
## @field addons.cilium {cilium} Cilium CNI plugin
|
||||
##
|
||||
cilium:
|
||||
## @field cilium.valuesOverride {object} Custom values to override
|
||||
valuesOverride: {}
|
||||
|
||||
## @field addons.gatewayAPI {gatewayAPI} Gateway API
|
||||
##
|
||||
gatewayAPI:
|
||||
## @field gatewayAPI.enabled {bool} Enable the Gateway API
|
||||
enabled: false
|
||||
|
||||
## @field addons.ingressNginx {ingressNginx} Ingress-NGINX Controller
|
||||
##
|
||||
ingressNginx:
|
||||
## @field ingressNginx.enabled {bool} Enable the Ingress-NGINX controller (requires nodes labeled with the 'ingress-nginx' role).
|
||||
enabled: false
|
||||
## @field ingressNginx.exposeMethod {string enum:"Proxied,LoadBalancer"} Method to expose the Ingress-NGINX controller. Allowed values: `Proxied`, `LoadBalancer`.
|
||||
exposeMethod: Proxied
|
||||
## @field ingressNginx.hosts {[]string} List of domain names that the parent cluster should route to this tenant cluster. Taken into account only when `exposeMethod` is set to `Proxied`.
|
||||
## e.g:
|
||||
## hosts:
|
||||
## - example.org
|
||||
## - foo.example.net
|
||||
##
|
||||
hosts: []
|
||||
## @field ingressNginx.valuesOverride {object} Custom values to override
|
||||
valuesOverride: {}
|
||||
|
||||
## @field addons.gpuOperator {gpuOperator} GPU-operator: NVIDIA GPU Operator
|
||||
##
|
||||
gpuOperator:
|
||||
## @field gpuOperator.enabled {bool} Enable the GPU-operator
|
||||
## @field gpuOperator.valuesOverride {object} Custom values to override
|
||||
enabled: false
|
||||
valuesOverride: {}
|
||||
|
||||
## @field addons.fluxcd {fluxcd} Flux CD
|
||||
##
|
||||
fluxcd:
|
||||
## @field fluxcd.enabled {bool} Enable FluxCD
|
||||
## @field fluxcd.valuesOverride {object} Custom values to override
|
||||
##
|
||||
enabled: false
|
||||
valuesOverride: {}
|
||||
|
||||
## @field addons.monitoringAgents {monitoringAgents} MonitoringAgents
|
||||
##
|
||||
monitoringAgents:
|
||||
## @field monitoringAgents.enabled {bool} Enable monitoring agents (Fluent Bit and VMAgents) to send logs and metrics. If tenant monitoring is enabled, data is sent to tenant storage; otherwise, it goes to root storage.
|
||||
## @field monitoringAgents.valuesOverride {object} Custom values to override
|
||||
##
|
||||
enabled: false
|
||||
valuesOverride: {}
|
||||
|
||||
## @field addons.verticalPodAutoscaler {verticalPodAutoscaler} VerticalPodAutoscaler
|
||||
##
|
||||
verticalPodAutoscaler:
|
||||
## @field verticalPodAutoscaler.valuesOverride {object} Custom values to override
|
||||
##
|
||||
valuesOverride: {}
|
||||
|
||||
## @field addons.velero {velero} Velero
|
||||
##
|
||||
velero:
|
||||
## @field velero.enabled {bool} Enable Velero for backup and recovery of a tenant Kubernetes cluster.
|
||||
## @field velero.valuesOverride {object} Custom values to override
|
||||
##
|
||||
enabled: false
|
||||
valuesOverride: {}
|
||||
|
||||
## @field addons.coredns {coredns} Coredns
|
||||
##
|
||||
coredns:
|
||||
## @field coredns.valuesOverride {object} Custom values to override
|
||||
##
|
||||
valuesOverride: {}
|
||||
|
||||
##
|
||||
## @section Kubernetes Control Plane Configuration
|
||||
##
|
||||
## @param controlPlane {controlPlane} Control Plane Configuration
|
||||
|
||||
## @typedef {struct} APIServer - API Server configuration.
|
||||
## @field {Resources} resources - CPU and memory resources for API Server.
|
||||
## @field {ResourcesPreset} resourcesPreset="medium" - Preset if `resources` omitted.
|
||||
|
||||
## @typedef {struct} ControllerManager - Controller Manager configuration.
|
||||
## @field {Resources} resources - CPU and memory resources for Controller Manager.
|
||||
## @field {ResourcesPreset} resourcesPreset="micro" - Preset if `resources` omitted.
|
||||
|
||||
## @typedef {struct} Scheduler - Scheduler configuration.
|
||||
## @field {Resources} resources - CPU and memory resources for Scheduler.
|
||||
## @field {ResourcesPreset} resourcesPreset="micro" - Preset if `resources` omitted.
|
||||
|
||||
## @typedef {struct} KonnectivityServer - Konnectivity Server configuration.
|
||||
## @field {Resources} resources - CPU and memory resources for Konnectivity.
|
||||
## @field {ResourcesPreset} resourcesPreset="micro" - Preset if `resources` omitted.
|
||||
|
||||
## @typedef {struct} Konnectivity - Konnectivity configuration.
|
||||
## @field {KonnectivityServer} server - Konnectivity Server configuration.
|
||||
|
||||
## @typedef {struct} ControlPlane - Kubernetes control plane configuration.
|
||||
## @field {int} replicas=2 - Number of control-plane replicas.
|
||||
## @field {APIServer} apiServer - API Server configuration.
|
||||
## @field {ControllerManager} controllerManager - Controller Manager configuration.
|
||||
## @field {Scheduler} scheduler - Scheduler configuration.
|
||||
## @field {Konnectivity} konnectivity - Konnectivity configuration.
|
||||
|
||||
## @param {ControlPlane} controlPlane - Kubernetes control-plane configuration.
|
||||
controlPlane:
|
||||
## @field controlPlane.replicas {int} Number of replicas for Kubernetes control plane components.
|
||||
replicas: 2
|
||||
## @field controlPlane.apiServer {apiServer} Control plane API server configuration.
|
||||
apiServer:
|
||||
## @field apiServer.resources {resources} Explicit CPU and memory configuration for the API Server. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## e.g:
|
||||
## resources:
|
||||
## cpu: 4000m
|
||||
## memory: 4Gi
|
||||
##
|
||||
resources: {}
|
||||
## @field apiServer.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
resourcesPreset: "medium"
|
||||
|
||||
## @field controlPlane.controllerManager {controllerManager} Controller Manager configuration.
|
||||
controllerManager:
|
||||
## @field controllerManager.resources {resources} Explicit CPU and memory configuration for the Controller Manager. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field controllerManager.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
resourcesPreset: "micro"
|
||||
resources: {}
|
||||
|
||||
## @field controlPlane.scheduler {scheduler} Scheduler configuration.
|
||||
resourcesPreset: "micro"
|
||||
scheduler:
|
||||
## @field scheduler.resources {resources} Explicit CPU and memory configuration for the Scheduler. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field scheduler.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
resourcesPreset: "micro"
|
||||
resources: {}
|
||||
|
||||
## @field controlPlane.konnectivity {konnectivity} Konnectivity configuration.
|
||||
resourcesPreset: "micro"
|
||||
konnectivity:
|
||||
## @field konnectivity.server {konnectivityServer} Konnectivity server configuration.
|
||||
server:
|
||||
## @field konnectivityServer.resources {resources} Explicit CPU and memory configuration for Konnectivity. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field konnectivityServer.resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
resourcesPreset: "micro"
|
||||
resources: {}
|
||||
resourcesPreset: "micro"
|
||||
|
||||
@@ -69,44 +69,44 @@ more details:
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `replicas` | Number of MariaDB replicas | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each MariaDB replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `nano` |
|
||||
| `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` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------- |
|
||||
| `replicas` | Number of MariaDB replicas. | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each MariaDB replica. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `nano` |
|
||||
| `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` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| -------------------------------- | --------------------------------------- | ------------------- | ------- |
|
||||
| `users` | Users configuration | `map[string]object` | `{...}` |
|
||||
| `users[name].password` | Password for the user | `string` | `""` |
|
||||
| `users[name].maxUserConnections` | Maximum amount of connections | `int` | `0` |
|
||||
| `databases` | Databases configuration | `map[string]object` | `{...}` |
|
||||
| `databases[name].roles` | Roles for the database | `*object` | `null` |
|
||||
| `databases[name].roles.admin` | List of users with admin privileges | `[]string` | `[]` |
|
||||
| `databases[name].roles.readonly` | List of users with read-only privileges | `[]string` | `[]` |
|
||||
| Name | Description | Type | Value |
|
||||
| -------------------------------- | ---------------------------------------- | ------------------- | ----- |
|
||||
| `users` | Users configuration map. | `map[string]object` | `{}` |
|
||||
| `users[name].password` | Password for the user. | `string` | `""` |
|
||||
| `users[name].maxUserConnections` | Maximum number of connections. | `int` | `0` |
|
||||
| `databases` | Databases configuration map. | `map[string]object` | `{}` |
|
||||
| `databases[name].roles` | Roles assigned to users. | `object` | `{}` |
|
||||
| `databases[name].roles.admin` | List of users with admin privileges. | `[]string` | `[]` |
|
||||
| `databases[name].roles.readonly` | List of users with read-only privileges. | `[]string` | `[]` |
|
||||
|
||||
|
||||
### Backup parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ---------------------------------------------- | -------- | ------------------------------------------------------ |
|
||||
| `backup` | Backup configuration | `object` | `{}` |
|
||||
| `backup.enabled` | Enable regular backups, default is `false`. | `bool` | `false` |
|
||||
| `backup.s3Region` | AWS S3 region where backups are stored | `string` | `us-east-1` |
|
||||
| `backup.s3Bucket` | S3 bucket used for storing backups | `string` | `s3.example.org/mysql-backups` |
|
||||
| `backup.schedule` | Cron schedule for automated backups | `string` | `0 2 * * *` |
|
||||
| `backup.cleanupStrategy` | Retention strategy for cleaning up old backups | `string` | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
||||
| `backup.s3AccessKey` | Access key for S3, used for authentication | `string` | `<your-access-key>` |
|
||||
| `backup.s3SecretKey` | Secret key for S3, used for authentication | `string` | `<your-secret-key>` |
|
||||
| `backup.resticPassword` | Password for Restic backup encryption | `string` | `<password>` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ----------------------------------------------- | -------- | ------------------------------------------------------ |
|
||||
| `backup` | Backup configuration. | `object` | `{}` |
|
||||
| `backup.enabled` | Enable regular backups (default: false). | `bool` | `false` |
|
||||
| `backup.s3Region` | AWS S3 region where backups are stored. | `string` | `us-east-1` |
|
||||
| `backup.s3Bucket` | S3 bucket used for storing backups. | `string` | `s3.example.org/mysql-backups` |
|
||||
| `backup.schedule` | Cron schedule for automated backups. | `string` | `0 2 * * *` |
|
||||
| `backup.cleanupStrategy` | Retention strategy for cleaning up old backups. | `string` | `--keep-last=3 --keep-daily=3 --keep-within-weekly=1m` |
|
||||
| `backup.s3AccessKey` | Access key for S3 authentication. | `string` | `<your-access-key>` |
|
||||
| `backup.s3SecretKey` | Secret key for S3 authentication. | `string` | `<your-secret-key>` |
|
||||
| `backup.resticPassword` | Password for Restic backup encryption. | `string` | `<password>` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-delete
|
||||
"helm.sh/hook-weight": "10"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
policy.cozystack.io/allow-to-apiserver: "true"
|
||||
spec:
|
||||
serviceAccountName: {{ .Release.Name }}-cleanup
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: cleanup
|
||||
image: docker.io/clastix/kubectl:v1.32
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
echo "Deleting orphaned PVCs for {{ .Release.Name }}..."
|
||||
kubectl delete pvc -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} || true
|
||||
echo "PVC cleanup complete."
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-delete
|
||||
helm.sh/hook-weight: "0"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-delete
|
||||
"helm.sh/hook-weight": "5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["persistentvolumeclaims"]
|
||||
verbs: ["get", "list", "delete"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-delete
|
||||
helm.sh/hook-weight: "5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
@@ -3,7 +3,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backup": {
|
||||
"description": "Backup configuration",
|
||||
"description": "Backup configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -18,67 +18,67 @@
|
||||
],
|
||||
"properties": {
|
||||
"cleanupStrategy": {
|
||||
"description": "Retention strategy for cleaning up old backups",
|
||||
"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 is `false`.",
|
||||
"description": "Enable regular backups (default: false).",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"resticPassword": {
|
||||
"description": "Password for Restic backup encryption",
|
||||
"description": "Password for Restic backup encryption.",
|
||||
"type": "string",
|
||||
"default": "\u003cpassword\u003e"
|
||||
},
|
||||
"s3AccessKey": {
|
||||
"description": "Access key for S3, used for authentication",
|
||||
"description": "Access key for S3 authentication.",
|
||||
"type": "string",
|
||||
"default": "\u003cyour-access-key\u003e"
|
||||
},
|
||||
"s3Bucket": {
|
||||
"description": "S3 bucket used for storing backups",
|
||||
"description": "S3 bucket used for storing backups.",
|
||||
"type": "string",
|
||||
"default": "s3.example.org/mysql-backups"
|
||||
},
|
||||
"s3Region": {
|
||||
"description": "AWS S3 region where backups are stored",
|
||||
"description": "AWS S3 region where backups are stored.",
|
||||
"type": "string",
|
||||
"default": "us-east-1"
|
||||
},
|
||||
"s3SecretKey": {
|
||||
"description": "Secret key for S3, used for authentication",
|
||||
"description": "Secret key for S3 authentication.",
|
||||
"type": "string",
|
||||
"default": "\u003cyour-secret-key\u003e"
|
||||
},
|
||||
"schedule": {
|
||||
"description": "Cron schedule for automated backups",
|
||||
"description": "Cron schedule for automated backups.",
|
||||
"type": "string",
|
||||
"default": "0 2 * * *"
|
||||
}
|
||||
}
|
||||
},
|
||||
"databases": {
|
||||
"description": "Databases configuration",
|
||||
"description": "Databases configuration map.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"roles": {
|
||||
"description": "Roles for the database",
|
||||
"description": "Roles assigned to users.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"admin": {
|
||||
"description": "List of users with admin privileges",
|
||||
"description": "List of users with admin privileges.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"readonly": {
|
||||
"description": "List of users with read-only privileges",
|
||||
"description": "List of users with read-only privileges.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
@@ -90,22 +90,22 @@
|
||||
}
|
||||
},
|
||||
"external": {
|
||||
"description": "Enable external access from outside the cluster",
|
||||
"description": "Enable external access from outside the cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of MariaDB replicas",
|
||||
"description": "Number of MariaDB replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each MariaDB replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"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",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -118,7 +118,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -133,7 +133,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "nano",
|
||||
"enum": [
|
||||
@@ -147,7 +147,7 @@
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume Claim size, available for application data",
|
||||
"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": [
|
||||
@@ -161,11 +161,12 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"users": {
|
||||
"description": "Users configuration",
|
||||
"description": "Users configuration map.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
@@ -176,11 +177,11 @@
|
||||
],
|
||||
"properties": {
|
||||
"maxUserConnections": {
|
||||
"description": "Maximum amount of connections",
|
||||
"description": "Maximum number of connections.",
|
||||
"type": "integer"
|
||||
},
|
||||
"password": {
|
||||
"description": "Password for the user",
|
||||
"description": "Password for the user.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,48 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param replicas {int} Number of MariaDB replicas
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each MariaDB replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @param {int} replicas - Number of MariaDB replicas.
|
||||
replicas: 2
|
||||
## @param resources {*resources} Explicit CPU and memory configuration for each MariaDB replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
|
||||
## @param {Resources} [resources] - Explicit CPU and memory configuration for each MariaDB replica. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
resources: {}
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
## @param resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
|
||||
## @param {ResourcesPreset} resourcesPreset="nano" - Default sizing preset used when `resources` is omitted.
|
||||
resourcesPreset: "nano"
|
||||
## @param size {quantity} Persistent Volume Claim size, available for application data
|
||||
|
||||
## @param {quantity} size - Persistent Volume Claim size available for application data.
|
||||
size: 10Gi
|
||||
## @param storageClass {string} StorageClass used to store the data
|
||||
|
||||
## @param {string} storageClass - StorageClass used to store the data.
|
||||
storageClass: ""
|
||||
## @param external {bool} Enable external access from outside the cluster
|
||||
|
||||
## @param {bool} external - Enable external access from outside the cluster.
|
||||
external: false
|
||||
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
## @param users {map[string]user} Users configuration
|
||||
## @field user.password {string} Password for the user
|
||||
## @field user.maxUserConnections {int} Maximum amount of connections
|
||||
|
||||
## @typedef {struct} User - User configuration.
|
||||
## @field {string} password - Password for the user.
|
||||
## @field {int} maxUserConnections - Maximum number of connections.
|
||||
|
||||
## @param {map[string]User} users - Users configuration map.
|
||||
users: {}
|
||||
## Example:
|
||||
## users:
|
||||
## user1:
|
||||
@@ -31,15 +51,16 @@ external: false
|
||||
## user2:
|
||||
## maxUserConnections: 1000
|
||||
## password: hackme
|
||||
##
|
||||
users: {}
|
||||
|
||||
## @typedef {struct} DatabaseRoles - Role assignments for a database.
|
||||
## @field {[]string} [admin] - List of users with admin privileges.
|
||||
## @field {[]string} [readonly] - List of users with read-only privileges.
|
||||
|
||||
## @param databases {map[string]database} Databases configuration
|
||||
## @field database.roles {*databaseRoles} Roles for the database
|
||||
## @field databaseRoles.admin {[]string} List of users with admin privileges
|
||||
## @field databaseRoles.readonly {[]string} List of users with read-only privileges
|
||||
##
|
||||
## @typedef {struct} Database - Database configuration.
|
||||
## @field {DatabaseRoles} [roles] - Roles assigned to users.
|
||||
|
||||
## @param {map[string]Database} databases - Databases configuration map.
|
||||
databases: {}
|
||||
## Example:
|
||||
## databases:
|
||||
## myapp1:
|
||||
@@ -48,19 +69,22 @@ users: {}
|
||||
## - user1
|
||||
## readonly:
|
||||
## - user2
|
||||
databases: {}
|
||||
|
||||
##
|
||||
## @section Backup parameters
|
||||
##
|
||||
## @param backup {backup} Backup configuration
|
||||
## @field backup.enabled {bool} Enable regular backups, default is `false`.
|
||||
## @field backup.s3Region {string} AWS S3 region where backups are stored
|
||||
## @field backup.s3Bucket {string} S3 bucket used for storing backups
|
||||
## @field backup.schedule {string} Cron schedule for automated backups
|
||||
## @field backup.cleanupStrategy {string} Retention strategy for cleaning up old backups
|
||||
## @field backup.s3AccessKey {string} Access key for S3, used for authentication
|
||||
## @field backup.s3SecretKey {string} Secret key for S3, used for authentication
|
||||
## @field backup.resticPassword {string} Password for Restic backup encryption
|
||||
|
||||
## @typedef {struct} Backup - Backup configuration.
|
||||
## @field {bool} enabled - Enable regular backups (default: false).
|
||||
## @field {string} s3Region - AWS S3 region where backups are stored.
|
||||
## @field {string} s3Bucket - S3 bucket used for storing backups.
|
||||
## @field {string} schedule - Cron schedule for automated backups.
|
||||
## @field {string} cleanupStrategy - Retention strategy for cleaning up old backups.
|
||||
## @field {string} s3AccessKey - Access key for S3 authentication.
|
||||
## @field {string} s3SecretKey - Secret key for S3 authentication.
|
||||
## @field {string} resticPassword - Password for Restic backup encryption.
|
||||
|
||||
## @param {Backup} backup - Backup configuration.
|
||||
backup:
|
||||
enabled: false
|
||||
s3Region: us-east-1
|
||||
@@ -70,4 +94,3 @@ backup:
|
||||
s3AccessKey: "<your-access-key>"
|
||||
s3SecretKey: "<your-secret-key>"
|
||||
resticPassword: "<password>"
|
||||
|
||||
|
||||
@@ -7,29 +7,29 @@ It provides a data layer for cloud native applications, IoT messaging, and micro
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `replicas` | Number of replicas | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each NATS replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `nano` |
|
||||
| `storageClass` | StorageClass used to store the data | `string` | `""` |
|
||||
| `external` | Enable external access from outside the cluster | `bool` | `false` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ---------- | ------- |
|
||||
| `replicas` | Number of replicas. | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each NATS replica. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `nano` |
|
||||
| `storageClass` | StorageClass used to store the data. | `string` | `""` |
|
||||
| `external` | Enable external access from outside the cluster. | `bool` | `false` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------- | ------- |
|
||||
| `users` | Users configuration | `map[string]object` | `{...}` |
|
||||
| `users[name].password` | Password for the user | `*string` | `null` |
|
||||
| `jetstream` | Jetstream configuration | `object` | `{}` |
|
||||
| `jetstream.enabled` | Enable or disable Jetstream. Set to `true` (default) to enable Jetstream for persistent messaging in NATS. | `bool` | `true` |
|
||||
| `jetstream.size` | Jetstream persistent storage size. Specifies the size of the persistent storage for Jetstream (message store). | `quantity` | `10Gi` |
|
||||
| `config` | NATS configuration | `object` | `{}` |
|
||||
| `config.merge` | Additional configuration to merge into NATS config (see example) | `*object` | `{}` |
|
||||
| `config.resolver` | Additional resolver configuration to merge into NATS config (see example) | `*object` | `{}` |
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------------- | ------------------------------------------------------------- | ------------------- | ------ |
|
||||
| `users` | Users configuration map. | `map[string]object` | `{}` |
|
||||
| `users[name].password` | Password for the user. | `string` | `""` |
|
||||
| `jetstream` | Jetstream configuration. | `object` | `{}` |
|
||||
| `jetstream.enabled` | Enable or disable Jetstream for persistent messaging in NATS. | `bool` | `true` |
|
||||
| `jetstream.size` | Jetstream persistent storage size. | `quantity` | `10Gi` |
|
||||
| `config` | NATS configuration. | `object` | `{}` |
|
||||
| `config.merge` | Additional configuration to merge into NATS config. | `*object` | `{}` |
|
||||
| `config.resolver` | Additional resolver configuration to merge into NATS config. | `*object` | `{}` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
{{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }}
|
||||
{{- $clusterDomain := (index $cozyConfig.data "cluster-domain") | default "cozy.local" }}
|
||||
{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace (printf "%s-credentials" .Release.Name) }}
|
||||
{{- $passwords := dict }}
|
||||
|
||||
{{- with (dig "data" (dict) $existingSecret) }}
|
||||
{{- range $k, $v := . }}
|
||||
{{- $_ := set $passwords $k (b64dec $v) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- range $user, $u := .Values.users }}
|
||||
{{- if $u.password }}
|
||||
{{- $_ := set $passwords $user $u.password }}
|
||||
@@ -55,14 +47,18 @@ spec:
|
||||
retries: -1
|
||||
values:
|
||||
nats:
|
||||
container:
|
||||
podTemplate:
|
||||
merge:
|
||||
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 12 }}
|
||||
spec:
|
||||
containers:
|
||||
- name: nats
|
||||
image: nats:2.10.17-alpine
|
||||
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 22 }}
|
||||
fullnameOverride: {{ .Release.Name }}
|
||||
config:
|
||||
{{- if or $passwords .Values.config.merge }}
|
||||
{{- if or (gt (len $passwords) 0) (gt (len .Values.config.merge) 0) }}
|
||||
merge:
|
||||
{{- if $passwords }}
|
||||
{{- if gt (len $passwords) 0 }}
|
||||
accounts:
|
||||
A:
|
||||
users:
|
||||
@@ -71,13 +67,13 @@ spec:
|
||||
password: "{{ $password }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.config.merge }}
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- if and .Values.config (hasKey .Values.config "merge") }}
|
||||
{{ toYaml .Values.config.merge | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.config.resolver }}
|
||||
{{- if and .Values.config (hasKey .Values.config "resolver") }}
|
||||
resolver:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{ toYaml .Values.config.resolver | nindent 12 }}
|
||||
{{- end }}
|
||||
cluster:
|
||||
enabled: true
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"config": {
|
||||
"description": "NATS configuration",
|
||||
"description": "NATS configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"merge": {
|
||||
"description": "Additional configuration to merge into NATS config (see example)",
|
||||
"description": "Additional configuration to merge into NATS config.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
},
|
||||
"resolver": {
|
||||
"description": "Additional resolver configuration to merge into NATS config (see example)",
|
||||
"description": "Additional resolver configuration to merge into NATS config.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"x-kubernetes-preserve-unknown-fields": true
|
||||
@@ -22,12 +22,12 @@
|
||||
}
|
||||
},
|
||||
"external": {
|
||||
"description": "Enable external access from outside the cluster",
|
||||
"description": "Enable external access from outside the cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"jetstream": {
|
||||
"description": "Jetstream configuration",
|
||||
"description": "Jetstream configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -36,12 +36,12 @@
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Enable or disable Jetstream. Set to `true` (default) to enable Jetstream for persistent messaging in NATS.",
|
||||
"description": "Enable or disable Jetstream for persistent messaging in NATS.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"size": {
|
||||
"description": "Jetstream persistent storage size. Specifies the size of the persistent storage for Jetstream (message store).",
|
||||
"description": "Jetstream persistent storage size.",
|
||||
"default": "10Gi",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
@@ -57,17 +57,17 @@
|
||||
}
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of replicas",
|
||||
"description": "Number of replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each NATS replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "Explicit CPU and memory configuration for each NATS replica. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each replica",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -80,7 +80,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -95,7 +95,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "nano",
|
||||
"enum": [
|
||||
@@ -109,18 +109,19 @@
|
||||
]
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"users": {
|
||||
"description": "Users configuration",
|
||||
"description": "Users configuration map.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"password": {
|
||||
"description": "Password for the user",
|
||||
"description": "Password for the user.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +1,64 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param replicas {int} Number of replicas
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each NATS replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @param {int} replicas - Number of replicas.
|
||||
replicas: 2
|
||||
## @param resources {*resources} Explicit CPU and memory configuration for each NATS replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
|
||||
## @param {Resources} [resources] - Explicit CPU and memory configuration for each NATS replica. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
resources: {}
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
## @param resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
|
||||
## @param {ResourcesPreset} resourcesPreset="nano" - Default sizing preset used when `resources` is omitted.
|
||||
resourcesPreset: "nano"
|
||||
## @param storageClass {string} StorageClass used to store the data
|
||||
|
||||
## @param {string} storageClass - StorageClass used to store the data.
|
||||
storageClass: ""
|
||||
## @param external {bool} Enable external access from outside the cluster
|
||||
|
||||
## @param {bool} external - Enable external access from outside the cluster.
|
||||
external: false
|
||||
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
## @param users {map[string]user} Users configuration
|
||||
## @field user.password {*string} Password for the user
|
||||
|
||||
## @typedef {struct} User - User configuration.
|
||||
## @field {string} [password] - Password for the user.
|
||||
|
||||
## @param {map[string]User} users - Users configuration map.
|
||||
users: {}
|
||||
## Example:
|
||||
## users:
|
||||
## user1:
|
||||
## password: strongpassword
|
||||
## user2: {}
|
||||
users: {}
|
||||
|
||||
## @param jetstream {jetstream} Jetstream configuration
|
||||
## @typedef {struct} Jetstream - Jetstream configuration.
|
||||
## @field {bool} enabled=true - Enable or disable Jetstream for persistent messaging in NATS.
|
||||
## @field {quantity} size - Jetstream persistent storage size.
|
||||
|
||||
## @param {Jetstream} jetstream - Jetstream configuration.
|
||||
jetstream:
|
||||
## @field jetstream.enabled {bool} Enable or disable Jetstream. Set to `true` (default) to enable Jetstream for persistent messaging in NATS.
|
||||
##
|
||||
## Default: true
|
||||
enabled: true
|
||||
## @field jetstream.size {quantity} Jetstream persistent storage size. Specifies the size of the persistent storage for Jetstream (message store).
|
||||
##
|
||||
size: 10Gi
|
||||
|
||||
## @param config {config} NATS configuration
|
||||
config:
|
||||
## @field config.merge {*object} Additional configuration to merge into NATS config (see example)
|
||||
## Allows you to customize NATS server settings by merging additional configurations.
|
||||
## For example, you can add extra parameters, configure authentication, or set custom settings.
|
||||
## Default: {}
|
||||
## example:
|
||||
##
|
||||
## merge:
|
||||
## $include: ./my-config.conf
|
||||
## zzz$include: ./my-config-last.conf
|
||||
## server_name: nats
|
||||
## authorization:
|
||||
## token: << $TOKEN >>
|
||||
## jetstream:
|
||||
## max_memory_store: << 1GB >>
|
||||
##
|
||||
## will yield the config:
|
||||
## {
|
||||
## include ./my-config.conf;
|
||||
## "authorization": {
|
||||
## "token": $TOKEN
|
||||
## },
|
||||
## "jetstream": {
|
||||
## "max_memory_store": 1GB
|
||||
## },
|
||||
## "server_name": "nats",
|
||||
## include ./my-config-last.conf;
|
||||
## }
|
||||
merge: {}
|
||||
## @field config.resolver {*object} Additional resolver configuration to merge into NATS config (see example)
|
||||
## Allows you to customize NATS server settings by merging resolver configurations.
|
||||
## Default: {}
|
||||
## Example: https://github.com/nats-io/k8s/blob/94414664c254b0bbac3a07fc9693f6c4f8f88709/helm/charts/nats/values.yaml#L248-L270
|
||||
resolver: {}
|
||||
## @typedef {struct} Config - NATS configuration.
|
||||
## @field {*object} [merge] - Additional configuration to merge into NATS config.
|
||||
## @field {*object} [resolver] - Additional resolver configuration to merge into NATS config.
|
||||
|
||||
## @param {Config} config - NATS configuration.
|
||||
config:
|
||||
merge: {}
|
||||
resolver: {}
|
||||
|
||||
@@ -66,60 +66,78 @@ See:
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `replicas` | Number of Postgres replicas | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each PostgreSQL replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `micro` |
|
||||
| `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` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | ---------- | ------- |
|
||||
| `replicas` | Number of Postgres replicas. | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each PostgreSQL replica. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `micro` |
|
||||
| `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` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------- | ------- |
|
||||
| `postgresql` | PostgreSQL server configuration | `object` | `{}` |
|
||||
| `postgresql.parameters` | PostgreSQL server parameters | `object` | `{}` |
|
||||
| `postgresql.parameters.max_connections` | Determines the maximum number of concurrent connections to the database server. The default is typically 100 connections | `int` | `100` |
|
||||
| `quorum` | Quorum configuration for synchronous replication | `object` | `{}` |
|
||||
| `quorum.minSyncReplicas` | Minimum number of synchronous replicas that must acknowledge a transaction before it is considered committed. | `int` | `0` |
|
||||
| `quorum.maxSyncReplicas` | Maximum number of synchronous replicas that can acknowledge a transaction (must be lower than the number of instances). | `int` | `0` |
|
||||
| `users` | Users configuration | `map[string]object` | `{...}` |
|
||||
| `users[name].password` | Password for the user | `*string` | `null` |
|
||||
| `users[name].replication` | Whether the user has replication privileges | `*bool` | `null` |
|
||||
| `databases` | Databases configuration | `map[string]object` | `{...}` |
|
||||
| `databases[name].roles` | Roles for the database | `*object` | `null` |
|
||||
| `databases[name].roles.admin` | List of users with admin privileges | `[]string` | `[]` |
|
||||
| `databases[name].roles.readonly` | List of users with read-only privileges | `[]string` | `[]` |
|
||||
| `databases[name].extensions` | Extensions enabled for the database | `[]string` | `[]` |
|
||||
| Name | Description | Type | Value |
|
||||
| --------------------------------------- | ---------------------------------------------------------------- | -------- | ----- |
|
||||
| `postgresql` | PostgreSQL server configuration. | `object` | `{}` |
|
||||
| `postgresql.parameters` | PostgreSQL server parameters. | `object` | `{}` |
|
||||
| `postgresql.parameters.max_connections` | Maximum number of concurrent connections to the database server. | `int` | `100` |
|
||||
|
||||
|
||||
### Quorum-based synchronous replication
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ---------------------------------------------------------------------------------- | -------- | ----- |
|
||||
| `quorum` | Quorum configuration for synchronous replication. | `object` | `{}` |
|
||||
| `quorum.minSyncReplicas` | Minimum number of synchronous replicas required for commit. | `int` | `0` |
|
||||
| `quorum.maxSyncReplicas` | Maximum number of synchronous replicas allowed (must be less than total replicas). | `int` | `0` |
|
||||
|
||||
|
||||
### Users configuration
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------- | -------------------------------------------- | ------------------- | ------- |
|
||||
| `users` | Users configuration map. | `map[string]object` | `{}` |
|
||||
| `users[name].password` | Password for the user. | `string` | `""` |
|
||||
| `users[name].replication` | Whether the user has replication privileges. | `bool` | `false` |
|
||||
|
||||
|
||||
### Databases configuration
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| -------------------------------- | ---------------------------------------- | ------------------- | ----- |
|
||||
| `databases` | Databases configuration map. | `map[string]object` | `{}` |
|
||||
| `databases[name].roles` | Roles assigned to users. | `object` | `{}` |
|
||||
| `databases[name].roles.admin` | List of users with admin privileges. | `[]string` | `[]` |
|
||||
| `databases[name].roles.readonly` | List of users with read-only privileges. | `[]string` | `[]` |
|
||||
| `databases[name].extensions` | List of enabled PostgreSQL extensions. | `[]string` | `[]` |
|
||||
|
||||
|
||||
### Backup parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ---------------------------------------------------------- | --------- | ----------------------------------- |
|
||||
| `backup` | Backup configuration | `object` | `{}` |
|
||||
| `backup.enabled` | Enable regular backups | `*bool` | `false` |
|
||||
| `backup.schedule` | Cron schedule for automated backups | `*string` | `0 2 * * * *` |
|
||||
| `backup.retentionPolicy` | Retention policy | `*string` | `30d` |
|
||||
| `backup.destinationPath` | Path to store the backup (i.e. s3://bucket/path/to/folder) | `*string` | `s3://bucket/path/to/folder/` |
|
||||
| `backup.endpointURL` | S3 Endpoint used to upload data to the cloud | `*string` | `http://minio-gateway-service:9000` |
|
||||
| `backup.s3AccessKey` | Access key for S3, used for authentication | `*string` | `<your-access-key>` |
|
||||
| `backup.s3SecretKey` | Secret key for S3, used for authentication | `*string` | `<your-secret-key>` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ------------------------------------------------------ | -------- | ----------------------------------- |
|
||||
| `backup` | Backup configuration. | `object` | `{}` |
|
||||
| `backup.enabled` | Enable regular backups. | `bool` | `false` |
|
||||
| `backup.schedule` | Cron schedule for automated backups. | `string` | `0 2 * * * *` |
|
||||
| `backup.retentionPolicy` | Retention policy (e.g. "30d"). | `string` | `30d` |
|
||||
| `backup.destinationPath` | Destination path for backups (e.g. s3://bucket/path/). | `string` | `s3://bucket/path/to/folder/` |
|
||||
| `backup.endpointURL` | S3 endpoint URL for uploads. | `string` | `http://minio-gateway-service:9000` |
|
||||
| `backup.s3AccessKey` | Access key for S3 authentication. | `string` | `<your-access-key>` |
|
||||
| `backup.s3SecretKey` | Secret key for S3 authentication. | `string` | `<your-secret-key>` |
|
||||
|
||||
|
||||
### Bootstrap (recovery) parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | -------------------------------------------------------------------------------------------------------------------- | --------- | ------- |
|
||||
| `bootstrap` | Bootstrap configuration | `object` | `{}` |
|
||||
| `bootstrap.enabled` | Restore database cluster from a backup | `bool` | `false` |
|
||||
| `bootstrap.recoveryTime` | Timestamp (PITR) up to which recovery will proceed, expressed in RFC 3339 format. If left empty, will restore latest | `*string` | `""` |
|
||||
| `bootstrap.oldName` | Name of database cluster before deleting | `string` | `""` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------ | ------------------------------------------------------------------- | -------- | ------- |
|
||||
| `bootstrap` | Bootstrap configuration. | `object` | `{}` |
|
||||
| `bootstrap.enabled` | Whether to restore from a backup. | `bool` | `false` |
|
||||
| `bootstrap.recoveryTime` | Timestamp (RFC3339) for point-in-time recovery; empty means latest. | `string` | `""` |
|
||||
| `bootstrap.oldName` | Previous cluster name before deletion. | `string` | `""` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -3,49 +3,52 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backup": {
|
||||
"description": "Backup configuration",
|
||||
"description": "Backup configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"enabled"
|
||||
],
|
||||
"properties": {
|
||||
"destinationPath": {
|
||||
"description": "Path to store the backup (i.e. s3://bucket/path/to/folder)",
|
||||
"description": "Destination path for backups (e.g. s3://bucket/path/).",
|
||||
"type": "string",
|
||||
"default": "s3://bucket/path/to/folder/"
|
||||
},
|
||||
"enabled": {
|
||||
"description": "Enable regular backups",
|
||||
"description": "Enable regular backups.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"endpointURL": {
|
||||
"description": "S3 Endpoint used to upload data to the cloud",
|
||||
"description": "S3 endpoint URL for uploads.",
|
||||
"type": "string",
|
||||
"default": "http://minio-gateway-service:9000"
|
||||
},
|
||||
"retentionPolicy": {
|
||||
"description": "Retention policy",
|
||||
"description": "Retention policy (e.g. \"30d\").",
|
||||
"type": "string",
|
||||
"default": "30d"
|
||||
},
|
||||
"s3AccessKey": {
|
||||
"description": "Access key for S3, used for authentication",
|
||||
"description": "Access key for S3 authentication.",
|
||||
"type": "string",
|
||||
"default": "\u003cyour-access-key\u003e"
|
||||
},
|
||||
"s3SecretKey": {
|
||||
"description": "Secret key for S3, used for authentication",
|
||||
"description": "Secret key for S3 authentication.",
|
||||
"type": "string",
|
||||
"default": "\u003cyour-secret-key\u003e"
|
||||
},
|
||||
"schedule": {
|
||||
"description": "Cron schedule for automated backups",
|
||||
"description": "Cron schedule for automated backups.",
|
||||
"type": "string",
|
||||
"default": "0 2 * * * *"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bootstrap": {
|
||||
"description": "Bootstrap configuration",
|
||||
"description": "Bootstrap configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -54,47 +57,49 @@
|
||||
],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"description": "Restore database cluster from a backup",
|
||||
"description": "Whether to restore from a backup.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"oldName": {
|
||||
"description": "Name of database cluster before deleting",
|
||||
"type": "string"
|
||||
"description": "Previous cluster name before deletion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"recoveryTime": {
|
||||
"description": "Timestamp (PITR) up to which recovery will proceed, expressed in RFC 3339 format. If left empty, will restore latest",
|
||||
"type": "string"
|
||||
"description": "Timestamp (RFC3339) for point-in-time recovery; empty means latest.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"databases": {
|
||||
"description": "Databases configuration",
|
||||
"description": "Databases configuration map.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"extensions": {
|
||||
"description": "Extensions enabled for the database",
|
||||
"description": "List of enabled PostgreSQL extensions.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"description": "Roles for the database",
|
||||
"description": "Roles assigned to users.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"admin": {
|
||||
"description": "List of users with admin privileges",
|
||||
"description": "List of users with admin privileges.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"readonly": {
|
||||
"description": "List of users with read-only privileges",
|
||||
"description": "List of users with read-only privileges.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
@@ -106,28 +111,22 @@
|
||||
}
|
||||
},
|
||||
"external": {
|
||||
"description": "Enable external access from outside the cluster",
|
||||
"description": "Enable external access from outside the cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"postgresql": {
|
||||
"description": "PostgreSQL server configuration",
|
||||
"description": "PostgreSQL server configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"parameters"
|
||||
],
|
||||
"properties": {
|
||||
"parameters": {
|
||||
"description": "PostgreSQL server parameters",
|
||||
"description": "PostgreSQL server parameters.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
"max_connections"
|
||||
],
|
||||
"properties": {
|
||||
"max_connections": {
|
||||
"description": "Determines the maximum number of concurrent connections to the database server. The default is typically 100 connections",
|
||||
"description": "Maximum number of concurrent connections to the database server.",
|
||||
"type": "integer",
|
||||
"default": 100
|
||||
}
|
||||
@@ -136,7 +135,7 @@
|
||||
}
|
||||
},
|
||||
"quorum": {
|
||||
"description": "Quorum configuration for synchronous replication",
|
||||
"description": "Quorum configuration for synchronous replication.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -145,29 +144,29 @@
|
||||
],
|
||||
"properties": {
|
||||
"maxSyncReplicas": {
|
||||
"description": "Maximum number of synchronous replicas that can acknowledge a transaction (must be lower than the number of instances).",
|
||||
"description": "Maximum number of synchronous replicas allowed (must be less than total replicas).",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
},
|
||||
"minSyncReplicas": {
|
||||
"description": "Minimum number of synchronous replicas that must acknowledge a transaction before it is considered committed.",
|
||||
"description": "Minimum number of synchronous replicas required for commit.",
|
||||
"type": "integer",
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of Postgres replicas",
|
||||
"description": "Number of Postgres replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each PostgreSQL replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"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",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -180,7 +179,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -195,7 +194,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "micro",
|
||||
"enum": [
|
||||
@@ -209,7 +208,7 @@
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume Claim size, available for application data",
|
||||
"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": [
|
||||
@@ -223,22 +222,23 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"users": {
|
||||
"description": "Users configuration",
|
||||
"description": "Users configuration map.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"password": {
|
||||
"description": "Password for the user",
|
||||
"description": "Password for the user.",
|
||||
"type": "string"
|
||||
},
|
||||
"replication": {
|
||||
"description": "Whether the user has replication privileges",
|
||||
"description": "Whether the user has replication privileges.",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +1,76 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param replicas {int} Number of Postgres replicas
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each PostgreSQL replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @param {int} replicas - Number of Postgres replicas.
|
||||
replicas: 2
|
||||
## @param resources {*resources} Explicit CPU and memory configuration for each PostgreSQL replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
|
||||
## @param {Resources} [resources] - Explicit CPU and memory configuration for each PostgreSQL replica. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
resources: {}
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
## @param resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
|
||||
## @param {ResourcesPreset} resourcesPreset="micro" - Default sizing preset used when `resources` is omitted.
|
||||
resourcesPreset: "micro"
|
||||
## @param size {quantity} Persistent Volume Claim size, available for application data
|
||||
|
||||
## @param {quantity} size - Persistent Volume Claim size available for application data.
|
||||
size: 10Gi
|
||||
## @param storageClass {string} StorageClass used to store the data
|
||||
|
||||
## @param {string} storageClass - StorageClass used to store the data.
|
||||
storageClass: ""
|
||||
## @param external {bool} Enable external access from outside the cluster
|
||||
|
||||
## @param {bool} external - Enable external access from outside the cluster.
|
||||
external: false
|
||||
|
||||
## @section Application-specific parameters
|
||||
## @param postgresql {postgresql} PostgreSQL server configuration
|
||||
## @field postgresql.parameters {postgresqlParameters} PostgreSQL server parameters
|
||||
## @field postgresqlParameters.max_connections {int} Determines the maximum number of concurrent connections to the database server. The default is typically 100 connections
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
|
||||
## @typedef {struct} PostgreSQLParameters - PostgreSQL server parameters.
|
||||
## @field {int} [max_connections] - Maximum number of concurrent connections to the database server.
|
||||
|
||||
## @typedef {struct} PostgreSQL - PostgreSQL server configuration.
|
||||
## @field {PostgreSQLParameters} [parameters] - PostgreSQL server parameters.
|
||||
|
||||
## @param {PostgreSQL} postgresql - PostgreSQL server configuration.
|
||||
postgresql:
|
||||
parameters:
|
||||
max_connections: 100
|
||||
|
||||
## Configuration for the quorum-based synchronous replication
|
||||
## @param quorum {quorum} Quorum configuration for synchronous replication
|
||||
## @field quorum.minSyncReplicas {int} Minimum number of synchronous replicas that must acknowledge a transaction before it is considered committed.
|
||||
## @field quorum.maxSyncReplicas {int} Maximum number of synchronous replicas that can acknowledge a transaction (must be lower than the number of instances).
|
||||
##
|
||||
## @section Quorum-based synchronous replication
|
||||
##
|
||||
|
||||
## @typedef {struct} Quorum - Quorum configuration for synchronous replication.
|
||||
## @field {int} minSyncReplicas - Minimum number of synchronous replicas required for commit.
|
||||
## @field {int} maxSyncReplicas - Maximum number of synchronous replicas allowed (must be less than total replicas).
|
||||
|
||||
## @param {Quorum} quorum - Quorum configuration for synchronous replication.
|
||||
quorum:
|
||||
minSyncReplicas: 0
|
||||
maxSyncReplicas: 0
|
||||
|
||||
## @param users {map[string]user} Users configuration
|
||||
## @field user.password {*string} Password for the user
|
||||
## @field user.replication {*bool} Whether the user has replication privileges
|
||||
##
|
||||
## @section Users configuration
|
||||
##
|
||||
|
||||
## @typedef {struct} User - User configuration.
|
||||
## @field {string} [password] - Password for the user.
|
||||
## @field {bool} [replication] - Whether the user has replication privileges.
|
||||
|
||||
## @param {map[string]User} users - Users configuration map.
|
||||
users: {}
|
||||
## Example:
|
||||
## users:
|
||||
## user1:
|
||||
@@ -49,15 +81,21 @@ quorum:
|
||||
## password: qwerty123
|
||||
## debezium:
|
||||
## replication: true
|
||||
##
|
||||
users: {}
|
||||
|
||||
## @param databases {map[string]database} Databases configuration
|
||||
## @field database.roles {*databaseRoles} Roles for the database
|
||||
## @field databaseRoles.admin {[]string} List of users with admin privileges
|
||||
## @field databaseRoles.readonly {[]string} List of users with read-only privileges
|
||||
## @field database.extensions {[]string} Extensions enabled for the database
|
||||
##
|
||||
## @section Databases configuration
|
||||
##
|
||||
|
||||
## @typedef {struct} DatabaseRoles - Role assignments for a database.
|
||||
## @field {[]string} [admin] - List of users with admin privileges.
|
||||
## @field {[]string} [readonly] - List of users with read-only privileges.
|
||||
|
||||
## @typedef {struct} Database - Database configuration.
|
||||
## @field {DatabaseRoles} [roles] - Roles assigned to users.
|
||||
## @field {[]string} [extensions] - List of enabled PostgreSQL extensions.
|
||||
|
||||
## @param {map[string]Database} databases - Databases configuration map.
|
||||
databases: {}
|
||||
## Example:
|
||||
## databases:
|
||||
## myapp:
|
||||
@@ -73,18 +111,21 @@ users: {}
|
||||
## - airflow
|
||||
## extensions:
|
||||
## - hstore
|
||||
databases: {}
|
||||
|
||||
##
|
||||
## @section Backup parameters
|
||||
##
|
||||
|
||||
## @param backup {backup} Backup configuration
|
||||
## @field backup.enabled {*bool} Enable regular backups
|
||||
## @field backup.schedule {*string} Cron schedule for automated backups
|
||||
## @field backup.retentionPolicy {*string} Retention policy
|
||||
## @field backup.destinationPath {*string} Path to store the backup (i.e. s3://bucket/path/to/folder)
|
||||
## @field backup.endpointURL {*string} S3 Endpoint used to upload data to the cloud
|
||||
## @field backup.s3AccessKey {*string} Access key for S3, used for authentication
|
||||
## @field backup.s3SecretKey {*string} Secret key for S3, used for authentication
|
||||
## @typedef {struct} Backup - Backup configuration.
|
||||
## @field {bool} enabled - Enable regular backups.
|
||||
## @field {string} [schedule] - Cron schedule for automated backups.
|
||||
## @field {string} [retentionPolicy] - Retention policy (e.g. "30d").
|
||||
## @field {string} [destinationPath] - Destination path for backups (e.g. s3://bucket/path/).
|
||||
## @field {string} [endpointURL] - S3 endpoint URL for uploads.
|
||||
## @field {string} [s3AccessKey] - Access key for S3 authentication.
|
||||
## @field {string} [s3SecretKey] - Secret key for S3 authentication.
|
||||
|
||||
## @param {Backup} backup - Backup configuration.
|
||||
backup:
|
||||
enabled: false
|
||||
retentionPolicy: 30d
|
||||
@@ -94,16 +135,18 @@ backup:
|
||||
s3AccessKey: "<your-access-key>"
|
||||
s3SecretKey: "<your-secret-key>"
|
||||
|
||||
## @section Bootstrap (recovery) parameters
|
||||
|
||||
## @param bootstrap {bootstrap} Bootstrap configuration
|
||||
## @field bootstrap.enabled {bool} Restore database cluster from a backup
|
||||
## @field bootstrap.recoveryTime {*string} Timestamp (PITR) up to which recovery will proceed, expressed in RFC 3339 format. If left empty, will restore latest
|
||||
## @field bootstrap.oldName {string} Name of database cluster before deleting
|
||||
##
|
||||
## @section Bootstrap (recovery) parameters
|
||||
##
|
||||
|
||||
## @typedef {struct} Bootstrap - Bootstrap configuration for restoring a database cluster from a backup.
|
||||
## @field {bool} enabled - Whether to restore from a backup.
|
||||
## @field {string} [recoveryTime] - Timestamp (RFC3339) for point-in-time recovery; empty means latest.
|
||||
## @field {string} oldName - Previous cluster name before deletion.
|
||||
|
||||
## @param {Bootstrap} bootstrap - Bootstrap configuration.
|
||||
bootstrap:
|
||||
enabled: false
|
||||
# example: 2020-11-26 15:22:00.00000+00
|
||||
recoveryTime: ""
|
||||
oldName: ""
|
||||
|
||||
|
||||
@@ -13,28 +13,28 @@ The service utilizes official RabbitMQ operator. This ensures the reliability an
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `replicas` | Number of RabbitMQ replicas | `int` | `3` |
|
||||
| `resources` | Explicit CPU and memory configuration for each RabbitMQ replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `nano` |
|
||||
| `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` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------- |
|
||||
| `replicas` | Number of RabbitMQ replicas. | `int` | `3` |
|
||||
| `resources` | Explicit CPU and memory configuration for each RabbitMQ replica. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `nano` |
|
||||
| `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` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ----------------------------- | --------------------------- | ------------------- | ------- |
|
||||
| `users` | Users configuration | `map[string]object` | `{...}` |
|
||||
| `users[name].password` | Password for the user | `*string` | `null` |
|
||||
| `vhosts` | Virtual Hosts configuration | `map[string]object` | `{...}` |
|
||||
| `vhosts[name].roles` | Virtual host roles list | `object` | `{}` |
|
||||
| `vhosts[name].roles.admin` | List of admin users | `[]string` | `[]` |
|
||||
| `vhosts[name].roles.readonly` | List of readonly users | `[]string` | `[]` |
|
||||
| Name | Description | Type | Value |
|
||||
| ----------------------------- | -------------------------------- | ------------------- | ----- |
|
||||
| `users` | Users configuration map. | `map[string]object` | `{}` |
|
||||
| `users[name].password` | Password for the user. | `string` | `""` |
|
||||
| `vhosts` | Virtual hosts configuration map. | `map[string]object` | `{}` |
|
||||
| `vhosts[name].roles` | Virtual host roles list. | `object` | `{}` |
|
||||
| `vhosts[name].roles.admin` | List of admin users. | `[]string` | `[]` |
|
||||
| `vhosts[name].roles.readonly` | List of readonly users. | `[]string` | `[]` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"external": {
|
||||
"description": "Enable external access from outside the cluster",
|
||||
"description": "Enable external access from outside the cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of RabbitMQ replicas",
|
||||
"description": "Number of RabbitMQ replicas.",
|
||||
"type": "integer",
|
||||
"default": 3
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each RabbitMQ replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "Explicit CPU and memory configuration for each RabbitMQ replica. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each replica",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -31,7 +31,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -46,7 +46,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "nano",
|
||||
"enum": [
|
||||
@@ -60,7 +60,7 @@
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume Claim size, available for application data",
|
||||
"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": [
|
||||
@@ -74,25 +74,26 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"users": {
|
||||
"description": "Users configuration",
|
||||
"description": "Users configuration map.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"password": {
|
||||
"description": "Password for the user",
|
||||
"description": "Password for the user.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vhosts": {
|
||||
"description": "Virtual Hosts configuration",
|
||||
"description": "Virtual hosts configuration map.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
@@ -102,18 +103,18 @@
|
||||
],
|
||||
"properties": {
|
||||
"roles": {
|
||||
"description": "Virtual host roles list",
|
||||
"description": "Virtual host roles list.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"admin": {
|
||||
"description": "List of admin users",
|
||||
"description": "List of admin users.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"readonly": {
|
||||
"description": "List of readonly users",
|
||||
"description": "List of readonly users.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
|
||||
@@ -1,29 +1,47 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param replicas {int} Number of RabbitMQ replicas
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each RabbitMQ replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @param {int} replicas - Number of RabbitMQ replicas.
|
||||
replicas: 3
|
||||
## @param resources {*resources} Explicit CPU and memory configuration for each RabbitMQ replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
|
||||
## @param {Resources} [resources] - Explicit CPU and memory configuration for each RabbitMQ replica. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
resources: {}
|
||||
|
||||
## @param resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
## @param {ResourcesPreset} resourcesPreset="nano" - Default sizing preset used when `resources` is omitted.
|
||||
resourcesPreset: "nano"
|
||||
## @param size {quantity} Persistent Volume Claim size, available for application data
|
||||
|
||||
## @param {quantity} size - Persistent Volume Claim size available for application data.
|
||||
size: 10Gi
|
||||
## @param storageClass {string} StorageClass used to store the data
|
||||
|
||||
## @param {string} storageClass - StorageClass used to store the data.
|
||||
storageClass: ""
|
||||
## @param external {bool} Enable external access from outside the cluster
|
||||
|
||||
## @param {bool} external - Enable external access from outside the cluster.
|
||||
external: false
|
||||
|
||||
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
## @param users {map[string]user} Users configuration
|
||||
## @field user.password {*string} Password for the user
|
||||
|
||||
## @typedef {struct} User - User configuration.
|
||||
## @field {string} [password] - Password for the user.
|
||||
|
||||
## @param {map[string]User} users - Users configuration map.
|
||||
users: {}
|
||||
## Example:
|
||||
## users:
|
||||
## user1:
|
||||
@@ -32,14 +50,16 @@ external: false
|
||||
## password: hackme
|
||||
## user3:
|
||||
## password: testtest
|
||||
##
|
||||
users: {}
|
||||
|
||||
## @param vhosts {map[string]vhost} Virtual Hosts configuration
|
||||
## @field vhost.roles {roles} Virtual host roles list
|
||||
## @field roles.admin {[]string} List of admin users
|
||||
## @field roles.readonly {[]string} List of readonly users
|
||||
##
|
||||
## @typedef {struct} Roles - Virtual host roles.
|
||||
## @field {[]string} [admin] - List of admin users.
|
||||
## @field {[]string} [readonly] - List of readonly users.
|
||||
|
||||
## @typedef {struct} Vhost - Virtual host configuration.
|
||||
## @field {Roles} roles - Virtual host roles list.
|
||||
|
||||
## @param {map[string]Vhost} vhosts - Virtual hosts configuration map.
|
||||
vhosts: {}
|
||||
## Example:
|
||||
## vhosts:
|
||||
## myapp:
|
||||
@@ -53,5 +73,3 @@ users: {}
|
||||
## roles:
|
||||
## admin:
|
||||
## - user3
|
||||
vhosts: {}
|
||||
|
||||
|
||||
@@ -13,23 +13,23 @@ Service utilizes the Spotahome Redis Operator for efficient management and orche
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------- |
|
||||
| `replicas` | Number of Redis replicas | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each Redis replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `nano` |
|
||||
| `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` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------- |
|
||||
| `replicas` | Number of Redis replicas. | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each Redis replica. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `nano` |
|
||||
| `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` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------- | -------------------------- | ------ | ------ |
|
||||
| `authEnabled` | Enable password generation | `bool` | `true` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------- | --------------------------- | ------ | ------ |
|
||||
| `authEnabled` | Enable password generation. | `bool` | `true` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -27,7 +27,6 @@ spec:
|
||||
replicas: 3
|
||||
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 6 }}
|
||||
redis:
|
||||
image: "redis:8.2.0"
|
||||
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 6 }}
|
||||
replicas: {{ .Values.replicas }}
|
||||
{{- with .Values.size }}
|
||||
|
||||
@@ -3,27 +3,27 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"authEnabled": {
|
||||
"description": "Enable password generation",
|
||||
"description": "Enable password generation.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"external": {
|
||||
"description": "Enable external access from outside the cluster",
|
||||
"description": "Enable external access from outside the cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of Redis replicas",
|
||||
"description": "Number of Redis replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each Redis replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"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",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -36,7 +36,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -51,7 +51,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "nano",
|
||||
"enum": [
|
||||
@@ -65,7 +65,7 @@
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"description": "Persistent Volume Claim size, available for application data",
|
||||
"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": [
|
||||
@@ -79,8 +79,9 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"storageClass": {
|
||||
"description": "StorageClass used to store the data",
|
||||
"type": "string"
|
||||
"description": "StorageClass used to store the data.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,41 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param replicas {int} Number of Redis replicas
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each Redis replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @param {int} replicas - Number of Redis replicas.
|
||||
replicas: 2
|
||||
## @param resources {*resources} Explicit CPU and memory configuration for each Redis replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
|
||||
## @param {Resources} [resources] - Explicit CPU and memory configuration for each Redis replica. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
resources: {}
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
## @param resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
|
||||
## @param {ResourcesPreset} resourcesPreset="nano" - Default sizing preset used when `resources` is omitted.
|
||||
resourcesPreset: "nano"
|
||||
## @param size {quantity} Persistent Volume Claim size, available for application data
|
||||
|
||||
## @param {quantity} size - Persistent Volume Claim size available for application data.
|
||||
size: 1Gi
|
||||
## @param storageClass {string} StorageClass used to store the data
|
||||
|
||||
## @param {string} storageClass - StorageClass used to store the data.
|
||||
storageClass: ""
|
||||
## @param external {bool} Enable external access from outside the cluster
|
||||
|
||||
## @param {bool} external - Enable external access from outside the cluster.
|
||||
external: false
|
||||
|
||||
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
## @param authEnabled {bool} Enable password generation
|
||||
|
||||
## @param {bool} authEnabled - Enable password generation.
|
||||
authEnabled: true
|
||||
|
||||
@@ -12,28 +12,28 @@ Managed TCP Load Balancer Service efficiently utilizes HAProxy for load balancin
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | ------- |
|
||||
| `replicas` | Number of HAProxy replicas | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each TCP Balancer replica. When left empty, the preset defined in `resourcesPreset` is applied. | `*object` | `null` |
|
||||
| `resources.cpu` | CPU available to each replica | `*quantity` | `null` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica | `*quantity` | `null` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`. | `string` | `nano` |
|
||||
| `external` | Enable external access from outside the cluster | `bool` | `false` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------- |
|
||||
| `replicas` | Number of HAProxy replicas. | `int` | `2` |
|
||||
| `resources` | Explicit CPU and memory configuration for each TCP Balancer replica. When omitted, the preset defined in `resourcesPreset` is applied. | `object` | `{}` |
|
||||
| `resources.cpu` | CPU available to each replica. | `quantity` | `""` |
|
||||
| `resources.memory` | Memory (RAM) available to each replica. | `quantity` | `""` |
|
||||
| `resourcesPreset` | Default sizing preset used when `resources` is omitted. | `string` | `nano` |
|
||||
| `external` | Enable external access from outside the cluster. | `bool` | `false` |
|
||||
|
||||
|
||||
### Application-specific parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| -------------------------------- | ---------------------------------------------------------------- | ---------- | ------- |
|
||||
| `httpAndHttps` | HTTP and HTTPS configuration | `object` | `{}` |
|
||||
| `httpAndHttps.mode` | Mode for balancer. Allowed values: `tcp` and `tcp-with-proxy` | `string` | `tcp` |
|
||||
| `httpAndHttps.targetPorts` | Target ports configuration | `object` | `{}` |
|
||||
| `httpAndHttps.targetPorts.http` | HTTP port number. | `int` | `80` |
|
||||
| `httpAndHttps.targetPorts.https` | HTTPS port number. | `int` | `443` |
|
||||
| `httpAndHttps.endpoints` | Endpoint addresses list | `[]string` | `[]` |
|
||||
| `whitelistHTTP` | Secure HTTP by whitelisting client networks, `false` by default. | `bool` | `false` |
|
||||
| `whitelist` | List of allowed client networks | `[]string` | `[]` |
|
||||
| Name | Description | Type | Value |
|
||||
| -------------------------------- | ------------------------------------------------------------- | ---------- | ------- |
|
||||
| `httpAndHttps` | HTTP and HTTPS configuration. | `object` | `{}` |
|
||||
| `httpAndHttps.mode` | Mode for balancer. | `string` | `tcp` |
|
||||
| `httpAndHttps.targetPorts` | Target ports configuration. | `object` | `{}` |
|
||||
| `httpAndHttps.targetPorts.http` | HTTP port number. | `int` | `80` |
|
||||
| `httpAndHttps.targetPorts.https` | HTTPS port number. | `int` | `443` |
|
||||
| `httpAndHttps.endpoints` | Endpoint addresses list. | `[]string` | `[]` |
|
||||
| `whitelistHTTP` | Secure HTTP by whitelisting client networks (default: false). | `bool` | `false` |
|
||||
| `whitelist` | List of allowed client networks. | `[]string` | `[]` |
|
||||
|
||||
|
||||
## Parameter examples and reference
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"external": {
|
||||
"description": "Enable external access from outside the cluster",
|
||||
"description": "Enable external access from outside the cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"httpAndHttps": {
|
||||
"description": "HTTP and HTTPS configuration",
|
||||
"description": "HTTP and HTTPS configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -17,7 +17,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"endpoints": {
|
||||
"description": "Endpoint addresses list",
|
||||
"description": "Endpoint addresses list.",
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
@@ -25,7 +25,7 @@
|
||||
}
|
||||
},
|
||||
"mode": {
|
||||
"description": "Mode for balancer. Allowed values: `tcp` and `tcp-with-proxy`",
|
||||
"description": "Mode for balancer.",
|
||||
"type": "string",
|
||||
"default": "tcp",
|
||||
"enum": [
|
||||
@@ -34,7 +34,7 @@
|
||||
]
|
||||
},
|
||||
"targetPorts": {
|
||||
"description": "Target ports configuration",
|
||||
"description": "Target ports configuration.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"required": [
|
||||
@@ -57,16 +57,17 @@
|
||||
}
|
||||
},
|
||||
"replicas": {
|
||||
"description": "Number of HAProxy replicas",
|
||||
"description": "Number of HAProxy replicas.",
|
||||
"type": "integer",
|
||||
"default": 2
|
||||
},
|
||||
"resources": {
|
||||
"description": "Explicit CPU and memory configuration for each TCP Balancer replica. When left empty, the preset defined in `resourcesPreset` is applied.",
|
||||
"description": "Explicit CPU and memory configuration for each TCP Balancer replica. When omitted, the preset defined in `resourcesPreset` is applied.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"description": "CPU available to each replica",
|
||||
"description": "CPU available to each replica.",
|
||||
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -79,7 +80,7 @@
|
||||
"x-kubernetes-int-or-string": true
|
||||
},
|
||||
"memory": {
|
||||
"description": "Memory (RAM) available to each replica",
|
||||
"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": [
|
||||
{
|
||||
@@ -94,7 +95,7 @@
|
||||
}
|
||||
},
|
||||
"resourcesPreset": {
|
||||
"description": "Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.",
|
||||
"description": "Default sizing preset used when `resources` is omitted.",
|
||||
"type": "string",
|
||||
"default": "nano",
|
||||
"enum": [
|
||||
@@ -108,7 +109,7 @@
|
||||
]
|
||||
},
|
||||
"whitelist": {
|
||||
"description": "List of allowed client networks",
|
||||
"description": "List of allowed client networks.",
|
||||
"type": "array",
|
||||
"default": [],
|
||||
"items": {
|
||||
@@ -116,7 +117,7 @@
|
||||
}
|
||||
},
|
||||
"whitelistHTTP": {
|
||||
"description": "Secure HTTP by whitelisting client networks, `false` by default.",
|
||||
"description": "Secure HTTP by whitelisting client networks (default: false).",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
|
||||
@@ -1,44 +1,50 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
## @param replicas {int} Number of HAProxy replicas
|
||||
|
||||
## @typedef {struct} Resources - Explicit CPU and memory configuration for each TCP Balancer replica.
|
||||
## @field {quantity} [cpu] - CPU available to each replica.
|
||||
## @field {quantity} [memory] - Memory (RAM) available to each replica.
|
||||
|
||||
## @enum {string} ResourcesPreset - Default sizing preset.
|
||||
## @value nano
|
||||
## @value micro
|
||||
## @value small
|
||||
## @value medium
|
||||
## @value large
|
||||
## @value xlarge
|
||||
## @value 2xlarge
|
||||
|
||||
## @param {int} replicas - Number of HAProxy replicas.
|
||||
replicas: 2
|
||||
## @param resources {*resources} Explicit CPU and memory configuration for each TCP Balancer replica. When left empty, the preset defined in `resourcesPreset` is applied.
|
||||
## @field resources.cpu {*quantity} CPU available to each replica
|
||||
## @field resources.memory {*quantity} Memory (RAM) available to each replica
|
||||
#resources: {}
|
||||
# resources:
|
||||
# cpu: 4000m
|
||||
# memory: 4Gi
|
||||
## @param resourcesPreset {string enum:"nano,micro,small,medium,large,xlarge,2xlarge"} Default sizing preset used when `resources` is omitted. Allowed values: `nano`, `micro`, `small`, `medium`, `large`, `xlarge`, `2xlarge`.
|
||||
|
||||
## @param {Resources} [resources] - Explicit CPU and memory configuration for each TCP Balancer replica. When omitted, the preset defined in `resourcesPreset` is applied.
|
||||
resources: {}
|
||||
|
||||
## @param {ResourcesPreset} resourcesPreset="nano" - Default sizing preset used when `resources` is omitted.
|
||||
resourcesPreset: "nano"
|
||||
##
|
||||
## @param external {bool} Enable external access from outside the cluster
|
||||
|
||||
## @param {bool} external - Enable external access from outside the cluster.
|
||||
external: false
|
||||
|
||||
|
||||
##
|
||||
## @section Application-specific parameters
|
||||
##
|
||||
## @param httpAndHttps {httpAndHttps} HTTP and HTTPS configuration
|
||||
## @field httpAndHttps.mode {string enum:"tcp,tcp-with-proxy"} Mode for balancer. Allowed values: `tcp` and `tcp-with-proxy`
|
||||
## @field httpAndHttps.targetPorts {targetPorts} Target ports configuration
|
||||
## @field targetPorts.http {int} HTTP port number.
|
||||
## @field targetPorts.https {int} HTTPS port number.
|
||||
## @field httpAndHttps.endpoints {[]string} Endpoint addresses list
|
||||
## Example:
|
||||
##
|
||||
## httpAndHttps:
|
||||
## mode: tcp
|
||||
## targetPorts:
|
||||
## http: 80
|
||||
## https: 443
|
||||
## endpoints:
|
||||
## - 10.100.3.1
|
||||
## - 10.100.3.11
|
||||
## - 10.100.3.2
|
||||
## - 10.100.3.12
|
||||
## - 10.100.3.3
|
||||
## - 10.100.3.13
|
||||
|
||||
## @enum {string} Mode - Mode for balancer.
|
||||
## @value tcp
|
||||
## @value tcp-with-proxy
|
||||
|
||||
## @typedef {struct} TargetPorts - Target ports configuration.
|
||||
## @field {int} http - HTTP port number.
|
||||
## @field {int} https - HTTPS port number.
|
||||
|
||||
## @typedef {struct} HttpAndHttps - HTTP and HTTPS configuration.
|
||||
## @field {Mode} mode - Mode for balancer.
|
||||
## @field {TargetPorts} targetPorts - Target ports configuration.
|
||||
## @field {[]string} endpoints - Endpoint addresses list.
|
||||
|
||||
## @param {HttpAndHttps} httpAndHttps - HTTP and HTTPS configuration.
|
||||
httpAndHttps:
|
||||
mode: tcp
|
||||
targetPorts:
|
||||
@@ -46,14 +52,14 @@ httpAndHttps:
|
||||
https: 443
|
||||
endpoints: []
|
||||
|
||||
## @param whitelistHTTP {bool} Secure HTTP by whitelisting client networks, `false` by default.
|
||||
## @param whitelist {[]string} List of allowed client networks
|
||||
## @param {bool} whitelistHTTP - Secure HTTP by whitelisting client networks (default: false).
|
||||
whitelistHTTP: false
|
||||
## Example:
|
||||
## whitelistHTTP: true
|
||||
## whitelist:
|
||||
## - "1.2.3.4"
|
||||
## - "10.100.0.0/16"
|
||||
##
|
||||
whitelistHTTP: false
|
||||
whitelist: []
|
||||
|
||||
## @param {[]string} whitelist - List of allowed client networks.
|
||||
whitelist: []
|
||||
|
||||
@@ -69,13 +69,13 @@ tenant-u1
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------- |
|
||||
| `host` | The hostname used to access tenant services (defaults to using the tenant name as a subdomain for it's parent tenant host). | `*string` | `""` |
|
||||
| `etcd` | Deploy own Etcd cluster | `bool` | `false` |
|
||||
| `monitoring` | Deploy own Monitoring Stack | `bool` | `false` |
|
||||
| `ingress` | Deploy own Ingress Controller | `bool` | `false` |
|
||||
| `seaweedfs` | Deploy own SeaweedFS | `bool` | `false` |
|
||||
| `isolated` | Enforce tenant namespace with network policies, `true` by default | `bool` | `true` |
|
||||
| `resourceQuotas` | Define resource quotas for the tenant | `map[string]quantity` | `{}` |
|
||||
| Name | Description | Type | Value |
|
||||
| ---------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------- | ------- |
|
||||
| `host` | The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host). | `string` | `""` |
|
||||
| `etcd` | Deploy own Etcd cluster. | `bool` | `false` |
|
||||
| `monitoring` | Deploy own Monitoring Stack. | `bool` | `false` |
|
||||
| `ingress` | Deploy own Ingress Controller. | `bool` | `false` |
|
||||
| `seaweedfs` | Deploy own SeaweedFS. | `bool` | `false` |
|
||||
| `isolated` | Enforce tenant namespace with network policies (default: true). | `bool` | `true` |
|
||||
| `resourceQuotas` | Define resource quotas for the tenant. | `map[string]quantity` | `{}` |
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "tenant.name" . }}-cleanup
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-delete
|
||||
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
|
||||
helm.sh/hook-weight: "-5"
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "tenant.name" . }}-cleanup
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-delete
|
||||
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
|
||||
helm.sh/hook-weight: "-5"
|
||||
rules:
|
||||
- apiGroups: ["helm.toolkit.fluxcd.io"]
|
||||
resources: ["helmreleases"]
|
||||
verbs: ["get", "list", "delete"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "tenant.name" . }}-cleanup
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-delete
|
||||
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
|
||||
helm.sh/hook-weight: "-5"
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ include "tenant.name" . }}-cleanup
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "tenant.name" . }}-cleanup
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ include "tenant.name" . }}-cleanup
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-delete
|
||||
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
|
||||
helm.sh/hook-weight: "0"
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 300
|
||||
template:
|
||||
metadata:
|
||||
name: {{ include "tenant.name" . }}-cleanup
|
||||
labels:
|
||||
policy.cozystack.io/allow-to-apiserver: "true"
|
||||
spec:
|
||||
serviceAccountName: {{ include "tenant.name" . }}-cleanup
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: cleanup
|
||||
image: bitnami/kubectl:latest
|
||||
command:
|
||||
- /bin/bash
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
NAMESPACE="{{ include "tenant.name" . }}"
|
||||
|
||||
echo "Cleaning up HelmReleases in namespace: $NAMESPACE"
|
||||
|
||||
echo "Deleting Applications"
|
||||
kubectl delete helmreleases.helm.toolkit.fluxcd.io -n "$NAMESPACE" \
|
||||
-l 'cozystack.io/ui=true,internal.cozystack.io/tenantmodule!=true' \
|
||||
--ignore-not-found=true --wait=true
|
||||
|
||||
echo "Deleting Tenant Modules"
|
||||
kubectl delete helmreleases.helm.toolkit.fluxcd.io -n "$NAMESPACE" \
|
||||
-l 'cozystack.io/ui=true,internal.cozystack.io/tenantmodule=true' \
|
||||
--ignore-not-found=true --wait=true
|
||||
|
||||
echo "Cleanup completed successfully"
|
||||
@@ -20,7 +20,11 @@ metadata:
|
||||
name: allow-external-communication
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
spec:
|
||||
endpointSelector: {}
|
||||
endpointSelector:
|
||||
matchExpressions:
|
||||
- key: policy.cozystack.io/allow-external-communication
|
||||
operator: NotIn
|
||||
values: ["false"]
|
||||
ingress:
|
||||
- fromEntities:
|
||||
- world
|
||||
|
||||
@@ -28,13 +28,13 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups:
|
||||
- core.cozystack.io
|
||||
resources:
|
||||
- tenantmodules
|
||||
- tenantsecrets
|
||||
- tenantsecretstables
|
||||
verbs: ["get", "list", "watch"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
@@ -113,7 +113,6 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
---
|
||||
kind: RoleBinding
|
||||
@@ -122,7 +121,7 @@ metadata:
|
||||
name: {{ include "tenant.name" . }}-view
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
subjects:
|
||||
{{ include "cozy-lib.rbac.subjectsForTenantAndAccessLevel" (list "view" (include "tenant.name" .)) | nindent 2 }}
|
||||
{{ include "cozy-lib.rbac.subjectsForTenant" (list "view" (include "tenant.name" .)) | nindent 2 }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "tenant.name" . }}-view
|
||||
@@ -185,13 +184,13 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups:
|
||||
- core.cozystack.io
|
||||
resources:
|
||||
- tenantmodules
|
||||
- tenantsecrets
|
||||
- tenantsecretstables
|
||||
verbs: ["get", "list", "watch"]
|
||||
---
|
||||
kind: RoleBinding
|
||||
@@ -200,7 +199,7 @@ metadata:
|
||||
name: {{ include "tenant.name" . }}-use
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
subjects:
|
||||
{{ include "cozy-lib.rbac.subjectsForTenantAndAccessLevel" (list "use" (include "tenant.name" .)) | nindent 2 }}
|
||||
{{ include "cozy-lib.rbac.subjectsForTenant" (list "use" (include "tenant.name" .)) | nindent 2 }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "tenant.name" . }}-use
|
||||
@@ -271,6 +270,7 @@ rules:
|
||||
- vmdisks
|
||||
- vminstances
|
||||
- infos
|
||||
- virtualprivateclouds
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
@@ -283,13 +283,13 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups:
|
||||
- core.cozystack.io
|
||||
resources:
|
||||
- tenantmodules
|
||||
- tenantsecrets
|
||||
- tenantsecretstables
|
||||
verbs: ["get", "list", "watch"]
|
||||
---
|
||||
kind: RoleBinding
|
||||
@@ -298,7 +298,7 @@ metadata:
|
||||
name: {{ include "tenant.name" . }}-admin
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
subjects:
|
||||
{{ include "cozy-lib.rbac.subjectsForTenantAndAccessLevel" (list "admin" (include "tenant.name" .)) | nindent 2 }}
|
||||
{{ include "cozy-lib.rbac.subjectsForTenant" (list "admin" (include "tenant.name" .)) | nindent 2 }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "tenant.name" . }}-admin
|
||||
@@ -357,13 +357,13 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups:
|
||||
- core.cozystack.io
|
||||
resources:
|
||||
- tenantmodules
|
||||
- tenantsecrets
|
||||
- tenantsecretstables
|
||||
verbs: ["get", "list", "watch"]
|
||||
---
|
||||
kind: RoleBinding
|
||||
@@ -372,7 +372,7 @@ metadata:
|
||||
name: {{ include "tenant.name" . }}-super-admin
|
||||
namespace: {{ include "tenant.name" . }}
|
||||
subjects:
|
||||
{{ include "cozy-lib.rbac.subjectsForTenantAndAccessLevel" (list "super-admin" (include "tenant.name" .) ) | nindent 2 }}
|
||||
{{ include "cozy-lib.rbac.subjectsForTenant" (list "super-admin" (include "tenant.name" .) ) | nindent 2 }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "tenant.name" . }}-super-admin
|
||||
|
||||
@@ -3,31 +3,32 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"etcd": {
|
||||
"description": "Deploy own Etcd cluster",
|
||||
"description": "Deploy own Etcd cluster.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"host": {
|
||||
"description": "The hostname used to access tenant services (defaults to using the tenant name as a subdomain for it's parent tenant host).",
|
||||
"type": "string"
|
||||
"description": "The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host).",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"ingress": {
|
||||
"description": "Deploy own Ingress Controller",
|
||||
"description": "Deploy own Ingress Controller.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"isolated": {
|
||||
"description": "Enforce tenant namespace with network policies, `true` by default",
|
||||
"description": "Enforce tenant namespace with network policies (default: true).",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"monitoring": {
|
||||
"description": "Deploy own Monitoring Stack",
|
||||
"description": "Deploy own Monitoring Stack.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"resourceQuotas": {
|
||||
"description": "Define resource quotas for the tenant",
|
||||
"description": "Define resource quotas for the tenant.",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": {
|
||||
@@ -44,7 +45,7 @@
|
||||
}
|
||||
},
|
||||
"seaweedfs": {
|
||||
"description": "Deploy own SeaweedFS",
|
||||
"description": "Deploy own SeaweedFS.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
##
|
||||
## @section Common parameters
|
||||
##
|
||||
|
||||
## @param host {*string} The hostname used to access tenant services (defaults to using the tenant name as a subdomain for it's parent tenant host).
|
||||
## @param etcd {bool} Deploy own Etcd cluster
|
||||
## @param monitoring {bool} Deploy own Monitoring Stack
|
||||
## @param ingress {bool} Deploy own Ingress Controller
|
||||
## @param seaweedfs {bool} Deploy own SeaweedFS
|
||||
## @param isolated {bool} Enforce tenant namespace with network policies, `true` by default
|
||||
## @param {string} [host] - The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host).
|
||||
host: ""
|
||||
|
||||
## @param {bool} etcd - Deploy own Etcd cluster.
|
||||
etcd: false
|
||||
|
||||
## @param {bool} monitoring - Deploy own Monitoring Stack.
|
||||
monitoring: false
|
||||
|
||||
## @param {bool} ingress - Deploy own Ingress Controller.
|
||||
ingress: false
|
||||
|
||||
## @param {bool} seaweedfs - Deploy own SeaweedFS.
|
||||
seaweedfs: false
|
||||
|
||||
## @param {bool} isolated - Enforce tenant namespace with network policies (default: true).
|
||||
isolated: true
|
||||
## @param resourceQuotas {map[string]quantity} Define resource quotas for the tenant
|
||||
|
||||
## @param {map[string]quantity} resourceQuotas - Define resource quotas for the tenant.
|
||||
resourceQuotas: {}
|
||||
# resourceQuotas:
|
||||
# cpu: "1"
|
||||
# memory: "1Gi"
|
||||
# nvidia.com/gpu: 4
|
||||
# storage: 100Gi
|
||||
|
||||
@@ -36,27 +36,29 @@ virtctl ssh <user>@<vm>
|
||||
|
||||
### Common parameters
|
||||
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------ |
|
||||
| `external` | Enable external access from outside the cluster | `bool` | `false` |
|
||||
| `externalMethod` | Specify method to pass through the traffic to the virtual machine. Allowed values: `WholeIP` and `PortList` | `string` | `PortList` |
|
||||
| `externalPorts` | Specify ports to forward from outside the cluster | `[]int` | `[22]` |
|
||||
| `running` | if the virtual machine should be running | `bool` | `true` |
|
||||
| `instanceType` | Virtual Machine instance type | `string` | `u1.medium` |
|
||||
| `instanceProfile` | Virtual Machine preferences profile | `string` | `ubuntu` |
|
||||
| `systemDisk` | System disk configuration | `object` | `{}` |
|
||||
| `systemDisk.image` | The base image for the virtual machine. Allowed values: `ubuntu`, `cirros`, `alpine`, `fedora` and `talos` | `string` | `ubuntu` |
|
||||
| `systemDisk.storage` | The size of the disk allocated for the virtual machine | `string` | `5Gi` |
|
||||
| `systemDisk.storageClass` | StorageClass used to store the data | `*string` | `replicated` |
|
||||
| `gpus` | List of GPUs to attach | `[]object` | `[]` |
|
||||
| `gpus[i].name` | The name of the GPU to attach. This should match the GPU resource name in the cluster. | `string` | `""` |
|
||||
| `resources` | Resources | `*object` | `null` |
|
||||
| `resources.cpu` | The number of CPU cores allocated to the virtual machine | `*quantity` | `null` |
|
||||
| `resources.sockets` | The number of CPU sockets allocated to the virtual machine (used to define vCPU topology) | `*quantity` | `null` |
|
||||
| `resources.memory` | The amount of memory allocated to the virtual machine | `*quantity` | `null` |
|
||||
| `sshKeys` | List of SSH public keys for authentication. Can be a single key or a list of keys. | `[]string` | `[]` |
|
||||
| `cloudInit` | Cloud-init user data config. See cloud-init documentation for more details: [format](https://cloudinit.readthedocs.io/en/latest/explanation/format.html), [examples](https://cloudinit.readthedocs.io/en/latest/reference/examples.html). | `string` | `""` |
|
||||
| `cloudInitSeed` | A seed string to generate an SMBIOS UUID for the VM. | `string` | `""` |
|
||||
| Name | Description | Type | Value |
|
||||
| ------------------------- | ------------------------------------------------------------------ | ---------- | ------------ |
|
||||
| `external` | Enable external access from outside the cluster. | `bool` | `false` |
|
||||
| `externalMethod` | Method to pass through traffic to the VM. | `string` | `PortList` |
|
||||
| `externalPorts` | Ports to forward from outside the cluster. | `[]int` | `[22]` |
|
||||
| `running` | Whether the virtual machine should be running. | `bool` | `true` |
|
||||
| `instanceType` | Virtual Machine instance type. | `string` | `u1.medium` |
|
||||
| `instanceProfile` | Virtual Machine preferences profile. | `string` | `ubuntu` |
|
||||
| `systemDisk` | System disk configuration. | `object` | `{}` |
|
||||
| `systemDisk.image` | The base image for the virtual machine. | `string` | `ubuntu` |
|
||||
| `systemDisk.storage` | The size of the disk allocated for the virtual machine. | `string` | `5Gi` |
|
||||
| `systemDisk.storageClass` | StorageClass used to store the data. | `string` | `replicated` |
|
||||
| `subnets` | Additional subnets (management subnet will be attached by default) | `[]object` | `[]` |
|
||||
| `subnets[i].name` | Name of the subnet to attach | `string` | `""` |
|
||||
| `gpus` | List of GPUs to attach. | `[]object` | `[]` |
|
||||
| `gpus[i].name` | The name of the GPU resource to attach. | `string` | `""` |
|
||||
| `resources` | Resource configuration for the virtual machine. | `object` | `{}` |
|
||||
| `resources.cpu` | Number of CPU cores allocated. | `quantity` | `""` |
|
||||
| `resources.sockets` | Number of CPU sockets (vCPU topology). | `quantity` | `""` |
|
||||
| `resources.memory` | Amount of memory allocated. | `quantity` | `""` |
|
||||
| `sshKeys` | List of SSH public keys for authentication. | `[]string` | `[]` |
|
||||
| `cloudInit` | Cloud-init user data. | `string` | `""` |
|
||||
| `cloudInitSeed` | Seed string to generate SMBIOS UUID for the VM. | `string` | `""` |
|
||||
|
||||
|
||||
## U Series
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# if subnets are specified and image is either ubunu or alpine
|
||||
{{- if and .Values.subnets (or (eq .Values.systemDisk.image "ubuntu") (eq .Values.systemDisk.image "alpine")) }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "virtual-machine.fullname" $ }}-network-config
|
||||
stringData:
|
||||
networkData: |
|
||||
network:
|
||||
version: 1
|
||||
config:
|
||||
{{- if eq .Values.systemDisk.image "ubuntu" }}
|
||||
# main iface
|
||||
- type: physical
|
||||
name: enp1s0
|
||||
subnets:
|
||||
- type: dhcp
|
||||
# additional ifaces attached to subnets
|
||||
{{- range $i, $subnet := .Values.subnets }}
|
||||
- type: physical
|
||||
name: enp{{ add 2 $i }}s0
|
||||
subnets:
|
||||
- type: dhcp
|
||||
{{- end }}
|
||||
{{- else if eq .Values.systemDisk.image "alpine" }}
|
||||
#main iface
|
||||
- type: physical
|
||||
name: eth0
|
||||
subnets:
|
||||
- type: dhcp
|
||||
# additional ifaces attached to subnets
|
||||
{{- range $i, $subnet := .Values.subnets }}
|
||||
- type: physical
|
||||
name: eth{{ add1 $i }}
|
||||
subnets:
|
||||
- type: dhcp
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -28,3 +28,27 @@ spec:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
name: {{ include "virtual-machine.fullname" . }}
|
||||
spec:
|
||||
endpointSelector:
|
||||
matchLabels:
|
||||
{{- include "virtual-machine.selectorLabels" . | nindent 6 }}
|
||||
ingress:
|
||||
- fromEntities:
|
||||
- cluster
|
||||
- fromEntities:
|
||||
- world
|
||||
{{- if eq .Values.externalMethod "PortList" }}
|
||||
toPorts:
|
||||
- ports:
|
||||
{{- range .Values.externalPorts }}
|
||||
- port: {{ quote . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
egress:
|
||||
- toEntities:
|
||||
- world
|
||||
|
||||
@@ -27,11 +27,7 @@
|
||||
{{- if and $existingPVC $desiredStorage -}}
|
||||
{{- $currentStorage := $existingPVC.spec.resources.requests.storage | toString -}}
|
||||
{{- if not (eq $currentStorage $desiredStorage) -}}
|
||||
{{- $oldSize := (include "cozy-lib.resources.toFloat" $currentStorage) | float64 -}}
|
||||
{{- $newSize := (include "cozy-lib.resources.toFloat" $desiredStorage) | float64 -}}
|
||||
{{- if gt $newSize $oldSize -}}
|
||||
{{- $needResizePVC = true -}}
|
||||
{{- end -}}
|
||||
{{- $needResizePVC = true -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user