Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ metadata:
annotations:
argocd.argoproj.io/sync-options: Prune=false
spec:
natsClusterRef:
namespace: nats
name: local-nats
accountLimits:
conn: 100
exports: 100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ metadata:
annotations:
argocd.argoproj.io/sync-options: Prune=false
spec:
natsClusterRef:
namespace: nats
name: local-nats
accountLimits:
conn: 100
exports: 100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ metadata:
name: example-account
namespace: simple-account
spec:
natsClusterRef:
namespace: nats
name: local-nats
accountLimits:
conn: 100
exports: 10
Expand Down
4 changes: 2 additions & 2 deletions local/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ The task scripts live under `.mise-tasks/nauth` and can be run individually.
## Local overrides

- `local/nats/values.yaml`: NATS chart overrides for the test environment.
- `local/nauth/values.yaml`: Nauth chart overrides for the test environment.
- `local/nauth/manifests/operator.yaml`: extra manifests applied during setup. Do not modify as it is also used by KUTTL tests.
- `local/nauth/values.yaml`: Nauth chart overrides for the test environment (no legacy `nats.url` override).
- `local/nauth/manifests/operator.yaml`: shared bootstrap manifests applied during setup, including `NatsCluster` (`local-nats`) and referenced secrets.
- `local/prometheus/values.yaml`: Prometheus chart overrides (if used).

## Cleanup
Expand Down
21 changes: 16 additions & 5 deletions local/nauth/manifests/operator.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# DO NOT MODIFY THIS FILE
# Local development and E2E bootstrap resources for NAUTH.
# Includes shared test secrets and a default NatsCluster in the `nats` namespace.
# The values in this file is bound to the secrets used in `local/nauth/values.yaml`

apiVersion: v1
Expand All @@ -15,8 +16,6 @@ kind: Secret
type: Opaque
metadata:
name: operator-op-sign
labels:
nauth.io/secret-type: operator-sign
data:
default: U09BSUZQVEZJNllHM1ZPTlBBMjRCTkgyNzYyR0lTVEJYSU5VVE1PVFpBUjJESkFMRUY0TE9WRElBQQ==

Expand Down Expand Up @@ -44,7 +43,19 @@ kind: Secret
type: Opaque
metadata:
name: operator-sau-creds
labels:
nauth.io/secret-type: system-account-user-creds
data:
default: LS0tLS1CRUdJTiBOQVRTIFVTRVIgSldULS0tLS0KZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKbFpESTFOVEU1TFc1clpYa2lmUS5leUpxZEdraU9pSklXbEJCUjFKUFJsTlZRVFphVkU5UVNEVkZObGxSTjAxYVdGRldSVGRKV2s5UE5FeEtSVXBaTlU1U05WbEdXRmt6TTBoUklpd2lhV0YwSWpveE56UTVOakkwT0RjNUxDSnBjM01pT2lKQlFraFBVelpXU0U1VU4xSk9Na3BEVDAxSlZqWk5WRFExV0VWV01rTlVORTVWUVZrMFRUUXlSVkJaUms5VVVVMU1VRWxYTkZkVVVpSXNJbTVoYldVaU9pSnplWE4wWlcwaUxDSnpkV0lpT2lKVlFUTkhVbEpOUlZVMVIwRTBWMFJXTkRjeVJVRkVSRlF5VkVsWVYxVktVVWd5VmxkVVMxVlBVa2xDVkZWRVQwd3lURGMyVGxkTlFTSXNJbTVoZEhNaU9uc2ljSFZpSWpwN2ZTd2ljM1ZpSWpwN2ZTd2ljM1ZpY3lJNkxURXNJbVJoZEdFaU9qRXdOek0zTkRFNE1qUXNJbkJoZVd4dllXUWlPaTB4TENKcGMzTjFaWEpmWVdOamIzVnVkQ0k2SWtGQ04wTk9XRGRHTWtKSlRVVkVXa2xQTTBFME5UWkxVVk5QVWxsSlZVbFNObEpITWxkRVdWTlNUbEpUVjAxVk4weFdRMEpYVmxnMklpd2lkSGx3WlNJNkluVnpaWElpTENKMlpYSnphVzl1SWpveWZYMC5ra0ZtMGlDaC1HVzR2OFBSRi1DWmI4QzJxYnNFRVZFMWoyQzltakNtaVppRDEyMVdFR25mdUFVS2FoNHhxU0VUSW9udGN4RURGSGhBc09qcUt3LVdCZwotLS0tLS1FTkQgTkFUUyBVU0VSIEpXVC0tLS0tLQoKKioqKioqKioqKioqKioqKioqKioqKioqKiBJTVBPUlRBTlQgKioqKioqKioqKioqKioqKioqKioqKioqKgpOS0VZIFNlZWQgcHJpbnRlZCBiZWxvdyBjYW4gYmUgdXNlZCB0byBzaWduIGFuZCBwcm92ZSBpZGVudGl0eS4KTktFWXMgYXJlIHNlbnNpdGl2ZSBhbmQgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgc2VjcmV0cy4KCi0tLS0tQkVHSU4gVVNFUiBOS0VZIFNFRUQtLS0tLQpTVUFLS0lUR0VBTTQ0SlgyUTVTS0lIWE9WVjVCSlI2VFRNT1RNVEVVSkpSWUxFRzMyV0hQNlNTSEs0Ci0tLS0tLUVORCBVU0VSIE5LRVkgU0VFRC0tLS0tLQoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgo=

---
apiVersion: nauth.io/v1alpha1
kind: NatsCluster
metadata:
name: local-nats
spec:
url: nats://nats.nats.svc.cluster.local:4222
operatorSigningKeySecretRef:
name: operator-op-sign
key: default
systemAccountUserCredsSecretRef:
name: operator-sau-creds
key: default
3 changes: 0 additions & 3 deletions local/nauth/values.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
nats:
url: nats://nats.nats.svc.cluster.local:4222

# # Uncomment if running observability stack locally
# monitoring:
# enabled: false
Expand Down
3 changes: 3 additions & 0 deletions test/e2e/account-deletion/01-account-creation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@ kind: Account
metadata:
name: example-account
spec:
natsClusterRef:
namespace: nats
name: local-nats
accountLimits:
conn: 100
4 changes: 4 additions & 0 deletions test/e2e/account-import-observe/03-account-import.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ metadata:
labels:
account.nauth.io/id: ADDS6I3G7LBIBNDMZ5Q32VUJN2XNSW2QK4HY2SY5ZA7I2JLBFYF4KJDO
nauth.io/management-policy: observe
spec:
natsClusterRef:
namespace: nats
name: local-nats
65 changes: 30 additions & 35 deletions test/e2e/basic-test/00-assert-operator-secrets.yaml
Original file line number Diff line number Diff line change
@@ -1,52 +1,47 @@
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: operator-op-root
namespace: nats
data:
default: U09BR1MySVVEVFBJTE9ZQkZaMkY0QUlGVlBWM0VKQk1QQVpaTVI3VUI3NERIUTdYSkQzNUJKTzY0QQ==

---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: operator-op-sign
namespace: nats
labels:
nauth.io/secret-type: operator-sign
data:
default: U09BSUZQVEZJNllHM1ZPTlBBMjRCTkgyNzYyR0lTVEJYSU5VVE1PVFpBUjJESkFMRUY0TE9WRElBQQ==

---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: operator-sa-root
name: operator-sau-creds
namespace: nats
data:
default: U0FBREpESU9BTklQRUJMVTZPNFROVVhES0w1Rk1PRFZJWTUzTjNZNTVWNktTRFBOV1hISkwzS0ZBNA==

---
apiVersion: v1
kind: Secret
type: Opaque
apiVersion: nauth.io/v1alpha1
kind: NatsCluster
metadata:
name: operator-sa-sign
name: local-nats
namespace: nats
data:
default: U0FBT1dLM0dCSUNZTTZaWjZSM0U0N0hQN00yQUI1UERPWUJYS0NOVUJJS1dRRlVIMko2VUhHNUU1QQ==
spec:
url: nats://nats.nats.svc.cluster.local:4222
operatorSigningKeySecretRef:
name: operator-op-sign
key: default
systemAccountUserCredsSecretRef:
name: operator-sau-creds
key: default

---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: operator-sau-creds
namespace: nats
labels:
nauth.io/secret-type: system-account-user-creds
data:
default: LS0tLS1CRUdJTiBOQVRTIFVTRVIgSldULS0tLS0KZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKbFpESTFOVEU1TFc1clpYa2lmUS5leUpxZEdraU9pSklXbEJCUjFKUFJsTlZRVFphVkU5UVNEVkZObGxSTjAxYVdGRldSVGRKV2s5UE5FeEtSVXBaTlU1U05WbEdXRmt6TTBoUklpd2lhV0YwSWpveE56UTVOakkwT0RjNUxDSnBjM01pT2lKQlFraFBVelpXU0U1VU4xSk9Na3BEVDAxSlZqWk5WRFExV0VWV01rTlVORTVWUVZrMFRUUXlSVkJaUms5VVVVMU1VRWxYTkZkVVVpSXNJbTVoYldVaU9pSnplWE4wWlcwaUxDSnpkV0lpT2lKVlFUTkhVbEpOUlZVMVIwRTBWMFJXTkRjeVJVRkVSRlF5VkVsWVYxVktVVWd5VmxkVVMxVlBVa2xDVkZWRVQwd3lURGMyVGxkTlFTSXNJbTVoZEhNaU9uc2ljSFZpSWpwN2ZTd2ljM1ZpSWpwN2ZTd2ljM1ZpY3lJNkxURXNJbVJoZEdFaU9qRXdOek0zTkRFNE1qUXNJbkJoZVd4dllXUWlPaTB4TENKcGMzTjFaWEpmWVdOamIzVnVkQ0k2SWtGQ04wTk9XRGRHTWtKSlRVVkVXa2xQTTBFME5UWkxVVk5QVWxsSlZVbFNObEpITWxkRVdWTlNUbEpUVjAxVk4weFdRMEpYVmxnMklpd2lkSGx3WlNJNkluVnpaWElpTENKMlpYSnphVzl1SWpveWZYMC5ra0ZtMGlDaC1HVzR2OFBSRi1DWmI4QzJxYnNFRVZFMWoyQzltakNtaVppRDEyMVdFR25mdUFVS2FoNHhxU0VUSW9udGN4RURGSGhBc09qcUt3LVdCZwotLS0tLS1FTkQgTkFUUyBVU0VSIEpXVC0tLS0tLQoKKioqKioqKioqKioqKioqKioqKioqKioqKiBJTVBPUlRBTlQgKioqKioqKioqKioqKioqKioqKioqKioqKgpOS0VZIFNlZWQgcHJpbnRlZCBiZWxvdyBjYW4gYmUgdXNlZCB0byBzaWduIGFuZCBwcm92ZSBpZGVudGl0eS4KTktFWXMgYXJlIHNlbnNpdGl2ZSBhbmQgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgc2VjcmV0cy4KCi0tLS0tQkVHSU4gVVNFUiBOS0VZIFNFRUQtLS0tLQpTVUFLS0lUR0VBTTQ0SlgyUTVTS0lIWE9WVjVCSlI2VFRNT1RNVEVVSkpSWUxFRzMyV0hQNlNTSEs0Ci0tLS0tLUVORCBVU0VSIE5LRVkgU0VFRC0tLS0tLQoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgo=
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 20
commands:
- script: |
set -eu

op_sign="$(kubectl get secret -n nats operator-op-sign -o jsonpath='{.data.default}')"
test -n "$op_sign"

sys_creds="$(kubectl get secret -n nats operator-sau-creds -o jsonpath='{.data.default}')"
test -n "$sys_creds"

ref="$(kubectl get natscluster.nauth.io local-nats -n nats -o jsonpath='{.spec.operatorSigningKeySecretRef.name}')"
test "$ref" = "operator-op-sign"

ref="$(kubectl get natscluster.nauth.io local-nats -n nats -o jsonpath='{.spec.systemAccountUserCredsSecretRef.name}')"
test "$ref" = "operator-sau-creds"
5 changes: 4 additions & 1 deletion test/e2e/basic-test/01-create-account.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ kind: Account
metadata:
name: example-account
spec:
natsClusterRef:
namespace: nats
name: local-nats
displayName: My Example Account
accountLimits:
conn: 100
Expand All @@ -26,4 +29,4 @@ spec:
exports:
- name: export-test
subject: foo.>
type: stream
type: stream
124 changes: 75 additions & 49 deletions test/script/nats-jwt-upload.sh
Original file line number Diff line number Diff line change
@@ -1,100 +1,126 @@
#!/bin/bash
# Usage: nats-jwt-upload.sh <jwt-file>
# Example: ./nats-jwt-upload.sh /tmp/account.jwt
# Usage: nats-jwt-upload.sh <jwt-file> [nats-cluster-name] [nats-cluster-namespace]
# Example: ./nats-jwt-upload.sh /tmp/account.jwt local-nats nats
#
# This script uploads an account JWT to the NATS server using the system account credentials.
# It mimics what the nauth operator does when it calls UploadAccountJWT().
# Note: NATS server and system account credentials are always in the 'nats' namespace.
# Uploads an account JWT to NATS using system account credentials resolved from
# a NatsCluster resource.

set -euo pipefail

if [ "$#" -ne 1 ]; then
echo "[$0] Usage: $0 <jwt-file>" >&2
if [ "$#" -lt 1 ] || [ "$#" -gt 3 ]; then
echo "[$0] Usage: $0 <jwt-file> [nats-cluster-name] [nats-cluster-namespace]" >&2
exit 1
fi

JWT_FILE="$1"

# NATS server and operator are always deployed in the 'nats' namespace
NATS_NAMESPACE="nats"
NATS_CLUSTER_NAME="${2:-local-nats}"
NATS_CLUSTER_NAMESPACE="${3:-nats}"

if [ ! -f "$JWT_FILE" ]; then
echo "[$0] ERROR: JWT file not found: $JWT_FILE" >&2
echo "[$0] Absolute path would be: $(realpath "$JWT_FILE" 2>&1 || echo 'cannot resolve')" >&2
exit 2
fi

# Extract JWT filename for use in temporary file names
JWT_FILENAME=$(basename "$JWT_FILE")

# Get the system account credentials from the secret in the nats namespace
CREDS_SECRET=$(kubectl get secret -n "$NATS_NAMESPACE" \
-l "nauth.io/secret-type=system-account-user-creds" \
-o jsonpath='{.items[0].metadata.name}' 2>&1)
if ! kubectl get natsclusters.nauth.io "$NATS_CLUSTER_NAME" -n "$NATS_CLUSTER_NAMESPACE" >/dev/null 2>&1; then
echo "[$0] ERROR: NatsCluster $NATS_CLUSTER_NAMESPACE/$NATS_CLUSTER_NAME not found" >&2
exit 3
fi

CREDS_SECRET_EXIT_CODE=$?
NATS_URL="$(kubectl get natsclusters.nauth.io "$NATS_CLUSTER_NAME" -n "$NATS_CLUSTER_NAMESPACE" -o jsonpath='{.spec.url}')"

if [ -z "$NATS_URL" ]; then
URL_FROM_KIND="$(kubectl get natsclusters.nauth.io "$NATS_CLUSTER_NAME" -n "$NATS_CLUSTER_NAMESPACE" -o jsonpath='{.spec.urlFrom.kind}')"
URL_FROM_NAME="$(kubectl get natsclusters.nauth.io "$NATS_CLUSTER_NAME" -n "$NATS_CLUSTER_NAMESPACE" -o jsonpath='{.spec.urlFrom.name}')"
URL_FROM_KEY="$(kubectl get natsclusters.nauth.io "$NATS_CLUSTER_NAME" -n "$NATS_CLUSTER_NAMESPACE" -o jsonpath='{.spec.urlFrom.key}')"
URL_FROM_NAMESPACE="$(kubectl get natsclusters.nauth.io "$NATS_CLUSTER_NAME" -n "$NATS_CLUSTER_NAMESPACE" -o jsonpath='{.spec.urlFrom.namespace}')"

if [ -z "$URL_FROM_NAMESPACE" ]; then
URL_FROM_NAMESPACE="$NATS_CLUSTER_NAMESPACE"
fi

case "$URL_FROM_KIND" in
ConfigMap|configmap)
NATS_URL="$(kubectl get configmap "$URL_FROM_NAME" -n "$URL_FROM_NAMESPACE" -o "go-template={{ index .data \"$URL_FROM_KEY\" }}" 2>/dev/null || true)"
;;
Secret|secret)
URL_B64="$(kubectl get secret "$URL_FROM_NAME" -n "$URL_FROM_NAMESPACE" -o "go-template={{ index .data \"$URL_FROM_KEY\" }}" 2>/dev/null || true)"
if [ -n "$URL_B64" ] && [ "$URL_B64" != "<no value>" ]; then
NATS_URL="$(printf '%s' "$URL_B64" | base64 -d)"
fi
;;
"")
;;
*)
echo "[$0] ERROR: Unsupported spec.urlFrom.kind '$URL_FROM_KIND' for NatsCluster $NATS_CLUSTER_NAMESPACE/$NATS_CLUSTER_NAME" >&2
exit 4
;;
esac
fi

if [ $CREDS_SECRET_EXIT_CODE -ne 0 ] || [ -z "$CREDS_SECRET" ] || echo "$CREDS_SECRET" | grep -q "error:"; then
echo "[$0] ERROR: System account credentials secret not found in namespace $NATS_NAMESPACE" >&2
kubectl get secrets -n "$NATS_NAMESPACE" 2>&1 | head -20 >&2
exit 3
if [ -z "$NATS_URL" ]; then
echo "[$0] ERROR: Unable to resolve NATS URL from NatsCluster $NATS_CLUSTER_NAMESPACE/$NATS_CLUSTER_NAME" >&2
exit 4
fi

# Extract the credentials to a temp file
CREDS_FILE=$(mktemp)
trap 'rm -f "$CREDS_FILE"' EXIT
CREDS_SECRET="$(kubectl get natsclusters.nauth.io "$NATS_CLUSTER_NAME" -n "$NATS_CLUSTER_NAMESPACE" -o jsonpath='{.spec.systemAccountUserCredsSecretRef.name}')"
CREDS_KEY="$(kubectl get natsclusters.nauth.io "$NATS_CLUSTER_NAME" -n "$NATS_CLUSTER_NAMESPACE" -o jsonpath='{.spec.systemAccountUserCredsSecretRef.key}')"

if [ -z "$CREDS_SECRET" ]; then
echo "[$0] ERROR: NatsCluster $NATS_CLUSTER_NAMESPACE/$NATS_CLUSTER_NAME does not define spec.systemAccountUserCredsSecretRef.name" >&2
exit 5
fi

kubectl get secret -n "$NATS_NAMESPACE" "$CREDS_SECRET" -o jsonpath='{.data.default}' | base64 -d > "$CREDS_FILE"
if [ -z "$CREDS_KEY" ]; then
CREDS_KEY="default"
fi

CREDS_B64="$(kubectl get secret "$CREDS_SECRET" -n "$NATS_CLUSTER_NAMESPACE" -o "go-template={{ index .data \"$CREDS_KEY\" }}" 2>/dev/null || true)"
if [ -z "$CREDS_B64" ] || [ "$CREDS_B64" = "<no value>" ]; then
echo "[$0] ERROR: Secret $NATS_CLUSTER_NAMESPACE/$CREDS_SECRET does not contain key '$CREDS_KEY'" >&2
exit 5
fi

# Instead of running nats CLI locally, we'll use kubectl exec to run it inside a pod
# This avoids DNS and networking issues when running outside the cluster
CREDS_FILE=$(mktemp)
trap 'rm -f "$CREDS_FILE"' EXIT
printf '%s' "$CREDS_B64" | base64 -d > "$CREDS_FILE"

# Find nats-box pod by name pattern (it has nats CLI installed)
EXEC_POD=$(kubectl get pods -n "$NATS_NAMESPACE" --field-selector=status.phase=Running -o name 2>&1 | grep "pod/nats-box" | head -1 | cut -d'/' -f2)
EXEC_POD=$(kubectl get pods -n "$NATS_CLUSTER_NAMESPACE" --field-selector=status.phase=Running -o name 2>&1 | grep "pod/nats-box" | head -1 | cut -d'/' -f2)

if [ -z "$EXEC_POD" ]; then
echo "[$0] ERROR: nats-box pod not found in namespace $NATS_NAMESPACE" >&2
echo "[$0] ERROR: nats-box pod not found in namespace $NATS_CLUSTER_NAMESPACE" >&2
echo "[$0] Available pods:" >&2
kubectl get pods -n "$NATS_NAMESPACE" -o wide 2>&1 >&2
kubectl get pods -n "$NATS_CLUSTER_NAMESPACE" -o wide 2>&1 >&2
echo "[$0] Note: nats-box pod is required (has nats CLI installed)" >&2
exit 6
fi

# Copy credentials to the pod (using PID and JWT filename for unique identification)
REMOTE_CREDS_PATH="/tmp/nauth-upload-creds-$$-${JWT_FILENAME%.jwt}.default"
kubectl cp "$CREDS_FILE" "$NATS_NAMESPACE/$EXEC_POD:$REMOTE_CREDS_PATH" 2>&1 | grep -v "tar:" || true
kubectl cp "$CREDS_FILE" "$NATS_CLUSTER_NAMESPACE/$EXEC_POD:$REMOTE_CREDS_PATH" 2>&1 | grep -v "tar:" || true

# Copy JWT to the pod (using PID and JWT filename for unique identification)
REMOTE_JWT_PATH="/tmp/nauth-upload-$$-${JWT_FILENAME%.jwt}.jwt"
kubectl cp "$JWT_FILE" "$NATS_NAMESPACE/$EXEC_POD:$REMOTE_JWT_PATH" 2>&1 | grep -v "tar:" || true
kubectl cp "$JWT_FILE" "$NATS_CLUSTER_NAMESPACE/$EXEC_POD:$REMOTE_JWT_PATH" 2>&1 | grep -v "tar:" || true

# Use the cluster-internal DNS name
NATS_URL="nats://nats.${NATS_NAMESPACE}.svc.cluster.local:4222"

# Use nats CLI inside the pod to publish the JWT to $SYS.REQ.CLAIMS.UPDATE
# Note: JWT must be passed as an argument, not via stdin
set +e # Don't exit on error, capture it
RESPONSE=$(kubectl exec -i -n "$NATS_NAMESPACE" "$EXEC_POD" -- sh -c \
set +e
RESPONSE=$(kubectl exec -i -n "$NATS_CLUSTER_NAMESPACE" "$EXEC_POD" -- sh -c \
"nats req --creds='$REMOTE_CREDS_PATH' --server='$NATS_URL' '\$SYS.REQ.CLAIMS.UPDATE' \"\$(cat '$REMOTE_JWT_PATH')\"" 2>&1)
NATS_EXIT_CODE=$?
set -e

# Cleanup remote files
kubectl exec -n "$NATS_NAMESPACE" "$EXEC_POD" -- rm -f "$REMOTE_CREDS_PATH" "$REMOTE_JWT_PATH" 2>/dev/null || true
kubectl exec -n "$NATS_CLUSTER_NAMESPACE" "$EXEC_POD" -- rm -f "$REMOTE_CREDS_PATH" "$REMOTE_JWT_PATH" 2>/dev/null || true

if [ $NATS_EXIT_CODE -ne 0 ]; then
echo "[$0] ERROR: nats CLI command failed" >&2
echo "[$0] Response: $RESPONSE" >&2
exit 4
exit 7
fi

# Check if the response indicates success (code 200)
if echo "$RESPONSE" | grep -q '"code":200'; then
exit 0
else
echo "[$0] ERROR: Failed to upload account JWT" >&2
echo "[$0] Response: $RESPONSE" >&2
exit 4
fi

echo "[$0] ERROR: Failed to upload account JWT" >&2
echo "[$0] Response: $RESPONSE" >&2
exit 7
Loading