diff --git a/helm/README.md b/helm/README.md index b0b8ab1dca..676b4df3d7 100644 --- a/helm/README.md +++ b/helm/README.md @@ -28,7 +28,7 @@ For how to build your local Fluss image and use it in Minikube refer to the Refer to the [official documentation](https://fluss.apache.org/docs/next/install-deploy/deploying-with-helm/#configuration-parameters) as well for configuration values. -We use the [`helm-unittest`](https://github.com/helm-unittest/helm-unittest) plugin for testing Fluss Helm charts. +We use the [`helm-unittest`](https://github.com/helm-unittest/helm-unittest) plugin for testing Fluss Helm charts. You can run tests locally via: ```bash @@ -36,6 +36,37 @@ You can run tests locally via: docker run -ti --rm -v $(pwd):/apps helmunittest/helm-unittest . ``` +### Validation Checks + +The chart runs the validation checks at install or upgrade time using templates in `_validate.tpl` file. + +The warnings are printed to the user, but errors abort the deployment. + +To add new validations, for example for a new feature: + +1. Define `fluss..validateWarning` or `fluss..validateError` templates in the feature `_.tpl` template file. +2. Add the corresponding `include` calls to `fluss.validateWarning` or `fluss.validateError` in `_validate.tpl` template file. + +For example, for the `security` checks, include and update these methods in the `_validate.tpl` file: + +``` +{{- define "fluss.validateWarning" -}} +... + +{{- $messages = append $messages (include "fluss.security.validateWarning" .) -}} + +... +{{- end -}} + +{{- define "fluss.validateError" -}} +... + +{{- $messages = append $messages (include "fluss.security.validateError" .) -}} + +... +{{- end -}} +``` + ## Contributing Follow the [development section](#development) for local development. diff --git a/helm/templates/NOTES.txt b/helm/templates/NOTES.txt index d7a4af26fb..04f13172d5 100644 --- a/helm/templates/NOTES.txt +++ b/helm/templates/NOTES.txt @@ -20,4 +20,4 @@ CHART NAME: {{ .Chart.Name }} CHART VERSION: {{ .Chart.Version }} APP VERSION: {{ .Chart.AppVersion }} -{{ include "fluss.security.validateValues" . }} +{{ include "fluss.validate" . }} diff --git a/helm/templates/_security.tpl b/helm/templates/_security.tpl index 210a35746f..725ea7d511 100644 --- a/helm/templates/_security.tpl +++ b/helm/templates/_security.tpl @@ -170,33 +170,25 @@ Usage: {{- end -}} {{/* -Compile all warnings and errors into a single message. +Collects security warning messages. Usage: - include "fluss.security.validateValues" . + include "fluss.security.validateWarning" . */}} -{{- define "fluss.security.validateValues" -}} +{{- define "fluss.security.validateWarning" -}} +{{- include "fluss.security.sasl.warnInternalUser" . -}} +{{- end -}} +{{/* +Collects security error messages. +Usage: + include "fluss.security.validateError" . +*/}} +{{- define "fluss.security.validateError" -}} {{- $errMessages := list -}} {{- $errMessages = append $errMessages (include "fluss.security.sasl.validateMechanisms" .) -}} {{- $errMessages = append $errMessages (include "fluss.security.sasl.validateClientPlainUsers" .) -}} - {{- $errMessages = without $errMessages "" -}} -{{- $errMessage := join "\n" $errMessages -}} - -{{- $warnMessages := list -}} -{{- $warnMessages = append $warnMessages (include "fluss.security.sasl.warnInternalUser" .) -}} - -{{- $warnMessages = without $warnMessages "" -}} -{{- $warnMessage := join "\n" $warnMessages -}} - -{{- if $warnMessage -}} -{{- printf "\nVALUES WARNING:\n%s" $warnMessage -}} -{{- end -}} - -{{- if $errMessage -}} -{{- printf "\nVALUES VALIDATION:\n%s" $errMessage | fail -}} -{{- end -}} - +{{- join "\n" $errMessages -}} {{- end -}} {{/* diff --git a/helm/templates/_validate.tpl b/helm/templates/_validate.tpl new file mode 100644 index 0000000000..00b9f85988 --- /dev/null +++ b/helm/templates/_validate.tpl @@ -0,0 +1,73 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# + +{{/* +Collects all warning messages from validation methods. +Usage: + include "fluss.validateWarning" . +*/}} +{{- define "fluss.validateWarning" -}} +{{- $messages := list -}} + +{{- $messages = append $messages (include "fluss.security.validateWarning" .) -}} + +{{- $messages = without $messages "" -}} +{{- join "\n" $messages -}} +{{- end -}} + +{{/* +Collects all error messages from validation methods. +Usage: + include "fluss.validateError" . +*/}} +{{- define "fluss.validateError" -}} +{{- $messages := list -}} + +{{- $messages = append $messages (include "fluss.security.validateError" .) -}} + +{{- $messages = without $messages "" -}} +{{- join "\n" $messages -}} +{{- end -}} + +{{/* +Global validation checks entry point. +Collects all warnings and errors, prints warnings and fails on errors. +Usage: + include "fluss.validate" . +*/}} +{{- define "fluss.validate" -}} + +{{- $warnMessages := list -}} +{{- $warnMessages = append $warnMessages (include "fluss.validateWarning" .) -}} +{{- $warnMessages = without $warnMessages "" -}} +{{- $warnMessage := join "\n" $warnMessages -}} + +{{- $errMessages := list -}} +{{- $errMessages = append $errMessages (include "fluss.validateError" .) -}} +{{- $errMessages = without $errMessages "" -}} +{{- $errMessage := join "\n" $errMessages -}} + +{{- if $warnMessage -}} +{{- printf "\nVALUES WARNING:\n%s" $warnMessage -}} +{{- end -}} + +{{- if $errMessage -}} +{{- printf "\nVALUES VALIDATION:\n%s" $errMessage | fail -}} +{{- end -}} + +{{- end -}} diff --git a/helm/tests/validate_test.yaml b/helm/tests/validate_test.yaml new file mode 100644 index 0000000000..2d561c56e6 --- /dev/null +++ b/helm/tests/validate_test.yaml @@ -0,0 +1,41 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# + +suite: validate-aggregation +templates: + - templates/NOTES.txt +tests: + - it: renders warning for auto-generated internal SASL credentials + set: + security.internal.sasl.mechanism: plain + asserts: + - matchRegexRaw: + pattern: 'VALUES WARNING:' + - matchRegexRaw: + pattern: 'AUTO-GENERATED SASL credentials' + + - it: fails with error for invalid mechanism through aggregator + set: + security.client.sasl.mechanism: bogus + asserts: + - failedTemplate: + errorMessage: "VALUES VALIDATION:\nsecurity.client.sasl.mechanism must be empty or: plain" + + - it: passes cleanly with default values + asserts: + - notFailedTemplate: {}