feat(cni): add specialized role ton install cni plugins
All checks were successful
development / Check commit compliance (push) Successful in 32s

This commit is contained in:
Bertrand Lanson 2024-07-22 22:26:24 +02:00
parent ca65a44eac
commit 09d0304748
Signed by: lanson
SSH Key Fingerprint: SHA256:/nqc6HGqld/PS208F6FUOvZlUzTS0rGpNNwR5O2bQBw
13 changed files with 468 additions and 0 deletions

View File

@ -0,0 +1,8 @@
---
- name: Converge
hosts: all
become: true
tasks:
- name: "Include ednz_cloud.hashistack.cni"
ansible.builtin.include_role:
name: "ednz_cloud.hashistack.cni"

View File

@ -0,0 +1,37 @@
---
dependency:
name: galaxy
options:
requirements-file: ./requirements.yml
driver:
name: docker
platforms:
- name: instance
image: geerlingguy/docker-${MOLECULE_TEST_OS}-ansible
command: ""
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup
cgroupns_mode: host
privileged: true
pre_build_image: true
provisioner:
name: ansible
config_options:
defaults:
remote_tmp: /tmp/.ansible
verifier:
name: ansible
scenario:
name: cni_default
test_sequence:
- dependency
- cleanup
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- verify
- cleanup
- destroy

View File

@ -0,0 +1,13 @@
---
- name: Prepare
hosts: all
become: true
tasks:
- name: "Install pre-required system packages"
ansible.builtin.include_role:
name: ednz_cloud.manage_apt_packages
vars:
manage_apt_packages_list:
- name: unzip
version: latest
state: present

View File

@ -0,0 +1,4 @@
---
# requirements file for molecule
roles:
- name: ednz_cloud.manage_apt_packages

View File

@ -0,0 +1,170 @@
---
- name: Verify
hosts: all
gather_facts: true
become: true
tasks:
- name: "Test: consul user and group"
block:
- name: "Getent user consul"
ansible.builtin.getent:
database: passwd
key: consul
register: consul_user
- name: "Getent group consul"
ansible.builtin.getent:
database: group
key: consul
register: consul_group
- name: "Verify consul user and group"
ansible.builtin.assert:
that:
- not consul_user.failed
- not consul_group.failed
- "'consul' in consul_user.ansible_facts.getent_passwd.keys()"
- "'/home/consul' in consul_user.ansible_facts.getent_passwd['consul']"
- "'/bin/false' in consul_user.ansible_facts.getent_passwd['consul']"
- "'consul' in consul_group.ansible_facts.getent_group.keys()"
- name: "Test: binary /usr/local/bin/consul"
block:
- name: "Stat binary /usr/local/bin/consul"
ansible.builtin.stat:
path: "/usr/local/bin/consul"
register: stat_usr_local_bin_consul
- name: "Verify binary /usr/local/bin/consul"
ansible.builtin.assert:
that:
- stat_usr_local_bin_consul.stat.exists
- stat_usr_local_bin_consul.stat.isreg
- stat_usr_local_bin_consul.stat.pw_name == 'root'
- stat_usr_local_bin_consul.stat.gr_name == 'root'
- stat_usr_local_bin_consul.stat.mode == '0755'
- name: "Test: directory /etc/consul.d"
block:
- name: "Stat directory /etc/consul.d"
ansible.builtin.stat:
path: "/etc/consul.d"
register: stat_etc_consul_d
- name: "Stat file /etc/consul.d/consul.env"
ansible.builtin.stat:
path: "/etc/consul.d/consul.env"
register: stat_etc_consul_d_consul_env
- name: "Stat file /etc/consul.d/consul.json"
ansible.builtin.stat:
path: "/etc/consul.d/consul.json"
register: stat_etc_consul_d_consul_json
- name: "Slurp file /etc/consul.d/consul.json"
ansible.builtin.slurp:
src: "/etc/consul.d/consul.json"
register: slurp_etc_consul_d_consul_json
- name: "Verify directory /etc/consul.d"
ansible.builtin.assert:
that:
- stat_etc_consul_d.stat.exists
- stat_etc_consul_d.stat.isdir
- stat_etc_consul_d.stat.pw_name == 'consul'
- stat_etc_consul_d.stat.gr_name == 'consul'
- stat_etc_consul_d.stat.mode == '0755'
- stat_etc_consul_d_consul_env.stat.exists
- stat_etc_consul_d_consul_env.stat.isreg
- stat_etc_consul_d_consul_env.stat.pw_name == 'consul'
- stat_etc_consul_d_consul_env.stat.gr_name == 'consul'
- stat_etc_consul_d_consul_env.stat.mode == '0600'
- stat_etc_consul_d_consul_json.stat.exists
- stat_etc_consul_d_consul_json.stat.isreg
- stat_etc_consul_d_consul_json.stat.pw_name == 'consul'
- stat_etc_consul_d_consul_json.stat.gr_name == 'consul'
- stat_etc_consul_d_consul_json.stat.mode == '0600'
- slurp_etc_consul_d_consul_json.content != ''
- name: "Test: directory /opt/consul"
block:
- name: "Stat directory /opt/consul"
ansible.builtin.stat:
path: "/opt/consul"
register: stat_opt_consul
- name: "Verify directory /opt/consul"
ansible.builtin.assert:
that:
- stat_opt_consul.stat.exists
- stat_opt_consul.stat.isdir
- stat_opt_consul.stat.pw_name == 'consul'
- stat_opt_consul.stat.gr_name == 'consul'
- stat_opt_consul.stat.mode == '0755'
- name: "Test: service consul"
block:
- name: "Get service consul"
ansible.builtin.service_facts:
- name: "Stat file /etc/systemd/system/consul.service"
ansible.builtin.stat:
path: "/etc/systemd/system/consul.service"
register: stat_etc_systemd_system_consul_service
- name: "Slurp file /etc/systemd/system/consul.service"
ansible.builtin.slurp:
src: "/etc/systemd/system/consul.service"
register: slurp_etc_systemd_system_consul_service
- name: "Verify service consul"
ansible.builtin.assert:
that:
- stat_etc_systemd_system_consul_service.stat.exists
- stat_etc_systemd_system_consul_service.stat.isreg
- stat_etc_systemd_system_consul_service.stat.pw_name == 'root'
- stat_etc_systemd_system_consul_service.stat.gr_name == 'root'
- stat_etc_systemd_system_consul_service.stat.mode == '0644'
- slurp_etc_systemd_system_consul_service.content != ''
- ansible_facts.services['consul.service'] is defined
- ansible_facts.services['consul.service']['source'] == 'systemd'
- ansible_facts.services['consul.service']['state'] == 'running'
- ansible_facts.services['consul.service']['status'] == 'enabled'
- name: "Test: interaction consul"
block:
- name: "Command consul kv put"
ansible.builtin.command: "consul kv put foo bar"
environment:
CONSUL_HTTP_ADDR: "http://{{ ansible_default_ipv4.address }}:8500"
changed_when: false
register: consul_kv_put
- name: "Command consul kv get"
ansible.builtin.command: "consul kv get foo"
environment:
CONSUL_HTTP_ADDR: "http://{{ ansible_default_ipv4.address }}:8500"
changed_when: false
register: consul_kv_get
- name: "Command consul kv delete"
ansible.builtin.command: "consul kv delete foo"
environment:
CONSUL_HTTP_ADDR: "http://{{ ansible_default_ipv4.address }}:8500"
changed_when: false
register: consul_kv_delete
- name: "Command consul members"
ansible.builtin.command: "consul members"
environment:
CONSUL_HTTP_ADDR: "http://{{ ansible_default_ipv4.address }}:8500"
changed_when: false
register: consul_members
- name: "Verify consul interaction"
ansible.builtin.assert:
that:
- "'instance' in consul_members.stdout"
- consul_kv_put.stdout == 'Success! Data written to: foo'
- consul_kv_get.stdout == 'bar'
- consul_kv_delete.stdout == 'Success! Deleted key: foo'

View File

@ -0,0 +1,7 @@
---
# defaults file for cni
cni_plugins_version: "latest"
cni_plugins_install_path: /opt/cni/bin
cni_plugins_install_consul_cni: false
cni_user: nomad
cni_group: nomad

View File

@ -0,0 +1,2 @@
---
# handlers file for cni

1
roles/cni/meta/main.yml Normal file
View File

@ -0,0 +1 @@
---

View File

@ -0,0 +1,70 @@
---
# task/cni_install file for cni
- name: "CNI Plugins | Get release for cni_plugins:{{ cni_plugins_version }}"
vars:
_cni_plugins_url_ext: "{% if cni_plugins_version == 'latest'%}releases{% else %}releases/tags{% endif %}"
ansible.builtin.uri:
url: "{{ cni_github_api }}/{{ cni_github_project }}/{{ _cni_plugins_url_ext }}/{{ cni_plugins_version }}"
return_content: true
register: _cni_plugins_latest_release
- name: "CNI Plugins | Check if cni plugin is already installed"
ansible.builtin.stat:
path: "{{ cni_plugins_install_path }}/.version"
changed_when: false
check_mode: false
register: _cni_plugins_is_installed
- name: "CNI Plugins | Check current cni plugin version"
ansible.builtin.command: "cat {{ cni_plugins_install_path }}/.version"
changed_when: false
check_mode: false
register: _cni_plugins_old_release
when: _cni_plugins_is_installed.stat.exists
- name: "CNI Plugins | Set facts for wanted cni plugins release"
ansible.builtin.set_fact:
cni_plugins_wanted_version: "{{ _cni_plugins_latest_release.json['tag_name']|regex_replace('v', '') }}"
when: _cni_plugins_latest_release.json is defined
and (_cni_plugins_latest_release.json | length > 0)
- name: "CNI Plugins | Set facts for current cni plugins release"
ansible.builtin.set_fact:
cni_plugins_current_version: "{{ _cni_plugins_old_release.stdout | regex_replace('v', '') }}"
when: _cni_plugins_old_release.stdout is defined
and (_cni_plugins_old_release.stdout | length > 0)
- name: "CNI Plugins | Install cni plugins"
when: cni_plugins_current_version is not defined
or cni_plugins_wanted_version not in cni_plugins_current_version
block:
- name: "CNI Plugins | Install cni plugins version:{{ cni_plugins_version }}"
ansible.builtin.get_url:
url: "{{ cni_github_url }}/{{ cni_github_project }}/releases/download/v{{ cni_plugins_wanted_version }}/cni-plugins-linux-{{ cni_architecture }}-v{{ cni_plugins_wanted_version }}.tgz"
dest: "/tmp/cni_plugin.tgz"
mode: "0644"
register: _cni_plugins_download_archive
until: _cni_plugins_download_archive is succeeded
retries: 5
delay: 2
check_mode: false
- name: "CNI Plugins | Unpack cni plugins"
ansible.builtin.unarchive:
src: "/tmp/cni_plugin.tgz"
dest: "{{ cni_plugins_install_path }}"
owner: "{{ cni_user }}"
group: "{{ cni_group }}"
mode: "0755"
remote_src: true
- name: "CNI Plugins | Remove temporary archive"
ansible.builtin.file:
path: "/tmp/cni_plugin.tgz"
state: absent
- name: "CNI Plugins | Update version file"
ansible.builtin.copy:
content: "{{ cni_plugins_wanted_version }}"
dest: "{{ cni_plugins_install_path }}/.version"
mode: "0600"

View File

@ -0,0 +1,114 @@
---
# task/consul_cni_install file for cni
- name: "CNI Plugins | Set wanted consul-cni version to latest tag"
ansible.builtin.set_fact:
_cni_consul_cni_wanted_version: "{{ _cni_plugins_latest_release.json['tag_name']|regex_replace('v', '') }}"
when: cni_plugins_version == 'latest'
- name: "CNI Plugins | Set wanted consul-cni version to {{ cni_plugins_version }}"
ansible.builtin.set_fact:
_cni_consul_cni_wanted_version: "{{ cni_plugins_version|regex_replace('v', '') }}"
when: cni_plugins_version != 'latest'
- name: "CNI Plugins | Get current consul-cni version"
block:
- name: "CNI Plugins | Stat consul-cni version file"
ansible.builtin.stat:
path: "{{ cni_plugins_install_path }}/.consul-cni-version"
changed_when: false
check_mode: false
register: _cni_consul_cni_version_file
- name: "CNI Plugins | Get current consul-cni version"
ansible.builtin.slurp:
src: "{{ _cni_consul_cni_version_file.stat.path }}"
when:
- _cni_consul_cni_version_file.stat.exists
- _cni_consul_cni_version_file.stat.isreg
register: _cni_consul_cni_current_version
- name: "CNI Plugins | Download and install consul-cni binary"
when: _cni_consul_cni_current_version is not defined
or _cni_consul_cni_wanted_version != (_cni_consul_cni_current_version.content|default('')|b64decode)
block:
- name: "CNI Plugins | Set consul-cni package name to download"
ansible.builtin.set_fact:
_cni_consul_cni_package_name: >-
consul-cni_{{ _cni_consul_cni_wanted_version }}_linux_{{ cni_deb_architecture_map[ansible_architecture] }}.zip
_cni_consul_cni_shasum_file_name: >-
consul-cni_{{ _cni_consul_cni_wanted_version }}_SHA256SUMS
- name: "CNI Plugins | Download checksum file for consul-cni archive"
ansible.builtin.get_url:
url: "{{ cni_consul_cni_repository_url }}/{{ _cni_consul_cni_wanted_version }}/{{ _cni_consul_cni_shasum_file_name }}"
dest: "/tmp/{{ _cni_consul_cni_shasum_file_name }}"
mode: "0644"
register: _cni_consul_cni_checksum_file
until: _cni_consul_cni_checksum_file is succeeded
retries: 5
delay: 2
check_mode: false
- name: "CNI Plugins | Extract correct checksum from checksum file"
ansible.builtin.command:
cmd: 'grep "{{ _cni_consul_cni_package_name }}" /tmp/{{ _cni_consul_cni_shasum_file_name }}'
changed_when: false
register: _cni_consul_cni_expected_checksum_line
- name: "CNI Plugins | Parse the expected checksum"
ansible.builtin.set_fact:
_cni_consul_cni_expected_checksum: "{{ _cni_consul_cni_expected_checksum_line.stdout.split()[0] }}"
- name: "CNI Plugins | Download consul-cni binary archive"
ansible.builtin.get_url:
url: "{{ cni_consul_cni_repository_url }}/{{ _cni_consul_cni_wanted_version }}/{{ _cni_consul_cni_package_name }}"
dest: "/tmp/{{ _cni_consul_cni_package_name }}"
mode: "0644"
checksum: "sha256:{{ _cni_consul_cni_expected_checksum }}"
register: _cni_consul_cni_binary_archive
until: _cni_consul_cni_binary_archive is succeeded
retries: 5
delay: 2
check_mode: false
- name: "CNI Plugins | Create temporary directory for archive decompression"
ansible.builtin.file:
path: /tmp/consul-cni
state: directory
mode: "0755"
- name: "CNI Plugins | Unpack consul-cni archive"
ansible.builtin.unarchive:
src: "/tmp/{{ _cni_consul_cni_package_name }}"
dest: "/tmp/consul-cni"
owner: "{{ cni_user }}"
group: "{{ cni_group }}"
mode: "0755"
remote_src: true
- name: "CNI Plugins | Copy consul-cni binary to {{ cni_plugins_install_path }}"
ansible.builtin.copy:
src: /tmp/consul-cni/consul-cni
dest: "{{ cni_plugins_install_path }}"
owner: "{{ cni_user }}"
group: "{{ cni_user }}"
mode: "0755"
remote_src: true
force: true
- name: "CNI Plugins | Update consul-cni version file"
ansible.builtin.copy:
content: "{{ _cni_consul_cni_wanted_version }}"
dest: "{{ cni_plugins_install_path }}/.consul-cni-version"
owner: "{{ cni_user }}"
group: "{{ cni_group }}"
mode: "0600"
- name: "CNI Plugins | Cleanup temporary directory"
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop:
- /tmp/consul-cni
- /tmp/{{ _cni_consul_cni_package_name }}
- /tmp/{{ _cni_consul_cni_shasum_file_name }}

10
roles/cni/tasks/main.yml Normal file
View File

@ -0,0 +1,10 @@
---
# task/main file for cni
- name: "CNI Plugins | Import prerequisites.yml"
ansible.builtin.include_tasks: prerequisites.yml
- name: "CNI Plugins | Import cni_install.yml"
ansible.builtin.include_tasks: cni_install.yml
- name: "CNI Plugins | Import consul_cni_install.yml"
ansible.builtin.include_tasks: consul_cni_install.yml

View File

@ -0,0 +1,21 @@
---
# task/prerequisites file for cni
- name: "CNI Plugins | Create group {{ cni_group }}"
ansible.builtin.group:
name: "{{ cni_user }}"
state: present
- name: "CNI Plugins | Create user {{ cni_user }}"
ansible.builtin.user:
name: "{{ cni_user }}"
group: "{{ cni_group }}"
shell: /bin/false
state: present
- name: "CNI Plugins | Create directory {{ cni_plugins_install_path }}"
ansible.builtin.file:
path: "{{ cni_plugins_install_path }}"
state: directory
owner: "{{ cni_user }}"
group: "{{ cni_group }}"
mode: "0755"

11
roles/cni/vars/main.yml Normal file
View File

@ -0,0 +1,11 @@
---
cni_github_api: https://api.github.com/repos
cni_github_project: containernetworking/plugins
cni_github_url: https://github.com
cni_deb_architecture_map:
x86_64: "amd64"
aarch64: "arm64"
armv7l: "arm"
armv6l: "arm"
cni_architecture: "{{ cni_deb_architecture_map[ansible_architecture] | default(ansible_architecture) }}"
cni_consul_cni_repository_url: https://releases.hashicorp.com/consul-cni