fix: support nss wrapper in Helm chart (#40673)
## Description Requires: https://github.com/appsmithorg/appsmith/pull/40642 Adds an environment variable activating nss_wrapper when the `securityPolicy.runAsUser` value is set so the UID can be set dynamically. This avoids the `I have no name!` in the prompt when doing a `kubectl exec` with that value set. I am also introducing [helm-unittest](https://github.com/helm-unittest/helm-unittest) for ensuring that changes to our defaults are made explicit. Fixes https://github.com/appsmithorg/appsmith/issues/38787 ## Automation /ok-to-test tags="" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!WARNING] > Tests have not run on the HEAD d30d87ffc66c107f980a3b27464e97db0910dcbe yet > <hr>Mon, 19 May 2025 18:59:10 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added automated unit testing for Helm charts, including snapshot and security context tests. - Introduced documentation for running and understanding Helm chart unit tests. - Added a GitHub Actions workflow to run Helm chart unit tests on pull requests and manually. - **Bug Fixes** - Ensured the LD_PRELOAD environment variable is set when a specific security context is configured in deployments. - **Documentation** - Updated Helm chart README to reference new testing documentation and improve clarity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Goutham Pratapa <goutham@appsmith.com>
This commit is contained in:
parent
3d7a99e922
commit
4c7a019adf
26
.github/workflows/helm-unittest.yml
vendored
Normal file
26
.github/workflows/helm-unittest.yml
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
name: Helm Unit Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- release
|
||||
paths:
|
||||
- "deploy/helm/**"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: deploy/helm
|
||||
shell: bash
|
||||
|
||||
steps:
|
||||
- name: Checkout the code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Unittest
|
||||
run: |
|
||||
docker run --rm -v $(pwd):/apps helmunittest/helm-unittest .
|
||||
|
|
@ -11,7 +11,7 @@ sources:
|
|||
- https://github.com/appsmithorg/appsmith
|
||||
home: https://www.appsmith.com/
|
||||
icon: https://assets.appsmith.com/appsmith-icon.png
|
||||
version: 3.6.2
|
||||
version: 3.6.3
|
||||
dependencies:
|
||||
- condition: redis.enabled
|
||||
name: redis
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
# Appsmith
|
||||
Appsmith is a JS-based internal tool development platform. Internal tools take a lot of time to build even though they involve the same UI components, data integrations, and user access management. Developers love Appsmith because it saves them hundreds of hours.
|
||||
|
||||
|
|
@ -228,3 +227,7 @@ helm upgrade --values values.yaml stable-appsmith/appsmith appsmith
|
|||
If at any time you encounter an error during the installation process, reach out to support@appsmith.com or join our Discord Server
|
||||
|
||||
If you know the error and would like to reinstall Appsmith, simply delete the installation folder and the templates folder and execute the script again
|
||||
|
||||
## Testing
|
||||
|
||||
Review tests/README.md for details on how the chart is tested.
|
||||
|
|
|
|||
|
|
@ -144,6 +144,11 @@ spec:
|
|||
value: kubernetes.KUBE_PING
|
||||
- name: APPSMITH_HEADLESS_SVC
|
||||
value: {{ include "appsmith.fullname" . }}-headless
|
||||
{{- if .Values.securityContext.runAsUser | default nil }}
|
||||
# ensure the interactive shell when connected via kubectl exec is set
|
||||
- name: LD_PRELOAD
|
||||
value: /usr/local/lib/libnss_wrapper.so
|
||||
{{- end }}
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: {{ include "appsmith.fullname" . }}
|
||||
|
|
|
|||
37
deploy/helm/tests/README.md
Normal file
37
deploy/helm/tests/README.md
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# Helm Chart Unit Tests
|
||||
|
||||
This directory contains unit tests for our Helm charts using [helm-unittest](https://github.com/helm-unittest/helm-unittest), a BDD-style testing framework for Helm charts.
|
||||
|
||||
## Running Tests Locally
|
||||
|
||||
You can run the tests locally using Docker:
|
||||
|
||||
```bash
|
||||
docker run -ti --rm -v $(pwd):/apps helmunittest/helm-unittest .
|
||||
```
|
||||
|
||||
## Snapshot Testing
|
||||
|
||||
Our tests use snapshot testing to validate the rendered Kubernetes manifests. This ensures that any changes to the defaults are intentional and reviewed.
|
||||
|
||||
### Updating Snapshots
|
||||
|
||||
When making changes that affect the rendered output (like updating labels or other metadata), you'll need to update the snapshots. This is particularly important during releases when labels are updated.
|
||||
|
||||
To update snapshots, run the tests with the `-u` flag:
|
||||
|
||||
```bash
|
||||
docker run -ti --rm -v $(pwd):/apps helmunittest/helm-unittest -u .
|
||||
```
|
||||
|
||||
**Important**: Always review the changes in the snapshots before committing them to ensure they match your expectations.
|
||||
|
||||
## Documentation
|
||||
|
||||
For more information about helm-unittest, including:
|
||||
- Writing test cases
|
||||
- Available assertions
|
||||
- Test suite configuration
|
||||
- Best practices
|
||||
|
||||
Please refer to the [official helm-unittest documentation](https://github.com/helm-unittest/helm-unittest).
|
||||
210
deploy/helm/tests/__snapshot__/defaults_snapshot_test.yaml.snap
Normal file
210
deploy/helm/tests/__snapshot__/defaults_snapshot_test.yaml.snap
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
"":
|
||||
1: |
|
||||
raw: |
|
||||
1. Get the application URL by running these commands:
|
||||
export POD_NAME=$(kubectl get pods --namespace NAMESPACE -l "app.kubernetes.io/name=appsmith,app.kubernetes.io/instance=RELEASE-NAME" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace NAMESPACE $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace NAMESPACE port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
|
||||
To expose your Appsmith service to be accessible from the Internet, please refer to our docs here https://docs.appsmith.com/getting-started/setup/installation-guides/kubernetes/publish-appsmith-online.
|
||||
2: |
|
||||
apiVersion: v1
|
||||
data:
|
||||
APPSMITH_DB_URL: |
|
||||
mongodb+srv://root:password@appsmith-mongodb.NAMESPACE.svc.cluster.local/appsmith?retryWrites=true&authSource=admin&ssl=false
|
||||
APPSMITH_DISABLE_IFRAME_WIDGET_SANDBOX: "false"
|
||||
APPSMITH_KEYCLOAK_DB_DRIVER: postgresql
|
||||
APPSMITH_KEYCLOAK_DB_PASSWORD: password
|
||||
APPSMITH_KEYCLOAK_DB_URL: RELEASE-NAME-postgresql.NAMESPACE.svc.cluster.local:5432/keycloak
|
||||
APPSMITH_KEYCLOAK_DB_USERNAME: root
|
||||
APPSMITH_REDIS_URL: redis://RELEASE-NAME-redis-master.NAMESPACE.svc.cluster.local:6379
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: appsmith
|
||||
appsmith.sh/chart: appsmith-3.6.2
|
||||
name: RELEASE-NAME-appsmith
|
||||
namespace: NAMESPACE
|
||||
3: |
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: appsmith
|
||||
appsmith.sh/chart: appsmith-3.6.2
|
||||
name: RELEASE-NAME-appsmith
|
||||
namespace: NAMESPACE
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/name: appsmith
|
||||
serviceName: RELEASE-NAME-appsmith
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/name: appsmith
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: APPSMITH_ENABLE_EMBEDDED_DB
|
||||
value: "0"
|
||||
- name: JGROUPS_DISCOVERY_PROTOCOL
|
||||
value: kubernetes.KUBE_PING
|
||||
- name: APPSMITH_HEADLESS_SVC
|
||||
value: RELEASE-NAME-appsmith-headless
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: RELEASE-NAME-appsmith
|
||||
image: index.docker.io/appsmith/appsmith-ee:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: 80
|
||||
periodSeconds: 60
|
||||
name: appsmith
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: http
|
||||
protocol: TCP
|
||||
- containerPort: 443
|
||||
name: https
|
||||
protocol: TCP
|
||||
- containerPort: 2019
|
||||
name: metrics
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: 80
|
||||
periodSeconds: 60
|
||||
resources:
|
||||
limits: {}
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 3000Mi
|
||||
securityContext: {}
|
||||
startupProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /api/v1/health
|
||||
port: 80
|
||||
periodSeconds: 60
|
||||
volumeMounts:
|
||||
- mountPath: /appsmith-stacks
|
||||
name: data
|
||||
initContainers:
|
||||
- command:
|
||||
- sh
|
||||
- -c
|
||||
- until redis-cli -h RELEASE-NAME-redis-master.NAMESPACE.svc.cluster.local ping ; do echo waiting for redis; sleep 2; done
|
||||
image: docker.io/redis:7.0.15
|
||||
name: redis-init-container
|
||||
- command:
|
||||
- sh
|
||||
- -c
|
||||
- until mongosh --host appsmith-mongodb.NAMESPACE.svc.cluster.local --eval 'db.runCommand({ping:1})' ; do echo waiting for mongo; sleep 2; done
|
||||
image: docker.io/bitnami/mongodb:6.0.13
|
||||
name: mongo-init-container
|
||||
- command:
|
||||
- sh
|
||||
- -c
|
||||
- until pg_isready -U $postgresuser -d $postgresdb -h RELEASE-NAME-postgresql.NAMESPACE.svc.cluster.local; do echo waiting for postgresql; sleep 2; done
|
||||
image: docker.io/bitnami/postgresql:14.5.0-debian-11-r21
|
||||
name: psql-init-container
|
||||
securityContext: {}
|
||||
serviceAccountName: RELEASE-NAME-appsmith
|
||||
volumes: null
|
||||
updateStrategy: null
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: data
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
4: |
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: appsmith
|
||||
appsmith.sh/chart: appsmith-3.6.2
|
||||
name: RELEASE-NAME-appsmith-headless
|
||||
namespace: NAMESPACE
|
||||
spec:
|
||||
clusterIP: None
|
||||
clusterIPs:
|
||||
- None
|
||||
internalTrafficPolicy: Cluster
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/name: appsmith
|
||||
type: ClusterIP
|
||||
5: |
|
||||
apiVersion: policy/v1beta1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: RELEASE-NAME-appsmith-pdb
|
||||
namespace: NAMESPACE
|
||||
spec:
|
||||
minAvailable: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/name: appsmith
|
||||
6: |
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: appsmith
|
||||
appsmith.sh/chart: appsmith-3.6.2
|
||||
name: RELEASE-NAME-appsmith
|
||||
namespace: NAMESPACE
|
||||
spec:
|
||||
ports:
|
||||
- name: appsmith
|
||||
nodePort: null
|
||||
port: 80
|
||||
targetPort: http
|
||||
selector:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/name: appsmith
|
||||
type: ClusterIP
|
||||
7: |
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: RELEASE-NAME
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: appsmith
|
||||
appsmith.sh/chart: appsmith-3.6.2
|
||||
name: RELEASE-NAME-appsmith
|
||||
namespace: NAMESPACE
|
||||
secrets:
|
||||
- name: RELEASE-NAME-appsmith
|
||||
9
deploy/helm/tests/defaults_snapshot_test.yaml
Normal file
9
deploy/helm/tests/defaults_snapshot_test.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# snapshot tests to capture expected changes to defaults
|
||||
|
||||
# exclude dependent charts from the snapshot
|
||||
excludeTemplates:
|
||||
- charts/*
|
||||
tests:
|
||||
- name: manifest should match snapshot from default values
|
||||
asserts:
|
||||
- matchSnapshot: {}
|
||||
27
deploy/helm/tests/runAsUser_test.yaml
Normal file
27
deploy/helm/tests/runAsUser_test.yaml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
templates:
|
||||
- deployment.yaml
|
||||
tests:
|
||||
- name: runAsUser should be 9999
|
||||
set:
|
||||
podSecurityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "80"
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 9999
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.template.spec.containers[?(@.name == "appsmith")].securityContext
|
||||
value:
|
||||
runAsUser: 9999
|
||||
runAsNonRoot: true
|
||||
- equal:
|
||||
path: spec.template.spec.securityContext
|
||||
value:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "80"
|
||||
- equal:
|
||||
path: spec.template.spec.containers[?(@.name == "appsmith")].env[?(@.name == "LD_PRELOAD")].value
|
||||
value: "/usr/local/lib/libnss_wrapper.so"
|
||||
Loading…
Reference in New Issue
Block a user