[kind]: https://github.com/kubernetes-sigs/kind # Demo: Namespaces and Prune This demo shows that namespaces will **not** be pruned if there are objects remaining in them. The namespace for the inventory object will be the default namespace, since not all of the app objects are in the same namespace (pod-b is in the default namespace). When pod-a, pod-b, and the test-namespace are omitted from the subsequent apply the test-namespace will be considered for pruning, but it will **not** happend because there is still one object in the namespace--pod-c. First define a place to work: ``` DEMO_HOME=$(mktemp -d) ``` Alternatively, use > ``` > DEMO_HOME=~/demo > ``` ## Establish the base ``` BASE=$DEMO_HOME/base mkdir -p $BASE OUTPUT=$DEMO_HOME/output mkdir -p $OUTPUT GREEN='\033[0;32m' RED='\033[0;31m' NC='\033[0m' # No Color function expectedOutputLine() { if ! grep -q "$@" "$OUTPUT/status"; then echo -e "${RED}Error: output line not found${NC}" echo -e "${RED}Expected: $@${NC}" exit 1 else echo -e "${GREEN}Success: output line found${NC}" fi } ``` ## Create the first "app" Create the config yaml for three config maps: (cm-a, cm-b, cm-c). ``` cat <$BASE/namespace.yaml apiVersion: v1 kind: Namespace metadata: name: test-namespace EOF cat <$BASE/config-map-a.yaml apiVersion: v1 kind: ConfigMap metadata: name: cm-a namespace: test-namespace labels: name: test-config-map-label EOF cat <$BASE/config-map-b.yaml apiVersion: v1 kind: ConfigMap metadata: name: cm-b labels: name: test-config-map-label EOF cat <$BASE/config-map-c.yaml apiVersion: v1 kind: ConfigMap metadata: name: cm-c namespace: test-namespace labels: name: test-config-map-label EOF ``` ## Run end-to-end tests The following requires installation of [kind]. Delete any existing kind cluster and create a new one. By default the name of the cluster is "kind". ``` kind delete cluster kind create cluster ``` Use the kapply init command to generate the inventory template. This contains the namespace and inventory id used by apply to create inventory objects. ``` kapply init $BASE | tee $OUTPUT/status expectedOutputLine "namespace: default is used for inventory object" ``` Apply the "app" to the cluster. All the config maps should be created, and no resources should be pruned. ``` kapply apply $BASE --reconcile-timeout=1m | tee $OUTPUT/status expectedOutputLine "namespace/test-namespace apply successful" expectedOutputLine "configmap/cm-a apply successful" expectedOutputLine "configmap/cm-b apply successful" expectedOutputLine "configmap/cm-c apply successful" expectedOutputLine "apply result: 4 attempted, 4 successful, 0 skipped, 0 failed" expectedOutputLine "reconcile result: 4 attempted, 4 successful, 0 skipped, 0 failed, 0 timed out" # There should be only one inventory object kubectl get cm --selector='cli-utils.sigs.k8s.io/inventory-id' --no-headers | wc -l | tee $OUTPUT/status expectedOutputLine "1" # Capture the inventory object name for later testing invName=$(kubectl get cm --selector='cli-utils.sigs.k8s.io/inventory-id' --no-headers | awk '{print $1}') # There should be four config maps: one inventory in default, two in test-namespace, one in default namespace kubectl get cm --selector='cli-utils.sigs.k8s.io/inventory-id' --no-headers | wc -l | tee $OUTPUT/status expectedOutputLine "1" kubectl get cm -n test-namespace --selector='name=test-config-map-label' --no-headers | wc -l | tee $OUTPUT/status expectedOutputLine "2" kubectl get cm --selector='name=test-config-map-label' --no-headers | wc -l | tee $OUTPUT/status expectedOutputLine "1" # ConfigMap cm-a had been created in the cluster kubectl get configmap/cm-a -n test-namespace --no-headers | wc -l | tee $OUTPUT/status expectedOutputLine "1" # ConfigMap cm-b had been created in the cluster kubectl get configmap/cm-b --no-headers | wc -l | tee $OUTPUT/status expectedOutputLine "1" # ConfigMap cm-c had been created in the cluster kubectl get configmap/cm-c -n test-namespace --no-headers | wc -l | tee $OUTPUT/status expectedOutputLine "1" ``` ## Update the "app" to remove a two of the config maps, and the namespace. Remove test-namespace Remove cm-a Remove cm-b ``` rm -f $BASE/namespace.yaml rm -f $BASE/config-map-a.yaml rm -f $BASE/config-map-b.yaml ``` ## Apply the updated "app" cm-a should be pruned (since it has been deleted locally). cm-b should be pruned (since it has been deleted locally). test-namespace should **not** be pruned. ``` kapply apply $BASE --reconcile-timeout=1m | tee $OUTPUT/status expectedOutputLine "configmap/cm-c apply skipped: dependency scheduled for delete: _test-namespace__Namespace" expectedOutputLine "configmap/cm-c reconcile skipped" expectedOutputLine "configmap/cm-a prune successful" expectedOutputLine "configmap/cm-b prune successful" expectedOutputLine "namespace/test-namespace prune skipped: namespace still in use: test-namespace" expectedOutputLine "namespace/test-namespace reconcile skipped" expectedOutputLine "configmap/cm-a reconcile successful" expectedOutputLine "configmap/cm-b reconcile successful" expectedOutputLine "configmap/cm-c reconcile skipped" expectedOutputLine "apply result: 1 attempted, 0 successful, 1 skipped, 0 failed" expectedOutputLine "prune result: 3 attempted, 2 successful, 1 skipped, 0 failed" expectedOutputLine "reconcile result: 4 attempted, 2 successful, 2 skipped, 0 failed, 0 timed out" # The test-namespace should not be pruned. kubectl get ns test-namespace --no-headers | wc -l | tee $OUTPUT/status expectedOutputLine "1" # Inventory object should have two items: namespace and cm-c. kubectl get cm --selector='cli-utils.sigs.k8s.io/inventory-id' --no-headers | awk '{print $2}' | tee $OUTPUT/status expectedOutputLine "2" # The inventory object should have the same name kubectl get configmap/${invName} --no-headers | tee $OUTPUT/status expectedOutputLine "${invName}" # ConfigMap cm-c remains in the cluster. kubectl get configmap/cm-c -n test-namespace --no-headers | wc -l | tee $OUTPUT/status expectedOutputLine "1" ```