diff --git a/ansible/inventory/demo/host.yml b/ansible/inventory/demo/host.yml index 920a8b06a..0caa01901 100644 --- a/ansible/inventory/demo/host.yml +++ b/ansible/inventory/demo/host.yml @@ -18,7 +18,7 @@ wiab: wire_ip: "" # artifact_hash - artifact_hash: "8e5087a0d9c58a9bd34c6c02f87514abe8b3ce0e" + artifact_hash: "94523acf6df5a177fd7fc1a7fdc004ce5335233b" # docker vars docker_ce_version: "5:28.1.1-1~ubuntu.24.04~noble" diff --git a/ansible/wiab-demo/deploy_wiab.yml b/ansible/wiab-demo/deploy_wiab.yml index 9d15493d8..d60f950b4 100644 --- a/ansible/wiab-demo/deploy_wiab.yml +++ b/ansible/wiab-demo/deploy_wiab.yml @@ -36,16 +36,62 @@ import_playbook: ./install_pkgs.yml tags: install_pkgs +- name: Check and configure Ansible Python interpreter for Kubernetes operations + tags: always + hosts: deploy_node + tasks: + - name: Detect available Python interpreters and Kubernetes module + block: + - name: Check if kubernetes module is available in system Python + shell: "python3 -c 'import kubernetes; print(kubernetes.__version__)' 2>/dev/null" + register: system_k8s_check + changed_when: false + failed_when: false + + - name: Check virtual environment only if system Python doesn't have kubernetes + block: + - name: Check if kubernetes module is available in virtual environment + shell: "/opt/ansible-venv/bin/python -c 'import kubernetes; print(kubernetes.__version__)' 2>/dev/null" + register: venv_k8s_check + changed_when: false + failed_when: false + + - name: Configure to use virtual environment + block: + - name: Set ansible_python_interpreter to use virtual environment + set_fact: + ansible_python_interpreter: /opt/ansible-venv/bin/python + ansible_venv_path: /opt/ansible-venv + + when: venv_k8s_check.rc == 0 + + - name: Kubernetes module not found - run install_pkgs playbook + fail: + msg: | + ❌ Kubernetes Python module not found! + + System Python (/usr/bin/python3): + Status: NOT available + + Virtual Environment (/opt/ansible-venv/bin/python): + Status: NOT available + + To install kubernetes module, run: + ansible-playbook -i inventory.yml deploy_wiab.yml --tags install_pkgs + when: venv_k8s_check.rc != 0 + + when: system_k8s_check.rc != 0 + - name: Manage SSH keys (dependency for minikube, asset_host, seed_containers) import_playbook: ./setup_ssh.yml tags: always when: > - (('minikube' not in ansible_skip_tags or + ('minikube' not in ansible_skip_tags or 'asset_host' not in ansible_skip_tags or 'seed_containers' not in ansible_skip_tags) - and (ansible_skip_tags | length > 0)) - or - ('minikube' in ansible_run_tags or + and + ('all' in ansible_run_tags or + 'minikube' in ansible_run_tags or 'asset_host' in ansible_run_tags or 'seed_containers' in ansible_run_tags) @@ -104,15 +150,16 @@ tags: always when: > - (('minikube' not in ansible_skip_tags or + ('minikube' not in ansible_skip_tags or 'asset_host' not in ansible_skip_tags or - 'seed_containers' not in ansible_skip_tags) - and (ansible_skip_tags | length > 0)) - or - ('minikube' in ansible_run_tags or + 'seed_containers' not in ansible_skip_tags or + 'helm_install' not in ansible_skip_tags) + and + ('all' in ansible_run_tags or + 'minikube' in ansible_run_tags or 'asset_host' in ansible_run_tags or - 'seed_containers' in ansible_run_tags) - or use_cert_manager + 'seed_containers' in ansible_run_tags or + 'helm_install' in ansible_run_tags) - name: Configure Iptables rules import_playbook: ./iptables_rules.yml @@ -126,6 +173,7 @@ hosts: deploy_node become: yes become_user: "{{ ansible_user }}" + tags: always tasks: - name: Create a block for Minikube node tasks block: @@ -209,13 +257,12 @@ delegate_facts: true with_items: "{{ groups['k8s-cluster'] }}" - tags: always when: > - (('asset_host' not in ansible_skip_tags or + ('asset_host' not in ansible_skip_tags or 'seed_containers' not in ansible_skip_tags) - and (ansible_skip_tags | length > 0)) - or - ('asset_host' in ansible_run_tags or + and + ('all' in ansible_run_tags or + 'asset_host' in ansible_run_tags or 'seed_containers' in ansible_run_tags) - name: Setup Asset Host @@ -246,11 +293,6 @@ import_playbook: ./helm_install.yml tags: helm_install -- name: Veirfy Cert Manager hairpin Networking - import_playbook: ./hairpin_networking.yml - tags: always - when: use_cert_manager - # since, the temp_dir are created in a different set of tasks, these directories need to be searched - name: Clean up temporary directories hosts: localhost diff --git a/ansible/wiab-demo/helm_install.yml b/ansible/wiab-demo/helm_install.yml index 2d295e0f5..669598ea1 100644 --- a/ansible/wiab-demo/helm_install.yml +++ b/ansible/wiab-demo/helm_install.yml @@ -271,3 +271,7 @@ - "For more information:" - "https://github.com/wireapp/wire-server/tree/develop/charts/nginx-ingress-services" when: not use_cert_manager + +- name: Verify Cert Manager hairpin Networking + import_playbook: ./hairpin_networking.yml + when: use_cert_manager diff --git a/ansible/wiab-demo/install_pkgs.yml b/ansible/wiab-demo/install_pkgs.yml index 76bdcbb67..a375ef1c3 100644 --- a/ansible/wiab-demo/install_pkgs.yml +++ b/ansible/wiab-demo/install_pkgs.yml @@ -65,17 +65,30 @@ - name: Ensure required Python libraries are installed for Kubernetes operations block: - - name: Install kubernetes Python library via pip + - name: Create Python virtual environment for Ansible + command: python3 -m venv /opt/ansible-venv + args: + creates: /opt/ansible-venv/bin/python + become: yes + + - name: Install kubernetes Python library in virtual environment pip: name: - kubernetes>=18.0.0 - pyyaml>=5.4.1 - executable: /usr/bin/pip3 + executable: /opt/ansible-venv/bin/pip state: present - extra_args: "--break-system-packages" become: yes register: pip_install_result + - name: Create symbolic link for ansible Python interpreter + file: + src: /opt/ansible-venv/bin/python + dest: /usr/local/bin/ansible-python + state: link + force: yes + become: yes + - name: Check if Docker CE is installed with correct version shell: apt policy docker-ce | grep "Installed:" | awk '{print $2}' register: installed_docker_version diff --git a/ansible/wiab-demo/wire_secrets.yml b/ansible/wiab-demo/wire_secrets.yml index 13a3bbbe4..8b1ef9681 100644 --- a/ansible/wiab-demo/wire_secrets.yml +++ b/ansible/wiab-demo/wire_secrets.yml @@ -73,52 +73,43 @@ - name: Initialize secrets.yaml files from demo templates block: - - name: Discover all chart directories in values_dir for initialization + - name: Find all demo-secrets.example.yaml files in one pass find: paths: "{{ values_dir }}" - file_type: directory - recurse: no - register: chart_dirs + patterns: "demo-secrets.example.yaml" + recurse: yes + register: demo_secrets_files + changed_when: false - - name: Verify demo-secrets.example.yaml template files exist - stat: - path: "{{ item.path }}/demo-secrets.example.yaml" - register: demo_secrets_stat - loop: "{{ chart_dirs.files }}" + - name: Backup and initialize secrets for all charts + shell: | + #!/bin/bash + set -e + demo_file="{{ item }}" + chart_dir="$(dirname "$demo_file")" + secrets_file="$chart_dir/secrets.yaml" + + # Create timestamped backup if secrets.yaml exists + if [ -f "$secrets_file" ]; then + backup_file="${secrets_file}.bak.$(date +%Y%m%d_%H%M%S)" + mv "$secrets_file" "$backup_file" + echo "Backed up: $backup_file" + fi + + # Copy demo template to secrets.yaml + cp "$demo_file" "$secrets_file" + echo "Initialized: $secrets_file" + args: + executable: /bin/bash + register: init_result + changed_when: "'Initialized:' in init_result.stdout" + loop: "{{ demo_secrets_files.files | map(attribute='path') | list }}" no_log: true - - name: Create timestamped backups of existing secrets.yaml files - block: - - name: Check if secrets.yaml file exists before backup - stat: - path: "{{ item.item.path }}/secrets.yaml" - register: secrets_file_stat - loop: "{{ demo_secrets_stat.results }}" - no_log: true - - - name: Create backup with timestamp - shell: | - #!/bin/bash - source_file="{{ item.item.path }}/secrets.yaml" - backup_file="{{ item.item.path }}/secrets.yaml.bak.{{ lookup('pipe', 'date +%Y%m%d_%H%M%S') }}" - if [ -f "$source_file" ]; then - mv "$source_file" "$backup_file" - fi - args: - executable: /bin/bash - when: item.stat.exists - loop: "{{ demo_secrets_stat.results }}" - register: backup_result - no_log: true - - - name: Initialize secrets.yaml from demo template for each chart - copy: - src: "{{ item.item.path }}/demo-secrets.example.yaml" - dest: "{{ item.item.path }}/secrets.yaml" - remote_src: yes - when: item.stat.exists - loop: "{{ demo_secrets_stat.results }}" - no_log: true + - name: Display backup and initialization summary + debug: + msg: "{{ init_result.results | map(attribute='stdout_lines') | flatten | list }}" + when: init_result.results | length > 0 when: not skip_secret_generation @@ -165,12 +156,9 @@ set_fact: temp_dir: "{{ zauth_temp_dir.path }}" - - name: Generate Ed25519 private key in PEM format - openssl_privatekey: - path: "{{ temp_dir }}/key.pem" - type: Ed25519 - force: yes - no_log: true + - name: Generate Ed25519 private key using openssl + shell: "openssl genpkey -algorithm ed25519 -out '{{ temp_dir }}/key.pem'" + changed_when: false - name: Extract private key in DER format shell: "openssl pkey -in '{{ temp_dir }}/key.pem' -outform DER 2>/dev/null > '{{ temp_dir }}/priv.der'" @@ -193,12 +181,12 @@ changed_when: false - name: Encode combined key to base64 (private key) - shell: "base64 -w 0 < '{{ temp_dir }}/combined.bytes'" + shell: "base64 -w 0 < '{{ temp_dir }}/combined.bytes' | tr -- '+/' '-_'" register: libsodium_priv changed_when: false - name: Encode public key to base64 - shell: "base64 -w 0 < '{{ temp_dir }}/pub.bytes'" + shell: "base64 -w 0 < '{{ temp_dir }}/pub.bytes' | tr -- '+/' '-_'" register: libsodium_pub changed_when: false @@ -230,29 +218,33 @@ - name: Verify private key is valid base64 assert: that: - - libsodium_priv.stdout is regex('^[A-Za-z0-9+/]+=*$') + - libsodium_priv.stdout is regex('^[A-Za-z0-9_-]+=*$') fail_msg: "Private key is not valid base64: {{ libsodium_priv.stdout }}" quiet: yes - name: Verify public key is valid base64 assert: that: - - libsodium_pub.stdout is regex('^[A-Za-z0-9+/]+=*$') + - libsodium_pub.stdout is regex('^[A-Za-z0-9_-]+=*$') fail_msg: "Public key is not valid base64: {{ libsodium_pub.stdout }}" quiet: yes - name: Validate decoded key lengths block: - name: Decode and verify private key length (should be 64 bytes) - shell: "echo '{{ libsodium_priv.stdout }}' | base64 -d | wc -c" + shell: "printf '%s' '{{ libsodium_priv.stdout }}' | tr -- '-_' '+/' | base64 -d | wc -c" register: priv_decoded_len changed_when: false - name: Decode and verify public key length (should be 32 bytes) - shell: "echo '{{ libsodium_pub.stdout }}' | base64 -d | wc -c" + shell: "printf '%s' '{{ libsodium_pub.stdout }}' | tr -- '-_' '+/' | base64 -d | wc -c" register: pub_decoded_len changed_when: false + - name: debug + debug: + msg: " {{libsodium_pub.stdout}} {{libsodium_priv.stdout }}" + - name: Assert decoded key lengths are correct assert: that: diff --git a/ansible/wiab-demo/wire_values.yml b/ansible/wiab-demo/wire_values.yml index 573c591bb..eb142881d 100644 --- a/ansible/wiab-demo/wire_values.yml +++ b/ansible/wiab-demo/wire_values.yml @@ -85,52 +85,44 @@ - name: Initialize Helm chart values from demo templates block: - - name: Discover all chart directories in values_dir for initialization + - name: Find all demo-values.example.yaml files in one pass find: paths: "{{ values_dir }}" - file_type: directory - recurse: no - register: chart_dirs - - - name: Verify demo-values.example.yaml template files exist - stat: - path: "{{ item.path }}/demo-values.example.yaml" - register: demo_values_stat - loop: "{{ chart_dirs.files }}" + patterns: "demo-values.example.yaml" + recurse: yes + register: demo_values_files + changed_when: false + + - name: Backup and initialize values for all charts + shell: | + #!/bin/bash + set -e + demo_file="{{ item }}" + chart_dir="$(dirname "$demo_file")" + values_file="$chart_dir/values.yaml" + + # Create timestamped backup if values.yaml exists + if [ -f "$values_file" ]; then + backup_file="${values_file}.bak.$(date +%Y%m%d_%H%M%S)" + mv "$values_file" "$backup_file" + echo "Backed up: $backup_file" + fi + + # Copy demo template to values.yaml + cp "$demo_file" "$values_file" + echo "Initialized: $values_file" + args: + executable: /bin/bash + register: init_result + changed_when: "'Initialized:' in init_result.stdout" + loop: "{{ demo_values_files.files | map(attribute='path') | list }}" no_log: true - - name: Create timestamped backups of existing values.yaml files - block: - - name: Check if values.yaml file exists before backup - stat: - path: "{{ item.item.path }}/values.yaml" - register: values_file_stat - loop: "{{ demo_values_stat.results }}" - no_log: true - - - name: Create backup with timestamp - shell: | - #!/bin/bash - source_file="{{ item.item.path }}/values.yaml" - backup_file="{{ item.item.path }}/values.yaml.bak.{{ lookup('pipe', 'date +%Y%m%d_%H%M%S') }}" - if [ -f "$source_file" ]; then - mv "$source_file" "$backup_file" - fi - args: - executable: /bin/bash - when: item.stat.exists - loop: "{{ demo_values_stat.results }}" - register: backup_result - no_log: true + - name: Display backup and initialization summary + debug: + msg: "{{ init_result.results | map(attribute='stdout_lines') | flatten | list }}" + when: init_result.results | length > 0 - - name: Initialize values.yaml from demo template for each chart - copy: - src: "{{ item.item.path }}/demo-values.example.yaml" - dest: "{{ item.item.path }}/values.yaml" - remote_src: yes - when: item.stat.exists - loop: "{{ demo_values_stat.results }}" - no_log: true when: wire_values_changed - name: Update core Wire service Helm chart values diff --git a/bin/offline-env-wiab.sh b/bin/offline-env-wiab.sh index 3607eace3..59ec26ec7 100644 --- a/bin/offline-env-wiab.sh +++ b/bin/offline-env-wiab.sh @@ -9,21 +9,28 @@ check_or_load_image() { # Check if any image matching pattern exists in docker local existing_image - existing_image=$(sudo docker images --format "{{.Repository}}:{{.Tag}}" | grep "$image_pattern" | head -1) + existing_image=$(sudo docker images --format "{{.Repository}}:{{.Tag}}" | grep -F "$image_pattern" | head -1) if [[ -n "$existing_image" ]]; then echo "$existing_image" return 0 fi # If no existing image, load from tar - sudo docker load -i "$tar_file" | awk '{print $3}' + if [[ -z "$tar_file" || ! -f "$tar_file" ]]; then + echo "Tar file does not exist: $tar_file, skipping" >&2 + else + sudo docker load -i "$tar_file" | awk '{print $3}' + fi } +ZAUTH_TAR=$(find "$SCRIPT_DIR/../containers-adminhost" -maxdepth 1 -name "quay.io_wire_zauth_*.tar" -type f | sort | tail -1) + # Get container image names efficiently -ZAUTH_CONTAINER=$(check_or_load_image "$SCRIPT_DIR/../containers-adminhost/quay.io_wire_zauth_"*.tar "quay.io/wire/zauth") -WSD_CONTAINER=$(check_or_load_image "$SCRIPT_DIR/../containers-adminhost/container-wire-server-deploy.tgz" "quay.io/wire/wire-server-deploy") +ZAUTH_CONTAINER=$(check_or_load_image "$ZAUTH_TAR" "quay.io/wire/zauth") || true +WSD_CONTAINER=$(check_or_load_image "$SCRIPT_DIR/../containers-adminhost/container-wire-server-deploy.tgz" "quay.io/wire/wire-server-deploy") || true -export ZAUTH_CONTAINER +# Export only if ZAUTH_CONTAINER is not empty +[[ -n "$ZAUTH_CONTAINER" ]] && export ZAUTH_CONTAINER # detect if d should run interactively d() { diff --git a/bin/wiab-demo/offline_deploy_k8s.sh b/bin/wiab-demo/offline_deploy_k8s.sh deleted file mode 100644 index 151ce624e..000000000 --- a/bin/wiab-demo/offline_deploy_k8s.sh +++ /dev/null @@ -1,223 +0,0 @@ -#!/usr/bin/env bash -# shellcheck disable=SC2087 -set -Eeo pipefail - -# Read values from environment variables with defaults -BASE_DIR="${BASE_DIR:-/wire-server-deploy}" -TARGET_SYSTEM="${TARGET_SYSTEM:-example.com}" -CERT_MASTER_EMAIL="${CERT_MASTER_EMAIL:-certmaster@example.com}" - -# this IP should match the DNS A record value for TARGET_SYSTEM -HOST_IP="${HOST_IP:-}" - -# make sure these align with the iptables rules -SFT_NODE="${SFT_NODE:-}" -# picking a node for nginx -NGINX_K8S_NODE="${NGINX_K8S_NODE:-}" -# picking a node for coturn -COTURN_NODE="${COTURN_NODE:-}" - -# Validate that required environment variables are set -# Usage: validate_required_vars VAR_NAME1 VAR_NAME2 ... -validate_required_vars() { - local error=0 - - for var_name in "$@"; do - if [[ -z "${!var_name:-}" ]]; then - echo "$var_name environment variable is not set." - error=1 - fi - done - - if [[ $error -eq 1 ]]; then - exit 1 - fi -} - -# Creates values.yaml from demo-values.example.yaml and secrets.yaml from demo-secrets.example.yaml -# This script is for WIAB/demo deployments only -# Works on all chart directories in $BASE_DIR/values/ -process_charts() { - - ENV=$1 - TYPE=$2 - - if [[ "$ENV" != "demo" ]] || [[ -z "$TYPE" ]] ; then - echo "Error: This function only supports demo deployments with TYPE as values or secrets. ENV must be 'demo', got: '$ENV' and '$TYPE'" - exit 1 - fi - timestp=$(date +"%Y%m%d_%H%M%S") - for chart_dir in "$BASE_DIR"/values/*/; do - - if [[ -d "$chart_dir" ]]; then - if [[ -f "$chart_dir/${ENV}-${TYPE}.example.yaml" ]]; then - if [[ ! -f "$chart_dir/${TYPE}.yaml" ]]; then - cp "$chart_dir/${ENV}-${TYPE}.example.yaml" "$chart_dir/${TYPE}.yaml" - echo "Used template ${ENV}-${TYPE}.example.yaml to create $chart_dir/${TYPE}.yaml" - else - echo "$chart_dir/${TYPE}.yaml already exists, archiving it and creating a new one." - mv "$chart_dir/${TYPE}.yaml" "$chart_dir/${TYPE}.yaml.bak.$timestp" - cp "$chart_dir/${ENV}-${TYPE}.example.yaml" "$chart_dir/${TYPE}.yaml" - fi - fi - fi - done -} - -# selectively setting values of following charts which requires additional values -# wire-server, webapp, team-settings, account-pages, nginx-ingress-services, ingress-nginx-controller, sftd and coturn -process_values() { - validate_required_vars HOST_IP SFT_NODE NGINX_K8S_NODE COTURN_NODE - - TEMP_DIR=$(mktemp -d) - trap 'rm -rf $TEMP_DIR' EXIT - - # to find IP address of coturn NODE - COTURN_NODE_IP=$(kubectl get node "$COTURN_NODE" -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}') - - # Fixing the hosts with TARGET_SYSTEM and setting the turn server - sed -e "s/example.com/$TARGET_SYSTEM/g" \ - "$BASE_DIR/values/wire-server/values.yaml" > "$TEMP_DIR/wire-server-values.yaml" - - # fixing the turnStatic values - yq eval -i ".brig.turnStatic.v2 = [\"turn:$HOST_IP:3478\", \"turn:$HOST_IP:3478?transport=tcp\"]" "$TEMP_DIR/wire-server-values.yaml" - - # Fixing the hosts in webapp team-settings and account-pages charts - for chart in webapp team-settings account-pages; do - sed "s/example.com/$TARGET_SYSTEM/g" "$BASE_DIR/values/$chart/values.yaml" > "$TEMP_DIR/$chart-values.yaml" - done - - # Setting certManager and DNS records - sed -e 's/useCertManager: false/useCertManager: true/g' \ - -e "/certmasterEmail:$/s/certmasterEmail:/certmasterEmail: $CERT_MASTER_EMAIL/" \ - -e "s/example.com/$TARGET_SYSTEM/" \ - "$BASE_DIR/values/nginx-ingress-services/values.yaml" > "$TEMP_DIR/nginx-ingress-services-values.yaml" - - # adding nodeSelector for ingress controller as it should run as Deployment in the k8s cluster i.e. lack of external load balancer - sed -e 's/kind: DaemonSet/kind: Deployment/' \ - "$BASE_DIR/values/ingress-nginx-controller/values.yaml" > "$TEMP_DIR/ingress-nginx-controller-values.yaml" - if ! grep -q "kubernetes.io/hostname: $NGINX_K8S_NODE" "$TEMP_DIR/ingress-nginx-controller-values.yaml"; then - echo -e " nodeSelector:\n kubernetes.io/hostname: $NGINX_K8S_NODE" >> "$TEMP_DIR/ingress-nginx-controller-values.yaml" - fi - - # Fixing SFTD hosts and setting the cert-manager to http01 - sed -e "s/webapp.example.com/webapp.$TARGET_SYSTEM/" \ - -e "s/sftd.example.com/sftd.$TARGET_SYSTEM/" \ - -e 's/name: letsencrypt-prod/name: letsencrypt-http01/' \ - "$BASE_DIR/values/sftd/values.yaml" > "$TEMP_DIR/sftd-values.yaml" - - # Setting coturn node IP values - yq eval -i ".coturnTurnListenIP = \"$COTURN_NODE_IP\"" "$BASE_DIR/values/coturn/values.yaml" - yq eval -i ".coturnTurnRelayIP = \"$COTURN_NODE_IP\"" "$BASE_DIR/values/coturn/values.yaml" - yq eval -i ".coturnTurnExternalIP = \"$HOST_IP\"" "$BASE_DIR/values/coturn/values.yaml" - - # Compare and copy files if different - for file in wire-server-values.yaml webapp-values.yaml team-settings-values.yaml account-pages-values.yaml \ - nginx-ingress-services-values.yaml ingress-nginx-controller-values.yaml sftd-values.yaml; do - if ! cmp -s "$TEMP_DIR/$file" "$BASE_DIR/values/${file%-values.yaml}/values.yaml"; then - cp "$TEMP_DIR/$file" "$BASE_DIR/values/${file%-values.yaml}/values.yaml" - echo "Updating $BASE_DIR/values/${file%-values.yaml}/values.yaml" - fi - done - -} - -deploy_charts() { - - local charts=("$@") - echo "Following charts will be deployed: ${charts[*]}" - - for chart in "${charts[@]}"; do - chart_dir="$BASE_DIR/charts/$chart" - values_file="$BASE_DIR/values/$chart/values.yaml" - secrets_file="$BASE_DIR/values/$chart/secrets.yaml" - - if [[ ! -d "$chart_dir" ]]; then - echo "Error: Chart directory $chart_dir does not exist." - continue - fi - - if [[ ! -f "$values_file" ]]; then - echo "Warning: Values file $values_file does not exist. Deploying without values." - values_file="" - fi - - if [[ ! -f "$secrets_file" ]]; then - secrets_file="" - fi - - helm_command="helm upgrade --install --wait --timeout=15m0s $chart $chart_dir" - - if [[ -n "$values_file" ]]; then - helm_command+=" --values $values_file" - fi - - if [[ -n "$secrets_file" ]]; then - helm_command+=" --values $secrets_file" - fi - - # handle wire-server to inject PostgreSQL password from databases-ephemeral - if [[ "$chart" == "wire-server" ]]; then - - echo "Retrieving PostgreSQL password from databases-ephemeral for wire-server deployment..." - if kubectl get secret wire-postgresql-secret &>/dev/null; then - # Usage: sync-k8s-secret-to-wire-secrets.sh - "$BASE_DIR/bin/sync-k8s-secret-to-wire-secrets.sh" \ - wire-postgresql-secret password \ - "$BASE_DIR/values/wire-server/secrets.yaml" \ - .brig.secrets.pgPassword .galley.secrets.pgPassword - else - echo "⚠️ Warning: PostgreSQL secret 'wire-postgresql-secret' not found, skipping secret sync" - echo " Make sure databases-ephemeral chart is deployed before wire-server" - fi - fi - - echo "Deploying $chart as $helm_command" - eval "$helm_command" - done - - # display running pods post deploying all helm charts in default namespace - kubectl get pods --sort-by=.metadata.creationTimestamp -} - -deploy_cert_manager() { - - kubectl get namespace cert-manager-ns || kubectl create namespace cert-manager-ns - helm upgrade --install -n cert-manager-ns cert-manager "$BASE_DIR/charts/cert-manager" --values "$BASE_DIR/values/cert-manager/values.yaml" - - # display running pods - kubectl get pods --sort-by=.metadata.creationTimestamp -n cert-manager-ns -} - -deploy_calling_services() { - validate_required_vars SFT_NODE HOST_IP COTURN_NODE - - echo "Deploying sftd and coturn" - # select the node to deploy sftd - kubectl annotate node "$SFT_NODE" wire.com/external-ip="$HOST_IP" --overwrite - helm upgrade --install sftd "$BASE_DIR/charts/sftd" --set "nodeSelector.kubernetes\\.io/hostname=$SFT_NODE" --values "$BASE_DIR/values/sftd/values.yaml" - - kubectl annotate node "$COTURN_NODE" wire.com/external-ip="$HOST_IP" --overwrite - helm upgrade --install coturn "$BASE_DIR/charts/coturn" --set "nodeSelector.kubernetes\\.io/hostname=$COTURN_NODE" --values "$BASE_DIR/values/coturn/values.yaml" --values "$BASE_DIR/values/coturn/secrets.yaml" -} - -# if required, this function can be run manually -run_manually() { -# process_charts processes demo values for WIAB deployment -process_charts "demo" -process_values -# deploying cert manager to issue certs, by default letsencrypt-http01 issuer is configured -deploy_cert_manager - -# deploying with external datastores, useful for prod setup -#deploy_charts cassandra-external elasticsearch-external minio-external fake-aws smtp rabbitmq databases-ephemeral reaper wire-server webapp account-pages team-settings smallstep-accomp ingress-nginx-controller nginx-ingress-services - -# deploying with ephemeral datastores, useful for all k8s setup withou external datastore requirement -deploy_charts fake-aws smtp rabbitmq databases-ephemeral reaper wire-server webapp account-pages team-settings smallstep-accomp ingress-nginx-controller nginx-ingress-services - -# deploying sft and coturn services -deploy_calling_services - -# print status of certs -kubectl get certificate -} \ No newline at end of file diff --git a/changelog.d/3-deploy-builds/demo-wiab-ansible-only b/changelog.d/3-deploy-builds/demo-wiab-ansible-only index d84de9833..d16158884 100644 --- a/changelog.d/3-deploy-builds/demo-wiab-ansible-only +++ b/changelog.d/3-deploy-builds/demo-wiab-ansible-only @@ -5,3 +5,4 @@ Added: helm secrets handling moved from offline_deploy_k8s.sh to wire_secrets pl Changed: added helm and kubernetes packages to install_pkgs, converted native kubectl commands to ansible native tasks Changed: improved wiab-demo documentation and refactored clean_cluster playbook according to new changes Removed: zauth container from demo bundle, copy only offline-env.sh +Fixed: Pip --break-system-packages fix for k8s python module management and general optimzations diff --git a/offline/demo-wiab.md b/offline/demo-wiab.md index 90867aa97..a7dc81e05 100644 --- a/offline/demo-wiab.md +++ b/offline/demo-wiab.md @@ -121,8 +121,7 @@ The deployment process follows these steps as defined in the main playbook: - kubernetes >= 18.0.0 (Kubernetes Python client) - pyyaml >= 5.4.1 (YAML parser) -> **Note on PEP668 Override:** Python packages are installed using `--break-system-packages` flag to override [PEP668](https://peps.python.org/pep-0668/) constraints on Ubuntu 24.04. This is necessary because the deployment requires system-wide access to Ansible Python modules (kubernetes, pyyaml) for infrastructure provisioning. The playbook installs these packages system-wide rather than in virtual environments to ensure they are available in the Ansible execution context. - +> **Virtual Environment Approach:** Python packages are installed in an isolated virtual environment at `/opt/ansible-venv` instead of system-wide installation. This eliminates conflicts with system Python packages and respects [PEP668](https://peps.python.org/pep-0668/) constraints on Ubuntu 24.04. The playbook automatically detects the best Python interpreter available (system Python if kubernetes is installed, or venv otherwise) and configures Ansible accordingly. If neither has the kubernetes module, it fails with clear remediation instructions. ### 4. SSH Key Management (Automatic Dependency) @@ -137,20 +136,20 @@ The deployment process follows these steps as defined in the main playbook: - All minikube configurable parameters are available in [host.yml](../ansible/inventory/demo/host.yml) - Can be skipped using `--skip-tags minikube` -### 7. IPTables Rules +### 6. IPTables Rules - Imports [iptables_rules.yml](../ansible/wiab-demo/iptables_rules.yml) to configure network rules on deploy_node - Configures network forwarding and postrouting rules to route traffic to k8s node - Runs automatically with `--tags minikube` - Can be skipped using `--skip-tags minikube` -### 8. Wire Artifact Download +### 7. Wire Artifact Download - Imports [download_artifact.yml](../ansible/wiab-demo/download_artifact.yml) to fetch the Wire components - Required to download all artifacts needed for further installation - Can be skipped using `--skip-tags download` -### 9. Minikube Node Inventory Setup (Automatic Dependency) +### 8. Minikube Node Inventory Setup (Automatic Dependency) - Adds Minikube node(s) to Ansible inventory dynamically - Extracts internal IP addresses from all Kubernetes nodes @@ -159,19 +158,19 @@ The deployment process follows these steps as defined in the main playbook: - Creates temporary directory for SSH keys on localhost - Cannot be run independently or skipped manually - controlled entirely by dependent components -### 10. Asset Host Setup +### 9. Asset Host Setup - Imports [setup-offline-sources.yml](../ansible/setup-offline-sources.yml) to configure the asset host - Offers Wire deployment artifacts as HTTP service for installation - Can be skipped using `--skip-tags asset_host` -### 11. Container Seeding +### 10. Container Seeding - Imports [seed-offline-containerd.yml](../ansible/seed-offline-containerd.yml) to seed containers in K8s cluster nodes - Seeds Docker images shipped for Wire-related Helm charts in the Minikube K8s node - Can be skipped using `--skip-tags seed_containers` -### 12. Wire Helm Chart Values Preparation +### 11. Wire Helm Chart Values Preparation - Imports [wire_values.yml](../ansible/wiab-demo/wire_values.yml) to prepare Helm chart values - Updates configurations for: @@ -183,7 +182,7 @@ The deployment process follows these steps as defined in the main playbook: - The playbook backs up existing values files before replacing them - Uses idempotency checks to avoid unnecessary updates -### 13. Wire Secrets Creation +### 12. Wire Secrets Creation - Imports [wire_secrets.yml](../ansible/wiab-demo/wire_secrets.yml) to create required secrets for Wire Helm charts - Generates: @@ -195,7 +194,7 @@ The deployment process follows these steps as defined in the main playbook: - If existing secret files are present, the playbook backs them up before replacing them - Can be skipped using `--skip-tags wire_secrets` -### 14. Helm Chart Installation +### 13. Helm Chart Installation - Imports [helm_install.yml](../ansible/wiab-demo/helm_install.yml) to deploy Wire components using Helm - Deploys core charts: fake-aws, smtp, rabbitmq, databases, postgresql, reaper, wire-server, webapp, and more @@ -203,13 +202,11 @@ The deployment process follows these steps as defined in the main playbook: - Reports deployment status and pod health - Can be skipped using `--skip-tags helm_install` -### 15. Cert Manager Hairpin Networking Configuration - -- Imports [hairpin_networking.yml](../ansible/wiab-demo/hairpin_networking.yml) -- Configures hairpin (NAT) behavior on the host so workloads (pods) can reach external/public IPs that resolve back to the same node -- **Always runs when** `use_cert_manager` is true +**Cert Manager Hairpin Networking Configuration:** +- If `use_cert_manager` is true, automatically configures hairpin (NAT) behavior on the host so workloads (pods) can reach external/public IPs that resolve back to the same node +- Runs automatically at the end of helm chart installation when cert-manager is enabled -### 16. Temporary Cleanup +### 14. Temporary Cleanup - Locates all temporary SSH key directories created during deployment - Lists and removes these directories @@ -303,8 +300,7 @@ The following tags are available for controlling playbook execution: | `seed_containers` | Container seeding | Minikube node inventory setup | Yes (`--skip-tags seed_containers`) | | `wire_values` | Setup Wire Helm values | None | Yes (`--skip-tags wire_values`) | | `wire_secrets` | Create Wire secrets | None | Yes (`--skip-tags wire_secrets`) | -| `helm_install` | Helm chart installation | None | Yes (`--skip-tags helm_install`) | -| `cert_manager_networking` | Cert Manager hairpin networking | None | Yes (`use_cert_manager=true`) | +| `helm_install` | Helm chart installation + cert-manager hairpin networking | None | Yes (`--skip-tags helm_install`) | | `cleanup` | Temporary file cleanup | None | Yes (`--skip-tags cleanup`) |