diff --git a/ansible/group_vars/bridge-status-test.yml b/ansible/group_vars/bridge-status-test.yml new file mode 100644 index 0000000..fce84a2 --- /dev/null +++ b/ansible/group_vars/bridge-status-test.yml @@ -0,0 +1,26 @@ +--- +nim_waku_bridge_service_name: 'nim-waku-bridge' +nim_waku_bridge_cont_tag: 'deploy-bridge-{{ stage }}' +nim_waku_bridge_log_level: 'info' +nim_waku_bridge_v1_fleet_name: '{{ stage }}' + +# Ports +nim_waku_bridge_libp2p_port: 9000 +nim_waku_bridge_devp2p_port: 30303 +nim_waku_bridge_metrics_port: 8008 +nim_waku_bridge_rpc_tcp_port: 8545 + +# Node Keys +#nim_waku_bridge_nodekey_v1: ~ +#nim_waku_bridge_nodekey_v2: ~ + +# Open LibP2P Ports +open_ports_default_comment: '{{ nim_waku_bridge_service_name }}' +open_ports_default_protocol: 'tcp' +open_ports_default_chain: 'SERVICES' +open_ports_list: + - { port: '{{ nim_waku_bridge_libp2p_port }}' } + - { port: '{{ nim_waku_bridge_devp2p_port }}' } + - { port: '{{ nim_waku_bridge_metrics_port }}', chain: 'VPN', ipset: 'metrics.hq' } + - { port: '{{ nim_waku_bridge_rpc_tcp_port }}', chain: 'VPN', ipset: '{{ env }}.{{ stage }}' } + diff --git a/ansible/group_vars/status.prod.yml b/ansible/group_vars/status-prod.yml similarity index 100% rename from ansible/group_vars/status.prod.yml rename to ansible/group_vars/status-prod.yml diff --git a/ansible/group_vars/status.test.yml b/ansible/group_vars/status-test.yml similarity index 100% rename from ansible/group_vars/status.test.yml rename to ansible/group_vars/status-test.yml diff --git a/ansible/main.yml b/ansible/main.yml index 8eff4fa..4c303c7 100644 --- a/ansible/main.yml +++ b/ansible/main.yml @@ -11,9 +11,18 @@ - name: Configure Waku Nodes hosts: - - status.test - - status.prod + - status-test + - status-prod roles: - - { role: open-ports, tags: open-ports } - - { role: swap-file, tags: swap-file } - - { role: nim-waku, tags: nim-waku } + - { role: open-ports, tags: open-ports } + - { role: swap-file, tags: swap-file } + - { role: nim-waku, tags: nim-waku } + +- name: Configure Waku V1-V2 bridge + hosts: + - bridge-status-test + - bridge-status-prod + roles: + - { role: open-ports, tags: open-ports } + - { role: swap-file, tags: swap-file } + - { role: nim-waku-bridge, tags: nim-waku-bridge } diff --git a/ansible/roles/nim-waku-bridge/README.md b/ansible/roles/nim-waku-bridge/README.md new file mode 100644 index 0000000..df6987b --- /dev/null +++ b/ansible/roles/nim-waku-bridge/README.md @@ -0,0 +1,23 @@ +# Description + +This role configures `nim-waku` [bridge](https://github.com/status-im/nim-waku/blob/master/waku/common/config_bridge.nim) service which bridges messages from old Waku v1 fleet running `status-go`(`eth.test`, `eth.prod`) to the new Waku v2 fleets(`status.test`, `status.prod`). + +# Configuration + +Bare minimum would include: +```yaml +nim_waku_bridge_service_name: 'nim-waku-bridge' +nim_waku_bridge_cont_tag: 'deploy-bridge-test' +nim_waku_bridge_log_level: 'info' +nim_waku_bridge_v1_fleet_name: 'test' +# Secret +nim_waku_bridge_nodekey_v1: 'super-secret-v1-nodekey' +nim_waku_bridge_nodekey_v2: 'super-secret-v2-nodekey' +``` + +# Management + +# Links + +* https://github.com/status-im/infra-status/issues/4 +* https://github.com/status-im/nim-waku/blob/master/docs/tutorial/bridge.md diff --git a/ansible/roles/nim-waku-bridge/defaults/main.yml b/ansible/roles/nim-waku-bridge/defaults/main.yml new file mode 100644 index 0000000..10b55a0 --- /dev/null +++ b/ansible/roles/nim-waku-bridge/defaults/main.yml @@ -0,0 +1,35 @@ +--- +nim_waku_bridge_service_name: 'nim-waku-bridge' +nim_waku_bridge_service_path: '/docker/{{ nim_waku_bridge_service_name }}' +nim_waku_bridge_compose_path: '{{ nim_waku_bridge_service_path }}/docker-compose.yml' + +nim_waku_bridge_cont_name: '{{ nim_waku_bridge_service_name }}' +nim_waku_bridge_cont_vol: '{{ nim_waku_bridge_service_path }}/data' +nim_waku_bridge_cont_tag: 'latest' +nim_waku_bridge_cont_image: 'statusteam/nim-waku:{{ nim_waku_bridge_cont_tag }}' + +# Available: error, warn, info, debug +nim_waku_bridge_log_level: 'info' + +# Node Keys +#nim_waku_bridge_nodekey_v1: ~ +#nim_waku_bridge_nodekey_v2: ~ + +# Sync +nim_waku_bridge_v1_fleet_name: 'test' + +# Visibility +nim_waku_bridge_dns_domain_name: '{{ dns_entry }}' +nim_waku_bridge_public_address: '{{ ansible_host }}' + +# Ports +nim_waku_bridge_libp2p_port: 9000 +nim_waku_bridge_devp2p_port: 30303 +nim_waku_bridge_metrics_port: 8008 +nim_waku_bridge_rpc_tcp_port: 8545 +nim_waku_bridge_rpc_tcp_addr: '127.0.0.1' + +# general container management +compose_recreate: 'smart' +compose_state: 'present' +compose_restart: false diff --git a/ansible/roles/nim-waku-bridge/tasks/consul.yml b/ansible/roles/nim-waku-bridge/tasks/consul.yml new file mode 100644 index 0000000..2ebe05a --- /dev/null +++ b/ansible/roles/nim-waku-bridge/tasks/consul.yml @@ -0,0 +1,39 @@ +--- + +- name: 'Consul service definition - {{ nim_waku_bridge_cont_name }}' + include_role: name=consul-service + vars: + consul_config_name: '{{ nim_waku_bridge_cont_name | replace("-", "_") }}' + consul_services: + - id: '{{ nim_waku_bridge_cont_name }}' + name: '{{ nim_waku_bridge_cont_name }}' + port: '{{ nim_waku_bridge_libp2p_port }}' + address: '{{ ansible_host }}' + tags: ['env:{{ env }}', 'stage:{{ stage }}', 'nim', 'waku', 'bridge'] + meta: + node_enode: '{{ nim_waku_bridge_libp2p_multiaddr | default("unknown") }}' + checks: + - name: '{{ nim_waku_bridge_cont_name }}-libp2p-health' + type: 'tcp' + tcp: 'localhost:{{ nim_waku_bridge_libp2p_port }}' + - name: '{{ nim_waku_bridge_cont_name }}-devp2p-health' + type: 'tcp' + tcp: 'localhost:{{ nim_waku_bridge_devp2p_port }}' + + - id: '{{ nim_waku_bridge_cont_name }}-metrics' + name: '{{ nim_waku_bridge_cont_name }}-metrics' + port: '{{ nim_waku_bridge_metrics_port }}' + address: '{{ ansible_local.wireguard.vpn_ip }}' + tags: ['env:{{ env }}', 'stage:{{ stage }}', 'nim', 'waku', 'bridge', 'metrics'] + meta: + container: '{{ nim_waku_bridge_cont_name }}' + checks: + - name: 'beacon-node-metrics-health' + type: 'http' + http: 'http://localhost:{{ nim_waku_bridge_metrics_port }}/health' + + - id: '{{ nim_waku_bridge_cont_name }}-rpc' + name: '{{ nim_waku_bridge_cont_name }}-rpc' + port: '{{ nim_waku_bridge_rpc_tcp_port }}' + address: '{{ ansible_local.wireguard.vpn_ip }}' + tags: ['env:{{ env }}', 'stage:{{ stage }}', 'nim', 'waku', 'bridge', 'rpc'] diff --git a/ansible/roles/nim-waku-bridge/tasks/docker.yml b/ansible/roles/nim-waku-bridge/tasks/docker.yml new file mode 100644 index 0000000..7fb3931 --- /dev/null +++ b/ansible/roles/nim-waku-bridge/tasks/docker.yml @@ -0,0 +1,34 @@ +--- +- name: 'Create service folder' + file: + dest: '{{ nim_waku_bridge_service_path }}' + state: 'directory' + owner: dockremap + group: docker + mode: 0775 + +- name: Create script for calling RPC endpoint + template: + src: 'rpc.sh.j2' + dest: '{{ nim_waku_bridge_service_path }}/rpc.sh' + owner: dockremap + group: docker + mode: 0755 + +- name: 'Create compose file: {{ nim_waku_bridge_cont_name }}' + template: + src: 'docker-compose.yml.j2' + dest: '{{ nim_waku_bridge_compose_path }}' + owner: dockremap + group: docker + mode: 0644 + +- name: 'Create container: {{ nim_waku_bridge_cont_name }}' + docker_compose: + project_src: '{{ nim_waku_bridge_service_path }}' + pull: true + state: '{{ compose_state }}' + restarted: '{{ compose_restart }}' + recreate: '{{ compose_recreate }}' + # Avoid deprecation warning + tls_hostname: 'localhost' diff --git a/ansible/roles/nim-waku-bridge/tasks/main.yml b/ansible/roles/nim-waku-bridge/tasks/main.yml new file mode 100644 index 0000000..b91bd64 --- /dev/null +++ b/ansible/roles/nim-waku-bridge/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- import_tasks: docker.yml +- import_tasks: consul.yml diff --git a/ansible/roles/nim-waku-bridge/templates/docker-compose.yml.j2 b/ansible/roles/nim-waku-bridge/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..0bdf339 --- /dev/null +++ b/ansible/roles/nim-waku-bridge/templates/docker-compose.yml.j2 @@ -0,0 +1,37 @@ +--- +version: '3.7' +services: + node: + container_name: '{{ nim_waku_bridge_cont_name }}' + image: '{{ nim_waku_bridge_cont_image }}' + labels: + # auto-updating of docker image + com.centurylinklabs.watchtower.enable: 'true' + restart: 'always' + volumes: + - '{{ nim_waku_bridge_cont_vol }}:/data' + ports: + - '{{ nim_waku_bridge_libp2p_port }}:{{ nim_waku_bridge_libp2p_port }}/tcp' + - '{{ nim_waku_bridge_devp2p_port }}:{{ nim_waku_bridge_devp2p_port }}/tcp' + - '{{ nim_waku_bridge_metrics_port }}:{{ nim_waku_bridge_metrics_port }}/tcp' + - '{{ nim_waku_bridge_rpc_tcp_addr }}:{{ nim_waku_bridge_rpc_tcp_port }}:{{ nim_waku_bridge_rpc_tcp_port }}/tcp' + command: | + --log-level={{ nim_waku_bridge_log_level }} + --relay + --listen-address=0.0.0.0 + --libp2p-tcp-port={{ nim_waku_bridge_libp2p_port }} + --devp2p-tcp-port={{ nim_waku_bridge_devp2p_port }} + --nat=extip:{{ nim_waku_bridge_public_address }} + --rpc + --rpc-address={{ nim_waku_bridge_rpc_tcp_addr }} + --rpc-port={{ nim_waku_bridge_rpc_tcp_port }} + --metrics-server + --metrics-server-port={{ nim_waku_bridge_metrics_port }} + --metrics-server-address=0.0.0.0 + --fleet-v1={{ nim_waku_bridge_v1_fleet_name }} +{% if nim_waku_bridge_nodekey_v1 is defined %} + --nodekey-v1={{ nim_waku_bridge_nodekey_v1 }} +{% endif %} +{% if nim_waku_bridge_nodekey_v2 is defined %} + --nodekey-v2={{ nim_waku_bridge_nodekey_v2 }} +{% endif %} diff --git a/ansible/roles/nim-waku-bridge/templates/rpc.sh.j2 b/ansible/roles/nim-waku-bridge/templates/rpc.sh.j2 new file mode 100644 index 0000000..1b6c7c4 --- /dev/null +++ b/ansible/roles/nim-waku-bridge/templates/rpc.sh.j2 @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# vim: set ft=sh: + +URL="http://localhost:{{ nim_waku_bridge_rpc_tcp_port }}/" + +METHOD="$1" +shift +PARAMS=("$@") + +if [[ -z "${METHOD}" ]]; then + echo "No method specified!" >&2 + exit 1 +fi +if [[ -n "${PARAMS}" ]]; then + PARAMS_STR=$(printf '%s\",\"' "${PARAMS[@]}") + # Params are a nested array because of a bug in nim-json-rpc. + # https://github.com/status-im/nim-json-rpc/issues/90 + PARAMS_STR="[\"${PARAMS_STR%%\",\"}\"]" +else + PARAMS_STR='' +fi + +PAYLOAD="{ + \"id\": 1, + \"jsonrpc\": \"2.0\", + \"method\": \"${METHOD}\", + \"params\": [${PARAMS_STR}] +}" + +# The jq script checks if error exists and adjusts exit code. +curl -f -s -X POST \ + -H "Content-type:application/json" \ + --data "${PAYLOAD}" \ + "${URL}" | \ + jq -e '., if .error != null then null|halt_error(2) else halt end'