diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..43c89e1 --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - 'var-naming[no-role-prefix]' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a10c1fc..816a5ce 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,41 +1,24 @@ name: 'Lint' on: - pull_request: {} - push: {} + pull_request: { } + push: { } jobs: lint: name: 'Lint' runs-on: ubuntu-latest - container: - image: python:3.9-alpine steps: - name: 'Checkout' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - - name: Setup ansible - run: | - apk add --update --no-cache --virtual build_dependencies gcc musl-dev libffi-dev openssl-dev rust cargo - pip install --no-cache-dir ansible-core - - ansible-galaxy collection install community.general - - - name: 'Yamllint' - uses: karancode/yamllint-github-action@master + - name: Cache .venv directory + uses: actions/cache@v3 with: - yamllint_file_or_dir: 'roles' - yamllint_strict: false - yamllint_comment: false + path: .venv + key: ${{ runner.os }}-venv-${{ hashFiles('**/requirements.txt') }} - - name: Checkout - uses: actions/checkout@v3 - - - name: "Ansible lint playbooks" - uses: ansible/ansible-lint-action@v6.11.0 - with: - path: "playbooks/*" - - - name: "Ansible lint roles" - uses: ansible/ansible-lint-action@v6.11.0 - with: - path: "roles/*" + - name: Lint + run: | + make init-venv + + make lint diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a11da13..09230ee 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,16 +7,16 @@ permissions: on: create: tags: - - v* + - 'v[0-9]+.[0-9]+.[0-9]+' jobs: release: runs-on: ubuntu-latest container: - image: python:3.9-alpine + image: python:3.11-alpine steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Publish collection to ansible galaxy env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..814be8c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,26 @@ +name: 'Molecule Test' +on: + pull_request: { } + push: + branches: + - master + +jobs: + lint: + name: 'Test' + runs-on: ubuntu-latest + steps: + - name: 'Checkout' + uses: actions/checkout@v4 + + - name: Cache .venv directory + uses: actions/cache@v3 + with: + path: .venv + key: ${{ runner.os }}-venv-${{ hashFiles('**/requirements.txt') }} + + - name: Converge + run: | + make init-venv + + make molecule-converge diff --git a/.gitignore b/.gitignore index d947e77..4d1beb5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea .vagrant .vscode +.venv diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5f32897 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +init-venv: + python3 -m venv .venv + . .venv/bin/activate + pip install -r requirements.txt + ansible-galaxy collection install community.general==8.3.0 + +venv: + . .venv/bin/activate + +lint: venv + yamllint roles playbooks + ansible-lint roles/ playbooks/ + +molecule-converge: venv + cd roles/single && molecule converge -s docker + cd roles/vmagent && molecule converge -s docker + cd roles/vmalert && molecule converge -s docker + +molecule-destroy: venv + cd roles/single && molecule destroy -s docker + cd roles/vmagent && molecule destroy -s docker + cd roles/vmalert && molecule destroy -s docker diff --git a/README.md b/README.md index 5ba383a..c29423c 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,11 @@ Collection includes the following roles: - add non-docker environment - fix hardcoded ports -# Testing +# Development -I'm using vagrant and libvirt for testing purpose. visit vendors' web-site for instructions of installing program. -vagrant: https://www.vagrantup.com/downloads +In order to set up development environment, you need to have `docker`, `python` and `make` installed. +Run `make init-venv` to create virtual environment and install required packages for linting and testing with [molecule](https://ansible.readthedocs.io/projects/molecule). -Also, most roles are tested with `molecule`. Please, check out installation docs: https://ansible.readthedocs.io/projects/molecule/installation/ +Please, note that [cluster](./roles/cluster) role is tested with `vagrant` and `libvirt` provider and requires `vagrant` [to be installed](https://www.vagrantup.com/downloads). + +Refer to [Makefile](./Makefile) for available commands for linting and molecule testing. diff --git a/galaxy.yml b/galaxy.yml index 642996c..cd5c00e 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -19,6 +19,8 @@ build_ignore: - inventory_example - Vagrantfile - '*.tar.gz' + - Makefile + - requirements.txt homepage: "https://github.com/VictoriaMetrics/ansible-playbooks" documentation: "https://github.com/VictoriaMetrics/ansible-playbooks" issues: "https://github.com/VictoriaMetrics/ansible-playbooks/issues" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7af7199 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +ansible-compat==4.1.11 +ansible-core==2.16.3 +ansible-lint==24.2.0 +docker==7.0.0 +molecule==24.2.0 +molecule-plugins==23.5.3 +yamllint==1.35.1 diff --git a/roles/cluster/molecule/default/verify.yml b/roles/cluster/molecule/default/verify.yml index d6d8460..0d0610e 100644 --- a/roles/cluster/molecule/default/verify.yml +++ b/roles/cluster/molecule/default/verify.yml @@ -17,7 +17,7 @@ ansible.builtin.get_url: url: "{{ goss_url }}" dest: "{{ goss_bin }}" - sha256sum: "{{ goss_sha256sum }}" + sha256sum: "{{ goss_sha256sum }}" # noqa: args[module] mode: "u=rwx,go=rx" register: download_goss until: download_goss is succeeded diff --git a/roles/single/molecule/docker/converge.yml b/roles/single/molecule/docker/converge.yml new file mode 100644 index 0000000..c5985ff --- /dev/null +++ b/roles/single/molecule/docker/converge.yml @@ -0,0 +1,16 @@ +--- +- name: Converge + hosts: all + become: yes + vars: + victoriametrics_data_dir: "/tmp/victoria-metrics/" + victoriametrics_backup_enabled: false + victoriametrics_service_envflag_enabled: true + victoriametrics_service_envflag_data: + - "graphiteListenAddr=127.0.0.1:12345" + victoriametrics_service_args: + storageDataPath: "{{ victoriametrics_data_dir }}" + tasks: + - name: "Include single" + ansible.builtin.include_role: + name: "single" diff --git a/roles/single/molecule/docker/molecule.yml b/roles/single/molecule/docker/molecule.yml new file mode 100644 index 0000000..9053bcf --- /dev/null +++ b/roles/single/molecule/docker/molecule.yml @@ -0,0 +1,27 @@ +--- +lint: | + yamllint . + ansible-lint . + + +dependency: + name: galaxy + +driver: + name: docker + +platforms: + - name: vmsingle-debian11 + image: "geerlingguy/docker-${MOLECULE_DISTRO:-debian11}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true + +provisioner: + name: ansible + +verifier: + name: ansible diff --git a/roles/single/molecule/docker/verify.yml b/roles/single/molecule/docker/verify.yml new file mode 100644 index 0000000..9e608bb --- /dev/null +++ b/roles/single/molecule/docker/verify.yml @@ -0,0 +1,31 @@ +--- +# This is an example playbook to execute Ansible tests. + +- name: Verify + hosts: all + tasks: + - name: Check if port 12345 is listening + ansible.builtin.wait_for: + port: 12345 + delay: 5 + timeout: 10 + msg: "Timeout waiting for port to respond" + register: port_check + ignore_errors: yes + + - name: Validate victoria is listening + ansible.builtin.assert: + that: port_check is succeeded + + - name: Check if port 8428 is listening + ansible.builtin.wait_for: + port: 8428 + delay: 5 + timeout: 10 + msg: "Timeout waiting for port to respond" + register: port_check + ignore_errors: yes + + - name: Validate victoria is listening + ansible.builtin.assert: + that: port_check is succeeded diff --git a/roles/single/tasks/install.yml b/roles/single/tasks/install.yml index 3d882cd..d21a4e3 100644 --- a/roles/single/tasks/install.yml +++ b/roles/single/tasks/install.yml @@ -72,7 +72,7 @@ - not victoriametrics_is_installed.stat.exists or victoriametrics_version not in victoriametrics_current_version.stdout - - name: Upload VictoriaMetrics release binary + - name: Upload VictoriaMetrics release binary # noqa: no-handler ansible.builtin.copy: src: /tmp/vic-single/victoria-metrics-prod dest: /usr/local/bin @@ -82,7 +82,7 @@ when: - archive_downloaded is changed - - name: Download VictoriaMetrics utils + - name: Download VictoriaMetrics utils # noqa: no-handler become: no environment: http_proxy: '' @@ -95,7 +95,7 @@ when: - archive_downloaded is changed - - name: Upload VictoriaMetrics release binaries + - name: Upload VictoriaMetrics release binaries # noqa: no-handler ansible.builtin.copy: src: "/tmp/vic-utils/{{ item }}" dest: /usr/local/bin diff --git a/roles/single/tests/playbook.yml b/roles/single/tests/playbook.yml index 191b5c6..7b81d66 100644 --- a/roles/single/tests/playbook.yml +++ b/roles/single/tests/playbook.yml @@ -1,6 +1,6 @@ --- -- hosts: all - name: Test role +- name: Test role + hosts: all become: true roles: - "single" diff --git a/roles/vmagent/molecule/default/verify.yml b/roles/vmagent/molecule/default/verify.yml index 0f154f6..1a1bce3 100644 --- a/roles/vmagent/molecule/default/verify.yml +++ b/roles/vmagent/molecule/default/verify.yml @@ -17,7 +17,7 @@ ansible.builtin.get_url: url: "{{ goss_url }}" dest: "{{ goss_bin }}" - sha256sum: "{{ goss_sha256sum }}" + sha256sum: "{{ goss_sha256sum }}" # noqa: args[module] mode: "u=rwx,go=rx" register: download_goss until: download_goss is succeeded diff --git a/roles/vmagent/molecule/docker/converge.yml b/roles/vmagent/molecule/docker/converge.yml new file mode 100644 index 0000000..bd4e1f1 --- /dev/null +++ b/roles/vmagent/molecule/docker/converge.yml @@ -0,0 +1,8 @@ +--- +- name: Converge + hosts: all + become: yes + tasks: + - name: "Include vmagent" + ansible.builtin.include_role: + name: "vmagent" diff --git a/roles/vmagent/molecule/docker/molecule.yml b/roles/vmagent/molecule/docker/molecule.yml new file mode 100644 index 0000000..94d9cfa --- /dev/null +++ b/roles/vmagent/molecule/docker/molecule.yml @@ -0,0 +1,25 @@ +--- +lint: | + yamllint . + ansible-lint . + + +dependency: + name: galaxy +driver: + name: docker + +platforms: + - name: vmagent-debian11 + image: "geerlingguy/docker-${MOLECULE_DISTRO:-debian11}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true + +provisioner: + name: ansible +verifier: + name: ansible diff --git a/roles/vmagent/molecule/docker/tests/test_default.yml b/roles/vmagent/molecule/docker/tests/test_default.yml new file mode 100644 index 0000000..f69064b --- /dev/null +++ b/roles/vmagent/molecule/docker/tests/test_default.yml @@ -0,0 +1,4 @@ +service: + "vic-vmagent": + enabled: true + running: true diff --git a/roles/vmagent/molecule/docker/verify.yml b/roles/vmagent/molecule/docker/verify.yml new file mode 100644 index 0000000..1a1bce3 --- /dev/null +++ b/roles/vmagent/molecule/docker/verify.yml @@ -0,0 +1,93 @@ +--- +# Molecule Goss Tests + +- name: Verify + hosts: all + become: true + vars: + goss_version: v0.3.10 + goss_arch: amd64 + goss_bin: /usr/local/bin/goss + goss_sha256sum: 150f25495ca0d1d4fd2ef8d0e750dbd767a15e9a522505f99b61dd1dd40a76d4 + goss_url: "https://github.com/aelsabbahy/goss/releases/download/{{ goss_version }}/goss-linux-{{ goss_arch }}" + goss_test_directory: /tmp/molecule/goss + goss_format: documentation + tasks: + - name: Download and install Goss + ansible.builtin.get_url: + url: "{{ goss_url }}" + dest: "{{ goss_bin }}" + sha256sum: "{{ goss_sha256sum }}" # noqa: args[module] + mode: "u=rwx,go=rx" + register: download_goss + until: download_goss is succeeded + retries: 3 + + - name: Create Molecule directory for test files + ansible.builtin.file: + path: "{{ goss_test_directory }}" + state: directory + mode: "0755" + + - name: Find Goss tests on localhost + ansible.builtin.find: + paths: "{{ lookup('env', 'MOLECULE_VERIFIER_TEST_DIRECTORY') }}" + patterns: + - "test[-.\\w]*.yml" + - "test_host_{{ ansible_hostname }}[-.\\w]*.yml" + excludes: + - "test_host_(?!{{ ansible_hostname }})[-.\\w]*.yml" + use_regex: true + delegate_to: localhost + register: test_files + changed_when: false + become: false + + - name: Debug + ansible.builtin.debug: + msg: "{{ test_files.files }}" + verbosity: 3 + + - name: Copy Goss tests to remote + ansible.builtin.copy: + src: "{{ item.path }}" + dest: "{{ goss_test_directory }}/{{ item.path | basename }}" + mode: "0644" + with_items: + - "{{ test_files.files }}" + loop_control: + label: "{{ item.path | basename }}" + + - name: Register test files + ansible.builtin.find: + paths: + - "{{ goss_test_directory }}" + patterns: + - "test_*.yml" + register: test_files + + - name: Run verify + when: test_files is succeeded + block: + - name: Execute Goss tests # noqa: no-changed-when + ansible.builtin.command: "{{ goss_bin }} -g {{ item }} validate --format {{ goss_format }}" + register: test_results + with_items: "{{ test_files.files | map(attribute='path') | list }}" + loop_control: + label: "{{ item | basename }}" + failed_when: false + + - name: Display details about the Goss results + ansible.builtin.debug: + msg: "{{ item.stdout_lines }}" + with_items: "{{ test_results.results }}" + loop_control: + label: "{{ item[item.ansible_loop_var] | basename }}" + + - name: Fail when tests fail + ansible.builtin.fail: + msg: "Goss failed to validate" + when: item.rc != 0 + with_items: "{{ test_results.results }}" + loop_control: + label: "{{ item[item.ansible_loop_var] | basename }}" diff --git a/roles/vmagent/tasks/configure.yml b/roles/vmagent/tasks/configure.yml index 6ee272e..0947182 100644 --- a/roles/vmagent/tasks/configure.yml +++ b/roles/vmagent/tasks/configure.yml @@ -13,7 +13,7 @@ no_log: True notify: Restart VMagent service - - name: "Systemd | daemon-reload VMagent service" + - name: "Systemd | daemon-reload VMagent service" # noqa: no-handler become: true ansible.builtin.systemd: daemon_reload: true @@ -38,7 +38,7 @@ notify: Restart VMagent service register: config_template - - name: "Upstart | Enable vic-vmagent service" + - name: "Upstart | Enable vic-vmagent service" # noqa: no-handler ansible.builtin.service: name: "vic-vmagent" enabled: "yes" diff --git a/roles/vmalert/molecule/docker/converge.yml b/roles/vmalert/molecule/docker/converge.yml new file mode 100644 index 0000000..02f6219 --- /dev/null +++ b/roles/vmalert/molecule/docker/converge.yml @@ -0,0 +1,8 @@ +--- +- name: Converge + hosts: all + become: yes + tasks: + - name: "Include vmalert" + ansible.builtin.include_role: + name: "vmalert" diff --git a/roles/vmalert/molecule/docker/molecule.yml b/roles/vmalert/molecule/docker/molecule.yml new file mode 100644 index 0000000..4431bf8 --- /dev/null +++ b/roles/vmalert/molecule/docker/molecule.yml @@ -0,0 +1,25 @@ +--- +lint: | + yamllint . + ansible-lint . + + +dependency: + name: galaxy +driver: + name: docker + +platforms: + - name: vmalert-debian11 + image: "geerlingguy/docker-${MOLECULE_DISTRO:-debian11}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + pre_build_image: true + +provisioner: + name: ansible +verifier: + name: ansible diff --git a/roles/vmalert/molecule/docker/verify.yml b/roles/vmalert/molecule/docker/verify.yml new file mode 100644 index 0000000..86afba4 --- /dev/null +++ b/roles/vmalert/molecule/docker/verify.yml @@ -0,0 +1,9 @@ +--- +# This is an example playbook to execute Ansible tests. + +- name: Verify + hosts: all + tasks: + - name: Example assertion + ansible.builtin.assert: + that: true diff --git a/roles/vmalert/tasks/configure.yml b/roles/vmalert/tasks/configure.yml index a411136..e54fe68 100644 --- a/roles/vmalert/tasks/configure.yml +++ b/roles/vmalert/tasks/configure.yml @@ -13,7 +13,7 @@ notify: Restart VMalert service no_log: True - - name: "Systemd | daemon-reload VMalert service" + - name: "Systemd | daemon-reload VMalert service" # noqa: no-handler become: true ansible.builtin.systemd: daemon_reload: true diff --git a/roles/vmalert/tests/playbook.yml b/roles/vmalert/tests/playbook.yml index 93abc0f..836f981 100644 --- a/roles/vmalert/tests/playbook.yml +++ b/roles/vmalert/tests/playbook.yml @@ -1,6 +1,6 @@ --- -- hosts: all - name: Test vmalert role +- name: Test vmalert role + hosts: all become: true roles: - "vmalert"