diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index 83d504a974..e3f7ea5625 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -244,6 +244,7 @@ enable_cinder_backend_lvm: "no" enable_cloudkitty: "no" enable_congress: "no" enable_gnocchi: "no" +enable_grafana: "no" enable_heat: "yes" enable_horizon: "yes" enable_influxdb: "no" diff --git a/ansible/inventory/all-in-one b/ansible/inventory/all-in-one index d03fae6b7b..ff0fb614f8 100644 --- a/ansible/inventory/all-in-one +++ b/ansible/inventory/all-in-one @@ -20,6 +20,9 @@ localhost ansible_connection=local [collectd:children] compute +[grafana:children] +monitoring + [kibana:children] control diff --git a/ansible/inventory/multinode b/ansible/inventory/multinode index b705024849..95e5de4114 100644 --- a/ansible/inventory/multinode +++ b/ansible/inventory/multinode @@ -38,6 +38,9 @@ storage [collectd:children] compute +[grafana:children] +monitoring + [influxdb:children] monitoring diff --git a/ansible/roles/grafana/defaults/main.yml b/ansible/roles/grafana/defaults/main.yml new file mode 100644 index 0000000000..e101161c52 --- /dev/null +++ b/ansible/roles/grafana/defaults/main.yml @@ -0,0 +1,16 @@ +--- +project_name: "grafana" + +#################### +# Database +#################### +grafana_database_name: "grafana" +grafana_database_user: "grafana" +grafana_database_address: "{{ kolla_internal_fqdn }}:{{ database_port }}" + +########## +# Grafana +########## +grafana_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kolla_install_type }}-grafana" +grafana_tag: "{{ openstack_release }}" +grafana_image_full: "{{ grafana_image }}:{{ grafana_tag }}" diff --git a/ansible/roles/grafana/meta/main.yml b/ansible/roles/grafana/meta/main.yml new file mode 100644 index 0000000000..6b4fff8fef --- /dev/null +++ b/ansible/roles/grafana/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - { role: common } diff --git a/ansible/roles/grafana/tasks/bootstrap.yml b/ansible/roles/grafana/tasks/bootstrap.yml new file mode 100644 index 0000000000..492b516e20 --- /dev/null +++ b/ansible/roles/grafana/tasks/bootstrap.yml @@ -0,0 +1,38 @@ +--- +- name: Creating grafana database + command: docker exec -t kolla_toolbox /usr/bin/ansible localhost + -m mysql_db + -a "login_host='{{ database_address }}' + login_port='{{ database_port }}' + login_user='{{ database_user }}' + login_password='{{ database_password }}' + name='{{ grafana_database_name }}'" + register: database + changed_when: "{{ database.stdout.find('localhost | SUCCESS => ') != -1 and + (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}" + failed_when: database.stdout.split()[2] != 'SUCCESS' + run_once: True + delegate_to: "{{ groups['grafana'][0] }}" + +- name: Reading json from variable + set_fact: + database_created: "{{ (database.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}" + +- name: Creating grafana database user and setting permissions + command: docker exec -t kolla_toolbox /usr/bin/ansible localhost + -m mysql_user + -a "login_host='{{ database_address }}' + login_port='{{ database_port }}' + login_user='{{ database_user }}' + login_password='{{ database_password }}' + name='{{ grafana_database_name }}' + password='{{ grafana_database_password }}' + host='%' + priv='{{ grafana_database_name }}.*:ALL' + append_privs='yes'" + register: database_user_create + changed_when: "{{ database_user_create.stdout.find('localhost | SUCCESS => ') != -1 and + (database_user_create.stdout.split('localhost | SUCCESS => ')[1]|from_json).changed }}" + failed_when: database_user_create.stdout.split()[2] != 'SUCCESS' + run_once: True + delegate_to: "{{ groups['grafana'][0] }}" diff --git a/ansible/roles/grafana/tasks/config.yml b/ansible/roles/grafana/tasks/config.yml new file mode 100644 index 0000000000..ca3ddabc23 --- /dev/null +++ b/ansible/roles/grafana/tasks/config.yml @@ -0,0 +1,27 @@ +--- +- name: Ensuring config directories exist + file: + path: "{{ node_config_directory }}/{{ item }}" + state: "directory" + recurse: yes + with_items: + - "grafana" + +- name: Copying over config.json files + template: + src: "{{ item }}.json.j2" + dest: "{{ node_config_directory }}/{{ item }}/config.json" + with_items: + - "grafana" + +- name: Copying over grafana.ini + merge_configs: + vars: + service_name: "{{ item }}" + sources: + - "{{ role_path }}/templates/grafana.ini.j2" + - "{{ node_custom_config }}/{{ item }}.ini" + - "{{ node_custom_config }}/grafana/{{ inventory_hostname }}/{{ item }}.ini" + dest: "{{ node_config_directory }}/grafana/grafana.ini" + with_items: + - "grafana" diff --git a/ansible/roles/grafana/tasks/deploy.yml b/ansible/roles/grafana/tasks/deploy.yml new file mode 100644 index 0000000000..98b45ee90c --- /dev/null +++ b/ansible/roles/grafana/tasks/deploy.yml @@ -0,0 +1,9 @@ +--- +- include: config.yml + when: inventory_hostname in groups['grafana'] + +- include: bootstrap.yml + when: inventory_hostname in groups['grafana'] + +- include: start.yml + when: inventory_hostname in groups['grafana'] diff --git a/ansible/roles/grafana/tasks/do_reconfigure.yml b/ansible/roles/grafana/tasks/do_reconfigure.yml new file mode 100644 index 0000000000..b8ca4ed270 --- /dev/null +++ b/ansible/roles/grafana/tasks/do_reconfigure.yml @@ -0,0 +1,47 @@ +--- +- name: Ensuring the containers up + kolla_docker: + name: "grafana" + action: "get_container_state" + register: container_state + failed_when: container_state.Running == false + when: inventory_hostname in groups['grafana'] + +- include: config.yml + +- name: Check the configs + command: docker exec grafana /usr/local/bin/kolla_set_configs --check + changed_when: false + failed_when: false + register: check_results + when: inventory_hostname in groups['grafana'] + +# NOTE(jeffrey4l): when config_strategy == 'COPY_ALWAYS' +# and container env['KOLLA_CONFIG_STRATEGY'] == 'COPY_ONCE', +# just remove the container and start again +- name: Containers config strategy + kolla_docker: + name: "grafana" + action: "get_container_env" + register: container_envs + when: inventory_hostname in groups['grafana'] + +- name: Remove the containers + kolla_docker: + name: "grafana" + action: "remove_container" + register: remove_containers + when: + - config_strategy == "COPY_ONCE" + - inventory_hostname in groups['grafana'] + +- include: start.yml + when: remove_containers.changed + +- name: Restart containers + kolla_docker: + name: "grafana" + action: "restart_container" + when: + - config_strategy == 'COPY_ALWAYS' + - inventory_hostname in groups['grafana'] diff --git a/ansible/roles/grafana/tasks/main.yml b/ansible/roles/grafana/tasks/main.yml new file mode 100644 index 0000000000..b017e8b4ad --- /dev/null +++ b/ansible/roles/grafana/tasks/main.yml @@ -0,0 +1,2 @@ +--- +- include: "{{ action }}.yml" diff --git a/ansible/roles/grafana/tasks/pull.yml b/ansible/roles/grafana/tasks/pull.yml new file mode 100644 index 0000000000..376892ab61 --- /dev/null +++ b/ansible/roles/grafana/tasks/pull.yml @@ -0,0 +1,7 @@ +--- +- name: Pulling grafana image + kolla_docker: + action: "pull_image" + common_options: "{{ docker_common_options }}" + image: "{{ grafana_image_full }}" + when: inventory_hostname in groups['grafana'] diff --git a/ansible/roles/grafana/tasks/reconfigure.yml b/ansible/roles/grafana/tasks/reconfigure.yml new file mode 100644 index 0000000000..0b28cb949a --- /dev/null +++ b/ansible/roles/grafana/tasks/reconfigure.yml @@ -0,0 +1,3 @@ +--- +- include: do_reconfigure.yml + when: inventory_hostname in groups['grafana'] diff --git a/ansible/roles/grafana/tasks/start.yml b/ansible/roles/grafana/tasks/start.yml new file mode 100644 index 0000000000..0d3114dab7 --- /dev/null +++ b/ansible/roles/grafana/tasks/start.yml @@ -0,0 +1,13 @@ +--- +- name: Starting grafana container + kolla_docker: + action: "start_container" + common_options: "{{ docker_common_options }}" + image: "{{ grafana_image_full }}" + name: "grafana" + volumes: + - "{{ node_config_directory }}/grafana/:{{ container_config_directory }}/:ro" + - "/etc/localtime:/etc/localtime:ro" + - "grafana:/var/lib/grafana/" + - "kolla_logs:/var/log/kolla/" + when: inventory_hostname in groups['grafana'] diff --git a/ansible/roles/grafana/tasks/upgrade.yml b/ansible/roles/grafana/tasks/upgrade.yml new file mode 100644 index 0000000000..98daa4021c --- /dev/null +++ b/ansible/roles/grafana/tasks/upgrade.yml @@ -0,0 +1,6 @@ +--- +- include: config.yml + +- include: bootstrap.yml + +- include: start.yml diff --git a/ansible/roles/grafana/templates/grafana.ini.j2 b/ansible/roles/grafana/templates/grafana.ini.j2 new file mode 100644 index 0000000000..582488a72a --- /dev/null +++ b/ansible/roles/grafana/templates/grafana.ini.j2 @@ -0,0 +1,38 @@ +[paths] +data = /var/lib/grafana +logs = /var/log/kolla/grafana +plugins = /var/lib/grafana/plugins + +[server] +protocol = http +http_addr = {{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }} +http_port = 3000 + +router_logging = true + +static_root_path = public + +enable_gzip = false + +[database] +type = mysql +host = {{ grafana_database_address }} +name = {{ grafana_database_name }} +user = {{ grafana_database_user }} +password = {{ grafana_database_password }} +ssl_mode = disable + +[session] +provider = memcache +provider_config = {% for host in groups['memcached'] %}{{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ memcached_port }}{% if not loop.last %},{% endif %}{% endfor %} +cookie_name = grafana_sess +cookie_secure = false +session_life_time = 86400 + +[analytics] +reporting_enabled = false +check_for_updates = false + +[security] +admin_user = admin +admin_password = {{ grafana_admin_password }} diff --git a/ansible/roles/grafana/templates/grafana.json.j2 b/ansible/roles/grafana/templates/grafana.json.j2 new file mode 100644 index 0000000000..1e26464af7 --- /dev/null +++ b/ansible/roles/grafana/templates/grafana.json.j2 @@ -0,0 +1,11 @@ +{ + "command": "/usr/sbin/grafana-server --config=/etc/grafana/grafana.ini", + "config_files": [ + { + "source": "{{ container_config_directory }}/grafana.ini", + "dest": "/etc/grafana/grafana.ini", + "owner": "grafana", + "perm": "0600" + } + ] +} diff --git a/ansible/site.yml b/ansible/site.yml index 6f87631de6..a7cf1c9d8a 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -337,6 +337,14 @@ tags: watcher, when: enable_watcher | bool } +- hosts: + - grafana + serial: '{{ "30%" if action == "upgrade" else "0" }}' + roles: + - { role: grafana, + tags: grafana, + when: enable_grafana | bool } + - hosts: - cloudkitty-api - cloudkitty-processor diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml index 5415874954..a114d3835a 100644 --- a/etc/kolla/globals.yml +++ b/etc/kolla/globals.yml @@ -121,6 +121,7 @@ kolla_internal_vip_address: "10.10.10.254" #enable_cinder_backend_lvm: "no" #enable_cloudkitty: "no" #enable_congress: "no" +#enable_grafana: "no" #enable_heat: "yes" #enable_horizon: "yes" #enable_influxdb: "no" diff --git a/etc/kolla/passwords.yml b/etc/kolla/passwords.yml index e570a9d906..cac0a66404 100644 --- a/etc/kolla/passwords.yml +++ b/etc/kolla/passwords.yml @@ -30,6 +30,9 @@ barbican_keystone_password: keystone_admin_password: keystone_database_password: +grafana_database_password: +grafana_admin_password: + glance_database_password: glance_keystone_password: