Skip to content

Commit

Permalink
feat: support openstack-exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
ntk148v committed Aug 7, 2024
1 parent 711d0c2 commit 6017d09
Show file tree
Hide file tree
Showing 16 changed files with 323 additions and 4 deletions.
2 changes: 2 additions & 0 deletions ansible/group_vars/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ enable_alertmanager: "yes"
enable_haproxy: "yes"
enable_mysqld_exporter: "no"
enable_fluentd: "no"
enable_openstack_exporter: "no"

# Special variable to handle case, you want to only ONE Prometheus running instance at time.
prometheus_active_passive_mode: "no"
Expand All @@ -80,6 +81,7 @@ node_exporter_port: "9100"
cadvisor_port: "8080"
grafana_port: "3000"
mysqld_exporter_port: "9104"
openstack_exporter_port: "9180"

###############
# Image version
Expand Down
3 changes: 3 additions & 0 deletions ansible/inventory/all-in-one
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ localhost ansible_connection=local

[fluentd]
localhost ansible_connection=local

[openstack_exporter]
localhost ansible_connection=local
13 changes: 9 additions & 4 deletions ansible/inventory/multinode
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ prometheus
alertmanager
cadvisor
node_exporter
openstack_exporter

[haproxy]
haproxy-host-01
Expand All @@ -13,10 +14,11 @@ haproxy-host-02
[prometheus]
# These hostname must be resolvable from your deployment host
prom-host-01
prom-host-02

[alertmanager]
# By default, start alertmanager service in the same host with prometheus
prom-host-01
am-hot-01

[grafana]
grafana-host-01
Expand All @@ -26,10 +28,13 @@ cadvisor-host-01
cadvisor-host-02

[node_exporter]
prom-host-01
node-host-01

[mysqld_exporter]
prom-host-01
mysql-host-01

[fluentd]
prom-host-01
fluentd-host-01

[openstack_exporter]
openstack-host-01
19 changes: 19 additions & 0 deletions ansible/roles/openstack_exporter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Ansible Role: node-exporter

Deploy [node-exporter](https://github.com/prometheus/openstack_exporter) using Ansible and Docker.

## Requirements

- Ansible >= 2.9 (It might work on previous versions, but we cannot guarantee it).

## Role variables

All variables which can be overridden are stored in [defaults/main.yml](./defaults/main.yml) file as well as in [meta/argument_specs.yml](./meta/argument_specs.yml).

## Example playbook

```yaml
- hosts: all
roles:
- { role: openstack_exporter }
```
86 changes: 86 additions & 0 deletions ansible/roles/openstack_exporter/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
# NOTE(kiennt26): Normally, I prevent using 'latest' tag as much as possible.
# But only latest build contains the most wanted feature [1].
# Will come back later when openstack-exporter releases new tag.
# [1] <https://github.com/openstack-exporter/openstack-exporter/issues/351>
openstack_exporter_version: "latest"
openstack_exporter_port: 9180
openstack_exporter_container_name: "openstack_exporter"
openstack_exporter_docker_namespace: "{{ docker_namespace if docker_namespace else 'openstack-exporter' }}"
openstack_exporter_docker_log_driver: "{{ docker_log_driver }}"
openstack_exporter_docker_log_opts: "{{ docker_log_opts }}"
openstack_exporter_image: "{{ docker_registry ~ '/' if docker_registry else 'ghcr.io/' }}{{ openstack_exporter_docker_namespace }}/openstack-exporter:{{ openstack_exporter_version }}"
# Docker resource limit
openstack_exporter_docker_memory_limit: "{{ docker_memory_limit }}"
openstack_exporter_docker_memory_swap_limit: "{{ docker_memory_swap_limit }}"
openstack_exporter_docker_cpus_limit: "{{ docker_cpus_limit }}"

# openstack-exporter arguments
# ----------------------------
openstack_exporter_web_listen_address: "{{ api_interface_address }}:{{ openstack_exporter_port }}"
openstack_exporter_config_dir: "{{ ansitheus_config_dir }}/openstack_exporter"
openstack_exporter_web_telemetry_path: "/metrics"
openstack_exporter_disable_services:
- gnocchi
- dns
- database
- object-store
openstack_exporter_endpoint_type: "internal"
openstack_exporter_disable_deprecated_metrics: "yes"
openstack_exporter_disable_slow_metrics: "yes"
openstack_exporter_enable_cache: "yes"
openstack_exporter_cache_ttl: "300s"
openstack_exporter_cmdline_extras: ""

# openstack credentials
openstack_region_name: "RegionOne"
openstack_keystone_admin_user: "admin"
openstack_keystone_admin_project: "admin"
openstack_keystone_admin_password: "secret"
openstack_keystone_internal_url: "http://localhost:5000"
# openstack_cacert: |
# ---- BEGIN CERTIFICATE ---
# ...
openstack_cacert: ''
openstack_cloud_name: 'cloud01'

openstack_exporter_services:
openstack_exporter:
container_name: "{{ openstack_exporter_container_name }}"
group: "openstack_exporter"
enabled: "{{ enable_openstack_exporter }}"
image: "{{ openstack_exporter_image }}"
privileged: "no"
state: "started"
port: "{{ openstack_exporter_port }}"
volumes:
- "{{ openstack_exporter_config_dir }}:/etc/openstack"
command: >
'--endpoint-type={{ openstack_exporter_endpoint_type }}'
'--os-client-config=/etc/openstack/clouds.yml'
'--web.listen-address={{ openstack_exporter_web_listen_address }}'
'--web.telemetry-path={{ openstack_exporter_web_telemetry_path }}'
{% for service in openstack_exporter_disable_services -%}
'--disable-service.{{ service }}'
{% endfor -%}
{% if openstack_exporter_disable_deprecated_metrics %}
'--disable-deprecated-metrics'
{% endif %}
{% if openstack_exporter_disable_slow_metrics %}
'--disable-slow-metrics'
{% endif %}
{% if openstack_exporter_enable_cache %}
'--cache'
'--cache-ttl={{ openstack_exporter_cache_ttl }}'
{% endif %}
{% if openstack_exporter_cmdline_extras != "" %}
{{ openstack_exporter_cmdline_extras }}
{% endif %}
{{ openstack_cloud_name }}
restart_policy: "unless-stopped"
network_mode: "host"
log_driver: "{{ openstack_exporter_docker_log_driver }}"
log_options: "{{ openstack_exporter_docker_log_opts }}"
memory: "{{ openstack_exporter_docker_memory_limit }}"
memory_swap: "{{ openstack_exporter_docker_memory_swap_limit }}"
cpus: "{{ openstack_exporter_docker_cpus_limit }}"
21 changes: 21 additions & 0 deletions ansible/roles/openstack_exporter/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
- name: Restart openstack_exporter container
vars:
service_name: "openstack_exporter"
service: "{{ openstack_exporter_services[service_name] }}"
become: true
community.general.docker_container:
name: "{{ service.container_name }}"
image: "{{ service.image }}"
volumes: "{{ service.volumes }}"
command: "{{ service.command }}"
state: "{{ service.state }}"
restart: "yes"
restart_policy: "{{ service.restart_policy }}"
privileged: "{{ service.privileged }}"
network_mode: "{{ service.network_mode }}"
log_driver: "{{ service.log_driver }}"
log_options: "{{ service.log_options }}"
when:
- inventory_hostname in groups[service.group]
- service.enabled | bool
39 changes: 39 additions & 0 deletions ansible/roles/openstack_exporter/meta/argument_specs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
# yamllint disable rule:line-length
argument_specs:
main:
short_description: "Prometheus Openstack Exporter"
description:
- "Deploy prometheus openstack-exporter (https://github.com/openstack-exporter/openstack-exporter) using ansible"
author:
- "Kien Nguyen Tuan"
options:
openstack_exporter_version:
description: "Openstack-exporter version."
default: "1.8.0"
openstack_exporter_web_listen_address:
description: "Address on which openstack-exporter will listen"
default: "<ip-address>:9180"
openstack_exporter_web_telemetry_path:
description: "Path under which to expose metrics"
default: "/metrics"
openstack_exporter_disable_services:
description:
- "List of disable services."
type: "list"
elements: "str"
openstack_exporter_endpoint_type:
description: "openstack endpoint type to use (i.e: public, internal, admin)"
type: "str"
openstack_exporter_disable_deprecated_metrics:
description: "Disable deprecated metrics"
type: "bool"
openstack_exporter_disable_slow_metrics:
description: "Disable slow metrics for performance reasons"
type: "bool"
openstack_exporter_enable_cache:
description: "Enable Cache mechanism globally"
type: "bool"
openstack_exporter_cache_ttl:
description: "TTL duration for cache expiry(eg. 10s, 11m, 1h)"
type: "str"
30 changes: 30 additions & 0 deletions ansible/roles/openstack_exporter/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
galaxy_info:
author: "Kien Nguyen Tuan"
description: "Prometheus OPenstack Exporter"
license: "Apache"
min_ansible_version: "2.9"
platforms:
- name: "Ubuntu"
versions:
- "focal"
- "jammy"
- name: "Debian"
versions:
- "bullseye"
- "buster"
- name: "EL"
versions:
- "7"
- "8"
- "9"
- name: "Fedora"
versions:
- "37"
- "38"
galaxy_tags:
- "monitoring"
- "prometheus"
- "exporter"
- "metrics"
- "openstack"
40 changes: 40 additions & 0 deletions ansible/roles/openstack_exporter/tasks/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
- name: Ensuring openstack_exporter config directory exist
ansible.builtin.file:
path: "{{ openstack_exporter_config_dir }}"
state: "directory"
owner: "{{ config_owner_user }}"
group: "{{ config_owner_group }}"
mode: 0755

- name: Copying cloud config file for openstack exporter
ansible.builtin.template:
src: "{{ item }}"
dest: "{{ openstack_exporter_config_dir }}/clouds.yml"
mode: "0755"
with_first_found:
- "{{ ansitheus_custom_config_dir }}/openstack_exporter/{{ inventory_hostname }}/clouds.yml"
- "{{ ansitheus_custom_config_dir }}/openstack_exporter/clouds.yml"
- "{{ role_path }}/templates/clouds.yml.j2"
notify:
- Restart openstack_exporter container

- name: Recreating if not exist running containers
community.general.docker_container:
name: "{{ item.value.container_name }}"
image: "{{ item.value.image }}"
volumes: "{{ item.value.volumes }}"
command: "{{ item.value.command }}"
state: "{{ item.value.state }}"
restart_policy: "{{ item.value.restart_policy }}"
privileged: "{{ item.value.privileged }}"
network_mode: "{{ item.value.network_mode }}"
log_driver: "{{ item.value.log_driver }}"
log_options: "{{ item.value.log_options }}"
memory: "{{ item.value.memory }}"
memory_swap: "{{ item.value.memory_swap }}"
cpus: "{{ item.value.cpus }}"
when:
- inventory_hostname in groups[item.value.group]
- item.value.enabled | bool
with_dict: "{{ openstack_exporter_services }}"
2 changes: 2 additions & 0 deletions ansible/roles/openstack_exporter/tasks/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
- include_tasks: config.yml
20 changes: 20 additions & 0 deletions ansible/roles/openstack_exporter/tasks/destroy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
- name: Stop and remove containers
community.general.docker_container:
name: "{{ item.value.container_name }}"
state: "absent"
keep_volumes: "{{ not destroy_include_volumes | bool }}"
when:
- inventory_hostname in groups[item.value.group]
- item.value.enabled | bool
with_dict: "{{ openstack_exporter_services }}"

- name: Remove images
docker_image:
name: "{{ item.value.image }}"
state: "absent"
when:
- inventory_hostname in groups[item.value.group]
- item.value.enabled | bool
- destroy_include_images | bool
with_dict: "{{ openstack_exporter_services }}"
2 changes: 2 additions & 0 deletions ansible/roles/openstack_exporter/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
- include_tasks: "{{ ansitheus_action }}.yml"
11 changes: 11 additions & 0 deletions ansible/roles/openstack_exporter/tasks/precheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
- name: Check free ports for openstack_exporter
wait_for:
host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}"
port: "{{ item.value.port }}"
connect_timeout: 1
timeout: 1
state: stopped
when:
- inventory_hostname in groups[item.value.group]
with_dict: "{{ openstack_exporter_services }}"
9 changes: 9 additions & 0 deletions ansible/roles/openstack_exporter/tasks/pull.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
- name: Pull image without running containers
docker_image:
name: "{{ item.value.image }}"
source: pull
when:
- inventory_hostname in groups[item.value.group]
- item.value.enabled | bool
with_dict: "{{ openstack_exporter_services }}"
18 changes: 18 additions & 0 deletions ansible/roles/openstack_exporter/templates/clouds.yml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
{{ ansible_managed | comment }}
clouds:
{{ openstack_cloud_name }}:
region_name: {{ openstack_region_name }}
identity_api_version: 3
identity_interface: "internal"
volume_api_version: 3
auth:
username: {{ openstack_keystone_admin_user }}
password: {{ openstack_keystone_admin_password }}
project_name: {{ openstack_keystone_admin_project }}
project_domain_name: 'Default'
user_domain_name: 'Default'
{% if openstack_cacert != '' %}
cacert: {{ openstack_cacert }}
{% endif %}
auth_url: {{ openstack_keystone_internal_url }}
12 changes: 12 additions & 0 deletions ansible/site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@
when: enable_mysqld_exporter | bool,
}

- name: Apply role openstack_exporter
gather_facts: false
become: true
hosts:
- openstack_exporter
roles:
- {
role: openstack_exporter,
tags: [exporters, openstack_exporter],
when: enable_openstack_exporter | bool,
}

- name: Apply role grafana
gather_facts: false
become: true
Expand Down

0 comments on commit 6017d09

Please sign in to comment.