diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index de3419cc0c..80f70ed947 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -602,7 +602,7 @@ enable_fluentd: "yes" enable_freezer: "no" enable_gnocchi: "no" enable_gnocchi_statsd: "no" -enable_grafana: "no" +enable_grafana: "{{ enable_monasca | bool }}" enable_hacluster: "no" enable_heat: "{{ enable_openstack_core | bool }}" enable_horizon: "{{ enable_openstack_core | bool }}" diff --git a/ansible/roles/grafana/defaults/main.yml b/ansible/roles/grafana/defaults/main.yml index 20c3482116..06d6ff66cb 100644 --- a/ansible/roles/grafana/defaults/main.yml +++ b/ansible/roles/grafana/defaults/main.yml @@ -53,6 +53,15 @@ grafana_data_sources: jsonData: esVersion: 5 timeField: "@timestamp" + monasca: + enabled: "{{ enable_monasca | bool }}" + data: + name: "Monasca" + type: "monasca-datasource" + access: "proxy" + url: "{{ monasca_api_internal_base_endpoint }}" + jsonData: + keystoneAuth: True ########## # Grafana diff --git a/ansible/roles/haproxy/tasks/precheck.yml b/ansible/roles/haproxy/tasks/precheck.yml index 0590c7609a..b0e71b9fe1 100644 --- a/ansible/roles/haproxy/tasks/precheck.yml +++ b/ansible/roles/haproxy/tasks/precheck.yml @@ -564,33 +564,6 @@ - haproxy_vip_prechecks - monasca_log_api_port != monasca_api_port -- name: Checking free port for Monasca Grafana API internal HAProxy - wait_for: - host: "{{ kolla_internal_vip_address }}" - port: "{{ monasca_grafana_server_port }}" - connect_timeout: 1 - timeout: 1 - state: stopped - when: - - enable_monasca | bool - - inventory_hostname in groups['haproxy'] - - haproxy_stat.find('monasca_grafana_server') == -1 - - haproxy_vip_prechecks - -- name: Checking free port for Monasca Grafana API public HAProxy - wait_for: - host: "{{ kolla_external_vip_address }}" - port: "{{ monasca_grafana_server_port }}" - connect_timeout: 1 - timeout: 1 - state: stopped - when: - - haproxy_enable_external_vip | bool - - enable_monasca | bool - - inventory_hostname in groups['haproxy'] - - haproxy_stat.find('monasca_grafana_server_external') == -1 - - haproxy_vip_prechecks - - name: Checking free port for Murano API HAProxy wait_for: host: "{{ kolla_internal_vip_address }}" diff --git a/ansible/roles/monasca/defaults/main.yml b/ansible/roles/monasca/defaults/main.yml index 4755be9df4..ab5c8f8d6b 100644 --- a/ansible/roles/monasca/defaults/main.yml +++ b/ansible/roles/monasca/defaults/main.yml @@ -86,10 +86,12 @@ monasca_services: image: "{{ monasca_agent_image_full }}" volumes: "{{ monasca_agent_forwarder_default_volumes + monasca_agent_forwarder_extra_volumes }}" dimensions: "{{ monasca_agent_dimensions }}" + # TODO(dszumski): Remove monasca-grafana entry here and all other references after the + # Xena release. It exists here to support cleanup operations. monasca-grafana: container_name: monasca_grafana group: monasca-grafana - enabled: true + enabled: false image: "{{ monasca_grafana_image_full }}" volumes: "{{ monasca_grafana_default_volumes + monasca_grafana_extra_volumes }}" dimensions: "{{ monasca_grafana_dimensions }}" @@ -110,7 +112,6 @@ monasca_services: #################### monasca_database_name: "monasca" monasca_database_user: "{% if use_preconfigured_databases | bool and use_common_mariadb_user | bool %}{{ database_user }}{% else %}monasca{% endif %}" -monasca_grafana_database_name: "monasca_grafana" monasca_database_address: "{{ database_address }}" monasca_database_port: "{{ database_port }}" @@ -223,23 +224,6 @@ monasca_agent_check_frequency: 30 monasca_log_pipeline_threads: 2 monasca_metric_pipeline_threads: 2 -# Local password for Grafana. This account allows you to bypass Keystone -# 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: "{{ monasca_api_internal_base_endpoint }}" - isDefault: True - basicAuth: false - jsonData: - keystoneAuth: True - #################### # Docker #################### @@ -385,8 +369,6 @@ monasca_api_public_endpoint: "{{ monasca_api_public_base_endpoint }}/v2.0" monasca_logging_debug: "{{ openstack_logging_debug }}" -monasca_grafana_internal_endpoint: "{{ internal_protocol }}://{{ kolla_internal_fqdn | put_address_in_context('url') }}:{{ monasca_grafana_server_port }}" - #################### # Keystone #################### diff --git a/ansible/roles/monasca/handlers/main.yml b/ansible/roles/monasca/handlers/main.yml index 1346e5356b..a69b8ef8b0 100644 --- a/ansible/roles/monasca/handlers/main.yml +++ b/ansible/roles/monasca/handlers/main.yml @@ -134,56 +134,3 @@ dimensions: "{{ service.dimensions }}" when: - kolla_action != "config" - -- name: Restart first monasca-grafana container - listen: Restart monasca-grafana container - vars: - service_name: "monasca-grafana" - service: "{{ monasca_services[service_name] }}" - become: true - kolla_docker: - action: "recreate_or_restart_container" - common_options: "{{ docker_common_options }}" - name: "{{ service.container_name }}" - image: "{{ service.image }}" - volumes: "{{ service.volumes }}" - dimensions: "{{ service.dimensions }}" - when: - - kolla_action != "config" - - inventory_hostname == groups[service.group]|first - -- name: Waiting for monasca-grafana to start on first node - listen: Restart monasca-grafana container - vars: - service_name: "monasca-grafana" - service: "{{ monasca_services[service_name] }}" - become: true - kolla_toolbox: - module_name: uri - module_args: - url: "http://{{ api_interface_address | put_address_in_context('url') }}:{{ monasca_grafana_server_port }}/login" - status_code: 200 - register: result - until: result.get('status') == 200 - retries: 40 - delay: 2 - when: - - kolla_action != "config" - - inventory_hostname == groups[service.group]|first - -- name: Restart remaining monasca-grafana containers - listen: Restart monasca-grafana container - vars: - service_name: "monasca-grafana" - service: "{{ monasca_services[service_name] }}" - become: true - kolla_docker: - action: "recreate_or_restart_container" - common_options: "{{ docker_common_options }}" - name: "{{ service.container_name }}" - image: "{{ service.image }}" - volumes: "{{ service.volumes }}" - dimensions: "{{ service.dimensions }}" - when: - - kolla_action != "config" - - inventory_hostname != groups[service.group]|first diff --git a/ansible/roles/monasca/tasks/bootstrap.yml b/ansible/roles/monasca/tasks/bootstrap.yml index b116beb06d..0ae726e0fd 100644 --- a/ansible/roles/monasca/tasks/bootstrap.yml +++ b/ansible/roles/monasca/tasks/bootstrap.yml @@ -13,7 +13,6 @@ delegate_to: "{{ groups['monasca-api'][0] }}" with_items: - "{{ monasca_database_name }}" - - "{{ monasca_grafana_database_name }}" when: - not use_preconfigured_databases | bool @@ -29,7 +28,7 @@ name: "{{ monasca_database_user }}" password: "{{ monasca_database_password }}" host: "%" - priv: "{{ monasca_database_name }}.*:ALL/{{ monasca_grafana_database_name }}.*:ALL" + priv: "{{ monasca_database_name }}.*:ALL" append_privs: "yes" run_once: True delegate_to: "{{ groups['monasca-api'][0] }}" diff --git a/ansible/roles/monasca/tasks/config.yml b/ansible/roles/monasca/tasks/config.yml index 41f3a0869c..fe391ff344 100644 --- a/ansible/roles/monasca/tasks/config.yml +++ b/ansible/roles/monasca/tasks/config.yml @@ -347,22 +347,3 @@ - service.enabled | bool notify: - Restart monasca-persister container - -- name: Copying over monasca-grafana config file - vars: - service: "{{ monasca_services['monasca-grafana'] }}" - merge_configs: - sources: - - "{{ role_path }}/templates/monasca-grafana/{{ item }}.j2" - - "{{ node_custom_config }}/monasca/{{ item }}" - - "{{ node_custom_config }}/monasca/{{ inventory_hostname }}/{{ item }}" - dest: "{{ node_config_directory }}/monasca-grafana/{{ item }}" - mode: "0660" - become: true - with_items: - - grafana.ini - when: - - inventory_hostname in groups[service['group']] - - service.enabled | bool - notify: - - Restart monasca-grafana container diff --git a/ansible/roles/monasca/tasks/deploy.yml b/ansible/roles/monasca/tasks/deploy.yml index 49b806555a..b2afb693ea 100644 --- a/ansible/roles/monasca/tasks/deploy.yml +++ b/ansible/roles/monasca/tasks/deploy.yml @@ -11,5 +11,3 @@ meta: flush_handlers - import_tasks: check.yml - -- import_tasks: post_config.yml diff --git a/ansible/roles/monasca/tasks/post_config.yml b/ansible/roles/monasca/tasks/post_config.yml deleted file mode 100644 index bd0df522e8..0000000000 --- a/ansible/roles/monasca/tasks/post_config.yml +++ /dev/null @@ -1,120 +0,0 @@ ---- -- name: Wait for Monasca Grafana to load - become: true - kolla_toolbox: - module_name: uri - module_args: - url: "{{ monasca_grafana_internal_endpoint }}/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_id }}" - -- name: List Monasca Grafana organisations - become: true - kolla_toolbox: - module_name: uri - module_args: - method: GET - url: "{{ monasca_grafana_internal_endpoint }}/api/orgs" - user: '{{ monasca_grafana_admin_username }}' - password: '{{ monasca_grafana_admin_password }}' - return_content: true - force_basic_auth: true - run_once: True - register: monasca_grafana_orgs - -- name: Create default control plane organisation if it doesn't exist - become: true - vars: - monasca_orgs_body: - name: '{{ monasca_grafana_control_plane_org }}' - kolla_toolbox: - module_name: uri - module_args: - method: POST - url: "{{ monasca_grafana_internal_endpoint }}/api/orgs" - user: '{{ monasca_grafana_admin_username }}' - password: '{{ monasca_grafana_admin_password }}' - body_format: json - body: "{{ monasca_orgs_body | to_json }}" - force_basic_auth: true - run_once: 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 - become: true - kolla_toolbox: - module_name: uri - module_args: - method: GET - url: "{{ monasca_grafana_internal_endpoint }}/api/orgs/name/{{ monasca_grafana_control_plane_org }}" # noqa 204 - user: '{{ monasca_grafana_admin_username }}' - password: '{{ monasca_grafana_admin_password }}' - return_content: true - force_basic_auth: true - run_once: True - register: monasca_grafana_conf_org - -- name: Add {{ monasca_grafana_admin_username }} user to control plane organisation - vars: - monasca_user_body: - loginOrEmail: '{{ monasca_grafana_admin_username }}' - role: Admin - become: true - kolla_toolbox: - module_name: uri - module_args: - method: POST - url: "{{ monasca_grafana_internal_endpoint }}/api/orgs/{{ monasca_grafana_conf_org.json.id }}/users" # noqa 204 - user: '{{ monasca_grafana_admin_username }}' - password: '{{ monasca_grafana_admin_password }}' - body: "{{ monasca_user_body | to_json }}" - 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 - become: true - kolla_toolbox: - module_name: uri - module_args: - method: POST - url: "{{ monasca_grafana_internal_endpoint }}/api/user/using/{{ monasca_grafana_conf_org.json.id }}" # noqa 204 - user: '{{ monasca_grafana_admin_username }}' - password: '{{ monasca_grafana_admin_password }}' - force_basic_auth: true - run_once: True - -- name: Enable Monasca Grafana datasource for control plane organisation - become: true - kolla_toolbox: - module_name: uri - module_args: - url: "{{ monasca_grafana_internal_endpoint }}/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 - "name already exists" not in monasca_grafana_datasource_response.json.message|default("")) - with_dict: "{{ monasca_grafana_data_sources }}" - when: item.value.enabled | bool diff --git a/ansible/roles/monasca/tasks/precheck.yml b/ansible/roles/monasca/tasks/precheck.yml index f8ce136638..51196b9967 100644 --- a/ansible/roles/monasca/tasks/precheck.yml +++ b/ansible/roles/monasca/tasks/precheck.yml @@ -43,14 +43,3 @@ when: - inventory_hostname in groups[monasca_services['monasca-agent-statsd']['group']] - container_facts['monasca_agent_statsd'] is not defined - -- name: Checking free port for monasca-grafana server - wait_for: - host: "{{ api_interface_address }}" - port: "{{ monasca_grafana_server_port }}" - connect_timeout: 1 - timeout: 1 - state: stopped - when: - - inventory_hostname in groups[monasca_services['monasca-grafana']['group']] - - container_facts['monasca_grafana'] is not defined diff --git a/ansible/roles/monasca/tasks/upgrade.yml b/ansible/roles/monasca/tasks/upgrade.yml index c5b8e5bbe2..ff9990bb1d 100644 --- a/ansible/roles/monasca/tasks/upgrade.yml +++ b/ansible/roles/monasca/tasks/upgrade.yml @@ -1,40 +1,10 @@ --- -- name: Checking if Monasca Grafana container needs upgrading - vars: - service_name: "monasca-grafana" - service: "{{ monasca_services[service_name] }}" - become: true - kolla_docker: - action: "compare_image" - common_options: "{{ docker_common_options }}" - name: "{{ project_name }}" - image: "{{ monasca_grafana_image_full }}" - when: inventory_hostname in groups['monasca-grafana'] - register: monasca_grafana_differs - - import_tasks: config.yml - import_tasks: cleanup.yml - import_tasks: check-containers.yml -# NOTE(dszumski): We don't want old Grafana instances running after -# a new instance has updated the DB schema. Since the first instance -# is upgraded first, we stop all the other ones. -- name: Stopping all Monasca Grafana instances but the first node - vars: - service_name: "monasca-grafana" - service: "{{ monasca_services[service_name] }}" - become: true - kolla_docker: - action: "stop_container" - common_options: "{{ docker_common_options }}" - name: "{{ service.container_name }}" - when: - - inventory_hostname in groups['monasca-grafana'] - - inventory_hostname != groups['monasca-grafana']|first - - monasca_grafana_differs['result'] - - import_tasks: register.yml - import_tasks: bootstrap_service.yml diff --git a/ansible/roles/monasca/templates/monasca-grafana/grafana.ini.j2 b/ansible/roles/monasca/templates/monasca-grafana/grafana.ini.j2 deleted file mode 100644 index 89067ef7bf..0000000000 --- a/ansible/roles/monasca/templates/monasca-grafana/grafana.ini.j2 +++ /dev/null @@ -1,55 +0,0 @@ -[paths] -data = /var/lib/grafana -logs = /var/log/kolla/monasca -plugins = /var/lib/grafana/plugins -provisioning = /etc/grafana/provisioning - -[users] -login_hint = OpenStack credentials -allow_org_create = false -allow_sign_up = false - -[server] -protocol = http -http_addr = {{ api_interface_address }} -http_port = {{ monasca_grafana_server_port }} -router_logging = true -static_root_path = public -enable_gzip = false - -[database] -type = mysql -host = {{ monasca_database_address | put_address_in_context('url') }}:{{ monasca_database_port }} -name = {{ monasca_grafana_database_name }} -user = {{ monasca_database_user }} -password = {{ monasca_database_password }} -ssl_mode = disable - -[alerting] -enabled = false -execute_alerts = false - -[session] -provider = mysql -provider_config = {{ monasca_database_user }}:{{ monasca_database_password }}@tcp({{ monasca_database_address | put_address_in_context('url') }}:{{ monasca_database_port }})/{{ monasca_grafana_database_name }} - -cookie_name = monasca_grafana_sess -cookie_secure = false -session_life_time = 86400 - -[analytics] -reporting_enabled = false -check_for_updates = false - -[security] -admin_user = {{ monasca_grafana_admin_username }} -admin_password = {{ monasca_grafana_admin_password }} - -[auth.keystone] -enabled = true -auth_url = {{ keystone_internal_url }} -default_domain = {{ default_project_domain_id }} -default_role = Viewer -admin_roles = admin -editor_roles = _member_ -verify_ssl_cert = false diff --git a/ansible/roles/monasca/templates/monasca-grafana/monasca-grafana.json.j2 b/ansible/roles/monasca/templates/monasca-grafana/monasca-grafana.json.j2 deleted file mode 100644 index b3fd0a6128..0000000000 --- a/ansible/roles/monasca/templates/monasca-grafana/monasca-grafana.json.j2 +++ /dev/null @@ -1,23 +0,0 @@ -{ - "command": "/usr/sbin/grafana-server --config=/etc/grafana/grafana.ini", - "config_files": [ - { - "source": "{{ container_config_directory }}/grafana.ini", - "dest": "/etc/grafana/grafana.ini", - "owner": "monasca", - "perm": "0600" - } - ], - "permissions": [ - { - "path": "/var/lib/grafana", - "owner": "monasca:monasca", - "recurse": true - }, - { - "path": "/var/log/kolla/monasca", - "owner": "monasca:monasca", - "recurse": true - } - ] -} diff --git a/doc/source/reference/logging-and-monitoring/monasca-guide.rst b/doc/source/reference/logging-and-monitoring/monasca-guide.rst index 6495cefeae..937138950d 100644 --- a/doc/source/reference/logging-and-monitoring/monasca-guide.rst +++ b/doc/source/reference/logging-and-monitoring/monasca-guide.rst @@ -261,9 +261,25 @@ Alternatively we could have assigned the user the read only role: openstack role add monasca_read_only_user --project monasca_control_plane --user mon_user -The user is now active and the credentials can be used to log into the -Monasca fork of Grafana which will be available by default on port `3001` on -both internal and external VIPs. +The user is now active and the credentials can be used to generate an +OpenStack token which can be added to the Monasca Grafana datasource in +Grafana. For example, first set the OpenStack credentials for the project +you wish to view metrics in. This is normally easiest to do by logging into +Horizon with the user you have configured for monitoring, switching to +the OpenStack project you wish to view metrics in, and then downloading +the credentials file for that project. The credentials file can then +be sourced from the command line. You can then generate a token for the +datasource using the following command: + +.. code-block:: console + + openstack token issue + +You should then log into Grafana. By default Grafana is available on port +`3000` on both internal and external VIPs. See the +:ref:`Grafana guide` for further details. Once in Grafana +you can select the Monasca datasource and add your token to it. You are +then ready to view metrics from Monasca. For log analysis Kibana is also available, by default on port `5601` on both internal and external VIPs. Currently the Keystone authentication plugin is @@ -280,25 +296,16 @@ databases. Migration of time series or log data is not considered. Migrating service databases ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The first step is to dump copies of the existing databases from wherever -they are deployed. For example: +The first step is to dump copies of the existing Monasca database. For example: .. code-block:: console - mysqldump -h 10.0.0.1 -u grafana_db_user -p grafana_db > grafana_db.sql mysqldump -h 10.0.0.1 -u monasca_db_user -p monasca_db > monasca_db.sql -These can then be loaded into the Kolla managed databases. Note that it -simplest to get the database password, IP and port from the Monasca API Kolla -config file in `/etc/kolla/monasca-api`. Note that the commands below drop and -recreate each database before loading in the existing database. - -.. code-block:: console - - mysql -h 192.168.0.1 -u monasca -p -e "drop database monasca_grafana; create database monasca_grafana;" - mysql -h 192.168.0.1 -u monasca -p monasca_grafana < grafana_db.sql - -A similar procedure is used to load the Monasca service database: +This can then be used to replace the Kolla managed Monasca database. Note that +it is simplest to get the database password, IP and port from the Monasca API +Kolla config file in `/etc/kolla/monasca-api`. Also note that the commands +below drop and recreate the database before loading in the existing database. .. code-block:: console @@ -317,7 +324,6 @@ The passwords which you may wish to set to match the original passwords are: .. code-block:: console monasca_agent_password: - monasca_grafana_admin_password: These can be found in the Kolla Ansible passwords file. @@ -445,13 +451,11 @@ Thresh and Monasca Notification. This can have a significant effect. Security impact ~~~~~~~~~~~~~~~ -The Monasca API, Log API and Grafana fork will be exposed on public -endpoints via HAProxy/Keepalived. If your public endpoints are exposed -externally, then you should use a firewall to restrict access. In -particular, external access to the Monasca Grafana endpoint should be -blocked, since it is effectively unmaintained and is likely to contain -unpatched vulnerabilities. You should also consider whether you -wish to allow tenants to access these services on the internal network. +The Monasca API, Log API, Grafana and Kibana ports will be exposed on +public endpoints via HAProxy/Keepalived. If your public endpoints are +exposed externally, then you should use a firewall to restrict access. +You should also consider whether you wish to allow tenants to access +these services on the internal network. If you are using the multi-tenant capabilities of Monasca there is a risk that tenants could gain access to other tenants logs and metrics. This could diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml index 5b595322b1..00abf88819 100644 --- a/etc/kolla/globals.yml +++ b/etc/kolla/globals.yml @@ -296,7 +296,7 @@ #enable_freezer: "no" #enable_gnocchi: "no" #enable_gnocchi_statsd: "no" -#enable_grafana: "no" +#enable_grafana: "{{ enable_monasca | bool }}" #enable_heat: "{{ enable_openstack_core | bool }}" #enable_horizon: "{{ enable_openstack_core | bool }}" #enable_horizon_blazar: "{{ enable_blazar | bool }}" diff --git a/etc/kolla/passwords.yml b/etc/kolla/passwords.yml index 2ed54f9f57..0ab2388d98 100644 --- a/etc/kolla/passwords.yml +++ b/etc/kolla/passwords.yml @@ -123,7 +123,6 @@ murano_agent_rabbitmq_password: monasca_agent_password: monasca_database_password: -monasca_grafana_admin_password: monasca_keystone_password: ironic_database_password: diff --git a/releasenotes/notes/remove-monasca-grafana-43cf1f74b09a6e54.yaml b/releasenotes/notes/remove-monasca-grafana-43cf1f74b09a6e54.yaml new file mode 100644 index 0000000000..b921b7182b --- /dev/null +++ b/releasenotes/notes/remove-monasca-grafana-43cf1f74b09a6e54.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + Due to the removal of the Monasca Grafana fork, the Monasca datasource + is now configured in vanilla Grafana. +upgrade: + - | + Service containers and configuration for the Monasca Grafana service + will be removed automatically. It is up to the operator to remove the + related HAProxy configuration, the Monasca Grafana database, and + associated Docker volumes.