diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml new file mode 100644 index 0000000..418a12e --- /dev/null +++ b/.github/workflows/helm-lint.yaml @@ -0,0 +1,110 @@ +name: Helm Lint + +on: + push: + branches: + - main + - mvp_demo + paths: + - 'charts/kruize/**' + - '.github/workflows/helm-lint.yaml' + pull_request: + types: [opened, synchronize, reopened] + branches: + - main + - mvp_demo + paths: + - 'charts/kruize/**' + - '.github/workflows/helm-lint.yaml' + workflow_dispatch: + +env: + HELM_VERSION: v3.13.0 + +jobs: + helm-lint: + name: Lint Helm Chart + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4.3.1 + with: + version: ${{ env.HELM_VERSION }} + + - name: Lint chart with default values + run: | + echo "=== Linting with default values ===" + helm lint charts/kruize + + - name: Lint chart with minikube values + if: always() + run: | + echo "=== Linting with minikube values ===" + if [ -f charts/kruize/values-minikube.yaml ]; then + helm lint charts/kruize -f charts/kruize/values-minikube.yaml + else + echo "⚠️ values-minikube.yaml not found, skipping" + fi + + - name: Lint chart with openshift values + if: always() + run: | + echo "=== Linting with openshift values ===" + if [ -f charts/kruize/values-openshift.yaml ]; then + helm lint charts/kruize -f charts/kruize/values-openshift.yaml + else + echo "⚠️ values-openshift.yaml not found, skipping" + fi + + - name: Validate chart structure + run: | + echo "=== Validating chart structure ===" + + # Check required files + echo "Checking required files..." + required_files=( + "charts/kruize/Chart.yaml" + "charts/kruize/values.yaml" + "charts/kruize/templates" + ) + + for file in "${required_files[@]}"; do + if [ -e "$file" ]; then + echo "✅ $file exists" + else + echo "❌ $file is missing" + exit 1 + fi + done + + echo "" + echo "Chart structure validation passed!" + + - name: Lint Summary + if: always() + run: | + echo "=== Helm Lint Summary ===" + echo "" + echo "Linted configurations:" + echo " ✅ Default values" + + if [ -f charts/kruize/values-minikube.yaml ]; then + echo " ✅ Minikube values" + else + echo " ⚠️ Minikube values (not found)" + fi + + if [ -f charts/kruize/values-openshift.yaml ]; then + echo " ✅ OpenShift values" + else + echo " ⚠️ OpenShift values (not found)" + fi + + echo "" + echo "Lint checks completed!" + + diff --git a/.github/workflows/helm-unittest.yaml b/.github/workflows/helm-unittest.yaml new file mode 100644 index 0000000..fa18560 --- /dev/null +++ b/.github/workflows/helm-unittest.yaml @@ -0,0 +1,142 @@ +name: Helm Unit Tests + +on: + push: + branches: + - main + - mvp_demo + paths: + - 'charts/kruize/**' + - '.github/workflows/helm-unittest.yaml' + pull_request: + types: [opened, synchronize, reopened] + branches: + - main + - mvp_demo + paths: + - 'charts/kruize/**' + - '.github/workflows/helm-unittest.yaml' + workflow_dispatch: + +env: + HELM_VERSION: v3.13.0 + +jobs: + helm-unittest: + name: Run Helm Unit Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4.3.1 + with: + version: ${{ env.HELM_VERSION }} + + - name: Install helm-unittest plugin + run: | + helm plugin install https://github.com/helm-unittest/helm-unittest --version 1.0.3 + + - name: Run unit tests + run: | + echo "Running all Helm unit tests with different values configurations..." + echo " • with-default-values/ - Tests using default values.yaml" + echo " • with-minikube-values/ - Tests using values-minikube.yaml" + echo " • with-openshift-values/ - Tests using values-openshift.yaml" + echo "" + helm unittest \ + -f 'tests/with-default-values/*.yaml' \ + -f 'tests/with-minikube-values/*.yaml' \ + -f 'tests/with-openshift-values/*.yaml' \ + --color --with-subchart=false \ + charts/kruize + + - name: Generate JUnit test report + if: always() + run: | + helm unittest \ + -f 'tests/with-default-values/*.yaml' \ + -f 'tests/with-minikube-values/*.yaml' \ + -f 'tests/with-openshift-values/*.yaml' \ + --output-type JUnit --output-file test-results.xml --with-subchart=false \ + charts/kruize + + - name: Generate HTML test report + if: always() + run: | + helm unittest \ + -f 'tests/with-default-values/*.yaml' \ + -f 'tests/with-minikube-values/*.yaml' \ + -f 'tests/with-openshift-values/*.yaml' \ + --output-type html --output-file test-results.html --with-subchart=false \ + charts/kruize + + - name: Upload test results (XML & HTML) + if: always() + uses: actions/upload-artifact@v7 + with: + name: helm-unittest-results + path: | + test-results.xml + test-results.html + retention-days: 4 + + - name: Test Summary + if: always() + run: | + echo "=== Helm Unit Test Summary ===" + echo "" + echo "Test suites executed:" + echo " • with-default-values/ - Tests using default values.yaml" + echo " • with-minikube-values/ - Tests using values-minikube.yaml" + echo " • with-openshift-values/ - Tests using values-openshift.yaml" + echo "" + echo "Note: All tests are unit tests that render and validate templates." + echo "No actual Kubernetes cluster is required to run these tests." + echo "" + if [ -f test-results.xml ]; then + echo "✅ Test results generated successfully" + echo "📊 View detailed results in the artifacts" + + # Count test results - try multiple patterns for different XML formats + TESTS=$(grep -oP 'tests="\K[0-9]+' test-results.xml | head -1) + FAILURES=$(grep -oP 'failures="\K[0-9]+' test-results.xml | head -1) + + # If empty, try testsuites format + if [ -z "$TESTS" ]; then + TESTS=$(grep -oP '= 1.25.0-0' + +sources: +- https://github.com/kruize/autotune +- https://github.com/kruize/kruize-ui + +maintainers: +- name: Dinakar Guniguntala + url: https://github.com/dinogun +- name: Chandrakala Subramanyam + url: https://github.com/chandrams + + diff --git a/charts/kruize/LICENSE b/charts/kruize/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/charts/kruize/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/charts/kruize/README.md b/charts/kruize/README.md new file mode 100644 index 0000000..01695b0 --- /dev/null +++ b/charts/kruize/README.md @@ -0,0 +1,234 @@ +# Kruize Helm Chart + +A Helm chart for deploying [Kruize](https://github.com/kruize/autotune) on Kubernetes/OpenShift clusters. + +## Introduction + +Kruize is an intelligent resource optimization platform that helps you optimize your Kubernetes workloads by providing recommendations for CPU and memory resources based on actual usage patterns. + +## Prerequisites + +- Kubernetes 1.23.0+ or OpenShift 4.10+ +- Helm 3.0+ +- [Prometheus](https://github.com/prometheus/prometheus) (for Minikube, Kind clusters) + +## Installation + +### From Source Code + +To install the chart from source code, run: + +git clone https://github.com/kruize/kruize-helm +cd kruize-helm + +#### OpenShift Installation + +To install the chart with OpenShift-specific configuration: + +```bash +helm install kruize ./charts/kruize -f ./charts/kruize/values-openshift.yaml +``` + +To install in a specific namespace: + +```bash +helm install kruize ./charts/kruize -f ./charts/kruize/values-openshift.yaml --namespace openshift-tuning --create-namespace +``` + +#### Minikube Installation + +To install the chart with Minikube-specific configuration: + +```bash +helm install kruize ./charts/kruize -f ./charts/kruize/values-minikube.yaml +``` + +To install in a specific namespace: + +```bash +helm install kruize ./charts/kruize -f ./charts/kruize/values-minikube.yaml --namespace monitoring --create-namespace +``` + +## Uninstalling the Chart + +To uninstall/delete the `kruize` deployment: + +```bash +helm uninstall kruize -n +``` + +## Configuration + +The following table lists the configurable parameters of the Kruize chart and their default values. + +### Kruize Container Parameters + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `kruize.image.repository` | Repository for Kruize container image | `quay.io/kruize/autotune_operator` | +| `kruize.image.pullPolicy` | Image pull policy for the Kruize container image | `Always` | +| `kruize.image.tag` | Image tag for Kruize container | `0.9` | +| `kruize.replicaCount` | Replica count for the Kruize container | `1` | +| `kruize.resources.requests.memory` | Memory resource request for the Kruize container | `768Mi` | +| `kruize.resources.requests.cpu` | CPU resource request for the Kruize container | `0.7` | +| `kruize.resources.limits.memory` | Memory resource limit for the Kruize container | `768Mi` | +| `kruize.resources.limits.cpu` | CPU resource limit for the Kruize container | `0.7` | +| `kruize.service.type` | Kruize service type | `NodePort` | +| `kruize.service.port` | Kruize service port | `8080` | + +### Kruize Environment Variables + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `kruize.env[].LOGGING_LEVEL` | Logging level for Kruize | `info` | +| `kruize.env[].ROOT_LOGGING_LEVEL` | Root logging level | `error` | +| `kruize.env[].DB_CONFIG_FILE` | Path to database configuration file | `/etc/config/dbconfigjson` | +| `kruize.env[].KRUIZE_CONFIG_FILE` | Path to Kruize configuration file | `/etc/config/kruizeconfigjson` | +| `kruize.env[].JAVA_TOOL_OPTIONS` | Java tool options | `-XX:MaxRAMPercentage=80` | +| `kruize.env[].KAFKA_BOOTSTRAP_SERVERS` | Kafka bootstrap servers | `kruize-kafka-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092` | +| `kruize.env[].KAFKA_TOPICS` | Kafka topics | `recommendations-topic,error-topic,summary-topic` | +| `kruize.env[].KAFKA_RESPONSE_FILTER_INCLUDE` | Kafka response filter include patterns | `experiments\|status\|apis\|recommendations\|response\|status_history` | +| `kruize.env[].KAFKA_RESPONSE_FILTER_EXCLUDE` | Kafka response filter exclude patterns | `""` | + +### Kruize Configuration Parameters + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `kruize.config.clusterType` | Type of cluster | `kubernetes` | +| `kruize.config.k8sType` | Kubernetes distribution type (openshift/minikube/kubernetes) | `kubernetes` | +| `kruize.config.authType` | Authentication type | `""` | +| `kruize.config.monitoringAgent` | Monitoring agent to use | `prometheus` | +| `kruize.config.monitoringService` | Monitoring service name | `prometheus-k8s` | +| `kruize.config.monitoringEndPoint` | Monitoring endpoint | `prometheus-k8s` | +| `kruize.config.saveToDB` | Enable saving data to database | `true` | +| `kruize.config.dbDriver` | Database driver | `jdbc:postgresql://` | +| `kruize.config.plots` | Enable plots generation | `true` | +| `kruize.config.isROSEnabled` | Enable ROS (Resource Optimization Service) | `false` | +| `kruize.config.local` | Run in local mode | `true` | +| `kruize.config.logAllHttpReqAndResp` | Log all HTTP requests and responses | `true` | +| `kruize.config.experimentNameFormat` | Format for experiment names | `%datasource%\|%clustername%\|%namespace%\|%workloadname%(%workloadtype%)\|%containername%` | +| `kruize.config.bulkapilimit` | Bulk API limit | `1000` | +| `kruize.config.isKafkaEnabled` | Enable Kafka integration | `false` | + +### Kruize Hibernate Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `kruize.config.hibernate.dialect` | Hibernate dialect | `org.hibernate.dialect.PostgreSQLDialect` | +| `kruize.config.hibernate.driver` | Hibernate driver | `org.postgresql.Driver` | +| `kruize.config.hibernate.c3p0minsize` | C3P0 minimum pool size | `5` | +| `kruize.config.hibernate.c3p0maxsize` | C3P0 maximum pool size | `10` | +| `kruize.config.hibernate.c3p0timeout` | C3P0 timeout | `300` | +| `kruize.config.hibernate.c3p0maxstatements` | C3P0 max statements | `100` | +| `kruize.config.hibernate.hbm2ddlauto` | Hibernate hbm2ddl.auto setting | `none` | +| `kruize.config.hibernate.showsql` | Show SQL queries | `false` | +| `kruize.config.hibernate.timezone` | Database timezone | `UTC` | + +### Kruize Logging Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `kruize.config.logging.cloudwatch.accessKeyId` | AWS CloudWatch access key ID | `""` | +| `kruize.config.logging.cloudwatch.logGroup` | CloudWatch log group | `kruize-logs` | +| `kruize.config.logging.cloudwatch.logStream` | CloudWatch log stream | `kruize-stream` | +| `kruize.config.logging.cloudwatch.region` | AWS region for CloudWatch | `""` | +| `kruize.config.logging.cloudwatch.secretAccessKey` | AWS CloudWatch secret access key | `""` | +| `kruize.config.logging.cloudwatch.logLevel` | CloudWatch log level | `INFO` | + +### Kruize Datasource Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `kruize.config.datasource` | Array of datasource configurations | `[]` (empty, platform-specific) | + +**Note:** Datasource configuration is platform-specific: +- **OpenShift**: Configured in `values-openshift.yaml` with prometheus-k8s and thanos-querier in openshift-monitoring namespace +- **Minikube**: Configured in `values-minikube.yaml` with prometheus-k8s in monitoring namespace +- **Generic Kubernetes**: Empty by default, configure based on your monitoring setup + +### Kruize Database Parameters + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `db.image.repository` | Repository for Kruize DB container image | `quay.io/kruizehub/postgres` | +| `db.image.pullPolicy` | Image pull policy for the Kruize DB container image | `IfNotPresent` | +| `db.image.tag` | Image tag for Kruize DB container | `15.2` | +| `db.service.name` | Kruize DB service name | `kruize-db-service` | +| `db.service.type` | Kruize DB service type | `ClusterIP` | +| `db.service.port` | Kruize DB service port | `5432` | +| `db.resources.requests.memory` | Memory resource request for the Kruize DB container | `100Mi` | +| `db.resources.requests.cpu` | CPU resource request for the Kruize DB container | `0.5` | +| `db.resources.limits.memory` | Memory resource limit for the Kruize DB container | `100Mi` | +| `db.resources.limits.cpu` | CPU resource limit for the Kruize DB container | `0.5` | +| `db.pvc.storageClass` | Storage class for database PVC | `manual` | +| `db.pvc.storageSize` | Storage size for database PVC | `500Mi` | +| `db.pvc.hostPath` | Host path for database storage | `/mnt/data` | +| `db.pvc.accessModes` | Access modes for PVC | `[ReadWriteMany]` | +| `db.volumeMountPath` | Volume mount path for database data | `/var/lib/pgsql/data` | +| `db.pgData` | PGDATA environment variable value | `/var/lib/pg_data` | +| `db.user` | User for Kruize DB container | `admin` | +| `db.password` | Password for Kruize DB container | `admin` | +| `db.adminUser` | Admin user for Kruize DB container | `admin` | +| `db.adminPassword` | Admin password for Kruize DB container | `admin` | +| `db.name` | Name of the Kruize DB | `kruizeDB` | +| `db.includeReleaseNameInDbName` | Include release name in database name for multi-instance support | `false` | +| `db.sslMode` | SSL mode for database connection | `require` | + +### Kruize UI Parameters + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `kruizeUI.image.repository` | Repository for Kruize UI container image | `quay.io/kruize/kruize-ui` | +| `kruizeUI.image.pullPolicy` | Image pull policy for the Kruize UI container image | `Always` | +| `kruizeUI.image.tag` | Image tag for Kruize UI container | `0.1.0` | +| `kruizeUI.replicaCount` | Replica count for the Kruize UI container | `1` | +| `kruizeUI.service.type` | Kruize UI service type | `NodePort` | +| `kruizeUI.service.port` | Kruize UI service port | `8080` | + +### Monitoring Parameters + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `monitoring.enabled` | Enable ServiceMonitor for Prometheus Operator | `true` | +| `monitoring.interval` | Metrics scraping interval | `30s` | + +### CronJob Parameters + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `cronJob.deletePartitionsThreshold` | Threshold for deleting old partitions (days) | `15` | +| `cronJob.createSchedule` | Schedule for running the cron job | `0 0 25 * *` | + +### Other Parameters + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `serviceAccount.create` | Specifies whether a service account should be created | `true` | +| `serviceAccount.name` | The name of the service account to use | `""` | +| `rbac.create` | Specifies whether OpenShift-specific RBAC resources should be created | `true` | +| `nameOverride` | Overrides the name of this Chart | `""` | +| `fullnameOverride` | Overrides the fully qualified application name | `""` | +| `networkPolicy.enabled` | Enable NetworkPolicy resources | `false` | + +## Example: Custom Values + +Create a `custom-values.yaml` file: + +```yaml +kruize: + replicaCount: 2 + resources: + requests: + memory: "1Gi" + cpu: "1" + limits: + memory: "1Gi" + cpu: "1" +``` + +Install with custom values: + +```bash +helm install kruize ./charts/kruize -f custom-values.yaml +``` + diff --git a/charts/kruize/templates/_helpers.tpl b/charts/kruize/templates/_helpers.tpl new file mode 100644 index 0000000..6dd828c --- /dev/null +++ b/charts/kruize/templates/_helpers.tpl @@ -0,0 +1,70 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "kruize.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kruize.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kruize.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels. +*/}} +{{- define "kruize.labels" -}} +helm.sh/chart: {{ include "kruize.chart" . }} +{{ include "kruize.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels. +*/}} +{{- define "kruize.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kruize.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use. +*/}} +{{- define "kruize.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "kruize.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the deployment. +*/}} +{{- define "kruize.deploymentName" -}} +{{- include "kruize.fullname" . -}} +{{- end -}} + diff --git a/charts/kruize/templates/configmap_kruize.yaml b/charts/kruize/templates/configmap_kruize.yaml new file mode 100644 index 0000000..a956909 --- /dev/null +++ b/charts/kruize/templates/configmap_kruize.yaml @@ -0,0 +1,81 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $fullName }}-config + namespace: {{ .Release.Namespace }} +data: + dbconfigjson: | + { + "database": { + "adminPassword": {{ .Values.db.adminPassword | quote }}, + "adminUsername": {{ .Values.db.adminUser | quote }}, + "hostname": "{{ $fullName }}-db-service", + "name": {{ if .Values.db.includeReleaseNameInDbName }}{{ printf "%s-%s" .Values.db.name $fullName | quote }}{{ else }}{{ .Values.db.name | quote }}{{ end }}, + "password": {{ .Values.db.password | quote }}, + "port": {{ .Values.db.service.port | quote }}, + "sslMode": {{ .Values.db.sslMode | quote }}, + "username": {{ .Values.db.user | quote }} + } + } + kruizeconfigjson: | + { + "clustertype": {{ .Values.kruize.config.clusterType | quote }}, + "k8stype": {{ .Values.kruize.config.k8sType | quote }}, + "authtype": {{ .Values.kruize.config.authType | quote }}, + "monitoringagent": {{ .Values.kruize.config.monitoringAgent | quote }}, + "monitoringservice": {{ .Values.kruize.config.monitoringService | quote }}, + "monitoringendpoint": {{ .Values.kruize.config.monitoringEndPoint | quote }}, + "savetodb": {{ .Values.kruize.config.saveToDB | quote }}, + "dbdriver": {{ .Values.kruize.config.dbDriver | quote }}, + "plots": {{ .Values.kruize.config.plots | quote }}, + "isROSEnabled": {{ .Values.kruize.config.isROSEnabled | quote }}, + "local": {{ .Values.kruize.config.local | quote }}, + "logAllHttpReqAndResp": {{ .Values.kruize.config.logAllHttpReqAndResp | quote }}, + "recommendationsURL" : {{ printf "http://%s.%s.svc.cluster.local:8080/generateRecommendations?experiment_name=%%s" $fullName .Release.Namespace | quote }}, + "experimentsURL" : {{ printf "http://%s.%s.svc.cluster.local:8080/createExperiment" $fullName .Release.Namespace | quote }}, + "experimentNameFormat" : {{ .Values.kruize.config.experimentNameFormat | quote }}, + "bulkapilimit" : {{ .Values.kruize.config.bulkapilimit | quote }}, + "isKafkaEnabled" : {{ .Values.kruize.config.isKafkaEnabled | quote }}, + "hibernate": { + "dialect": {{ .Values.kruize.config.hibernate.dialect | quote }}, + "driver": {{ .Values.kruize.config.hibernate.driver | quote }}, + "c3p0minsize": {{ .Values.kruize.config.hibernate.c3p0minsize | quote }}, + "c3p0maxsize": {{ .Values.kruize.config.hibernate.c3p0maxsize | quote }}, + "c3p0timeout": {{ .Values.kruize.config.hibernate.c3p0timeout | quote }}, + "c3p0maxstatements": {{ .Values.kruize.config.hibernate.c3p0maxstatements | quote }}, + "hbm2ddlauto": {{ .Values.kruize.config.hibernate.hbm2ddlauto | quote }}, + "showsql": {{ .Values.kruize.config.hibernate.showsql | quote}}, + "timezone": {{ .Values.kruize.config.hibernate.timezone | quote }} + }, + "logging" : { + "cloudwatch": { + "accessKeyId": {{ .Values.kruize.config.logging.cloudwatch.accessKeyId | quote }}, + "logGroup": {{ .Values.kruize.config.logging.cloudwatch.logGroup | quote }}, + "logStream": {{ .Values.kruize.config.logging.cloudwatch.logStream | quote }}, + "region": {{ .Values.kruize.config.logging.cloudwatch.region | quote }}, + "secretAccessKey": {{ .Values.kruize.config.logging.cloudwatch.secretAccessKey | quote }}, + "logLevel": {{ .Values.kruize.config.logging.cloudwatch.logLevel | quote }} + } + }, + + "datasource": [ + {{- range $index, $element := .Values.kruize.config.datasource }} + {{- if $index }},{{ end }} + { + "name": {{ $element.name | quote }}, + "provider": {{ $element.provider | quote }}, + "serviceName": {{ $element.serviceName | quote }}, + "namespace": {{ $element.namespace | quote }}, + "url": {{ $element.url | quote }}, + "authentication": { + "type": {{ $element.authentication.type | quote }}, + "credentials": { + "tokenFilePath": {{ $element.authentication.credentials.tokenFilePath | quote }} + } + } + } + {{- end }} + ] + } diff --git a/charts/kruize/templates/configmap_nginx.yaml b/charts/kruize/templates/configmap_nginx.yaml new file mode 100644 index 0000000..1e00801 --- /dev/null +++ b/charts/kruize/templates/configmap_nginx.yaml @@ -0,0 +1,32 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $fullName }}-nginx-config + namespace: {{ .Release.Namespace }} +data: + nginx.conf: | + events {} + http { + upstream kruize-api { + server {{ $fullName }}:8080; + } + + server { + listen 8080; + server_name localhost; + + root /usr/share/nginx/html; + + location ^~ /api/ { + rewrite ^/api(.*)$ $1 break; + proxy_pass http://kruize-api; + } + + location / { + index index.html; + error_page 404 =200 /index.html; + } + } + } diff --git a/charts/kruize/templates/cronjobs.yaml b/charts/kruize/templates/cronjobs.yaml new file mode 100644 index 0000000..a4deb20 --- /dev/null +++ b/charts/kruize/templates/cronjobs.yaml @@ -0,0 +1,95 @@ +{{- $fullName := include "kruize.fullname" . -}} +{{- $image := printf "%s:%s" .Values.kruize.image.repository .Values.kruize.image.tag -}} +{{- $namespace := .Release.Namespace -}} + +{{- $loggingLevel := "info" -}} +{{- $dbConfigFile := "" -}} +{{- $kruizeConfigFile := "" -}} + +{{- range .Values.kruize.env -}} + {{- if eq .name "LOGGING_LEVEL" -}} + {{- $loggingLevel = .value -}} + {{- end -}} + {{- if eq .name "DB_CONFIG_FILE" -}} + {{- $dbConfigFile = .value -}} + {{- end -}} + {{- if eq .name "KRUIZE_CONFIG_FILE" -}} + {{- $kruizeConfigFile = .value -}} + {{- end -}} +{{- end -}} +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ .Release.Name }}-create-partition + namespace: {{ $namespace }} +spec: + schedule: {{ default "0 0 25 * *" .Values.cronJob.createSchedule | quote }} # Run on 25th of every month at midnight + jobTemplate: + spec: + template: + spec: + containers: + - name: kruize-cron-create + image: {{ $image }} + imagePullPolicy: {{ .Values.kruize.image.pullPolicy }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + command: + - sh + - -c + - | + /home/autotune/app/target/bin/CreatePartition + env: + - name: START_AUTOTUNE + value: "false" + - name: LOGGING_LEVEL + value: {{ $loggingLevel | quote }} + - name: DB_CONFIG_FILE + value: {{ $dbConfigFile | quote }} + - name: KRUIZE_CONFIG_FILE + value: {{ $kruizeConfigFile | quote }} + volumes: + - name: config-volume + configMap: + name: {{ $fullName }}-config + restartPolicy: OnFailure +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ .Release.Name }}-delete-partition + namespace: {{ $namespace }} +spec: + schedule: {{ default "0 0 25 * *" .Values.cronJob.createSchedule | quote }} + jobTemplate: + spec: + template: + spec: + containers: + - name: kruize-cron-delete + image: {{ $image }} + imagePullPolicy: {{ .Values.kruize.image.pullPolicy }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + command: + - sh + - -c + - | + /home/autotune/app/target/bin/RetentionPartition + env: + - name: START_AUTOTUNE + value: "false" + - name: DB_CONFIG_FILE + value: {{ $dbConfigFile | quote }} + - name: KRUIZE_CONFIG_FILE + value: {{ $kruizeConfigFile | quote }} + - name: deletepartitionsthreshold + value: {{ .Values.cronJob.deletePartitionsThreshold | quote }} + volumes: + - name: config-volume + configMap: + name: {{ $fullName }}-config + restartPolicy: OnFailure diff --git a/charts/kruize/templates/kruize_db_deployment.yaml b/charts/kruize/templates/kruize_db_deployment.yaml new file mode 100644 index 0000000..ad05547 --- /dev/null +++ b/charts/kruize/templates/kruize_db_deployment.yaml @@ -0,0 +1,68 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "kruize.deploymentName" . }}-db + namespace: {{ .Release.Namespace }} + labels: + {{- include "kruize.labels" . | nindent 4 }} + app: {{ $fullName }}-db +spec: + replicas: 1 + selector: + matchLabels: + {{- include "kruize.selectorLabels" . | nindent 6 }} + app: {{ $fullName }}-db + template: + metadata: + labels: + {{- include "kruize.selectorLabels" . | nindent 8 }} + app: {{ $fullName }}-db + spec: + serviceAccountName: {{ include "kruize.serviceAccountName" . }} + containers: + - name: {{ .Chart.Name }}-db + image: "{{ .Values.db.image.repository }}:{{ .Values.db.image.tag }}" + imagePullPolicy: {{ .Values.db.image.pullPolicy }} + env: + - name: POSTGRES_PASSWORD + value: {{ .Values.db.password | quote }} + - name: POSTGRES_USER + value: {{ .Values.db.user | quote }} + - name: POSTGRES_DB + value: {{ if .Values.db.includeReleaseNameInDbName }}{{ printf "%s-%s" .Values.db.name $fullName | quote }}{{ else }}{{ .Values.db.name | quote }}{{ end }} + {{- if .Values.db.pgData }} + - name: PGDATA + value: {{ .Values.db.pgData }} + {{- end }} + {{- if or .Values.db.resources.requests.memory .Values.db.resources.requests.cpu .Values.db.resources.limits.memory .Values.db.resources.limits.cpu }} + resources: + {{- if or .Values.db.resources.requests.memory .Values.db.resources.requests.cpu }} + requests: + {{- if .Values.db.resources.requests.memory }} + memory: {{ .Values.db.resources.requests.memory | quote }} + {{- end }} + {{- if .Values.db.resources.requests.cpu }} + cpu: {{ .Values.db.resources.requests.cpu | quote }} + {{- end }} + {{- end }} + {{- if or .Values.db.resources.limits.memory .Values.db.resources.limits.cpu }} + limits: + {{- if .Values.db.resources.limits.memory }} + memory: {{ .Values.db.resources.limits.memory | quote }} + {{- end }} + {{- if .Values.db.resources.limits.cpu }} + cpu: {{ .Values.db.resources.limits.cpu | quote }} + {{- end }} + {{- end }} + {{- end }} + ports: + - containerPort: {{ .Values.db.service.port }} + volumeMounts: + - name: kruize-db-storage + mountPath: {{ .Values.db.volumeMountPath }} + volumes: + - name: kruize-db-storage + persistentVolumeClaim: + claimName: {{ $fullName }}-db-pv-claim diff --git a/charts/kruize/templates/kruize_db_service.yaml b/charts/kruize/templates/kruize_db_service.yaml new file mode 100644 index 0000000..a5cb095 --- /dev/null +++ b/charts/kruize/templates/kruize_db_service.yaml @@ -0,0 +1,19 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullName }}-db-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "kruize.labels" . | nindent 4 }} + app: {{ $fullName }}-db +spec: + type: {{ .Values.db.service.type }} + ports: + - name: kruize-db-port + port: {{ .Values.db.service.port }} + targetPort: {{ .Values.db.service.port }} + selector: + {{- include "kruize.selectorLabels" . | nindent 4 }} + app: {{ $fullName }}-db diff --git a/charts/kruize/templates/kruize_deployment.yaml b/charts/kruize/templates/kruize_deployment.yaml new file mode 100644 index 0000000..d9c3785 --- /dev/null +++ b/charts/kruize/templates/kruize_deployment.yaml @@ -0,0 +1,76 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "kruize.deploymentName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "kruize.labels" . | nindent 4 }} + app: {{ $fullName }} +spec: + replicas: {{ .Values.kruize.replicaCount | default 1 }} + selector: + matchLabels: + {{- include "kruize.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "kruize.selectorLabels" . | nindent 8 }} + app: {{ $fullName }} + spec: + serviceAccountName: {{ include "kruize.serviceAccountName" . }} + initContainers: + - name: wait-for-kruize-db + image: "{{ .Values.db.image.repository }}:{{ .Values.db.image.tag }}" + command: + - sh + - -c + - > + until pg_isready + -h "{{ $fullName }}-db-service" + -p {{ .Values.db.service.port | default 5432 }} + -U {{ .Values.db.user | quote }}; + do echo "Waiting for database..."; + sleep 2; + done + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.kruize.image.repository }}:{{ .Values.kruize.image.tag }}" + imagePullPolicy: {{ .Values.kruize.image.pullPolicy }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + env: + {{- range .Values.kruize.env }} + - name: {{ .name }} + value: {{ .value | quote }} + {{- end }} + {{- if or .Values.kruize.resources.requests.memory .Values.kruize.resources.requests.cpu .Values.kruize.resources.limits.memory .Values.kruize.resources.limits.cpu }} + resources: + {{- if or .Values.kruize.resources.requests.memory .Values.kruize.resources.requests.cpu }} + requests: + {{- if .Values.kruize.resources.requests.cpu }} + cpu: {{ .Values.kruize.resources.requests.cpu }} + {{- end }} + {{- if .Values.kruize.resources.requests.memory }} + memory: {{ .Values.kruize.resources.requests.memory }} + {{- end }} + {{- end }} + {{- if or .Values.kruize.resources.limits.memory .Values.kruize.resources.limits.cpu }} + limits: + {{- if .Values.kruize.resources.limits.cpu }} + cpu: {{ .Values.kruize.resources.limits.cpu }} + {{- end }} + {{- if .Values.kruize.resources.limits.memory }} + memory: {{ .Values.kruize.resources.limits.memory }} + {{- end }} + {{- end }} + {{- end }} + ports: + - name: kruize-port + containerPort: {{ .Values.kruize.service.port }} + volumes: + - name: config-volume + configMap: + name: {{ $fullName }}-config diff --git a/charts/kruize/templates/kruize_service.yaml b/charts/kruize/templates/kruize_service.yaml new file mode 100644 index 0000000..9a6bc5b --- /dev/null +++ b/charts/kruize/templates/kruize_service.yaml @@ -0,0 +1,23 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullName }} + namespace: {{ .Release.Namespace }} + annotations: + prometheus.io/scrape: 'true' + prometheus.io/path: '/metrics' + labels: + {{- include "kruize.labels" . | nindent 4 }} + app: {{ $fullName }} +spec: + type: {{ .Values.kruize.service.type }} + selector: + {{- include "kruize.selectorLabels" . | nindent 4 }} + app: {{ $fullName }} + ports: + - name: kruize-port + port: {{ .Values.kruize.service.port }} + targetPort: {{ .Values.kruize.service.port }} + diff --git a/charts/kruize/templates/kruize_ui_nginx_deployment.yaml b/charts/kruize/templates/kruize_ui_nginx_deployment.yaml new file mode 100644 index 0000000..32fe953 --- /dev/null +++ b/charts/kruize/templates/kruize_ui_nginx_deployment.yaml @@ -0,0 +1,36 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $fullName }}-ui-nginx + namespace: {{ .Release.Namespace }} + labels: + app: {{ $fullName }}-ui-nginx +spec: + replicas: {{ .Values.kruizeUI.replicaCount }} + strategy: + type: RollingUpdate + selector: + matchLabels: + app: {{ $fullName }}-ui-nginx + template: + metadata: + labels: + app: {{ $fullName }}-ui-nginx + spec: + containers: + - name: kruize-ui-nginx-container + image: "{{ .Values.kruizeUI.image.repository }}:{{ .Values.kruizeUI.image.tag }}" + imagePullPolicy: {{ .Values.kruizeUI.image.pullPolicy }} + env: + - name: KRUIZE_UI_ENV + value: "production" + volumeMounts: + - name: nginx-config-volume + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + volumes: + - name: nginx-config-volume + configMap: + name: {{ $fullName }}-nginx-config diff --git a/charts/kruize/templates/kruize_ui_nginx_service.yaml b/charts/kruize/templates/kruize_ui_nginx_service.yaml new file mode 100644 index 0000000..bf4e54a --- /dev/null +++ b/charts/kruize/templates/kruize_ui_nginx_service.yaml @@ -0,0 +1,17 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullName }}-ui-nginx-service + namespace: {{ .Release.Namespace }} + labels: + app: {{ $fullName }}-ui-nginx +spec: + type: {{ .Values.kruizeUI.service.type }} + ports: + - name: http + port: {{ .Values.kruizeUI.service.port }} + targetPort: {{ .Values.kruizeUI.service.port }} + selector: + app: {{ $fullName }}-ui-nginx diff --git a/charts/kruize/templates/network_policy.yaml b/charts/kruize/templates/network_policy.yaml new file mode 100644 index 0000000..5f3be99 --- /dev/null +++ b/charts/kruize/templates/network_policy.yaml @@ -0,0 +1,26 @@ +{{- if .Values.networkPolicy.enabled -}} +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ $fullName }}-to-prometheus + namespace: {{ .Release.Namespace }} + labels: + {{- include "kruize.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + {{- include "kruize.selectorLabels" . | nindent 14 }} + app: {{ $fullName }} + ports: + - protocol: TCP + port: 9090 +{{- end }} diff --git a/charts/kruize/templates/role.yaml b/charts/kruize/templates/role.yaml new file mode 100644 index 0000000..76a64aa --- /dev/null +++ b/charts/kruize/templates/role.yaml @@ -0,0 +1,64 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ $fullName }}-recommendation-updater +rules: + - apiGroups: + - "" + resources: + - pods + - customresourcedefinitions + verbs: + - '*' + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - '*' + - apiGroups: + - autoscaling.k8s.io + resources: + - verticalpodautoscalers + - verticalpodautoscalers/status + - verticalpodautoscalercheckpoints + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - '*' + - apiGroups: + - apps + resources: + - deployments + verbs: + - "*" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ $fullName }}-edit-ko +rules: + - apiGroups: [ "apps" ] + resources: [ "deployments", "statefulsets", "daemonsets" ] + verbs: [ "get", "list", "patch", "update" ] + - apiGroups: [ "batch" ] + resources: [ "jobs" ] + verbs: [ "get", "list", "create", "delete" ] + - apiGroups: [ "" ] + resources: [ "namespaces" ] + verbs: [ "get", "list" ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ $fullName }}-instaslices-access +rules: + - apiGroups: [ "inference.redhat.com" ] + resources: [ "instaslices" ] + verbs: [ "get", "list", "watch" ] diff --git a/charts/kruize/templates/rolebinding.yaml b/charts/kruize/templates/rolebinding.yaml new file mode 100644 index 0000000..11ed5fa --- /dev/null +++ b/charts/kruize/templates/rolebinding.yaml @@ -0,0 +1,71 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ $fullName }}-recommendation-updater-crb +subjects: + - kind: ServiceAccount + name: {{ include "kruize.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ $fullName }}-recommendation-updater +--- +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ $fullName }}-monitoring-view +subjects: + - kind: ServiceAccount + name: {{ include "kruize.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: cluster-monitoring-view + apiGroup: rbac.authorization.k8s.io +--- +{{- end }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ $fullName }}-instaslices-access-binding +subjects: + - kind: ServiceAccount + name: {{ include "kruize.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ $fullName }}-instaslices-access + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ $fullName }}-edit-ko-binding +subjects: + - kind: ServiceAccount + name: {{ include "kruize.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ $fullName }}-edit-ko + apiGroup: rbac.authorization.k8s.io +--- +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ $fullName }}-autotune-scc-crb +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: {{ include "kruize.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +--- +{{- end }} diff --git a/charts/kruize/templates/service_account.yaml b/charts/kruize/templates/service_account.yaml new file mode 100644 index 0000000..a140581 --- /dev/null +++ b/charts/kruize/templates/service_account.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "kruize.serviceAccountName" . }} + labels: + {{- include "kruize.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/kruize/templates/service_monitor.yaml b/charts/kruize/templates/service_monitor.yaml new file mode 100644 index 0000000..92274bb --- /dev/null +++ b/charts/kruize/templates/service_monitor.yaml @@ -0,0 +1,24 @@ +{{- $fullName := include "kruize.fullname" . -}} +{{- if .Values.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ $fullName }}-service-monitor + namespace: {{ .Release.Namespace }} + labels: + {{- include "kruize.labels" . | nindent 4 }} + app: {{ $fullName }} +spec: + selector: + matchLabels: + {{- include "kruize.selectorLabels" . | nindent 6 }} + app: {{ $fullName }} + endpoints: + - port: kruize-port + interval: {{ .Values.monitoring.interval }} + path: /metrics + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end }} + diff --git a/charts/kruize/templates/storage_manual.yaml b/charts/kruize/templates/storage_manual.yaml new file mode 100644 index 0000000..72e8764 --- /dev/null +++ b/charts/kruize/templates/storage_manual.yaml @@ -0,0 +1,10 @@ +{{- if not (lookup "storage.k8s.io/v1" "StorageClass" "" "manual") }} +--- +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: manual +provisioner: kubernetes.io/no-provisioner +reclaimPolicy: Retain +volumeBindingMode: Immediate +{{- end }} diff --git a/charts/kruize/templates/storage_pv.yaml b/charts/kruize/templates/storage_pv.yaml new file mode 100644 index 0000000..574c516 --- /dev/null +++ b/charts/kruize/templates/storage_pv.yaml @@ -0,0 +1,22 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +kind: PersistentVolume +apiVersion: v1 +metadata: + name: {{ $fullName }}-db-pv-volume + labels: + type: local + app: {{ $fullName }}-db + {{- include "kruize.labels" . | nindent 4 }} + +spec: + storageClassName: {{ .Values.db.pvc.storageClass | quote }} + capacity: + storage: {{ .Values.db.pvc.storageSize | quote }} + accessModes: + {{- toYaml .Values.db.pvc.accessModes | nindent 4 }} + {{- if .Values.db.pvc.reclaimPolicy }} + persistentVolumeReclaimPolicy: {{ .Values.db.pvc.reclaimPolicy }} + {{- end }} + hostPath: + path: {{ printf "%s/%s" .Values.db.pvc.hostPath $fullName | quote }} diff --git a/charts/kruize/templates/storage_pvc.yaml b/charts/kruize/templates/storage_pvc.yaml new file mode 100644 index 0000000..311565e --- /dev/null +++ b/charts/kruize/templates/storage_pvc.yaml @@ -0,0 +1,16 @@ +{{- $fullName := include "kruize.fullname" . -}} +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ $fullName }}-db-pv-claim + namespace: {{ .Release.Namespace }} + labels: + app: {{ $fullName }}-db +spec: + storageClassName: {{ .Values.db.pvc.storageClass | quote }} + accessModes: + {{- toYaml .Values.db.pvc.accessModes | nindent 4 }} + resources: + requests: + storage: {{ .Values.db.pvc.storageSize | quote }} diff --git a/charts/kruize/tests/README.md b/charts/kruize/tests/README.md new file mode 100644 index 0000000..372ac83 --- /dev/null +++ b/charts/kruize/tests/README.md @@ -0,0 +1,231 @@ +# Kruize Helm Chart Tests + +This directory contains unit tests for the Kruize Helm chart using the [helm-unittest](https://github.com/helm-unittest/helm-unittest) plugin. + +## Prerequisites + +Install the helm-unittest plugin: + +```bash +helm plugin install https://github.com/helm-unittest/helm-unittest +``` + +## Running Tests + +> **Note:** The default `helm unittest charts/kruize` command will not find tests in subdirectories. You must explicitly specify test file patterns using the `-f` flag. + +### Run all tests +```bash +helm unittest -f 'tests/with-default-values/*.yaml' -f 'tests/with-openshift-values/*.yaml' -f 'tests/with-minikube-values/*.yaml' charts/kruize +``` + +Or from within the chart directory: +```bash +cd charts/kruize +helm unittest -f 'tests/with-default-values/*.yaml' -f 'tests/with-openshift-values/*.yaml' -f 'tests/with-minikube-values/*.yaml' . +``` + +### Run tests with default values only +```bash +cd charts/kruize +helm unittest -f 'tests/with-default-values/*.yaml' . +``` + +### Run tests with OpenShift values +```bash +cd charts/kruize +helm unittest -f 'tests/with-openshift-values/*.yaml' . +``` + +### Run tests with Minikube values +```bash +cd charts/kruize +helm unittest -f 'tests/with-minikube-values/*.yaml' . +``` + +### Run tests with verbose output +```bash +cd charts/kruize +helm unittest -d -f tests/with-default-values/kruize_ui_test.yaml . +``` + +### Generate JUnit Test Report +```bash +cd charts/kruize +helm unittest --output-type JUnit --output-file test-results.xml -f 'tests/with-default-values/*.yaml' -f 'tests/with-openshift-values/*.yaml' -f 'tests/with-minikube-values/*.yaml' . +``` + +## Directory Structure + +``` +tests/ +├── with-default-values/ # Tests using default values.yaml (39 tests) +│ ├── configmap_test.yaml +│ ├── cronjobs_test.yaml +│ ├── kruize_db_deployment_test.yaml +│ ├── kruize_db_service_test.yaml +│ ├── kruize_service_test.yaml +│ ├── kruize_ui_test.yaml +│ ├── network_policy_test.yaml +│ ├── service_monitor_test.yaml +│ └── storage_test.yaml +│ +├── with-openshift-values/ # Tests using values-openshift.yaml (20 tests) +│ ├── kruize_deployment_test.yaml +│ └── rbac_test.yaml +│ +└── with-minikube-values/ # Tests using values-minikube.yaml (34 tests) + ├── kruize_db_deployment_minikube_test.yaml + ├── kruize_deployment_minikube_test.yaml + ├── network_policy_minikube_test.yaml + ├── rbac_minikube_test.yaml + ├── service_monitor_minikube_test.yaml + └── storage_minikube_test.yaml +``` + +> **Important:** All tests are **unit tests** that render and validate Helm templates. They do not require an actual Kubernetes cluster to run. The folder names indicate which values file configuration is being tested, not which cluster type is required. + +## Values-based Test Organization + +### Tests with Default Values (`tests/with-default-values/`) +Tests that use the default `values.yaml`. These validate core functionality with standard configurations. + +### Tests with OpenShift Values (`tests/with-openshift-values/`) +Tests that use `values-openshift.yaml` to validate OpenShift-specific configurations: +- `serviceAccount.create: true` — creates a dedicated service account +- `rbac.create: true` — includes OpenShift-specific ClusterRoleBindings (cluster-monitoring-view, SCC anyuid) +- Resource requests/limits are set +- Full KAFKA_RESPONSE_FILTER_INCLUDE configuration + +### Tests with Minikube Values (`tests/with-minikube-values/`) +Tests that use `values-minikube.yaml` to validate minikube-specific configurations: +- `serviceAccount.create: false` — uses the `default` service account +- `rbac.create: false` — skips OpenShift-specific ClusterRoleBindings +- `db.pgData: ""` — PGDATA env var is not set +- `db.volumeMountPath: /var/lib/postgresql/data` — minikube postgres path +- `db.pvc.storageSize: 1Gi` — smaller storage for minikube +- `db.pvc.accessModes: [ReadWriteOnce]` — minikube storage access mode +- `db.pvc.hostPath: /data/postgres` — minikube host path +- `db.pvc.reclaimPolicy: Retain` — retain policy for minikube +- `networkPolicy.enabled: true` — network policy is enabled on minikube +- `monitoring.enabled: true` — monitoring is enabled on minikube +- Empty resource requests/limits — no resource constraints on minikube +- `KAFKA_RESPONSE_FILTER_INCLUDE: summary` — simplified kafka filter for minikube + +## Test File Structure + +Each test file follows the below style: + +```yaml +suite: test +templates: + - + +tests: + - it: should create a with the correct default settings + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: + - equal: + path: metadata.name + value: RELEASE-NAME- + # ... all default assertions grouped together + + - it: should create a with the correct settings overrides + set: + some.value: override + asserts: + - equal: + path: spec.someField + value: override + + - it: should create a in the release namespace + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace +``` + +## Common Assertions + +- `equal` - Checks if a value equals the expected value +- `notEqual` - Checks if a value does not equal the expected value +- `exists` - Checks if a path exists +- `notExists` - Checks if a path does not exist +- `contains` - Checks if an array contains a specific element +- `hasDocuments` - Checks the number of documents in the output +- `matchRegex` - Checks if a value matches a regex pattern + + +## Adding New Tests + +When adding new templates or modifying existing ones: + +1. **For tests with default values**: + - Create or update test file in `charts/kruize/tests/with-default-values/` + - Follow naming convention: `_test.yaml` + - Use default `values.yaml` + +2. **For tests with OpenShift values**: + - Create or update test file in `charts/kruize/tests/with-openshift-values/` + - Add `values: - ../../values-openshift.yaml` to the test suite + - Test OpenShift-specific features (RBAC, SCC, monitoring, etc.) + +3. **For tests with Minikube values**: + - Create or update test file in `charts/kruize/tests/with-minikube-values/` + - Add `values: - ../../values-minikube.yaml` to the test suite + - Test minikube-specific overrides (empty resources, default SA, etc.) + +4. Include tests for: + - Default values + - Settings overrides (using `set:`) + - Conditional resource creation (enabled/disabled flags) + - Namespace propagation (using `release.namespace`) + - Label and selector validation + +## Updating Version Numbers in Tests + +Version numbers in test files are hardcoded because helm-unittest does not support dynamic value substitution in test assertions. + +when versions are updated (e.g., kruize from 0.9 to 0.10) update the values in the tests as well. + +**Verify all tests pass:** + ```bash + cd charts/kruize + helm unittest -f 'tests/with-default-values/*.yaml' -f 'tests/with-openshift-values/*.yaml' -f 'tests/with-minikube-values/*.yaml' . + ``` + +## Troubleshooting + +### Plugin Not Found + +```bash +helm plugin list +helm plugin install https://github.com/helm-unittest/helm-unittest +``` + +### Test Failures + +Run with verbose output to see detailed failure information: +```bash +helm unittest -d -f 'tests/with-default-values/*.yaml' -f 'tests/with-openshift-values/*.yaml' -f 'tests/with-minikube-values/*.yaml' charts/kruize +``` + +### Debugging Specific Tests + +```bash +helm unittest -f 'tests/with-default-values/kruize_db_deployment_test.yaml' charts/kruize +helm unittest -f 'tests/with-default-values/kruize_ui_test.yaml' charts/kruize +helm unittest -f 'tests/with-openshift-values/kruize_deployment_test.yaml' charts/kruize +helm unittest -f 'tests/with-minikube-values/kruize_deployment_minikube_test.yaml' charts/kruize +``` + +## Resources + +- [Helm Unittest Documentation](https://github.com/helm-unittest/helm-unittest/blob/main/DOCUMENT.md) +- [Helm Chart Testing Guide](https://helm.sh/docs/topics/chart_tests/) diff --git a/charts/kruize/tests/with-default-values/configmap_test.yaml b/charts/kruize/tests/with-default-values/configmap_test.yaml new file mode 100644 index 0000000..23aa8d8 --- /dev/null +++ b/charts/kruize/tests/with-default-values/configmap_test.yaml @@ -0,0 +1,60 @@ +suite: test configmap templates +templates: + - configmap_kruize.yaml + - configmap_nginx.yaml + +tests: + - it: should create a kruize ConfigMap with the correct default settings + template: configmap_kruize.yaml + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: ConfigMap + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-config + - exists: + path: data.dbconfigjson + - exists: + path: data.kruizeconfigjson + + - it: should create a kruize ConfigMap in the release namespace + template: configmap_kruize.yaml + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + + - it: should create a nginx ConfigMap with the correct default settings + template: configmap_nginx.yaml + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: ConfigMap + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-nginx-config + - exists: + path: data["nginx.conf"] + + - it: should create a nginx ConfigMap in the release namespace + template: configmap_nginx.yaml + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + diff --git a/charts/kruize/tests/with-default-values/cronjobs_test.yaml b/charts/kruize/tests/with-default-values/cronjobs_test.yaml new file mode 100644 index 0000000..8d654f2 --- /dev/null +++ b/charts/kruize/tests/with-default-values/cronjobs_test.yaml @@ -0,0 +1,104 @@ +suite: test cronjobs.yaml +templates: + - cronjobs.yaml + +tests: + - it: should create two CronJob documents + asserts: + - hasDocuments: + count: 2 + + - it: should create a create-partition CronJob with the correct default settings + documentIndex: 0 + asserts: + - equal: + path: kind + value: CronJob + - equal: + path: apiVersion + value: batch/v1 + - equal: + path: metadata.name + value: RELEASE-NAME-create-partition + - equal: + path: spec.schedule + value: "0 0 25 * *" + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].name + value: kruize-cron-create + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].image + value: "quay.io/kruize/autotune_operator:0.9" + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].imagePullPolicy + value: Always + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0].name + value: config-volume + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0].mountPath + value: /etc/config + - equal: + path: spec.jobTemplate.spec.template.spec.restartPolicy + value: OnFailure + - equal: + path: spec.jobTemplate.spec.template.spec.volumes[0].configMap.name + value: RELEASE-NAME-kruize-config + + - it: should create a delete-partition CronJob with the correct default settings + documentIndex: 1 + asserts: + - equal: + path: kind + value: CronJob + - equal: + path: metadata.name + value: RELEASE-NAME-delete-partition + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].name + value: kruize-cron-delete + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].image + value: "quay.io/kruize/autotune_operator:0.9" + - contains: + path: spec.jobTemplate.spec.template.spec.containers[0].env + content: + name: deletepartitionsthreshold + value: "15" + - equal: + path: spec.jobTemplate.spec.template.spec.restartPolicy + value: OnFailure + + - it: should create CronJobs with the correct settings overrides + documentIndex: 0 + set: + cronJob.createSchedule: "0 0 1 * *" + kruize.image.tag: "0.9.0" + asserts: + - equal: + path: spec.schedule + value: "0 0 1 * *" + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].image + value: "quay.io/kruize/autotune_operator:0.9.0" + + - it: should use custom deletePartitionsThreshold when specified + documentIndex: 1 + set: + cronJob.deletePartitionsThreshold: "30" + asserts: + - contains: + path: spec.jobTemplate.spec.template.spec.containers[0].env + content: + name: deletepartitionsthreshold + value: "30" + + - it: should create CronJobs in the release namespace + documentIndex: 0 + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + diff --git a/charts/kruize/tests/with-default-values/kruize_db_deployment_test.yaml b/charts/kruize/tests/with-default-values/kruize_db_deployment_test.yaml new file mode 100644 index 0000000..b7fd65a --- /dev/null +++ b/charts/kruize/tests/with-default-values/kruize_db_deployment_test.yaml @@ -0,0 +1,117 @@ +suite: test kruize_db_deployment.yaml +templates: + - kruize_db_deployment.yaml + +tests: + - it: should create a Deployment with the correct default settings + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: Deployment + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-db + - equal: + path: spec.replicas + value: 1 + - equal: + path: spec.selector.matchLabels.app + value: RELEASE-NAME-kruize-db + - equal: + path: spec.template.metadata.labels.app + value: RELEASE-NAME-kruize-db + - equal: + path: spec.template.spec.serviceAccountName + value: RELEASE-NAME-kruize + + - it: should validate kruize-db container settings + asserts: + - exists: + path: spec.template.spec.containers[?(@.name=='kruize-db')] + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].image + value: "quay.io/kruizehub/postgres:15.2" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].imagePullPolicy + value: "IfNotPresent" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].env[?(@.name=='POSTGRES_PASSWORD')] + value: + name: POSTGRES_PASSWORD + value: "admin" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].env[?(@.name=='POSTGRES_USER')] + value: + name: POSTGRES_USER + value: "admin" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].env[?(@.name=='POSTGRES_DB')] + value: + name: POSTGRES_DB + value: "kruizeDB" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].env[?(@.name=='PGDATA')] + value: + name: PGDATA + value: "/var/lib/pg_data" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].ports[0].containerPort + value: 5432 + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].volumeMounts[0].mountPath + value: "/var/lib/pgsql/data" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].volumeMounts[0].name + value: "kruize-db-storage" + + - it: should validate resource settings + asserts: + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].resources.requests.memory + value: "100Mi" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].resources.requests.cpu + value: "0.5" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].resources.limits.memory + value: "100Mi" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].resources.limits.cpu + value: "0.5" + + - it: should validate volume configuration + asserts: + - equal: + path: spec.template.spec.volumes[0].name + value: "kruize-db-storage" + - equal: + path: spec.template.spec.volumes[0].persistentVolumeClaim.claimName + value: "RELEASE-NAME-kruize-db-pv-claim" + + - it: should create a Deployment with the correct settings overrides + set: + db.image.tag: "16.0" + db.resources.requests.memory: "256Mi" + db.resources.requests.cpu: "1" + db.resources.limits.memory: "512Mi" + db.resources.limits.cpu: "2" + asserts: + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].image + value: "quay.io/kruizehub/postgres:16.0" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].resources.requests.memory + value: "256Mi" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].resources.requests.cpu + value: "1" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].resources.limits.memory + value: "512Mi" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].resources.limits.cpu + value: "2" + + diff --git a/charts/kruize/tests/with-default-values/kruize_db_service_test.yaml b/charts/kruize/tests/with-default-values/kruize_db_service_test.yaml new file mode 100644 index 0000000..47e8f06 --- /dev/null +++ b/charts/kruize/tests/with-default-values/kruize_db_service_test.yaml @@ -0,0 +1,62 @@ +suite: test kruize_db_service.yaml +templates: + - kruize_db_service.yaml + +tests: + - it: should create a Service with the correct default settings + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: Service + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-db-service + - equal: + path: metadata.labels.app + value: RELEASE-NAME-kruize-db + - equal: + path: spec.type + value: ClusterIP + - equal: + path: spec.ports[0].name + value: kruize-db-port + - equal: + path: spec.ports[0].port + value: 5432 + - equal: + path: spec.ports[0].targetPort + value: 5432 + - equal: + path: spec.selector.app + value: RELEASE-NAME-kruize-db + + - it: should create a Service with the correct settings overrides + set: + db.service.type: NodePort + db.service.port: 5433 + asserts: + - hasDocuments: + count: 1 + - equal: + path: spec.type + value: NodePort + - equal: + path: spec.ports[0].port + value: 5433 + - equal: + path: spec.ports[0].targetPort + value: 5433 + + - it: should create a Service in the release namespace + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + diff --git a/charts/kruize/tests/with-default-values/kruize_service_test.yaml b/charts/kruize/tests/with-default-values/kruize_service_test.yaml new file mode 100644 index 0000000..8d57bc1 --- /dev/null +++ b/charts/kruize/tests/with-default-values/kruize_service_test.yaml @@ -0,0 +1,76 @@ +suite: test kruize_service.yaml +templates: + - kruize_service.yaml + +tests: + - it: should create a Service with the correct default settings + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: Service + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize + - equal: + path: metadata.labels + value: + app: RELEASE-NAME-kruize + helm.sh/chart: kruize-0.1.0 + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/version: "0.9" + app.kubernetes.io/managed-by: Helm + - equal: + path: metadata.annotations + value: + prometheus.io/scrape: 'true' + prometheus.io/path: '/metrics' + - equal: + path: spec.type + value: NodePort + - equal: + path: spec.selector + value: + app: RELEASE-NAME-kruize + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + - equal: + path: spec.ports[0].name + value: kruize-port + - equal: + path: spec.ports[0].port + value: 8080 + - equal: + path: spec.ports[0].targetPort + value: 8080 + + - it: should create a Service with the correct settings overrides + set: + kruize.service.type: ClusterIP + kruize.service.port: 9090 + asserts: + - hasDocuments: + count: 1 + - equal: + path: spec.type + value: ClusterIP + - equal: + path: spec.ports[0].port + value: 9090 + - equal: + path: spec.ports[0].targetPort + value: 9090 + + - it: should create a Service in the release namespace + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + diff --git a/charts/kruize/tests/with-default-values/kruize_ui_test.yaml b/charts/kruize/tests/with-default-values/kruize_ui_test.yaml new file mode 100644 index 0000000..e896034 --- /dev/null +++ b/charts/kruize/tests/with-default-values/kruize_ui_test.yaml @@ -0,0 +1,146 @@ +suite: test kruize UI templates +templates: + - kruize_ui_nginx_deployment.yaml + - kruize_ui_nginx_service.yaml + +tests: + - it: should create a UI nginx Deployment with the correct default settings + template: kruize_ui_nginx_deployment.yaml + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: Deployment + - equal: + path: apiVersion + value: apps/v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-ui-nginx + - equal: + path: metadata.labels.app + value: RELEASE-NAME-kruize-ui-nginx + - equal: + path: spec.replicas + value: 1 + - equal: + path: spec.strategy.type + value: RollingUpdate + - equal: + path: spec.selector.matchLabels.app + value: RELEASE-NAME-kruize-ui-nginx + - equal: + path: spec.template.metadata.labels.app + value: RELEASE-NAME-kruize-ui-nginx + - equal: + path: spec.template.spec.containers[0].name + value: kruize-ui-nginx-container + - equal: + path: spec.template.spec.containers[0].image + value: "quay.io/kruize/kruize-ui:0.1.0" + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: Always + - contains: + path: spec.template.spec.containers[0].env + content: + name: KRUIZE_UI_ENV + value: "production" + - equal: + path: spec.template.spec.containers[0].volumeMounts[0].name + value: nginx-config-volume + - equal: + path: spec.template.spec.containers[0].volumeMounts[0].mountPath + value: /etc/nginx/nginx.conf + - equal: + path: spec.template.spec.containers[0].volumeMounts[0].subPath + value: nginx.conf + - equal: + path: spec.template.spec.volumes[0].name + value: nginx-config-volume + - equal: + path: spec.template.spec.volumes[0].configMap.name + value: RELEASE-NAME-kruize-nginx-config + + - it: should create a UI nginx Deployment with the correct settings overrides + template: kruize_ui_nginx_deployment.yaml + set: + kruizeUI.image.tag: "0.2.0" + kruizeUI.image.pullPolicy: IfNotPresent + kruizeUI.replicaCount: 3 + asserts: + - equal: + path: spec.replicas + value: 3 + - equal: + path: spec.template.spec.containers[0].image + value: "quay.io/kruize/kruize-ui:0.2.0" + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: IfNotPresent + + - it: should create a UI nginx Deployment in the release namespace + template: kruize_ui_nginx_deployment.yaml + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + + - it: should create a UI nginx Service with the correct default settings + template: kruize_ui_nginx_service.yaml + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: Service + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-ui-nginx-service + - equal: + path: spec.type + value: NodePort + - equal: + path: spec.ports[0].name + value: http + - equal: + path: spec.ports[0].port + value: 8080 + - equal: + path: spec.ports[0].targetPort + value: 8080 + - equal: + path: spec.selector.app + value: RELEASE-NAME-kruize-ui-nginx + + - it: should create a UI nginx Service with the correct settings overrides + template: kruize_ui_nginx_service.yaml + set: + kruizeUI.service.type: ClusterIP + kruizeUI.service.port: 9090 + asserts: + - equal: + path: spec.type + value: ClusterIP + - equal: + path: spec.ports[0].port + value: 9090 + - equal: + path: spec.ports[0].targetPort + value: 9090 + + - it: should create a UI nginx Service in the release namespace + template: kruize_ui_nginx_service.yaml + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + diff --git a/charts/kruize/tests/with-default-values/network_policy_test.yaml b/charts/kruize/tests/with-default-values/network_policy_test.yaml new file mode 100644 index 0000000..49d556d --- /dev/null +++ b/charts/kruize/tests/with-default-values/network_policy_test.yaml @@ -0,0 +1,65 @@ +suite: test network_policy.yaml +templates: + - network_policy.yaml + +tests: + - it: should not create NetworkPolicy when disabled + set: + networkPolicy.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should create a NetworkPolicy with the correct default settings + set: + networkPolicy.enabled: true + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: NetworkPolicy + - equal: + path: apiVersion + value: networking.k8s.io/v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-to-prometheus + - equal: + path: metadata.labels + value: + helm.sh/chart: kruize-0.1.0 + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/version: "0.9" + app.kubernetes.io/managed-by: Helm + - equal: + path: spec.podSelector.matchLabels + value: + app.kubernetes.io/name: prometheus + - equal: + path: spec.policyTypes[0] + value: Ingress + - equal: + path: spec.ingress[0].from[0].podSelector.matchLabels + value: + app: RELEASE-NAME-kruize + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + - equal: + path: spec.ingress[0].ports[0].protocol + value: TCP + - equal: + path: spec.ingress[0].ports[0].port + value: 9090 + + - it: should create a NetworkPolicy in the release namespace + set: + networkPolicy.enabled: true + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + diff --git a/charts/kruize/tests/with-default-values/service_monitor_test.yaml b/charts/kruize/tests/with-default-values/service_monitor_test.yaml new file mode 100644 index 0000000..e81a137 --- /dev/null +++ b/charts/kruize/tests/with-default-values/service_monitor_test.yaml @@ -0,0 +1,74 @@ +suite: test service_monitor.yaml +templates: + - service_monitor.yaml + +tests: + - it: should not create ServiceMonitor when monitoring is disabled + set: + monitoring.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should create a ServiceMonitor with the correct default settings + set: + monitoring.enabled: true + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: ServiceMonitor + - equal: + path: apiVersion + value: monitoring.coreos.com/v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-service-monitor + - equal: + path: metadata.labels + value: + app: RELEASE-NAME-kruize + helm.sh/chart: kruize-0.1.0 + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/version: "0.9" + app.kubernetes.io/managed-by: Helm + - equal: + path: spec.selector.matchLabels + value: + app: RELEASE-NAME-kruize + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + - equal: + path: spec.endpoints[0].port + value: kruize-port + - equal: + path: spec.endpoints[0].interval + value: 30s + - equal: + path: spec.endpoints[0].path + value: /metrics + + - it: should create a ServiceMonitor with the correct settings overrides + set: + monitoring.enabled: true + monitoring.interval: 60s + asserts: + - equal: + path: spec.endpoints[0].interval + value: 60s + + - it: should create a ServiceMonitor in the release namespace + set: + monitoring.enabled: true + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + - equal: + path: spec.namespaceSelector.matchNames[0] + value: custom-namespace + diff --git a/charts/kruize/tests/with-default-values/storage_test.yaml b/charts/kruize/tests/with-default-values/storage_test.yaml new file mode 100644 index 0000000..2587fcc --- /dev/null +++ b/charts/kruize/tests/with-default-values/storage_test.yaml @@ -0,0 +1,105 @@ +suite: test storage templates +templates: + - storage_pv.yaml + - storage_pvc.yaml + +tests: + - it: should create a PersistentVolume with the correct default settings + template: storage_pv.yaml + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: PersistentVolume + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-db-pv-volume + - equal: + path: metadata.labels.type + value: local + - equal: + path: metadata.labels.app + value: RELEASE-NAME-kruize-db + - equal: + path: spec.storageClassName + value: manual + - equal: + path: spec.capacity.storage + value: 500Mi + - equal: + path: spec.accessModes[0] + value: ReadWriteMany + - equal: + path: spec.hostPath.path + value: "/mnt/data/RELEASE-NAME-kruize" + + - it: should create a PersistentVolume with the correct settings overrides + template: storage_pv.yaml + set: + db.pvc.storageSize: "1Gi" + db.pvc.storageClass: "standard" + db.pvc.hostPath: "/data" + asserts: + - equal: + path: spec.capacity.storage + value: 1Gi + - equal: + path: spec.storageClassName + value: standard + - equal: + path: spec.hostPath.path + value: "/data/RELEASE-NAME-kruize" + + - it: should create a PersistentVolumeClaim with the correct default settings + template: storage_pvc.yaml + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: PersistentVolumeClaim + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-db-pv-claim + - equal: + path: metadata.labels.app + value: RELEASE-NAME-kruize-db + - equal: + path: spec.storageClassName + value: manual + - equal: + path: spec.accessModes[0] + value: ReadWriteMany + - equal: + path: spec.resources.requests.storage + value: 500Mi + + - it: should create a PersistentVolumeClaim with the correct settings overrides + template: storage_pvc.yaml + set: + db.pvc.storageSize: "2Gi" + db.pvc.storageClass: "standard" + asserts: + - equal: + path: spec.resources.requests.storage + value: 2Gi + - equal: + path: spec.storageClassName + value: standard + + - it: should create a PersistentVolumeClaim in the release namespace + template: storage_pvc.yaml + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + diff --git a/charts/kruize/tests/with-minikube-values/kruize_db_deployment_minikube_test.yaml b/charts/kruize/tests/with-minikube-values/kruize_db_deployment_minikube_test.yaml new file mode 100644 index 0000000..4f25104 --- /dev/null +++ b/charts/kruize/tests/with-minikube-values/kruize_db_deployment_minikube_test.yaml @@ -0,0 +1,40 @@ +suite: test kruize_db_deployment.yaml (minikube) +templates: + - kruize_db_deployment.yaml +values: + - ../../values-minikube.yaml + +tests: + - it: should create a Deployment with minikube-specific settings + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: Deployment + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-db + + - it: should use default service account when serviceAccount.create is false + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: default + + - it: should not set PGDATA env var when pgData is empty + asserts: + - notExists: + path: spec.template.spec.containers[?(@.name=='kruize-db')].env[?(@.name=='PGDATA')] + + - it: should use minikube volumeMountPath + asserts: + - equal: + path: spec.template.spec.containers[?(@.name=='kruize-db')].volumeMounts[0].mountPath + value: "/var/lib/postgresql/data" + + - it: should not set resource requests and limits when empty + asserts: + - notExists: + path: spec.template.spec.containers[?(@.name=='kruize-db')].resources + diff --git a/charts/kruize/tests/with-minikube-values/kruize_deployment_minikube_test.yaml b/charts/kruize/tests/with-minikube-values/kruize_deployment_minikube_test.yaml new file mode 100644 index 0000000..a6df123 --- /dev/null +++ b/charts/kruize/tests/with-minikube-values/kruize_deployment_minikube_test.yaml @@ -0,0 +1,139 @@ +suite: test kruize_deployment.yaml (minikube) +templates: + - kruize_deployment.yaml +values: + - ../../values-minikube.yaml + +tests: + - it: should create a Deployment with correct default settings + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: Deployment + - equal: + path: metadata.name + value: RELEASE-NAME-kruize + - equal: + path: metadata.namespace + value: NAMESPACE + - equal: + path: metadata.labels.app + value: RELEASE-NAME-kruize + - equal: + path: metadata.labels["app.kubernetes.io/name"] + value: kruize + - equal: + path: metadata.labels["app.kubernetes.io/instance"] + value: RELEASE-NAME + - equal: + path: metadata.labels["app.kubernetes.io/version"] + value: "0.9" + - equal: + path: metadata.labels["app.kubernetes.io/managed-by"] + value: Helm + - equal: + path: metadata.labels["helm.sh/chart"] + value: kruize-0.1.0 + - equal: + path: spec.replicas + value: 1 + - equal: + path: spec.selector.matchLabels + value: + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + - equal: + path: spec.template.metadata.labels + value: + app: RELEASE-NAME-kruize + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + + - it: should use default service account when serviceAccount.create is false + asserts: + - equal: + path: spec.template.spec.serviceAccountName + value: default + + - it: should validate init container for database wait + asserts: + - exists: + path: spec.template.spec.initContainers[?(@.name=='wait-for-kruize-db')] + - equal: + path: spec.template.spec.initContainers[?(@.name=='wait-for-kruize-db')].image + value: "quay.io/kruizehub/postgres:15.2" + - contains: + path: spec.template.spec.initContainers[?(@.name=='wait-for-kruize-db')].command + content: "sh" + - contains: + path: spec.template.spec.initContainers[?(@.name=='wait-for-kruize-db')].command + content: "-c" + + - it: should validate kruize container settings + asserts: + - exists: + path: spec.template.spec.containers[?(@.name=='kruize')] + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].image + value: "quay.io/kruize/autotune_operator:0.9" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].imagePullPolicy + value: "Always" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].ports[0].name + value: "kruize-port" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].ports[0].containerPort + value: 8080 + + - it: should validate environment variables + asserts: + - contains: + path: spec.template.spec.containers[?(@.name=='kruize')].env + content: + name: LOGGING_LEVEL + value: "info" + - contains: + path: spec.template.spec.containers[?(@.name=='kruize')].env + content: + name: ROOT_LOGGING_LEVEL + value: "error" + - contains: + path: spec.template.spec.containers[?(@.name=='kruize')].env + content: + name: DB_CONFIG_FILE + value: "/etc/config/dbconfigjson" + - contains: + path: spec.template.spec.containers[?(@.name=='kruize')].env + content: + name: KRUIZE_CONFIG_FILE + value: "/etc/config/kruizeconfigjson" + - contains: + path: spec.template.spec.containers[?(@.name=='kruize')].env + content: + name: KAFKA_RESPONSE_FILTER_INCLUDE + value: "summary" + + - it: should not set resource requests and limits when empty + asserts: + - notExists: + path: spec.template.spec.containers[?(@.name=='kruize')].resources + + - it: should validate volume mounts and config volume + asserts: + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].volumeMounts[0].name + value: "config-volume" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].volumeMounts[0].mountPath + value: "/etc/config" + - equal: + path: spec.template.spec.volumes[0].name + value: "config-volume" + - equal: + path: spec.template.spec.volumes[0].configMap.name + value: "RELEASE-NAME-kruize-config" + + diff --git a/charts/kruize/tests/with-minikube-values/network_policy_minikube_test.yaml b/charts/kruize/tests/with-minikube-values/network_policy_minikube_test.yaml new file mode 100644 index 0000000..135ca7f --- /dev/null +++ b/charts/kruize/tests/with-minikube-values/network_policy_minikube_test.yaml @@ -0,0 +1,64 @@ +suite: test network_policy.yaml (minikube) +templates: + - network_policy.yaml +values: + - ../../values-minikube.yaml + +tests: + - it: should create NetworkPolicy when enabled in minikube + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: NetworkPolicy + - equal: + path: apiVersion + value: networking.k8s.io/v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-to-prometheus + - equal: + path: metadata.labels + value: + helm.sh/chart: kruize-0.1.0 + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/version: "0.9" + app.kubernetes.io/managed-by: Helm + - equal: + path: spec.podSelector.matchLabels + value: + app.kubernetes.io/name: prometheus + - equal: + path: spec.policyTypes[0] + value: Ingress + - equal: + path: spec.ingress[0].from[0].podSelector.matchLabels + value: + app: RELEASE-NAME-kruize + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + - equal: + path: spec.ingress[0].ports[0].protocol + value: TCP + - equal: + path: spec.ingress[0].ports[0].port + value: 9090 + + - it: should not create NetworkPolicy when disabled + set: + networkPolicy.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should create a NetworkPolicy in the release namespace + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + + diff --git a/charts/kruize/tests/with-minikube-values/rbac_minikube_test.yaml b/charts/kruize/tests/with-minikube-values/rbac_minikube_test.yaml new file mode 100644 index 0000000..4fcda73 --- /dev/null +++ b/charts/kruize/tests/with-minikube-values/rbac_minikube_test.yaml @@ -0,0 +1,157 @@ +suite: test RBAC resources (minikube) +templates: + - service_account.yaml + - role.yaml + - rolebinding.yaml +values: + - ../../values-minikube.yaml + +tests: + - it: should not create ServiceAccount when serviceAccount.create is false + template: service_account.yaml + asserts: + - hasDocuments: + count: 0 + + - it: should create recommendation-updater ClusterRole with correct rules + template: role.yaml + documentIndex: 0 + asserts: + - equal: + path: kind + value: ClusterRole + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-recommendation-updater + - contains: + path: rules + content: + apiGroups: [""] + resources: ["pods", "customresourcedefinitions"] + verbs: ["*"] + - contains: + path: rules + content: + apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["*"] + + - it: should create edit-ko ClusterRole with correct rules + template: role.yaml + documentIndex: 1 + asserts: + - equal: + path: kind + value: ClusterRole + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-edit-ko + - contains: + path: rules + content: + apiGroups: ["apps"] + resources: ["deployments", "statefulsets", "daemonsets"] + verbs: ["get", "list", "patch", "update"] + - contains: + path: rules + content: + apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "list", "create", "delete"] + + - it: should create instaslices-access ClusterRole with correct rules + template: role.yaml + documentIndex: 2 + asserts: + - equal: + path: kind + value: ClusterRole + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-instaslices-access + - contains: + path: rules + content: + apiGroups: ["inference.redhat.com"] + resources: ["instaslices"] + verbs: ["get", "list", "watch"] + + - it: should not create monitoring-view and SCC ClusterRoleBindings when rbac.create is false + template: rolebinding.yaml + asserts: + - hasDocuments: + count: 3 + + - it: should not create monitoring-view ClusterRoleBinding in minikube + template: rolebinding.yaml + documentIndex: 0 + asserts: + - notEqual: + path: metadata.name + value: RELEASE-NAME-kruize-monitoring-view + + - it: should not create OpenShift SCC ClusterRoleBinding in minikube + template: rolebinding.yaml + documentIndex: 0 + asserts: + - notEqual: + path: metadata.name + value: RELEASE-NAME-kruize-autotune-scc-crb + + - it: should create recommendation-updater ClusterRoleBinding with correct settings + template: rolebinding.yaml + documentIndex: 0 + asserts: + - equal: + path: kind + value: ClusterRoleBinding + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-recommendation-updater-crb + - equal: + path: subjects[0].kind + value: ServiceAccount + - equal: + path: subjects[0].name + value: default + - equal: + path: roleRef.kind + value: ClusterRole + - equal: + path: roleRef.name + value: RELEASE-NAME-kruize-recommendation-updater + + - it: should create instaslices-access ClusterRoleBinding with correct settings + template: rolebinding.yaml + documentIndex: 1 + asserts: + - equal: + path: kind + value: ClusterRoleBinding + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-instaslices-access-binding + - equal: + path: subjects[0].name + value: default + - equal: + path: roleRef.name + value: RELEASE-NAME-kruize-instaslices-access + + - it: should create edit-ko ClusterRoleBinding with correct settings + template: rolebinding.yaml + documentIndex: 2 + asserts: + - equal: + path: kind + value: ClusterRoleBinding + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-edit-ko-binding + - equal: + path: subjects[0].name + value: default + - equal: + path: roleRef.name + value: RELEASE-NAME-kruize-edit-ko + diff --git a/charts/kruize/tests/with-minikube-values/service_monitor_minikube_test.yaml b/charts/kruize/tests/with-minikube-values/service_monitor_minikube_test.yaml new file mode 100644 index 0000000..82ed204 --- /dev/null +++ b/charts/kruize/tests/with-minikube-values/service_monitor_minikube_test.yaml @@ -0,0 +1,71 @@ +suite: test service_monitor.yaml (minikube) +templates: + - service_monitor.yaml +values: + - ../../values-minikube.yaml + +tests: + - it: should create a ServiceMonitor with the correct default settings + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: ServiceMonitor + - equal: + path: apiVersion + value: monitoring.coreos.com/v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-service-monitor + - equal: + path: metadata.labels + value: + app: RELEASE-NAME-kruize + helm.sh/chart: kruize-0.1.0 + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/version: "0.9" + app.kubernetes.io/managed-by: Helm + - equal: + path: spec.selector.matchLabels + value: + app: RELEASE-NAME-kruize + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + - equal: + path: spec.endpoints[0].port + value: kruize-port + - equal: + path: spec.endpoints[0].interval + value: 30s + - equal: + path: spec.endpoints[0].path + value: /metrics + + - it: should create a ServiceMonitor with the correct settings overrides + set: + monitoring.interval: 60s + asserts: + - equal: + path: spec.endpoints[0].interval + value: 60s + + - it: should not create ServiceMonitor when monitoring is disabled + set: + monitoring.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should create a ServiceMonitor in the release namespace + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + - equal: + path: spec.namespaceSelector.matchNames[0] + value: custom-namespace + diff --git a/charts/kruize/tests/with-minikube-values/storage_minikube_test.yaml b/charts/kruize/tests/with-minikube-values/storage_minikube_test.yaml new file mode 100644 index 0000000..57b792f --- /dev/null +++ b/charts/kruize/tests/with-minikube-values/storage_minikube_test.yaml @@ -0,0 +1,111 @@ +suite: test storage templates (minikube) +templates: + - storage_pv.yaml + - storage_pvc.yaml +values: + - ../../values-minikube.yaml + +tests: + - it: should create a PersistentVolume with minikube-specific settings + template: storage_pv.yaml + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: PersistentVolume + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-db-pv-volume + - equal: + path: metadata.labels.type + value: local + - equal: + path: metadata.labels.app + value: RELEASE-NAME-kruize-db + - equal: + path: spec.storageClassName + value: manual + - equal: + path: spec.capacity.storage + value: 1Gi + - equal: + path: spec.accessModes[0] + value: ReadWriteOnce + - equal: + path: spec.persistentVolumeReclaimPolicy + value: Retain + - equal: + path: spec.hostPath.path + value: "/data/postgres/RELEASE-NAME-kruize" + + - it: should create a PersistentVolume with the correct settings overrides + template: storage_pv.yaml + set: + db.pvc.storageSize: "2Gi" + db.pvc.storageClass: "standard" + db.pvc.hostPath: "/custom/data" + asserts: + - equal: + path: spec.capacity.storage + value: 2Gi + - equal: + path: spec.storageClassName + value: standard + - equal: + path: spec.hostPath.path + value: "/custom/data/RELEASE-NAME-kruize" + + - it: should create a PersistentVolumeClaim with minikube-specific settings + template: storage_pvc.yaml + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: PersistentVolumeClaim + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-db-pv-claim + - equal: + path: metadata.labels.app + value: RELEASE-NAME-kruize-db + - equal: + path: spec.storageClassName + value: manual + - equal: + path: spec.accessModes[0] + value: ReadWriteOnce + - equal: + path: spec.resources.requests.storage + value: 1Gi + + - it: should create a PersistentVolumeClaim with the correct settings overrides + template: storage_pvc.yaml + set: + db.pvc.storageSize: "2Gi" + db.pvc.storageClass: "standard" + asserts: + - equal: + path: spec.resources.requests.storage + value: 2Gi + - equal: + path: spec.storageClassName + value: standard + + - it: should create a PersistentVolumeClaim in the release namespace + template: storage_pvc.yaml + release: + namespace: custom-namespace + asserts: + - equal: + path: metadata.namespace + value: custom-namespace + + diff --git a/charts/kruize/tests/with-openshift-values/kruize_deployment_test.yaml b/charts/kruize/tests/with-openshift-values/kruize_deployment_test.yaml new file mode 100644 index 0000000..8960c37 --- /dev/null +++ b/charts/kruize/tests/with-openshift-values/kruize_deployment_test.yaml @@ -0,0 +1,165 @@ +suite: test kruize_deployment.yaml (openshift) +templates: + - kruize_deployment.yaml +values: + - ../../values-openshift.yaml + +tests: + - it: should create a Deployment with the correct default settings + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: Deployment + - equal: + path: metadata.name + value: RELEASE-NAME-kruize + - equal: + path: metadata.labels.app + value: RELEASE-NAME-kruize + - equal: + path: metadata.labels["app.kubernetes.io/name"] + value: kruize + - equal: + path: metadata.labels["app.kubernetes.io/instance"] + value: RELEASE-NAME + - equal: + path: metadata.labels["app.kubernetes.io/version"] + value: "0.9" + - equal: + path: metadata.labels["app.kubernetes.io/managed-by"] + value: Helm + - equal: + path: metadata.labels["helm.sh/chart"] + value: kruize-0.1.0 + - equal: + path: spec.replicas + value: 1 + - equal: + path: spec.selector.matchLabels + value: + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + - equal: + path: spec.template.metadata.labels + value: + app: RELEASE-NAME-kruize + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + - equal: + path: spec.template.spec.serviceAccountName + value: RELEASE-NAME-kruize + + - it: should validate init container for database wait + asserts: + - exists: + path: spec.template.spec.initContainers[?(@.name=='wait-for-kruize-db')] + - equal: + path: spec.template.spec.initContainers[?(@.name=='wait-for-kruize-db')].image + value: "quay.io/kruizehub/postgres:15.2" + - contains: + path: spec.template.spec.initContainers[?(@.name=='wait-for-kruize-db')].command + content: "sh" + - contains: + path: spec.template.spec.initContainers[?(@.name=='wait-for-kruize-db')].command + content: "-c" + + - it: should validate kruize container settings + asserts: + - exists: + path: spec.template.spec.containers[?(@.name=='kruize')] + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].image + value: "quay.io/kruize/autotune_operator:0.9" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].imagePullPolicy + value: "Always" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].ports[0].name + value: "kruize-port" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].ports[0].containerPort + value: 8080 + + - it: should validate environment variables + asserts: + - contains: + path: spec.template.spec.containers[?(@.name=='kruize')].env + content: + name: LOGGING_LEVEL + value: "info" + - contains: + path: spec.template.spec.containers[?(@.name=='kruize')].env + content: + name: ROOT_LOGGING_LEVEL + value: "error" + - contains: + path: spec.template.spec.containers[?(@.name=='kruize')].env + content: + name: DB_CONFIG_FILE + value: "/etc/config/dbconfigjson" + - contains: + path: spec.template.spec.containers[?(@.name=='kruize')].env + content: + name: KRUIZE_CONFIG_FILE + value: "/etc/config/kruizeconfigjson" + + - it: should validate resource settings + asserts: + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].resources.requests.memory + value: "768Mi" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].resources.requests.cpu + value: 0.7 + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].resources.limits.memory + value: "768Mi" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].resources.limits.cpu + value: 0.7 + + - it: should validate volume mounts and config volume + asserts: + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].volumeMounts[0].name + value: "config-volume" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].volumeMounts[0].mountPath + value: "/etc/config" + - equal: + path: spec.template.spec.volumes[0].name + value: "config-volume" + - equal: + path: spec.template.spec.volumes[0].configMap.name + value: "RELEASE-NAME-kruize-config" + + - it: should create a Deployment with the correct settings overrides + set: + kruize.replicaCount: 3 + kruize.image.tag: "0.9.0" + kruize.resources.requests.memory: "1Gi" + kruize.resources.requests.cpu: "1" + kruize.resources.limits.memory: "2Gi" + kruize.resources.limits.cpu: "2" + asserts: + - equal: + path: spec.replicas + value: 3 + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].image + value: "quay.io/kruize/autotune_operator:0.9.0" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].resources.requests.memory + value: "1Gi" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].resources.requests.cpu + value: 1 + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].resources.limits.memory + value: "2Gi" + - equal: + path: spec.template.spec.containers[?(@.name=='kruize')].resources.limits.cpu + value: 2 + diff --git a/charts/kruize/tests/with-openshift-values/rbac_test.yaml b/charts/kruize/tests/with-openshift-values/rbac_test.yaml new file mode 100644 index 0000000..be66eac --- /dev/null +++ b/charts/kruize/tests/with-openshift-values/rbac_test.yaml @@ -0,0 +1,211 @@ +suite: test RBAC resources (openshift) +templates: + - service_account.yaml + - role.yaml + - rolebinding.yaml +values: + - ../../values-openshift.yaml + +tests: + - it: should not create ServiceAccount when disabled + template: service_account.yaml + set: + serviceAccount.create: false + asserts: + - hasDocuments: + count: 0 + + - it: should create a ServiceAccount with the correct default settings + template: service_account.yaml + set: + serviceAccount.create: true + asserts: + - hasDocuments: + count: 1 + - equal: + path: kind + value: ServiceAccount + - equal: + path: metadata.name + value: RELEASE-NAME-kruize + - equal: + path: metadata.labels + value: + helm.sh/chart: kruize-0.1.0 + app.kubernetes.io/name: kruize + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/version: "0.9" + app.kubernetes.io/managed-by: Helm + + - it: should use custom ServiceAccount name when specified + template: service_account.yaml + set: + serviceAccount.create: true + serviceAccount.name: custom-sa + asserts: + - equal: + path: metadata.name + value: custom-sa + + - it: should create recommendation-updater ClusterRole with correct rules + template: role.yaml + documentIndex: 0 + asserts: + - equal: + path: kind + value: ClusterRole + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-recommendation-updater + - contains: + path: rules + content: + apiGroups: [""] + resources: ["pods", "customresourcedefinitions"] + verbs: ["*"] + - contains: + path: rules + content: + apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["*"] + + - it: should create edit-ko ClusterRole with correct rules + template: role.yaml + documentIndex: 1 + asserts: + - equal: + path: kind + value: ClusterRole + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-edit-ko + - contains: + path: rules + content: + apiGroups: ["apps"] + resources: ["deployments", "statefulsets", "daemonsets"] + verbs: ["get", "list", "patch", "update"] + - contains: + path: rules + content: + apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "list", "create", "delete"] + + - it: should create instaslices-access ClusterRole with correct rules + template: role.yaml + documentIndex: 2 + asserts: + - equal: + path: kind + value: ClusterRole + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-instaslices-access + - contains: + path: rules + content: + apiGroups: ["inference.redhat.com"] + resources: ["instaslices"] + verbs: ["get", "list", "watch"] + + - it: should create recommendation-updater ClusterRoleBinding with correct settings + template: rolebinding.yaml + documentIndex: 0 + asserts: + - equal: + path: kind + value: ClusterRoleBinding + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-recommendation-updater-crb + - equal: + path: subjects[0].kind + value: ServiceAccount + - equal: + path: subjects[0].name + value: RELEASE-NAME-kruize + - equal: + path: roleRef.kind + value: ClusterRole + - equal: + path: roleRef.name + value: RELEASE-NAME-kruize-recommendation-updater + + - it: should create monitoring-view ClusterRoleBinding when rbac.create is true + template: rolebinding.yaml + documentIndex: 1 + set: + rbac.create: true + asserts: + - equal: + path: kind + value: ClusterRoleBinding + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-monitoring-view + - equal: + path: roleRef.name + value: cluster-monitoring-view + + - it: should not create monitoring-view ClusterRoleBinding when rbac.create is false + template: rolebinding.yaml + set: + rbac.create: false + asserts: + - hasDocuments: + count: 3 + + - it: should create instaslices-access ClusterRoleBinding with correct settings + template: rolebinding.yaml + documentIndex: 2 + asserts: + - equal: + path: kind + value: ClusterRoleBinding + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-instaslices-access-binding + - equal: + path: roleRef.name + value: RELEASE-NAME-kruize-instaslices-access + + - it: should create edit-ko ClusterRoleBinding with correct settings + template: rolebinding.yaml + documentIndex: 3 + asserts: + - equal: + path: kind + value: ClusterRoleBinding + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-edit-ko-binding + - equal: + path: roleRef.name + value: RELEASE-NAME-kruize-edit-ko + + - it: should create OpenShift SCC ClusterRoleBinding when rbac.create is true + template: rolebinding.yaml + documentIndex: 4 + set: + rbac.create: true + asserts: + - equal: + path: kind + value: ClusterRoleBinding + - equal: + path: metadata.name + value: RELEASE-NAME-kruize-autotune-scc-crb + - equal: + path: roleRef.name + value: system:openshift:scc:anyuid + + - it: should not create OpenShift SCC ClusterRoleBinding when rbac.create is false + template: rolebinding.yaml + set: + rbac.create: false + asserts: + - hasDocuments: + count: 3 + diff --git a/charts/kruize/values-minikube.yaml b/charts/kruize/values-minikube.yaml new file mode 100644 index 0000000..d9aa40c --- /dev/null +++ b/charts/kruize/values-minikube.yaml @@ -0,0 +1,100 @@ +# Minikube-specific values for Kruize Helm Chart +# This file overrides the default values.yaml for minikube deployments + +# Kruize Configuration +kruize: + # Disable resource requests/limits for minikube + resources: + requests: + memory: "" + cpu: "" + limits: + memory: "" + cpu: "" + + config: + k8sType: "minikube" + + # Hibernate configuration - override only changed values + hibernate: + c3p0minsize: 2 + c3p0maxsize: 5 + c3p0maxstatements: 50 + + # Datasource configuration for minikube (single prometheus instance) + datasource: + - name: "prometheus-1" + provider: "prometheus" + serviceName: "prometheus-k8s" + namespace: "monitoring" + url: "" + authentication: + type: "" + credentials: + tokenFilePath: "" + + env: + - name: LOGGING_LEVEL + value: "info" + - name: ROOT_LOGGING_LEVEL + value: "error" + - name: DB_CONFIG_FILE + value: "/etc/config/dbconfigjson" + - name: KRUIZE_CONFIG_FILE + value: "/etc/config/kruizeconfigjson" + - name: JAVA_TOOL_OPTIONS + value: "-XX:MaxRAMPercentage=80" + - name: KAFKA_BOOTSTRAP_SERVERS + value: "kruize-kafka-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092" + - name: KAFKA_TOPICS + value: "recommendations-topic,error-topic,summary-topic" + - name: KAFKA_RESPONSE_FILTER_INCLUDE + value: "summary" + - name: KAFKA_RESPONSE_FILTER_EXCLUDE + value: "" + +# Database Configuration +db: + # Volume mount path for minikube + volumeMountPath: "/var/lib/postgresql/data" + # Disable PGDATA for minikube + pgData: "" + + # Disable resource requests/limits for minikube + resources: + requests: + memory: "" + cpu: "" + limits: + memory: "" + cpu: "" + + pvc: + storageSize: "1Gi" + hostPath: "/data/postgres" + storageClass: "manual" + accessModes: + - ReadWriteOnce + reclaimPolicy: "Retain" + +# RBAC Configuration +rbac: + # Disable OpenShift-specific RBAC resources for minikube + create: false + +# Service Account Configuration +serviceAccount: + # Use default service account in minikube + create: false + name: "default" + +# Network Policy Configuration +networkPolicy: + # Enable network policy for minikube + enabled: true + +# Monitoring Configuration +monitoring: + enabled: true + interval: 30s + diff --git a/charts/kruize/values-openshift.yaml b/charts/kruize/values-openshift.yaml new file mode 100644 index 0000000..f8b4e84 --- /dev/null +++ b/charts/kruize/values-openshift.yaml @@ -0,0 +1,52 @@ +# OpenShift-specific values for Kruize Helm Chart +# This file represents the default values.yaml settings for OpenShift deployments + +# Kruize Configuration +kruize: + config: + k8sType: "openshift" + + # OpenShift-specific datasource configuration + datasource: + - name: "prometheus-1" + provider: "prometheus" + serviceName: "prometheus-k8s" + namespace: "openshift-monitoring" + url: "" + authentication: + type: "bearer" + credentials: + tokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + + - name: "thanos-1" + provider: "prometheus" + serviceName: "thanos-querier" + namespace: "openshift-monitoring" + url: "" + authentication: + type: "bearer" + credentials: + tokenFilePath: "/var/run/secrets/kubernetes.io/serviceaccount/token" + +# RBAC Configuration +rbac: + # Enable OpenShift-specific RBAC resources + create: true + +# Service Account Configuration +serviceAccount: + # Create service account for OpenShift + create: true + name: "" + +# Network Policy Configuration +networkPolicy: + # Disable network policy for OpenShift (uses OpenShift's built-in network policies) + enabled: false + +# Monitoring Configuration +monitoring: + enabled: true + interval: 30s + + diff --git a/charts/kruize/values.schema.json b/charts/kruize/values.schema.json new file mode 100644 index 0000000..71a593e --- /dev/null +++ b/charts/kruize/values.schema.json @@ -0,0 +1,519 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Kruize Helm Chart Values", + "description": "Schema for Kruize Helm chart values", + "type": "object", + "properties": { + "kruize": { + "type": "object", + "description": "Configuration for the Kruize application", + "properties": { + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "description": "Repository for Kruize container image" + }, + "pullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "description": "Image pull policy for the Kruize container image" + }, + "tag": { + "type": "string", + "description": "Image tag for Kruize container" + } + }, + "required": ["repository", "pullPolicy", "tag"] + }, + "replicaCount": { + "type": "integer", + "minimum": 1, + "description": "Replica count for the Kruize container" + }, + "resources": { + "type": "object", + "properties": { + "requests": { + "type": "object", + "properties": { + "memory": { + "type": "string", + "description": "Memory resource request for the Kruize container" + }, + "cpu": { + "type": "string", + "description": "CPU resource request for the Kruize container" + } + } + }, + "limits": { + "type": "object", + "properties": { + "memory": { + "type": "string", + "description": "Memory resource limit for the Kruize container" + }, + "cpu": { + "type": "string", + "description": "CPU resource limit for the Kruize container" + } + } + } + } + }, + "service": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ClusterIP", "NodePort", "LoadBalancer"], + "description": "Kruize service type" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "description": "Kruize service port" + } + }, + "required": ["type", "port"] + }, + "env": { + "type": "array", + "description": "Environment variables for Kruize container", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["name", "value"] + } + }, + "config": { + "type": "object", + "properties": { + "clusterType": { + "type": "string", + "enum": ["kubernetes", "openshift"] + }, + "k8sType": { + "type": "string", + "enum": ["openshift", "minikube", "kubernetes"] + }, + "authType": { + "type": "string" + }, + "monitoringAgent": { + "type": "string" + }, + "monitoringService": { + "type": "string" + }, + "monitoringEndPoint": { + "type": "string" + }, + "saveToDB": { + "type": "string", + "enum": ["true", "false"] + }, + "dbDriver": { + "type": "string" + }, + "plots": { + "type": "string", + "enum": ["true", "false"] + }, + "isROSEnabled": { + "type": "string", + "enum": ["true", "false"] + }, + "local": { + "type": "string", + "enum": ["true", "false"] + }, + "logAllHttpReqAndResp": { + "type": "string", + "enum": ["true", "false"] + }, + "experimentNameFormat": { + "type": "string" + }, + "bulkapilimit": { + "type": "integer", + "minimum": 1 + }, + "isKafkaEnabled": { + "type": "string", + "enum": ["true", "false"] + }, + "hibernate": { + "type": "object", + "properties": { + "dialect": { + "type": "string" + }, + "driver": { + "type": "string" + }, + "c3p0minsize": { + "type": "integer", + "minimum": 1 + }, + "c3p0maxsize": { + "type": "integer", + "minimum": 1 + }, + "c3p0timeout": { + "type": "integer", + "minimum": 1 + }, + "c3p0maxstatements": { + "type": "integer", + "minimum": 1 + }, + "hbm2ddlauto": { + "type": "string" + }, + "showsql": { + "type": "string", + "enum": ["true", "false"] + }, + "timezone": { + "type": "string" + } + } + }, + "logging": { + "type": "object", + "properties": { + "cloudwatch": { + "type": "object", + "properties": { + "accessKeyId": { + "type": "string" + }, + "logGroup": { + "type": "string" + }, + "logStream": { + "type": "string" + }, + "region": { + "type": "string" + }, + "secretAccessKey": { + "type": "string" + }, + "logLevel": { + "type": "string", + "enum": ["DEBUG", "INFO", "WARN", "ERROR"] + } + } + } + } + }, + "datasource": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "serviceName": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "url": { + "type": "string" + }, + "authentication": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "credentials": { + "type": "object", + "properties": { + "tokenFilePath": { + "type": "string" + } + } + } + } + } + }, + "required": ["name", "provider"] + } + } + } + } + }, + "required": ["image", "service"] + }, + "cronJob": { + "type": "object", + "properties": { + "deletePartitionsThreshold": { + "type": "string" + }, + "createSchedule": { + "type": "string", + "description": "Cron schedule expression" + } + } + }, + "db": { + "type": "object", + "description": "Kruize DB configuration", + "properties": { + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "description": "Repository for Kruize DB container image" + }, + "pullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "description": "Image pull policy for the Kruize DB container image" + }, + "tag": { + "type": "string", + "description": "Image tag for Kruize DB container" + } + }, + "required": ["repository", "pullPolicy", "tag"] + }, + "service": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Kruize DB service name" + }, + "type": { + "type": "string", + "enum": ["ClusterIP", "NodePort", "LoadBalancer"], + "description": "Kruize DB service type" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "description": "Kruize DB service port" + } + }, + "required": ["name", "type", "port"] + }, + "resources": { + "type": "object", + "properties": { + "requests": { + "type": "object", + "properties": { + "memory": { + "type": "string", + "description": "Memory resource request for the Kruize DB container" + }, + "cpu": { + "type": "string", + "description": "CPU resource request for the Kruize DB container" + } + } + }, + "limits": { + "type": "object", + "properties": { + "memory": { + "type": "string", + "description": "Memory resource limit for the Kruize DB container" + }, + "cpu": { + "type": "string", + "description": "CPU resource limit for the Kruize DB container" + } + } + } + } + }, + "pvc": { + "type": "object", + "properties": { + "storageClass": { + "type": "string" + }, + "storageSize": { + "type": "string" + }, + "hostPath": { + "type": "string" + }, + "accessModes": { + "type": "array", + "items": { + "type": "string", + "enum": ["ReadWriteOnce", "ReadWriteMany", "ReadOnlyMany"] + } + }, + "reclaimPolicy": { + "type": "string", + "enum": ["Retain", "Delete", "Recycle"] + } + } + }, + "user": { + "type": "string", + "description": "User for Kruize DB container" + }, + "password": { + "type": "string", + "description": "Password for Kruize DB container" + }, + "adminUser": { + "type": "string", + "description": "Admin User for Kruize DB container" + }, + "adminPassword": { + "type": "string", + "description": "Admin password for Kruize DB container" + }, + "name": { + "type": "string", + "description": "Name of the Kruize DB" + }, + "includeReleaseNameInDbName": { + "type": "boolean", + "description": "Include release name in database name for multi-instance support" + }, + "volumeMountPath": { + "type": "string", + "description": "Volume mount path for database data" + }, + "pgData": { + "type": "string", + "description": "PGDATA environment variable value" + }, + "sslMode": { + "type": "string", + "enum": ["disable", "allow", "prefer", "require", "verify-ca", "verify-full"] + } + }, + "required": ["image", "service", "user", "password", "name"] + }, + "kruizeUI": { + "type": "object", + "description": "Kruize UI Configuration", + "properties": { + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "description": "Repository for Kruize UI container image" + }, + "pullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"], + "description": "Image pull policy for the Kruize UI container image" + }, + "tag": { + "type": "string", + "description": "Image tag for Kruize UI container" + } + }, + "required": ["repository", "pullPolicy", "tag"] + }, + "service": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ClusterIP", "NodePort", "LoadBalancer"], + "description": "Kruize UI service type" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "description": "Kruize UI service port" + } + }, + "required": ["type", "port"] + } + }, + "required": ["image", "service"] + }, + "serviceAccount": { + "type": "object", + "properties": { + "create": { + "type": "boolean", + "description": "Specifies whether a service account should be created" + }, + "name": { + "type": "string", + "description": "The name of the service account to use" + } + }, + "required": ["create"] + }, + "rbac": { + "type": "object", + "properties": { + "create": { + "type": "boolean", + "description": "Specifies whether Openshift-specific RBAC resources should be created" + } + }, + "required": ["create"] + }, + "nameOverride": { + "type": "string", + "description": "Overrides the name of this Chart" + }, + "fullnameOverride": { + "type": "string", + "description": "Overrides the fully qualified application name of [release name]-[chart name]" + }, + "monitoring": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable monitoring with ServiceMonitor" + }, + "interval": { + "type": "string", + "description": "Scrape interval for Prometheus" + } + }, + "required": ["enabled"] + }, + "networkPolicy": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable NetworkPolicy resources" + } + }, + "required": ["enabled"] + } + }, + "required": ["kruize", "db", "kruizeUI", "serviceAccount", "rbac"] +} \ No newline at end of file diff --git a/charts/kruize/values.yaml b/charts/kruize/values.yaml new file mode 100644 index 0000000..542968d --- /dev/null +++ b/charts/kruize/values.yaml @@ -0,0 +1,186 @@ +## @section Kruize Container +## @extra Configuration for the Kruize application + +kruize: + image: + ## @param kruize.image.repository Repository for Kruize container image + repository: quay.io/kruize/autotune_operator + ## @param kruize.image.pullPolicy Image pull policy for the Kruize container image + pullPolicy: Always + ## @param kruize.image.tag Image tag for Kruize container + tag: "0.9" + ## @param kruize.replicaCount Replica count for the Kruize container + replicaCount: 1 + resources: + requests: + ## @param kruize.resources.requests.memory Memory resource request for the Kruize container + memory: "768Mi" + ## @param kruize.resources.requests.cpu CPU resource request for the Kruize container + cpu: "0.7" + limits: + ## @param kruize.resources.limits.memory Memory resource limit for the Kruize container + memory: "768Mi" + ## @param kruize.resources.limits.cpu CPU resource limit for the Kruize container + cpu: "0.7" + service: + ## @param kruize.service.type Kruize service type + type: NodePort + ## @param kruize.service.port Kruize service port + port: 8080 + + env: + - name: LOGGING_LEVEL + value: "info" + - name: ROOT_LOGGING_LEVEL + value: "error" + - name: DB_CONFIG_FILE + value: "/etc/config/dbconfigjson" + - name: KRUIZE_CONFIG_FILE + value: "/etc/config/kruizeconfigjson" + - name: JAVA_TOOL_OPTIONS + value: "-XX:MaxRAMPercentage=80" + - name: KAFKA_BOOTSTRAP_SERVERS + value: "kruize-kafka-cluster-kafka-bootstrap.kafka.svc.cluster.local:9092" + - name: KAFKA_TOPICS + value: "recommendations-topic,error-topic,summary-topic" + - name: KAFKA_RESPONSE_FILTER_INCLUDE + value: "experiments|status|apis|recommendations|response|status_history" + - name: KAFKA_RESPONSE_FILTER_EXCLUDE + value: "" + + config: + clusterType: "kubernetes" + k8sType: "kubernetes" + authType: "" + monitoringAgent: "prometheus" + monitoringService: "prometheus-k8s" + monitoringEndPoint: "prometheus-k8s" + saveToDB: "true" + dbDriver: "jdbc:postgresql://" + plots: "true" + isROSEnabled: "false" + local: "true" + logAllHttpReqAndResp: "true" + experimentNameFormat: "%datasource%|%clustername%|%namespace%|%workloadname%(%workloadtype%)|%containername%" + bulkapilimit: 1000 + isKafkaEnabled: "false" + hibernate: + dialect: "org.hibernate.dialect.PostgreSQLDialect" + driver: "org.postgresql.Driver" + c3p0minsize: 5 + c3p0maxsize: 10 + c3p0timeout: 300 + c3p0maxstatements: 100 + hbm2ddlauto: "none" + showsql: "false" + timezone: "UTC" + + logging: + cloudwatch: + accessKeyId: "" + logGroup: "kruize-logs" + logStream: "kruize-stream" + region: "" + secretAccessKey: "" + logLevel: "INFO" + + datasource: [] + + +cronJob: + deletePartitionsThreshold: "15" + createSchedule: "0 0 25 * *" + +# Kruize DB configuration +db: + image: + ## @param db.image.repository Repository for Kruize DB container image + repository: quay.io/kruizehub/postgres + ## @param db.image.pullPolicy Image pull policy for the Kruize DB container image + pullPolicy: IfNotPresent + ## @param db.image.tag Image tag for Kruize DB container + tag: "15.2" + service: + ## @param db.service.name Kruize DB service name + name: kruize-db-service + ## @param db.service.type Kruize DB service type + type: ClusterIP + ## @param db.service.port Kruize DB service port + port: 5432 + resources: + requests: + ## @param db.resources.requests.memory Memory resource request for the Kruize DB container + memory: "100Mi" + ## @param db.resources.requests.cpu CPU resource request for the Kruize DB container + cpu: "0.5" + limits: + ## @param db.resources.limits.memory Memory resource limit for the Kruize DB container + memory: "100Mi" + ## @param db.resources.limits.cpu CPU resource limit for the Kruize DB container + cpu: "0.5" + pvc: + storageClass: manual + storageSize: "500Mi" + hostPath: "/mnt/data" + accessModes: + - ReadWriteMany + ## @param db.user User for Kruize DB container + user: admin + ## @param db.password User for Kruize DB container + password: admin + ## @param db.adminUser Admin User for Kruize DB container + adminUser: admin + ## @param db.adminPassword Admin password for Kruize DB container + adminPassword: admin + ## @param db.name Name of the Kruize DB + name: kruizeDB + ## @param db.includeReleaseNameInDbName Include release name in database name for multi-instance support + includeReleaseNameInDbName: false + ## @param db.volumeMountPath Volume mount path for database data + volumeMountPath: "/var/lib/pgsql/data" + ## @param db.pgData PGDATA environment variable value + pgData: "/var/lib/pg_data" + sslMode: require + +# Kruize UI Configuration + +kruizeUI: + image: + ## @param kruizeUI.image.repository Repository for Kruize UI container image + repository: quay.io/kruize/kruize-ui + ## @param kruizeUI.image.pullPolicy Image pull policy for the Kruize UI container image + pullPolicy: Always + ## @param kruizeUI.image.tag Image tag for Kruize UI container + tag: "0.1.0" + replicaCount: 1 + service: + ## @param kruizeUI.service.type Kruize UI service type + type: NodePort + ## @param kruizeUI.service.port Kruize UI service port + port: 8080 + + +## @section Other Parameters + +serviceAccount: + ## @param serviceAccount.create Specifies whether a service account should be created + create: true + ## @param serviceAccount.name The name of the service account to use + name: "" + +rbac: + ## @param rbac.create Specifies whether Openshift-specific RBAC resources should be created + create: true + +## @param nameOverride Overrides the name of this Chart +nameOverride: "" +## @param fullnameOverride Overrides the fully qualified application name of `[release name]-[chart name]` +fullnameOverride: "" + +monitoring: + enabled: true + interval: 30s + +networkPolicy: + ## @param networkPolicy.enabled Enable NetworkPolicy resources + enabled: false diff --git a/docs/images/kruize-icon.png b/docs/images/kruize-icon.png new file mode 100644 index 0000000..318781f Binary files /dev/null and b/docs/images/kruize-icon.png differ