diff --git a/.gitignore b/.gitignore index e73c109..8f1f772 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea /libvirt_exporter libvirt-exporter +.venv diff --git a/ansible/README.md b/ansible/README.md new file mode 100644 index 0000000..e2f078e --- /dev/null +++ b/ansible/README.md @@ -0,0 +1,47 @@ +END 2 END tests +--------------- + +Tested on: +- macOS: 12.3.1 +- Vagrant: 2.2.19 +- VMware Fusion: 12.2.3 + +Installation +============ + +Prerequisites (Instructions for macOS): +- VMware Fusion (personal license): https://customerconnect.vmware.com/web/vmware/evalcenter?p=fusion-player-personal +- Vagrant: https://www.vagrantup.com/downloads +- VMware Fusion provider for vagrant: https://www.vagrantup.com/docs/providers/vmware/installation +- Vagrant VMware Utility: https://www.vagrantup.com/docs/providers/vmware/vagrant-vmware-utility + +Ansible, molecule installation: +- create venv: ```cd ansible; mkdir .venv; python3 -m venv .venv``` +- update pip: ```source .venv/bin/activate; pip3 install -U pip``` +- install pip packages: ```pip install -r requirements.txt``` + +Ansible roles, collection installation: +- enter venv: ```source .venv/bin/activate``` +- install roles,collections: ```ansible-galaxy role install -r requirements.yml``` +- install collections: ```ansible-galaxy collection install -r requirements.yml``` + +Usage +===== + +All commands must be executed inside venv. + +Create test environment: ```molecule converge``` +Run tests: ```molecule verify``` + +Contribute +========== + +All tests located in verify playbook inside molecule tree. You can use variable ```libvirt_exporter_metrics``` to querry specific metrics and their values. Example: + +```yaml + - name: Assert that 'libvirt_up' in metrics + assert: + that: "libvirt_exporter_metrics | selectattr('name', 'equalto', 'libvirt_up') | first" +``` + +In this example, we use assert ansible module (https://docs.ansible.com/ansible/latest/collections/ansible/builtin/assert_module.html) to verify that there is a element in ```libvirt_exporter_metrics``` array with property ```name``` equals to ```libvirt_up```. ```libvirt_exporter_metrics``` array is a parsed json response from libvirt-exporter. diff --git a/ansible/molecule/default/converge.yml b/ansible/molecule/default/converge.yml new file mode 100644 index 0000000..d7a032c --- /dev/null +++ b/ansible/molecule/default/converge.yml @@ -0,0 +1,36 @@ +--- + +- name: Converge + hosts: all + become: True + vars: + image_name: "localhost/alekseizakharov/libvirt-exporter:latest" + sources_remote_path: "/srv/sources" + sources_local_path: "{{ playbook_dir }}/../../../" + tasks: + - name: Copy local sources to remote dir + ansible.posix.synchronize: + src: "{{ sources_local_path }}" + dest: "{{ sources_remote_path }}" + rsync_opts: + - "--no-motd" + - "--exclude=.venv" + + - name: Build libvirt-exporter image + containers.podman.podman_image: + name: "{{ image_name }}" + path: "{{ sources_remote_path }}" + build: + format: docker + annotation: + app: libvirt-exporter + info: metrics exporter for libvirt + + - name: Run libvirt-exporter container + containers.podman.podman_container: + name: libvirt_exporter + image: "{{ image_name }}" + state: started + recreate: true + publish: "9177:9177" + volume: "/var/run/libvirt:/var/run/libvirt" diff --git a/ansible/molecule/default/metrics.yml b/ansible/molecule/default/metrics.yml new file mode 100644 index 0000000..7172ec2 --- /dev/null +++ b/ansible/molecule/default/metrics.yml @@ -0,0 +1,205 @@ +--- + +metrics: + - name: go_gc_duration_seconds + type: SUMMARY + - name: go_goroutines + type: GAUGE + - name: go_info + type: GAUGE + - name: go_memstats_alloc_bytes + type: GAUGE + - name: go_memstats_alloc_bytes_total + type: COUNTER + - name: go_memstats_buck_hash_sys_bytes + type: GAUGE + - name: go_memstats_frees_total + type: COUNTER + - name: go_memstats_gc_cpu_fraction + type: GAUGE + - name: go_memstats_gc_sys_bytes + type: GAUGE + - name: go_memstats_heap_alloc_bytes + type: GAUGE + - name: go_memstats_heap_idle_bytes + type: GAUGE + - name: go_memstats_heap_inuse_bytes + type: GAUGE + - name: go_memstats_heap_objects + type: GAUGE + - name: go_memstats_heap_released_bytes + type: GAUGE + - name: go_memstats_heap_sys_bytes + type: GAUGE + - name: go_memstats_last_gc_time_seconds + type: GAUGE + - name: go_memstats_lookups_total + type: COUNTER + - name: go_memstats_mallocs_total + type: COUNTER + - name: go_memstats_mcache_inuse_bytes + type: GAUGE + - name: go_memstats_mcache_sys_bytes + type: GAUGE + - name: go_memstats_mspan_inuse_bytes + type: GAUGE + - name: go_memstats_mspan_sys_bytes + type: GAUGE + - name: go_memstats_next_gc_bytes + type: GAUGE + - name: go_memstats_other_sys_bytes + type: GAUGE + - name: go_memstats_stack_inuse_bytes + type: GAUGE + - name: go_memstats_stack_sys_bytes + type: GAUGE + - name: go_memstats_sys_bytes + type: GAUGE + - name: go_threads + type: GAUGE + - name: libvirt_domain_block_meta + type: GAUGE + - name: libvirt_domain_block_stats_allocation + type: GAUGE + - name: libvirt_domain_block_stats_capacity_bytes + type: GAUGE + - name: libvirt_domain_block_stats_flush_requests_total + type: COUNTER + - name: libvirt_domain_block_stats_flush_time_seconds_total + type: COUNTER + - name: libvirt_domain_block_stats_limit_burst_length_read_requests_seconds + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_length_total_requests_seconds + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_length_write_requests_seconds + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_read_bytes + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_read_bytes_length_seconds + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_read_requests + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_total_bytes + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_total_bytes_length_seconds + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_total_requests + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_write_bytes + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_write_bytes_length_seconds + type: GAUGE + - name: libvirt_domain_block_stats_limit_burst_write_requests + type: GAUGE + - name: libvirt_domain_block_stats_limit_read_bytes + type: GAUGE + - name: libvirt_domain_block_stats_limit_read_requests + type: GAUGE + - name: libvirt_domain_block_stats_limit_total_bytes + type: GAUGE + - name: libvirt_domain_block_stats_limit_total_requests + type: GAUGE + - name: libvirt_domain_block_stats_limit_write_bytes + type: GAUGE + - name: libvirt_domain_block_stats_limit_write_requests + type: GAUGE + - name: libvirt_domain_block_stats_physicalsize_bytes + type: GAUGE + - name: libvirt_domain_block_stats_read_bytes_total + type: COUNTER + - name: libvirt_domain_block_stats_read_requests_total + type: COUNTER + - name: libvirt_domain_block_stats_read_time_seconds_total + type: COUNTER + - name: libvirt_domain_block_stats_size_iops_bytes + type: GAUGE + - name: libvirt_domain_block_stats_write_bytes_total + type: COUNTER + - name: libvirt_domain_block_stats_write_requests_total + type: COUNTER + - name: libvirt_domain_block_stats_write_time_seconds_total + type: COUNTER + - name: libvirt_domain_info_cpu_time_seconds_total + type: COUNTER + - name: libvirt_domain_info_maximum_memory_bytes + type: GAUGE + - name: libvirt_domain_info_memory_usage_bytes + type: GAUGE + - name: libvirt_domain_info_meta + type: GAUGE + - name: libvirt_domain_info_virtual_cpus + type: GAUGE + - name: libvirt_domain_info_vstate + type: GAUGE + - name: libvirt_domain_interface_meta + type: GAUGE + - name: libvirt_domain_interface_stats_receive_bytes_total + type: COUNTER + - name: libvirt_domain_interface_stats_receive_drops_total + type: COUNTER + - name: libvirt_domain_interface_stats_receive_errors_total + type: COUNTER + - name: libvirt_domain_interface_stats_receive_packets_total + type: COUNTER + - name: libvirt_domain_interface_stats_transmit_bytes_total + type: COUNTER + - name: libvirt_domain_interface_stats_transmit_drops_total + type: COUNTER + - name: libvirt_domain_interface_stats_transmit_errors_total + type: COUNTER + - name: libvirt_domain_interface_stats_transmit_packets_total + type: COUNTER + - name: libvirt_domain_memory_stats_actual_balloon_bytes + type: GAUGE + - name: libvirt_domain_memory_stats_available_bytes + type: GAUGE + - name: libvirt_domain_memory_stats_disk_cache_bytes + type: GAUGE + - name: libvirt_domain_memory_stats_major_fault_total + type: COUNTER + - name: libvirt_domain_memory_stats_minor_fault_total + type: COUNTER + - name: libvirt_domain_memory_stats_rss_bytes + type: GAUGE + - name: libvirt_domain_memory_stats_unused_bytes + type: GAUGE + - name: libvirt_domain_memory_stats_usable_bytes + type: GAUGE + - name: libvirt_domain_memory_stats_used_percent + type: GAUGE + - name: libvirt_domain_vcpu_cpu + type: GAUGE + - name: libvirt_domain_vcpu_state + type: GAUGE + - name: libvirt_domain_vcpu_time_seconds_total + type: COUNTER + - name: libvirt_domain_vcpu_wait_seconds_total + type: COUNTER + - name: libvirt_pool_info_allocation_bytes + type: GAUGE + - name: libvirt_pool_info_available_bytes + type: GAUGE + - name: libvirt_pool_info_capacity_bytes + type: GAUGE + - name: libvirt_up + type: GAUGE + - name: libvirt_versions_info + type: GAUGE + - name: process_cpu_seconds_total + type: COUNTER + - name: process_max_fds + type: GAUGE + - name: process_open_fds + type: GAUGE + - name: process_resident_memory_bytes + type: GAUGE + - name: process_start_time_seconds + type: GAUGE + - name: process_virtual_memory_bytes + type: GAUGE + - name: process_virtual_memory_max_bytes + type: GAUGE + - name: promhttp_metric_handler_requests_in_flight + type: GAUGE + - name: promhttp_metric_handler_requests_total + type: COUNTER diff --git a/ansible/molecule/default/molecule.yml b/ansible/molecule/default/molecule.yml new file mode 100644 index 0000000..350ece3 --- /dev/null +++ b/ansible/molecule/default/molecule.yml @@ -0,0 +1,15 @@ +--- + +prerun: False +driver: + name: vagrant +platforms: + - name: ubuntu + box: generic/ubuntu2010 + config_options: + ssh.keep_alive: True + ssh.remote_user: 'vagrant' +provisioner: + name: ansible +verifier: + name: ansible diff --git a/ansible/molecule/default/pool.xml.j2 b/ansible/molecule/default/pool.xml.j2 new file mode 100644 index 0000000..1299ad6 --- /dev/null +++ b/ansible/molecule/default/pool.xml.j2 @@ -0,0 +1,17 @@ + + vms + 28954164-9810-47bc-88f7-ab3d847c38df + 66844176384 + 6587465728 + 60256710656 + + + + /var/lib/libvirt/images + + 0711 + 0 + 0 + + + diff --git a/ansible/molecule/default/prepare.yml b/ansible/molecule/default/prepare.yml new file mode 100644 index 0000000..d067008 --- /dev/null +++ b/ansible/molecule/default/prepare.yml @@ -0,0 +1,91 @@ +--- + +- name: Configure test vm + hosts: all + become: True + gather_facts: True + tasks: + - name: Install libvirtd + apt: + name: "{{ item.name }}={{ item.version }}" + update_cache: True + loop: + - name: libvirt-daemon + version: "6.6.0-1ubuntu3.5" + - name: libvirt-daemon-system + version: "6.6.0-1ubuntu3.5" + - name: libguestfs-tools + version: "1:1.42.0-9ubuntu1" + - name: virtinst + version: "1:2.2.1-4ubuntu2" + - name: python3-libvirt + version: "6.1.0-1" + - name: python3-lxml + version: "4.5.2-1ubuntu0.4" + - name: podman + version: "2.0.6+dfsg1-1ubuntu1.2" + - name: runc + version: "1.0.0~rc95-0ubuntu1~20.10.1" + + - name: Download prom2json + get_url: + url: 'https://github.com/prometheus/prom2json/releases/download/v1.3.0/prom2json-1.3.0.linux-amd64.tar.gz' + dest: /home/vagrant/prom2json-1.3.0.linux-amd64.tar.gz + + - name: Unpack prom2json + ansible.builtin.unarchive: + remote_src: True + src: /home/vagrant/prom2json-1.3.0.linux-amd64.tar.gz + dest: /home/vagrant + + - name: Install prom2json + copy: + remote_src: True + mode: '777' + src: /home/vagrant/prom2json-1.3.0.linux-amd64/prom2json + dest: /usr/local/bin/prom2json + + - name: List libvirt volume pools + community.libvirt.virt_pool: + command: list_pools + register: libvirt_pools + + - name: Create default libvirtd volume pool + community.libvirt.virt_pool: + command: define + name: vms + xml: '{{ lookup("template", "pool.xml.j2") }}' + when: "'default' not in libvirt_pools.list_pools" + + - name: Build vms pool + community.libvirt.virt_pool: + command: build + name: vms + when: "'vms' not in libvirt_pools.list_pools" + + - name: Create vms pool + community.libvirt.virt_pool: + state: active + name: vms + when: "'vms' not in libvirt_pools.list_pools" + + - name: Download qcow2 vm + get_url: + url: http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img + dest: /home/vagrant/cirros-0.4.0-x86_64-disk.qcow2 + + - name: Create volume + command: virsh vol-create-as vms cirros-image.qcow2 128M --format qcow2 + + - name: Upload image contents to volume + command: virsh vol-upload cirros-image.qcow2 /home/vagrant/cirros-0.4.0-x86_64-disk.qcow2 --pool vms + + - name: Define vm + community.libvirt.virt: + command: define + xml: "{{ lookup('template', 'vm.xml.j2') }}" + + - name: Create vm + community.libvirt.virt: + name: test-instance + state: running diff --git a/ansible/molecule/default/verify.yml b/ansible/molecule/default/verify.yml new file mode 100644 index 0000000..6e2e567 --- /dev/null +++ b/ansible/molecule/default/verify.yml @@ -0,0 +1,35 @@ +--- + +- name: Verify + hosts: all + become: True + gather_facts: True + vars_files: + - metrics.yml + vars: + libvirt_exporter_url: "http://localhost:9177/metrics" + tasks: + - name: Assert that libvirt_exporter is serving + uri: + url: "{{ libvirt_exporter_url }}" + status_code: 200 + + - name: Get /metrics content from libvirt_eporter + command: "prom2json {{ libvirt_exporter_url }}" + register: libvirt_exporter_response + + - name: Prettify libvirt_exporter_result + set_fact: + libvirt_exporter_metrics: "{{ libvirt_exporter_response.stdout | from_json }}" + + - name: Assert that all metrics are present + assert: + that: "libvirt_exporter_metrics | selectattr('name', 'equalto', item.name) | length" + loop: "{{ metrics }}" + + - name: Assert that all metrics metric have necessary type + vars: + libvirt_up_metric: "{{ libvirt_exporter_metrics | selectattr('name', 'equalto', item.name) | first }}" + assert: + that: "libvirt_up_metric.type == item.type" + loop: "{{ metrics }}" diff --git a/ansible/molecule/default/vm.xml.j2 b/ansible/molecule/default/vm.xml.j2 new file mode 100644 index 0000000..3131354 --- /dev/null +++ b/ansible/molecule/default/vm.xml.j2 @@ -0,0 +1,109 @@ + + test-instance + 524288 + 524288 + 1 + + /machine + + + hvm + + + + + + + + qemu64 + + + + + + + + + destroy + restart + destroy + + + + + + /usr/bin/qemu-system-x86_64 + + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ + + + + + + + + + +