From 75d095b64ef865739cdf55491c95d665e0d8b74e Mon Sep 17 00:00:00 2001 From: Doug Szumski Date: Thu, 25 Oct 2018 16:53:11 +0000 Subject: [PATCH] Automatically configure Monasca Grafana datasource In Kolla, an OpenStack project is created to store logs and metrics harvested from the control plane by Monasca. This commit enables the Monasca Datasource in the Grafana organisation which maps to this OpenStack control plane project. What this means in practice is that if a user logs into Monasca Grafana, and has access to the the control plane project, they will immediately be able to create dashboards using data from Monasca which has been gathered from the control plane. Support to enable creation of this datasource for other OpenStack projects can be added in a separate commit. Partially-Implements: blueprint monasca-grafana Change-Id: I03e741ddb1c582b7280c64637ed3e3683df6419b --- ansible/roles/monasca/defaults/main.yml | 13 +++ ansible/roles/monasca/tasks/deploy.yml | 2 + ansible/roles/monasca/tasks/post_config.yml | 90 +++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 ansible/roles/monasca/tasks/post_config.yml diff --git a/ansible/roles/monasca/defaults/main.yml b/ansible/roles/monasca/defaults/main.yml index 09a05de277..c690c36600 100644 --- a/ansible/roles/monasca/defaults/main.yml +++ b/ansible/roles/monasca/defaults/main.yml @@ -220,6 +220,19 @@ monasca_metric_pipeline_threads: 2 # authentication. This must *not* match any OpenStack username. monasca_grafana_admin_username: "grafana_local_admin" +monasca_grafana_data_sources: + monasca: + enabled: True + data: + name: "Monasca API" + type: "monasca-datasource" + access: "proxy" + url: "{{ internal_protocol }}://{{ kolla_internal_vip_address }}:{{ monasca_api_port }}" + isDefault: True + basicAuth: false + jsonData: + keystoneAuth: True + #################### # Docker #################### diff --git a/ansible/roles/monasca/tasks/deploy.yml b/ansible/roles/monasca/tasks/deploy.yml index b34874cc42..88878ee2b8 100644 --- a/ansible/roles/monasca/tasks/deploy.yml +++ b/ansible/roles/monasca/tasks/deploy.yml @@ -34,3 +34,5 @@ inventory_hostname in groups['monasca-thresh'] or inventory_hostname in groups['monasca-notification'] or inventory_hostname in groups['monasca-persister'] + +- include_tasks: post_config.yml diff --git a/ansible/roles/monasca/tasks/post_config.yml b/ansible/roles/monasca/tasks/post_config.yml new file mode 100644 index 0000000000..6d9f0ff066 --- /dev/null +++ b/ansible/roles/monasca/tasks/post_config.yml @@ -0,0 +1,90 @@ +--- +- name: Wait for Monasca Grafana to load + uri: + url: "{{ internal_protocol }}://{{ kolla_internal_vip_address }}:{{ monasca_grafana_server_port }}/login" + status_code: 200 + register: result + until: result.get('status') == 200 + retries: 10 + delay: 2 + run_once: true + +- name: Define Monasca Grafana control plane organisation name + set_fact: + monasca_grafana_control_plane_org: "{{ monasca_control_plane_project }}@{{ default_project_domain_name }}" + +- name: List Monasca Grafana organisations + uri: + method: GET + url: '{{ internal_protocol }}://{{ kolla_internal_vip_address }}:{{ monasca_grafana_server_port }}/api/orgs' + user: '{{ monasca_grafana_admin_username }}' + password: '{{ monasca_grafana_admin_password }}' + return_content: true + force_basic_auth: true + register: monasca_grafana_orgs + +- name: Create default control plane organisation if it doesn't exist + uri: + method: POST + url: '{{ internal_protocol }}://{{ kolla_internal_vip_address }}:{{ monasca_grafana_server_port }}/api/orgs' + user: '{{ monasca_grafana_admin_username }}' + password: '{{ monasca_grafana_admin_password }}' + body_format: json + body: + name: '{{ monasca_grafana_control_plane_org }}' + force_basic_auth: true + when: monasca_grafana_control_plane_org not in monasca_grafana_orgs.json|map(attribute='name')|unique + +- name: Lookup Monasca Grafana control plane organisation ID + uri: + method: GET + url: '{{ internal_protocol }}://{{ kolla_internal_vip_address }}:{{ monasca_grafana_server_port }}/api/orgs/name/{{ monasca_grafana_control_plane_org }}' + user: '{{ monasca_grafana_admin_username }}' + password: '{{ monasca_grafana_admin_password }}' + return_content: true + force_basic_auth: true + register: monasca_grafana_conf_org + +- name: Add {{ monasca_grafana_admin_username }} user to control plane organisation + uri: + method: POST + url: '{{ internal_protocol }}://{{ kolla_internal_vip_address }}:{{ monasca_grafana_server_port }}/api/orgs/{{ monasca_grafana_conf_org.json.id }}/users' + user: '{{ monasca_grafana_admin_username }}' + password: '{{ monasca_grafana_admin_password }}' + body: + loginOrEmail: '{{ monasca_grafana_admin_username }}' + role: Admin + force_basic_auth: true + body_format: json + status_code: 200, 409 + register: monasca_grafana_add_user_response + run_once: True + changed_when: monasca_grafana_add_user_response.status == 200 + failed_when: monasca_grafana_add_user_response.status not in [200, 409] or + monasca_grafana_add_user_response.status == 409 and ("User is already" not in monasca_grafana_add_user_response.json.message|default("")) + +- name: Switch Monasca Grafana to the control plane organisation + uri: + method: POST + url: '{{ internal_protocol }}://{{ kolla_internal_vip_address }}:{{ monasca_grafana_server_port }}/api/user/using/{{ monasca_grafana_conf_org.json.id }}' + user: '{{ monasca_grafana_admin_username }}' + password: '{{ monasca_grafana_admin_password }}' + force_basic_auth: true + +- name: Enable Monasca Grafana datasource for control plane organisation + uri: + url: "{{ internal_protocol }}://{{ kolla_internal_vip_address }}:{{ monasca_grafana_server_port }}/api/datasources" + method: POST + user: "{{ monasca_grafana_admin_username }}" + password: "{{ monasca_grafana_admin_password }}" + body: "{{ item.value.data | to_json }}" + body_format: json + force_basic_auth: true + status_code: 200, 409 + register: monasca_grafana_datasource_response + run_once: True + changed_when: monasca_grafana_datasource_response.status == 200 + failed_when: monasca_grafana_datasource_response.status not in [200, 409] or + monasca_grafana_datasource_response.status == 409 and ("Data source with same name already exists" not in monasca_grafana_datasource_response.json.message|default("")) + with_dict: "{{ monasca_grafana_data_sources }}" + when: item.value.enabled | bool