diff --git a/.circleci/config.yml b/.circleci/config.yml index f9b59e13..3af49ab4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -120,6 +120,20 @@ jobs: key: initialize-{{ .Environment.CIRCLE_SHA1 }} - run: yarn workspace ui run coverage - run: yarn workspace ui run coveralls + deployment: + machine: + image: circleci/classic:latest + docker_layer_caching: true + steps: + - checkout + - run: git submodule update --init + - run: sudo add-apt-repository ppa:jonathonf/python-3.6 -y + - run: sudo apt-get update + - run: sudo apt-get install python3.6 -y + - run: sudo apt-get install python3-pip python3.6-dev -y + - run: cd deployment && virtualenv -p python3.6 venv + - run: cd deployment && source venv/bin/activate && pip install -r requirements.txt + - run: cd deployment && source venv/bin/activate && molecule test workflows: version: 2 tokenbridge: @@ -148,3 +162,4 @@ workflows: - oracle-e2e - ui-e2e - monitor-e2e + - deployment diff --git a/.gitignore b/.gitignore index 573856b3..507a4afd 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,8 @@ hosts Vagrantfile vagrant-hosts.yml .vagrant +deployment/venv +__pycache__ #monitor monitor/responses/* diff --git a/deployment/.yamllint b/deployment/.yamllint new file mode 100644 index 00000000..ad0be760 --- /dev/null +++ b/deployment/.yamllint @@ -0,0 +1,11 @@ +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + line-length: disable + truthy: disable diff --git a/deployment/CONFIGURATION.md b/deployment/CONFIGURATION.md index 00fa7034..39208459 100644 --- a/deployment/CONFIGURATION.md +++ b/deployment/CONFIGURATION.md @@ -25,11 +25,13 @@ cp hosts.yml.example hosts.yml ```yaml : - hosts: + children: + oracle: + hosts: : - ansible_user: - VALIDATOR_ADDRESS_PRIVATE_KEY: "" - #syslog_server_port: "://:" # When this parameter is set all bridge logs will be redirected to : address. + ansible_user: + VALIDATOR_ADDRESS_PRIVATE_KEY: "" + #syslog_server_port: "://:" # When this parameter is set all bridge logs will be redirected to : address. ``` | Value | Description | diff --git a/deployment/README.md b/deployment/README.md index 79aedc20..0c13c240 100644 --- a/deployment/README.md +++ b/deployment/README.md @@ -14,11 +14,9 @@ Please refer to [Configuration](./CONFIGURATION.md). Please refer to [Execution](./EXECUTION.md). -## Linting +## Testing -- [ansible-lint](https://github.com/ansible/ansible-lint) is required - -`yarn ansible-lint` +Please refer to [Testing](./TESTING.md). ## Contributing diff --git a/deployment/TESTING.md b/deployment/TESTING.md new file mode 100644 index 00000000..5bd829c7 --- /dev/null +++ b/deployment/TESTING.md @@ -0,0 +1,24 @@ +# POA Token Bridge / Deployment Testing + +The deployment playbooks are tested using [Molecule](https://molecule.readthedocs.io). + +## Prepare virtual python environment + +``` +command -v virtualenv || pip3 install virtualenv +virtualenv -p python3 venv +source venv/bin/activate +pip install -r requirements.txt +``` + +## Run the tests + +``` +molecule test +``` + +## Exit the virtual environment + +``` +deactivate +``` diff --git a/deployment/hosts.yml.example b/deployment/hosts.yml.example index 7ef141fa..de9c2feb 100644 --- a/deployment/hosts.yml.example +++ b/deployment/hosts.yml.example @@ -1,6 +1,8 @@ sokol-kovan: - hosts: + children: + oracle: + hosts: 127.0.0.1: - ansible_user: ubuntu - VALIDATOR_ADDRESS_PRIVATE_KEY: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - #syslog_server_port: "udp://127.0.0.1:514" + ansible_user: ubuntu + VALIDATOR_ADDRESS_PRIVATE_KEY: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + #syslog_server_port: "udp://127.0.0.1:514" diff --git a/deployment/molecule/default/Dockerfile.j2 b/deployment/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..e6aa95d3 --- /dev/null +++ b/deployment/molecule/default/Dockerfile.j2 @@ -0,0 +1,14 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi diff --git a/deployment/molecule/default/molecule.yml b/deployment/molecule/default/molecule.yml new file mode 100644 index 00000000..497030fc --- /dev/null +++ b/deployment/molecule/default/molecule.yml @@ -0,0 +1,49 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + enabled: False +platforms: + - name: oracle-host + groups: + - example + children: + - oracle + image: ubuntu:16.04 + privileged: true + network_mode: host + volumes: + - /var/run/docker.sock:/var/run/docker.sock +provisioner: + name: ansible + lint: + name: ansible-lint + enabled: False + playbooks: + prepare: prepare.yml + converge: ../../site.yml + inventory: + host_vars: + oracle-host: + VALIDATOR_ADDRESS_PRIVATE_KEY: "8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9" + syslog_server_port: "udp://127.0.0.1:514" +verifier: + name: testinfra + lint: + name: flake8 +scenario: + name: default + test_sequence: + - lint + - cleanup + - destroy + - dependency + - syntax + - create + - prepare + - converge + - verify + - destroy diff --git a/deployment/molecule/default/prepare.yml b/deployment/molecule/default/prepare.yml new file mode 100644 index 00000000..dc31772e --- /dev/null +++ b/deployment/molecule/default/prepare.yml @@ -0,0 +1,13 @@ +--- +- name: prepare + hosts: all + tasks: + - name: install apt packages + apt: + name: "{{ packages }}" + vars: + packages: + - apt-transport-https + - rsyslog + - shell: service rsyslog start + - shell: groupadd docker && chgrp docker /var/run/docker.sock diff --git a/deployment/molecule/default/tests/test_all.py b/deployment/molecule/default/tests/test_all.py new file mode 100644 index 00000000..bcf2b47a --- /dev/null +++ b/deployment/molecule/default/tests/test_all.py @@ -0,0 +1,20 @@ +import os +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_repo(host): + assert host.file('/home/poadocker/bridge').exists + assert host.file('/home/poadocker/bridge').is_directory + assert host.file('/home/poadocker/bridge/package.json').exists + + +def test_docker_group(host): + assert host.group('docker').exists + + +def test_user(host): + assert host.user('poadocker').exists + assert 'docker' in host.user('poadocker').groups diff --git a/deployment/molecule/default/tests/test_oracle.py b/deployment/molecule/default/tests/test_oracle.py new file mode 100644 index 00000000..64c25423 --- /dev/null +++ b/deployment/molecule/default/tests/test_oracle.py @@ -0,0 +1,37 @@ +import os +import pytest +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('oracle') + + +@pytest.mark.parametrize("name", [ + ("oracle_rabbit_1"), + ("oracle_redis_1"), + ("oracle_bridge_request_1"), + ("oracle_bridge_collected_1"), + ("oracle_bridge_affirmation_1"), + ("oracle_bridge_senderhome_1"), + ("oracle_bridge_senderforeign_1"), +]) +def test_docker_containers(host, name): + container = host.docker(name) + assert container.is_running + + +@pytest.mark.parametrize("service", [ + ("poabridge"), + ("rsyslog") +]) +def test_services(host, service): + assert host.service(service).is_enabled + assert host.service(service).is_running + + +def test_remote_logging(host): + assert host.file('/etc/rsyslog.d/35-remote-logging.conf').exists + + +def test_docker_config(host): + assert host.file('/etc/docker/daemon.json').exists diff --git a/deployment/requirements.txt b/deployment/requirements.txt new file mode 100644 index 00000000..81e83c69 --- /dev/null +++ b/deployment/requirements.txt @@ -0,0 +1,4 @@ +# pre-release because it contains "CI Fixes for ansible 2.8" +molecule==2.22rc1 +docker +flake8 diff --git a/deployment/roles/repo/defaults/main.yml b/deployment/roles/common/defaults/main.yml similarity index 69% rename from deployment/roles/repo/defaults/main.yml rename to deployment/roles/common/defaults/main.yml index 66bd9f75..6e75965a 100644 --- a/deployment/roles/repo/defaults/main.yml +++ b/deployment/roles/common/defaults/main.yml @@ -1,3 +1,5 @@ +docker_compose_version: 1.23.2 +compose_service_user: poadocker bridge_path: "/home/{{ compose_service_user }}/bridge" bridge_repo: https://github.com/poanetwork/tokenbridge.git bridge_repo_branch: master diff --git a/deployment/roles/dependencies/files/daemon.json b/deployment/roles/common/files/daemon.json similarity index 100% rename from deployment/roles/dependencies/files/daemon.json rename to deployment/roles/common/files/daemon.json diff --git a/deployment/roles/dependencies/handlers/main.yml b/deployment/roles/common/handlers/main.yml similarity index 100% rename from deployment/roles/dependencies/handlers/main.yml rename to deployment/roles/common/handlers/main.yml diff --git a/deployment/roles/dependencies/tasks/main.yml b/deployment/roles/common/tasks/dependencies.yml similarity index 98% rename from deployment/roles/dependencies/tasks/main.yml rename to deployment/roles/common/tasks/dependencies.yml index 77407ea1..9539c612 100644 --- a/deployment/roles/dependencies/tasks/main.yml +++ b/deployment/roles/common/tasks/dependencies.yml @@ -67,7 +67,7 @@ - name: Configure docker engine copy: src: daemon.json - dest: /etc/docker/daemon.json + dest: /etc/docker/ owner: root group: root mode: 0640 diff --git a/deployment/roles/common/tasks/main.yml b/deployment/roles/common/tasks/main.yml new file mode 100644 index 00000000..be0c26b5 --- /dev/null +++ b/deployment/roles/common/tasks/main.yml @@ -0,0 +1,3 @@ +- include_tasks: python.yml +- include_tasks: dependencies.yml +- include_tasks: repo.yml diff --git a/deployment/roles/common/tasks/python.yml b/deployment/roles/common/tasks/python.yml new file mode 100644 index 00000000..0f479c82 --- /dev/null +++ b/deployment/roles/common/tasks/python.yml @@ -0,0 +1,2 @@ +- name: Install python if necessary + raw: "test -e {{ ansible_python_interpreter | default ('/usr/bin/python') }} || (sudo apt -y update && sudo apt install -y python-minimal)" diff --git a/deployment/roles/repo/tasks/main.yml b/deployment/roles/common/tasks/repo.yml similarity index 100% rename from deployment/roles/repo/tasks/main.yml rename to deployment/roles/common/tasks/repo.yml diff --git a/deployment/roles/dependencies/README.md b/deployment/roles/dependencies/README.md deleted file mode 100644 index 214cf1ac..00000000 --- a/deployment/roles/dependencies/README.md +++ /dev/null @@ -1,17 +0,0 @@ -This role installs required dependencies: - -* apt-transport-https - -* ca-certificates - -* curl - -* software-properties-common - -* docker-ce (+python library) - -* docker-compose (+python library) - -* git - -* python-pip \ No newline at end of file diff --git a/deployment/roles/dependencies/defaults/main.yml b/deployment/roles/dependencies/defaults/main.yml deleted file mode 100644 index 246fbbb9..00000000 --- a/deployment/roles/dependencies/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -docker_compose_version: 1.22.0 -compose_service_user: poadocker diff --git a/deployment/roles/jumpbox/README.md b/deployment/roles/jumpbox/README.md deleted file mode 100644 index ea214ea6..00000000 --- a/deployment/roles/jumpbox/README.md +++ /dev/null @@ -1 +0,0 @@ -This role brings up a docker container using docker-compose. \ No newline at end of file diff --git a/deployment/roles/jumpbox/defaults/main.yml b/deployment/roles/jumpbox/defaults/main.yml deleted file mode 100644 index 5c3f6216..00000000 --- a/deployment/roles/jumpbox/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -bridge_path: "/home/{{ compose_service_user }}/bridge" diff --git a/deployment/roles/logging/README.md b/deployment/roles/logging/README.md deleted file mode 100644 index 9a95125b..00000000 --- a/deployment/roles/logging/README.md +++ /dev/null @@ -1 +0,0 @@ -This role sets up remote logging for services. \ No newline at end of file diff --git a/deployment/roles/logging/defaults/main.yml b/deployment/roles/logging/defaults/main.yml deleted file mode 100644 index 01a3b019..00000000 --- a/deployment/roles/logging/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ -bridge_path: "/home/{{ compose_service_user }}/bridge" -syslog_server_port: udp://127.0.0.1:514 \ No newline at end of file diff --git a/deployment/roles/pre_config/defaults/main.yml b/deployment/roles/oracle/defaults/main.yml similarity index 67% rename from deployment/roles/pre_config/defaults/main.yml rename to deployment/roles/oracle/defaults/main.yml index 689e71d5..9e267945 100644 --- a/deployment/roles/pre_config/defaults/main.yml +++ b/deployment/roles/oracle/defaults/main.yml @@ -1,6 +1,7 @@ bridge_path: "/home/{{ compose_service_user }}/bridge" - ALLOW_HTTP: no QUEUE_URL: amqp://rabbit REDIS_URL: redis://redis REDIS_LOCK_TTL: 1000 +syslog_server_port: udp://127.0.0.1:514 +keyfile_path: "/root/.key" diff --git a/deployment/roles/oracle/meta/main.yml b/deployment/roles/oracle/meta/main.yml new file mode 100644 index 00000000..9711b330 --- /dev/null +++ b/deployment/roles/oracle/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - role: common diff --git a/deployment/roles/jumpbox/tasks/main.yml b/deployment/roles/oracle/tasks/jumpbox.yml similarity index 100% rename from deployment/roles/jumpbox/tasks/main.yml rename to deployment/roles/oracle/tasks/jumpbox.yml diff --git a/deployment/roles/logging/tasks/main.yml b/deployment/roles/oracle/tasks/logging.yml similarity index 100% rename from deployment/roles/logging/tasks/main.yml rename to deployment/roles/oracle/tasks/logging.yml diff --git a/deployment/roles/oracle/tasks/main.yml b/deployment/roles/oracle/tasks/main.yml new file mode 100644 index 00000000..1183938b --- /dev/null +++ b/deployment/roles/oracle/tasks/main.yml @@ -0,0 +1,5 @@ +- include_tasks: pre_config.yml +- include_tasks: jumpbox.yml +- include_tasks: post_config.yml +- include_tasks: logging.yml +- include_tasks: servinstall.yml diff --git a/deployment/roles/post_config/tasks/main.yml b/deployment/roles/oracle/tasks/post_config.yml similarity index 100% rename from deployment/roles/post_config/tasks/main.yml rename to deployment/roles/oracle/tasks/post_config.yml diff --git a/deployment/roles/pre_config/tasks/main.yml b/deployment/roles/oracle/tasks/pre_config.yml similarity index 100% rename from deployment/roles/pre_config/tasks/main.yml rename to deployment/roles/oracle/tasks/pre_config.yml diff --git a/deployment/roles/oracle/tasks/servinstall.yml b/deployment/roles/oracle/tasks/servinstall.yml new file mode 100644 index 00000000..b87ea5e6 --- /dev/null +++ b/deployment/roles/oracle/tasks/servinstall.yml @@ -0,0 +1,17 @@ +# This role creates a poabridge service which is designed to manage docker-compose bridge deployment. +# /etc/init.d/poabridge start, status, stop, restart - does what the services usually do in such cases. +# /etc/init.d/poabridge rebuild - builds a new bridge deployment from scratch. +--- +- name: "Set poabridge service" + template: + src: poabridge.j2 + dest: "/etc/init.d/poabridge" + owner: root + mode: 755 + +- name: "Start/Enable poabridge service" + service: + name: "poabridge" + state: started + enabled: yes + use: service diff --git a/deployment/roles/pre_config/templates/.env.j2 b/deployment/roles/oracle/templates/.env.j2 similarity index 100% rename from deployment/roles/pre_config/templates/.env.j2 rename to deployment/roles/oracle/templates/.env.j2 diff --git a/deployment/roles/logging/templates/30-docker.conf.j2 b/deployment/roles/oracle/templates/30-docker.conf.j2 similarity index 100% rename from deployment/roles/logging/templates/30-docker.conf.j2 rename to deployment/roles/oracle/templates/30-docker.conf.j2 diff --git a/deployment/roles/logging/templates/35-remote-logging.conf.j2 b/deployment/roles/oracle/templates/35-remote-logging.conf.j2 similarity index 100% rename from deployment/roles/logging/templates/35-remote-logging.conf.j2 rename to deployment/roles/oracle/templates/35-remote-logging.conf.j2 diff --git a/deployment/roles/logging/templates/docker-logs.j2 b/deployment/roles/oracle/templates/docker-logs.j2 similarity index 100% rename from deployment/roles/logging/templates/docker-logs.j2 rename to deployment/roles/oracle/templates/docker-logs.j2 diff --git a/deployment/roles/post_config/templates/key.j2 b/deployment/roles/oracle/templates/key.j2 similarity index 100% rename from deployment/roles/post_config/templates/key.j2 rename to deployment/roles/oracle/templates/key.j2 diff --git a/deployment/roles/servinstall/templates/poabridge.j2 b/deployment/roles/oracle/templates/poabridge.j2 similarity index 100% rename from deployment/roles/servinstall/templates/poabridge.j2 rename to deployment/roles/oracle/templates/poabridge.j2 diff --git a/deployment/roles/post_config/README.md b/deployment/roles/post_config/README.md deleted file mode 100644 index 35fa75d3..00000000 --- a/deployment/roles/post_config/README.md +++ /dev/null @@ -1 +0,0 @@ -This role gets the start blocks for both home and foreign networks. \ No newline at end of file diff --git a/deployment/roles/post_config/defaults/main.yml b/deployment/roles/post_config/defaults/main.yml deleted file mode 100644 index 5c3f6216..00000000 --- a/deployment/roles/post_config/defaults/main.yml +++ /dev/null @@ -1 +0,0 @@ -bridge_path: "/home/{{ compose_service_user }}/bridge" diff --git a/deployment/roles/pre_config/README.md b/deployment/roles/pre_config/README.md deleted file mode 100644 index dbf0c115..00000000 --- a/deployment/roles/pre_config/README.md +++ /dev/null @@ -1 +0,0 @@ -This role sets the .env config (excluding starting blocks). \ No newline at end of file diff --git a/deployment/roles/repo/README.md b/deployment/roles/repo/README.md deleted file mode 100644 index 97ce36d0..00000000 --- a/deployment/roles/repo/README.md +++ /dev/null @@ -1 +0,0 @@ -This role clones the repo from a specified URL. \ No newline at end of file diff --git a/deployment/roles/servinstall/README.md b/deployment/roles/servinstall/README.md deleted file mode 100644 index 983377c8..00000000 --- a/deployment/roles/servinstall/README.md +++ /dev/null @@ -1,5 +0,0 @@ -This role creates a poabridge service which is designed to manage docker-compose bridge deployment. - -/etc/init.d/poabridge start, status, stop, restart - does what the services usually do in such cases. - -/etc/init.d/poabridge rebuild - builds a new bridge deployment from scratch. diff --git a/deployment/roles/servinstall/defaults/main.yml b/deployment/roles/servinstall/defaults/main.yml deleted file mode 100644 index 61e145ac..00000000 --- a/deployment/roles/servinstall/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -# defaults -bridge_path: "/home/{{ compose_service_user }}/bridge" -keyfile_path: "/root/.key" diff --git a/deployment/roles/servinstall/tasks/main.yml b/deployment/roles/servinstall/tasks/main.yml deleted file mode 100644 index b9aa16c0..00000000 --- a/deployment/roles/servinstall/tasks/main.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: "Set poabridge service" - template: - src: poabridge.j2 - dest: "/etc/init.d/poabridge" - owner: root - mode: 755 - -- name: "Start/Enable poabridge service" - service: - name: "poabridge" - state: started - enabled: yes - use: service diff --git a/deployment/site.yml b/deployment/site.yml index 59009763..ca910464 100644 --- a/deployment/site.yml +++ b/deployment/site.yml @@ -1,19 +1,5 @@ -- name: Install python if necessary - hosts: all - gather_facts: false +- name: Install Oracle + hosts: oracle become: true - tasks: - - name: Install python - raw: "test -e {{ ansible_python_interpreter | default ('/usr/bin/python') }} || (sudo apt -y update && sudo apt install -y python-minimal)" - tags: install_dependencies - -- name: Install bridge - hosts: all roles: - - { role: dependencies, tags: install_dependencies, become: true } - - { role: repo, tags: clone_repo, become: true } - - { role: pre_config, tags: pre_config, become: true } - - { role: jumpbox, tags: launch_jumpbox, become: true } - - { role: post_config, tags: post_config, become: true } - - { role: logging, tags: set_logging, become: true} - - { role: servinstall, tags: install_service, become: true } + - { role: oracle }