Remove Monasca Grafana service

In the Xena cycle it was decided to remove the Monasca
Grafana fork due to lack of maintenance. This commit removes
the service and provides a limited workaround using the
Monasca Grafana datasource with vanilla Grafana.

Depends-On: I9db7ec2df050fa20317d84f6cea40d1f5fd42e60
Change-Id: I4917ece1951084f6665722ba9a91d47764d3709a
This commit is contained in:
Doug Szumski 2021-04-19 11:31:29 +01:00
parent 4579b76d89
commit 82cf40edf2
17 changed files with 55 additions and 391 deletions

View File

@ -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 }}"

View File

@ -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

View File

@ -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 }}"

View File

@ -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
####################

View File

@ -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

View File

@ -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] }}"

View File

@ -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

View File

@ -11,5 +11,3 @@
meta: flush_handlers
- import_tasks: check.yml
- import_tasks: post_config.yml

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}
]
}

View File

@ -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<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

View File

@ -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 }}"

View File

@ -123,7 +123,6 @@ murano_agent_rabbitmq_password:
monasca_agent_password:
monasca_database_password:
monasca_grafana_admin_password:
monasca_keystone_password:
ironic_database_password:

View File

@ -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.