diff --git a/defaults/main.yml b/defaults/main.yml index 4fefb07..f68d97b 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -15,157 +15,309 @@ # # (c) 2016 Donovan Francesco # (c) 2016 Paul Stevens + +## Verbosity Options +debug: False + +# Set the package install state for distribution and pip packages +# Options are 'present' and 'latest' monasca_package_state: "latest" monasca_pip_package_state: "latest" -debug: False +monasca_developer_mode: false +monasca_api_git_repo: "https://git.openstack.org/openstack/monasca-api" +monasca_api_git_install_branch: master +monasca_common_git_repo: "https://git.openstack.org/openstack/monasca-common" +monasca_common_git_install_branch: master +monasca_thresh_git_repo: "https://git.openstack.org/openstack/monasca-thresh" +monasca_thresh_git_install_branch: master +monasca_notification_git_repo: "https://git.openstack.org/openstack/monasca-notification" +monasca_notification_git_install_branch: master +monasca_persister_git_repo: "https://git.openstack.org/openstack/monasca-persister" +monasca_persister_git_install_branch: master +monasca_python_client_git_repo: "https://git.openstack.org/openstack/python-monascaclient" +monasca_python_client_git_install_branch: master +monasca_statsd_git_repo: "https://git.openstack.org/openstack/monasca-statsd" +monasca_statsd_git_install_branch: master -monasca_system_user_name: monasca -monasca_system_group_name: monasca -monasca_system_comment: Monasca system user -monasca_system_user_shell: /bin/false -monasca_system_user_home: "/var/lib/{{ monasca_system_user_name }}" -monasca_log_directory: "/var/log/monasca" -monasca_conf_directory: "/etc/monasca" -monasca_lock_path: "/var/lock/monasca" - -monasca_service_name: monasca -monasca_service_user_name: monasca -monasca_readonly_user_name: monasca-read-only -monasca_service_type: monitoring -monasca_service_description: "OpenStack Monitoring Service (Monasca)" -monasca_service_project_name: service -monasca_service_role_names: - - admin -monasca_role_names: - - monasca-user -monasca_service_region: RegionOne -monasca_service_host: "0.0.0.0" -monasca_bind_port: 8070 -monasca_service_publicuri_proto: http -monasca_service_publicurl: "{{ monasca_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ monasca_bind_port }}/v2.0" -monasca_service_internaluri_proto: http -monasca_service_internalurl: "{{ monasca_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ monasca_bind_port }}/v2.0" -monasca_service_adminuri_proto: http -monasca_service_adminurl: "{{ monasca_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ monasca_bind_port }}/v2.0" +monasca_developer_constraints: + - "git+{{ monasca_api_git_repo }}@{{ monasca_api_git_install_branch }}#egg=monasca-api" + - "git+{{ monasca_common_git_repo }}@{{ monasca_common_git_install_branch }}#egg=monasca-common" + - "git+{{ monasca_thresh_git_repo }}@{{ monasca_thresh_git_install_branch }}#egg=monasca-thresh" + - "git+{{ monasca_notification_git_repo }}@{{ monasca_notification_git_install_branch }}#egg=monasca-notification" + - "git+{{ monasca_persister_git_repo }}@{{ monasca_persister_git_install_branch }}#egg=monasca-persister" + - "git+{{ monasca_python_client_git_repo }}@{{ monasca_python_client_git_install_branch }}#egg=python-monascaclient" # Name of the virtual env to deploy into monasca_venv_tag: untagged +monasca_bin: "/openstack/venvs/monasca-{{ monasca_venv_tag }}/bin" +monasca_etc_dir: "{{ monasca_bin | dirname }}/etc/monasca" +_monasca_thresh_version: "2.1.1" + # venv_download, even when true, will use the fallback method of building the # venv from scratch if the venv download fails. monasca_venv_download: "{{ not monasca_developer_mode | bool }}" monasca_venv_download_url: http://127.0.0.1/venvs/untagged/ubuntu/monasca.tgz -monasca_bin: "/openstack/venvs/monasca-{{ monasca_venv_tag }}/bin" +## System info +monasca_system_user_name: monasca +monasca_system_group_name: monasca +monasca_system_shell: /bin/false +monasca_system_comment: monasca system user +monasca_system_user_home: "/var/lib/{{ monasca_system_user_name }}" -# Toggle developer mode -monasca_developer_mode: false +## DB info +monasca_galera_database: monasca +monasca_galera_user: monasca -monasca_api_git_repo: "https://git.openstack.org/openstack/monasca-api" -monasca_api_git_install_branch: master - -monasca_log_api_bind_port: 5607 -monasca_log_api_git_repo: "https://git.openstack.org/openstack/monasca-log-api" -monasca_log_api_git_install_branch: master - -monasca_ceilometer_git_repo: "https://git.openstack.org/openstack/monasca-ceilometer" -monasca_ceilometer_git_install_branch: master - -monasca_common_git_repo: "https://git.openstack.org/openstack/monasca-common" -monasca_common_git_install_branch: master - -monasca_thresh_git_repo: "https://git.openstack.org/openstack/monasca-thresh" -monasca_thresh_git_install_branch: master - -monasca_transform_git_repo: "https://git.openstack.org/openstack/monasca-transform" -monasca_transform_git_install_branch: master - -monasca_notification_git_repo: "https://git.openstack.org/openstack/monasca-notification" -monasca_notification_git_install_branch: master - -monasca_persister_git_repo: "https://git.openstack.org/openstack/monasca-persister" -monasca_persister_git_install_branch: master - -monasca_python_client_git_repo: "https://git.openstack.org/openstack/python-monascaclient" -monasca_python_client_git_install_branch: master - -monasca_developer_constraints: - - "git+{{ monasca_api_git_repo }}@{{ monasca_api_git_install_branch }}#egg=monasca-api" - - "git+{{ monasca_log_api_git_repo }}@{{ monasca_log_api_git_install_branch }}#egg=monasca-log-api" - - "git+{{ monasca_ceilometer_git_repo }}@{{ monasca_ceilometer_git_install_branch }}#egg=monasca-ceilometer" - - "git+{{ monasca_common_git_repo }}@{{ monasca_common_git_install_branch }}#egg=monasca-common" - - "git+{{ monasca_thresh_git_repo }}@{{ monasca_thresh_git_install_branch }}#egg=monasca-thresh" - - "git+{{ monasca_transform_git_repo }}@{{ monasca_transform_git_install_branch }}#egg=monasca-transform" - - "git+{{ monasca_notification_git_repo }}@{{ monasca_notification_git_install_branch }}#egg=monasca-notification" - - "git+{{ monasca_persister_git_repo }}@{{ monasca_persister_git_install_branch }}#egg=monasca-persister" - - "git+{{ monasca_python_client_git_repo }}@{{ monasca_python_client_git_install_branch }}#egg=python-monascaclient" +## InfluxDB info +monasca_influxdb_database: monasca +monasca_api_influxdb_user: monasca_api +monasca_api_influxdb_password: password +monasca_persister_influxdb_user: monasca_persister +monasca_persister_influxdb_password: password +monasca_influxdb_host: "{{ influxdb_host }}" +monasca_influxdb_port: "{{ influxdb_port }}" +monasca_influxdb_admin: root +monasca_influxdb_admin_password: root +monasca_influxdb_replication_factor: 1 +monasca_influxdb_retention_policy: "90d" +monasca_influxdb_shard_duration: "7d" +monasca_influxdb_users: + - username: "{{ monasca_api_influxdb_user }}" + password: "{{ monasca_api_influxdb_password }}" + - username: "{{ monasca_persister_influxdb_user }}" + password: "{{ monasca_persister_influxdb_password }}" # Keystone AuthToken/Middleware monasca_keystone_auth_plugin: password monasca_service_project_domain_name: Default monasca_service_user_domain_name: default -# Galera defaults -monasca_galera_address: 127.0.0.1 +monasca_role_name: admin +monasca_api_bind_address: 0.0.0.0 +monasca_api_service_port: 8070 -# Grafana Galera -monasca_grafana_galera_database: grafana -monasca_grafana_galera_username: grafana +## Service Type and Data +monasca_service_region: RegionOne +monasca_service_name: monasca +monasca_service_port: 8070 +monasca_service_proto: http +monasca_service_publicuri_proto: "{{ openstack_service_publicuri_proto | default(monasca_service_proto) }}" +monasca_service_adminuri_proto: "{{ openstack_service_adminuri_proto | default(monasca_service_proto) }}" +monasca_service_internaluri_proto: "{{ openstack_service_internaluri_proto | default(monasca_service_proto) }}" +monasca_service_type: monitoring +monasca_service_description: "OpenStack Monitoring Service" +monasca_service_user_name: monasca +monasca_service_project_name: service +monasca_service_project_domain_id: default +monasca_service_user_domain_id: default +monasca_service_publicuri: "{{ monasca_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ monasca_service_port }}" +monasca_service_publicurl: "{{ monasca_service_publicuri }}/v2.0" +monasca_service_internaluri: "{{ monasca_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ monasca_service_port }}" +monasca_service_internalurl: "{{ monasca_service_internaluri }}/v2.0" +monasca_service_adminuri: "{{ monasca_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ monasca_service_port }}" +monasca_service_adminurl: "{{ monasca_service_adminuri }}/v2.0" -monasca_backend_database: "influxdb" -monasca_use_mod_wsgi: false +## Monasca configuration +monasca_log_level: INFO +monasca_user_roles: + - monasca-user +monasca_agent_roles: + - monasca-agent +monasca_read_only_user_roles: + - monasca-read-only-user -monasca_api_metrics_driver: "monasca_api.common.repositories.influxdb.metrics_repository:MetricsRepository" +monasca_agent_user_name: monasca-agent +monasca_agent_project_name: admin +monasca_partition_interval_recheck_seconds: 15 -monasca_api_init_config_overrides: {} -monasca_log_api_init_config_overrides: {} +## Kafka configuration +kafka_events_partitions: 12 +kafka_metrics_partitions: 64 +# This should be the number of systems running the Notification Engine +kafka_retry_notifications_partitions: "{{ groups['monasca_notification'] | length }}" +kafka_replicas: "{{ groups['monasca_kafka'] | length }}" +kafka_topics: + metrics: + replicas: "{{ kafka_replicas }}" + partitions: "{{ kafka_metrics_partitions }}" + events: + replicas: "{{ kafka_replicas }}" + partitions: "{{ kafka_events_partitions }}" + alarm-state-transitions: + replicas: "{{ kafka_replicas }}" + partitions: "{{ kafka_events_partitions }}" + alarm-notifications: + replicas: "{{ kafka_replicas }}" + partitions: "{{ kafka_events_partitions }}" + retry-notifications: + replicas: "{{ kafka_replicas }}" + partitions: "{{ kafka_retry_notifications_partitions }}" + 60-seconds-notifications: + replicas: "{{ kafka_replicas }}" + partitions: "{{ kafka_retry_notifications_partitions }}" + +monasca_notification_address: root@localhost +monasca_notification_name: 'Default Email' +monasca_notification_type: EMAIL + +monasca_default_alarms: + - name: "Host Status" + description: "Alarms when the specified host is down or not reachable" + severity: "HIGH" + expression: "host_alive_status > 0" + - name: "HTTP Status" + description: "Alarms when the specified HTTP endpoint is down or not reachable" + severity: "HIGH" + expression: "http_status > 0" + match_by: ["service", "component", "hostname", "url"] + - name: "CPU Usage" + description: "Alarms when CPU usage is high" + expression: "avg(cpu.idle_perc) < 10 times 3" + - name: "Disk Inode Usage" + description: "Alarms when disk inode usage is high" + expression: "disk.inode_used_perc > 90" + match_by: ["hostname", "device"] + - name: "Disk Usage" + description: "Alarms when disk usage is high" + expression: "disk.space_used_perc > 90" + match_by: ["hostname", "device"] + - name: "Memory Usage" + description: "Alarms when memory usage is high" + severity: "MEDIUM" + expression: "avg(mem.usable_perc) < 10 times 3" + - name: "Kernel Crash Dumps" + description: "Kernel crash dumps are available on disk" + expression: "crash.dump_count > 1" + - name: "Network Errors" + description: "Alarms when either incoming or outgoing network errors are high" + severity: "MEDIUM" + expression: "net.in_errors_sec > 5 or net.out_errors_sec > 5" + - name: "Process Check" + description: "Alarms when the specified process is not running" + severity: "HIGH" + expression: "process.pid_count < 1" + match_by: ["process_name", "hostname"] + - name: "Instance CPU Usage" + description: "Alarms when the CPU usage of the specified instance is high" + expression: "avg(cpu.utilization_norm_perc) > 90 times 3" + match_by: ["resource_id"] + - name: "RabbitMQ Queue Depth" + description: "Alarms when the depth of the message queue is high" + expression: "avg(rabbitmq.queue.messages) > 10 times 3" + severity: "MEDIUM" + match_by: ["queue", "hostname"] + - name: "MySQL Slow Query Rate" + description: "Alarms when the slow query rate is high" + expression: "avg(mysql.performance.slow_queries) > 10 times 3" + - name: "Apache Status" + description: "Alarms on failure to reach the Apache status endpoint" + expression: "apache.status > 0" + severity: "HIGH" + - name: "Apache Idle Worker Count" + description: "Alarms when there are no idle workers in the Apache server" + expression: "avg(apache.performance.idle_worker_count) < 1 times 3" + severity: "MEDIUM" + - name: "NTP Time Sync" + description: "Alarms when the NTP time offset is high" + expression: "ntp.offset > 5 or ntp.offset < -5" + - name: "Kafka Consumer Lag" + description: "Alarms when the specified consumer_group is not keeping up with the incoming messages" + severity: "MEDIUM" + expression: "avg(kafka.consumer_lag) > 1000 times 3" + match_by: ["consumer_group", "hostname"] + - name: "Monasca Agent Collection Time" + description: "Alarms when the elapsed time the Monasca Agent takes to collect metrics is high" + expression: "avg(monasca.collection_time_sec) > 5 times 3" + - name: "Monasca Notification DB Query Time" + description: "Alarms when the elapsed time for queries to the Configuration DB by the Monasca Notification Engine is high" + expression: "avg(monasca.config_db_time) > 5 times 3" + - name: "Monasca Notification Email Time" + description: "Alarms when the elapsed time to send emails by the Monasca Notification Engine is high" + expression: "avg(monasca.email_time) > 2 times 3" + - name: "ZooKeeper Latency" + description: "Alarms when the ZooKeeper latency is high" + expression: "avg(zookeeper.avg_latency_sec) > 1 times 3" + - name: "HAProxy Backend Status" + description: "Alarms when the backend status is unavailable" + expression: "last(haproxy.count_per_status{status=unavailable})>0" + severity: "CRITICAL" + match_by: ["component"] + + +## Cap the maximum number of threads / workers when a user value is unspecified. +monasca_api_workers_max: 16 +monasca_api_workers: "{{ [[ansible_processor_vcpus|default(2) // 2, 1] | max, monasca_api_workers_max] | min }}" +monasca_persister_workers_max: 16 +monasca_persister_workers: "{{ [[ansible_processor_vcpus|default(2) // 2, 1] | max, monasca_persister_workers_max] | min }}" + +monasca_service_in_ldap: False + +## Monasca packages that must be installed before anything else +monasca_requires_pip_packages: + - httplib2 + - python-keystoneclient + - python-monascaclient + - virtualenv + - virtualenv-tools + +monasca_pip_packages: + - cassandra-driver + - gunicorn + - influxdb + - keystoneauth1 + - monasca-api + - monasca-common + - monasca-persister + - monasca-notification + - monasca-statsd + - pycrypto + - PyOpenSSL + - python-monascaclient + - python-memcached + +## Service Names monasca_services: monasca-api: group: monasca_api service_name: monasca-api service_init_bin: "{{ monasca_bin }}/gunicorn" - service_init_options: "-n monasca-api -k eventlet --worker-connections=2000 --backlog=1000 --paste /etc/monasca/api-config.ini" - init_config_overrides: "{{ monasca_api_init_config_overrides }}" - monasca-log-api: - group: monasca_log_api - service_name: monasca-log-api - service_init_bin: "{{ monasca_bin }}/gunicorn" - service_init_options: "-n monasca-log-api -k eventlet --worker-connections=2000 --backlog=1000 --paste /etc/monasca/log-api-config.ini" - init_config_overrides: "{{ monasca_log_api_init_config_overrides }}" + service_init_options: "-n monasca-api -k eventlet --worker-connections=2000 --backlog=1000 --paste /etc/monasca/api-config.ini -w {{ monasca_api_workers }}" + init_config_overrides: "{{ monasca_api_init_overrides }}" + monasca-persister: + group: monasca_persister + service_name: monasca-persister + service_init_bin: "{{ monasca_bin }}/python {{ monasca_bin }}/../lib/python2.7/site-packages/monasca_persister/persister.py" + service_init_options: "--config-file /etc/monasca/persister.conf" + init_config_overrides: "{{ monasca_persister_init_overrides }}" + monasca-thresh: + group: monasca_thresh + service_name: monasca-thresh + service_init_bin: "/opt/storm/current/bin/storm jar /usr/share/monasca-thresh/thresh/target/monasca-thresh-{{ _monasca_thresh_version.stdout | default('2.1.1') }}-shaded.jar" + service_init_options: "monasca.thresh.ThresholdingEngine /etc/monasca/thresh-config.yml thresh-cluster" + init_config_overrides: "{{ monasca_thresh_init_overrides }}" + monasca-notification: + group: monasca_notification + service_name: monasca-notification + init_config_overrides: "{{ monasca_notification_init_overrides }}" -monasca_requires_pip_packages: - - httplib2 - - python-glanceclient - - python-keystoneclient - - python-monascaclient - - pyyaml - - virtualenv - - virtualenv-tools - -monasca_pip_packages: - - keystoneauth1 - - simport - - gunicorn - - python-memcached - - monasca-common - - monasca-api - - monasca-log-api - - monasca-persister - - monasca-transform - - monasca-notification - - influxdb - -monasca_api_paste_ini_overrides: {} -monasca_api_config_overrides: {} -monasca_log_api_paste_ini_overrides: {} -monasca_log_api_config_overrides: {} -monasca_log_api_logging_overrides: {} -monasca_notification_yml_overrides: {} -monasca_persister_yml_overrides: {} +monasca_api_init_overrides: {} +monasca_persister_init_overrides: {} +monasca_thresh_init_overrides: {} +monasca_notification_init_overrides: {} # This variable is used by the repo_build process to determine # which host group to check for members of before building the # pip packages required by this role. The value is picked up # by the py_pkgs lookup. monasca_role_project_group: monasca_all + +monasca_api_config_overrides: {} +monasca_api_config_ini_overrides: {} +monasca_api_logging_config_overrides: {} +monasca_persister_config_overrides: {} +monasca_persister_logging_config_overrides: {} +monasca_thresh_config_overrides: {} +monasca_notification_config_overrides: {} diff --git a/doc/source/configure-monasca.rst b/doc/source/configure-monasca.rst new file mode 100644 index 0000000..f9fb7a8 --- /dev/null +++ b/doc/source/configure-monasca.rst @@ -0,0 +1,96 @@ +======================================================= +Configuring the Monitoring (monasca) service (optional) +======================================================= + +.. note:: + + This feature is experimental at this time and it has not been fully + production tested yet. + +Monasca is an open-source multi-tenant, highly scalable, performant, +fault-tolerant monitoring-as-a-service solution that integrates with +OpenStack. It uses a REST API for high-speed metrics processing and +querying and has a streaming alarm engine and notification engine. + +Monasca is configured using the ``/etc/openstack_deploy/conf.d/monasca.yml`` +file and the ``/etc/openstack_deploy/user_variables.yml`` file. + +Configuring target hosts +~~~~~~~~~~~~~~~~~~~~~~~~ + +Modify ``/etc/openstack_deploy/conf.d/monasca.yml`` by adding a list +containing the infrastructure target hosts for the ``monasca-infra_hosts`` +and its required services: + +In ``monasca.yml``: + + .. code-block:: yaml + + monasca-infra_hosts: + infra01: + ip: INFRA01_IP_ADDRESS + infra02: + ip: INFRA02_IP_ADDRESS + infra03: + ip: INFRA03_IP_ADDRESS + + monasca-zookeeper_hosts: + infra01: + ip: INFRA01_IP_ADDRESS + infra02: + ip: INFRA02_IP_ADDRESS + infra03: + ip: INFRA03_IP_ADDRESS + + monasca-kafka_hosts: + infra01: + ip: INFRA01_IP_ADDRESS + infra02: + ip: INFRA02_IP_ADDRESS + infra03: + ip: INFRA03_IP_ADDRESS + + monasca-influxdb_hosts: + infra01: + ip: INFRA01_IP_ADDRESS + infra02: + ip: INFRA02_IP_ADDRESS + infra03: + ip: INFRA03_IP_ADDRESS + + +Replace ``*_IP_ADDRESS`` with the IP address of the br-mgmt container +management bridge on each target host. + +This hosts will be used to deploy the containers where monasca and its +required services will be installed. + +Setting up Monasca +~~~~~~~~~~~~~~~~~~ + +Run the setup-hosts playbook, to create the monasca containers, and the +repo-build playbook to update the repository with the monasca packages: + + .. code-block:: console + + # cd /opt/openstack-ansible/playbooks + # openstack-ansible setup-hosts.yml + # openstack-ansible repo-build.yml + +Run the monasca and horizon playbooks to install monasca and enable the +Monitoring panel in horizon: + + .. code-block:: console + + # cd /opt/openstack-ansible/playbooks + # openstack-ansible os-monasca-install.yml + # openstack-ansible os-horizon-install.yml + +Monitoring Hosts +~~~~~~~~~~~~~~~~ + +To start monitoring, monasca requires the monasca-agent to be deployed on +the hosts which will be monitored. The monasca-agent deployment and +configuration is covered by the `monasca-agent role`_. + +.. _monasca-agent role: https://github.com/openstack/openstack-ansible-os_monasca-agent diff --git a/doc/source/index.rst b/doc/source/index.rst index ce0b375..b4c3ed4 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -2,8 +2,20 @@ OpenStack-Ansible Monasca ========================= +.. toctree:: + :maxdepth: 2 + + configure-monasca.rst + Ansible role for deploying Monasca Monitoring-as-a-Service. +This role installs the following Systemd services: + + * monasca-api + * monasca-notification + * monasca-persister + * monasca-thresh + To clone or view the source code for this repository, visit the role repository for `os_monasca `_. @@ -19,13 +31,16 @@ Required variables None. -Dependencies -~~~~~~~~~~~~ - -None. - Example playbook ~~~~~~~~~~~~~~~~ .. literalinclude:: ../../examples/playbook.yml :language: yaml + +Tags +~~~~ + +This role supports the following tags: + + * ``monasca-install``: used to install and upgrade; + * ``monasca-config``: used to manage configuration; diff --git a/examples/playbook.yml b/examples/playbook.yml index 92756e2..8d28314 100644 --- a/examples/playbook.yml +++ b/examples/playbook.yml @@ -1,5 +1,30 @@ -- name: Install Monasca - hosts: all - user: root - roles: - - role: "openstack-ansible-os_monasca" +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Install monasca server + hosts: monasca_all + user: root + roles: + - { role: "os_monasca", tags: [ "os-monasca" ] } + vars: + external_lb_vip_address: 172.16.24.1 + internal_lb_vip_address: 192.168.0.1 + monasca_galera_address: "{{ internal_lb_vip_address }}" + monasca_container_mysql_password: "SuperSecretePassword1" + monasca_service_password: "SuperSecretePassword2" + monasca_influxdb_admin_password: "secrete" + monasca_api_influxdb_password: "secrete" + monasca_persister_influxdb_password: "secrete" + monasca_agent_password: "secrete" + grafana_mysql_host: "{{ monasca_galera_address }}" + grafana_admin_password: "secrete" + grafana_galera_password: "secrete" diff --git a/extras/ansible-role-requirements.yml b/extras/ansible-role-requirements.yml new file mode 100644 index 0000000..414a649 --- /dev/null +++ b/extras/ansible-role-requirements.yml @@ -0,0 +1,15 @@ +- name: ansible-zookeeper + scm: git + src: https://github.com/Chillisystems/ansible-zookeeper +- name: ansible-kafka + scm: git + src: https://github.com/flaviodsr/ansible-kafka +- name: ansible-storm + scm: git + src: https://github.com/flaviodsr/ansible-storm +- name: ansible-influxdb + scm: git + src: https://github.com/flaviodsr/ansible-influxdb +- name: grafana-ansible + scm: git + src: https://github.com/flaviodsr/grafana-ansible diff --git a/extras/conf.d/monasca.yml b/extras/conf.d/monasca.yml new file mode 100644 index 0000000..2c1f015 --- /dev/null +++ b/extras/conf.d/monasca.yml @@ -0,0 +1,20 @@ +# The infra nodes that will be running the monasca services +monasca-infra_hosts: + aio1: + ip: 172.29.236.100 + +monasca-zookeeper_hosts: + aio1: + ip: 172.29.236.100 + +monasca-kafka_hosts: + aio1: + ip: 172.29.236.100 + +monasca-storm_hosts: + aio1: + ip: 172.29.236.100 + +monasca-influxdb_hosts: + aio1: + ip: 172.29.236.100 diff --git a/extras/conf.d/monasca.yml.example b/extras/conf.d/monasca.yml.example deleted file mode 100644 index 8638553..0000000 --- a/extras/conf.d/monasca.yml.example +++ /dev/null @@ -1,36 +0,0 @@ -# The infra nodes that will be running the monasca services -monasca-infra_hosts: - infra1: - ip: 172.20.236.111 - infra2: - ip: 172.20.236.112 - infra3: - ip: 172.20.236.113 -monasca-zookeeper_hosts: - infra1: - ip: 172.20.236.111 - infra2: - ip: 172.20.236.112 - infra3: - ip: 172.20.236.113 -monasca-kafka_hosts: - infra1: - ip: 172.20.236.111 - infra2: - ip: 172.20.236.112 - infra3: - ip: 172.20.236.113 -monasca-storm_hosts: - infra1: - ip: 172.20.236.111 - infra2: - ip: 172.20.236.112 - infra3: - ip: 172.20.236.113 -monasca-influxdb_hosts: - infra1: - ip: 172.20.236.111 - infra2: - ip: 172.20.236.112 - infra3: - ip: 172.20.236.113 diff --git a/extras/env.d/monasca.yml b/extras/env.d/monasca.yml index f0d843b..c92c184 100644 --- a/extras/env.d/monasca.yml +++ b/extras/env.d/monasca.yml @@ -20,13 +20,15 @@ component_skel: monasca_api: belongs_to: - monasca_all - monasca_events_api: + monasca_persister: belongs_to: - monasca_all - monasca_log_api: + monasca_thresh: + belongs_to: + - monasca_all + monasca_notification: belongs_to: - monasca_all - monasca_zookeeper: belongs_to: - monasca_all @@ -44,59 +46,45 @@ component_skel: - monasca_all container_skel: - monasca_api_container: + monasca_container: belongs_to: - monasca-infra_containers contains: - monasca_api - - monasca_common + - monasca_persister + - monasca_thresh + - monasca_notification + - monasca_storm properties: service_name: monasca - monasca_events_api_container: - belongs_to: - - monasca-infra_containers - contains: - - monasca_events_api - - monasca_common - properties: - service_name: monasca - monasca_log_api_container: - belongs_to: - - monasca-infra_containers - contains: - - monasca_log_api - - monasca_common - properties: - service_name: monasca - monasca_zookeeper_container: belongs_to: - monasca-zookeeper_containers contains: - monasca_zookeeper properties: - service_name: monasca + service_name: zookeeper monasca_kafka_container: belongs_to: - monasca-kafka_containers contains: - monasca_kafka properties: - service_name: monasca + service_name: kafka monasca_influxdb_container: belongs_to: - monasca-influxdb_containers contains: - monasca_influxdb properties: - service_name: monasca + service_name: influxdb monasca_grafana_container: belongs_to: - monasca-infra_containers contains: - monasca_grafana properties: - service_name: monasca + service_name: grafana physical_skel: monasca-zookeeper_containers: @@ -105,9 +93,6 @@ physical_skel: monasca-kafka_containers: belongs_to: - all_containers - monasca-storm_containers: - belongs_to: - - all_containers monasca-influxdb_containers: belongs_to: - all_containers @@ -123,9 +108,6 @@ physical_skel: monasca-kafka_hosts: belongs_to: - hosts - monasca-storm_hosts: - belongs_to: - - hosts monasca-influxdb_hosts: belongs_to: - hosts diff --git a/extras/group_vars/monasca_all.yml b/extras/group_vars/monasca_all.yml new file mode 100644 index 0000000..6a8b39c --- /dev/null +++ b/extras/group_vars/monasca_all.yml @@ -0,0 +1,26 @@ +--- +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +monasca_venv_tag: "{{ venv_tag }}" +monasca_venv_download_url: "{{ venv_base_download_url }}/monasca-{{ openstack_release }}-{{ ansible_architecture | lower }}.tgz" + +influxdb_host: "{{ internal_lb_vip_address }}" +influxdb_port: 8086 + +zookeeper_hosts: "{% for host in groups['monasca_zookeeper'] %}{{ hostvars[host]['ansible_host'] }}:{{ zookeeper_client_port }}{% if not loop.last %},{% endif %}{% endfor %}" + +kafka_hosts: "{% for host in groups['monasca_kafka'] %}{{ hostvars[host]['ansible_host'] }}:{{ kafka_port }}{% if not loop.last %},{% endif %}{% endfor %}" + +monasca_galera_user: monasca +monasca_galera_database: monasca +monasca_galera_address: "{{ galera_address }}" diff --git a/extras/haproxy_monasca.yml b/extras/haproxy_monasca.yml deleted file mode 100644 index 4de17e7..0000000 --- a/extras/haproxy_monasca.yml +++ /dev/null @@ -1,16 +0,0 @@ - - service: - haproxy_service_name: monasca-api - haproxy_backend_nodes: "{{ groups['monasca_api'] | default([]) }}" - haproxy_ssl: "{{ haproxy_ssl }}" - haproxy_port: "{{ monasca_api_service_port }}" - haproxy_balance_type: http - haproxy_backend_options: - - "httpchk HEAD /" - - service: - haproxy_service_name: monasca-log-api - haproxy_backend_nodes: "{{ groups['monasca_log_api'] | default([]) }}" - haproxy_ssl: "{{ haproxy_ssl }}" - haproxy_port: "{{ monasca_log_api_service_port }}" - haproxy_balance_type: http - haproxy_backend_options: - - "httpchk HEAD /" diff --git a/extras/os-monasca-install.yml b/extras/os-monasca-install.yml index f070e9c..730ead6 100644 --- a/extras/os-monasca-install.yml +++ b/extras/os-monasca-install.yml @@ -18,46 +18,41 @@ - name: Install monasca server hosts: monasca_all - max_fail_percentage: 20 + gather_facts: "{{ gather_facts | default(True) }}" user: root pre_tasks: - include: common-tasks/os-lxc-container-setup.yml + static: no - include: common-tasks/os-log-dir-setup.yml vars: log_dirs: - src: "/openstack/log/{{ inventory_hostname }}-monasca" dest: "/var/log/monasca" - - include: common-tasks/rabbitmq-vhost-user.yml - vars: - user: "{{ monasca_rabbitmq_userid }}" - password: "{{ monasca_rabbitmq_password }}" - vhost: "{{ monasca_rabbitmq_vhost }}" - when: - - inventory_hostname == groups['monasca_all'][0] - - groups['rabbitmq_all'] | length > 0 - include: common-tasks/mysql-db-user.yml vars: user_name: "{{ monasca_galera_user }}" - password: "{{ monasca_galera_password }}" + password: "{{ monasca_container_mysql_password }}" login_host: "{{ monasca_galera_address }}" db_name: "{{ monasca_galera_database }}" when: inventory_hostname == groups['monasca_all'][0] + - include: common-tasks/package-cache-proxy.yml roles: - role: "os_monasca" - monasca_venv_tag: "{{ openstack_release }}" - monasca_venv_download_url: "{{ openstack_repo_url }}/venvs/{{ openstack_release }}/{{ ansible_distribution | lower }}/monasca-{{ openstack_release }}.tgz" - pip_lock_to_internal_repo: "{{ (pip_links | length) >= 1 }}" + monasca_thresh_git_repo: "{{ openstack_repo_git_url }}/monasca-thresh" + monasca_common_git_repo: "{{ openstack_repo_git_url }}/monasca-common" + - role: "openstack_openrc" tags: - - "os-monasca" - - { role: "openstack_openrc", tags: [ "openstack-openrc" ] } + - openrc - role: "rsyslog_client" rsyslog_client_log_rotate_file: monasca_log_rotate rsyslog_client_log_dir: "/var/log/monasca" rsyslog_client_config_name: "99-monasca-rsyslog-client.conf" tags: - - "monasca-rsyslog-client" + - rsyslog - role: "system_crontab_coordination" tags: - - "system-crontab-coordination" + - crontab vars: is_metal: "{{ properties.is_metal|default(false) }}" + tags: + - monasca diff --git a/extras/os_horizon/defaults/main.yml b/extras/os_horizon/defaults/main.yml new file mode 100644 index 0000000..026a661 --- /dev/null +++ b/extras/os_horizon/defaults/main.yml @@ -0,0 +1,4 @@ +horizon_enable_monasca_ui: True +horizon_grafana_url: "https://{{ external_lb_vip_address }}:3000" +horizon_pip_packages: + - monasca-ui diff --git a/extras/os_horizon/tasks/horizon_post_install.yml b/extras/os_horizon/tasks/horizon_post_install.yml new file mode 100644 index 0000000..5711541 --- /dev/null +++ b/extras/os_horizon/tasks/horizon_post_install.yml @@ -0,0 +1,12 @@ +- name: Enable the monasca-ui-dashboard Horizon panel + file: + src: "{{ horizon_lib_dir }}/monitoring/enabled/_50_admin_add_monitoring_panel.py" + dest: "{{ horizon_lib_dir }}/openstack_dashboard/local/enabled/_50_admin_add_monitoring_panel.py" + state: "{{ horizon_enable_monasca_ui | ternary('link', 'absent') }}" + notify: Restart apache2 + +- name: Drop monasca-ui Config(s) + template: + src: "monasca-ui/local_settings.py.j2" + dest: "{{ horizon_lib_dir }}/monitoring/config/local_settings.py" + notify: Restart apache2 diff --git a/extras/os_horizon/templates/monasca-ui/local_settings.py.j2 b/extras/os_horizon/templates/monasca-ui/local_settings.py.j2 new file mode 100644 index 0000000..edaf82f --- /dev/null +++ b/extras/os_horizon/templates/monasca-ui/local_settings.py.j2 @@ -0,0 +1,75 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from django.conf import settings +from django.utils.translation import ugettext_lazy as _ + +# Service group names (global across all projects): +MONITORING_SERVICES_GROUPS = [ + {'name': _('OpenStack Services'), 'groupBy': 'service'}, + {'name': _('Servers'), 'groupBy': 'hostname'} +] + +# Services being monitored +MONITORING_SERVICES = getattr( + settings, + 'MONITORING_SERVICES_GROUPS', + MONITORING_SERVICES_GROUPS +) + +# +# Per project service groups. If in this form, +# '*' will be applied to all projects not explicitly listed. +# +# Note the above form (flat) is supported for backward compatibility. +# +# MONITORING_SERVICES_GROUPS = [ +# {'admin': [ +# {'name': _('OpenStack Services'), 'groupBy': 'service'}, +# {'name': _('Servers'), 'groupBy': 'hostname'}]}, +# {'*': [ +# {'name': _('Services'), 'groupBy': 'service'}, +# {'name': _('Instances'), 'groupBy': 'hostname'}]}, +# ] + +MONITORING_SERVICE_TYPE = getattr( + settings, 'MONITORING_SERVICE_TYPE', 'monitoring' +) + +# Grafana button titles/file names (global across all projects): +GRAFANA_LINKS = [] +DASHBOARDS = getattr(settings, 'GRAFANA_LINKS', GRAFANA_LINKS) + +# +# Horizon will link to the grafana home page when using Grafana2. +# For any Grafana version additional links to specific dashboards can be +# created in two formats. +# Flat: +# GRAFANA_LINKS = [ {'title': _('Dashboard'), 'path': 'openstack'} ] +# +# Per project: '*' will be applied to all projects not explicitly listed. +# GRAFANA_LINKS = [ +# {'admin': [ +# {'title': _('Dashboard'), 'path': 'openstack'}]}, +# {'*': [ +# {'title': _('OpenStack Dashboard'), 'path': 'project'}]} +# ] + +GRAFANA_URL = { 'RegionOne': '{{ horizon_grafana_url }}', } + +ENABLE_KIBANA_BUTTON = getattr(settings, 'ENABLE_KIBANA_BUTTON', False) +KIBANA_POLICY_RULE = getattr(settings, 'KIBANA_POLICY_RULE', 'admin_required') +KIBANA_POLICY_SCOPE = getattr(settings, 'KIBANA_POLICY_SCOPE', 'identity') +KIBANA_HOST = getattr(settings, 'KIBANA_HOST', 'http://192.168.10.4:5601/') + +OPENSTACK_SSL_NO_VERIFY = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) +OPENSTACK_SSL_CACERT = getattr(settings, 'OPENSTACK_SSL_CACERT', None) diff --git a/extras/repo_packages/openstack_monasca.yml b/extras/repo_packages/openstack_monasca.yml index 1e369e4..9e8cc30 100644 --- a/extras/repo_packages/openstack_monasca.yml +++ b/extras/repo_packages/openstack_monasca.yml @@ -15,46 +15,35 @@ # # (c) 2016 Donovan Francesco # (c) 2016 Paul Stevens + monasca_api_git_repo: "https://git.openstack.org/openstack/monasca-api" -monasca_api_git_install_branch: 1e56736bba2e0e70f35e3ac69967872276e6ebcc # master as of 23/09/2016 +monasca_api_git_install_branch: master monasca_api_git_dest: "/opt/monasca_{{ monasca_api_git_install_branch | replace('/', '_') }}" -monasca_events_api_git_repo: "https://git.openstack.org/openstack/monasca-events-api" -monasca_events_api_git_install_branch: dba30614943d6a003620336540a2774e238a567b # master as of 25/09/2016 -monasca_events_api_git_dest: "/opt/monasca_{{ monasca_events_api_git_install_branch | replace('/', '_') }}" - -monasca_log_api_git_repo: "https://git.openstack.org/openstack/monasca-log-api" -monasca_log_api_git_install_branch: 7175ff0c5595b2f119eb4b7cac1cf204dec175f4 # master as of 25/09/2016 -monasca_log_api_git_dest: "/opt/monasca_{{ monasca_log_api_git_install_branch | replace('/', '_') }}" - -monasca_ceilometer_git_repo: "https://git.openstack.org/openstack/monasca-ceilometer" -monasca_ceilometer_git_install_branch: c0f807294919cf6add64ec1f99f1b82e5a6330c3 # master as of 23/09/2016 -monasca_ceilometer_git_dest: "/opt/monasca_{{ monasca_ceilometer_git_install_branch | replace('/', '_') }}" +monasca_agent_git_repo: "https://git.openstack.org/openstack/monasca-agent" +monasca_agent_git_install_branch: master +monasca_agent_git_dest: "/opt/monasca_{{ monasca_log_api_git_install_branch | replace('/', '_') }}" monasca_common_git_repo: "https://git.openstack.org/openstack/monasca-common" -monasca_common_git_install_branch: da9fa8ca015efbac2248f017704c33cf83f6be5d # master as of 23/09/2016 +monasca_common_git_install_branch: master monasca_common_git_dest: "/opt/monasca_{{ monasca_api_git_install_branch | replace('/', '_') }}" monasca_thresh_git_repo: "https://git.openstack.org/openstack/monasca-thresh" -monasca_thresh_git_install_branch: a62c27a165e61d350fc96432878bec81c09a1587 # master as of 23/09/2016 +monasca_thresh_git_install_branch: master monasca_thresh_git_dest: "/opt/monasca_{{ monasca_thresh_git_install_branch | replace('/', '_') }}" -monasca_transform_git_repo: "https://git.openstack.org/openstack/monasca-transform" -monasca_transform_git_install_branch: 87a89604675f93028b9c4e985aba9f6a9a1e53a6 # master as of 23/09/2016 -monasca_transform_git_dest: "/opt/monasca_{{ monasca_transform_git_install_branch | replace('/', '_') }}" - monasca_notification_git_repo: "https://git.openstack.org/openstack/monasca-notification" -monasca_notification_git_install_branch: 4c39e3ad678cf117252f304fc8507020a7e98c2a # master as of 23/09/2016 +monasca_notification_git_install_branch: master monasca_notification_git_dest: "/opt/monasca_{{ monasca_notification_git_install_branch | replace('/', '_') }}" -monasca_analytics_git_repo: "https://git.openstack.org/openstack/monasca-analytics" -monasca_analytics_git_install_branch: ecfc9d6b955032d46eef02bcb1326869b820b626 # master as of 23/09/2016 -monasca_analytics_git_dest: "/opt/monasca_{{ monasca_analytics_git_install_branch | replace('/', '_') }}" - monasca_persister_git_repo: "https://git.openstack.org/openstack/monasca-persister" -monasca_persister_git_install_branch: 96fbd64a146f89b60317418d0aedb9bfafc14f0e # master as of 23/09/2016 +monasca_persister_git_install_branch: master monasca_persister_git_dest: "/opt/monasca_{{ monasca_persister_git_install_branch | replace('/', '_') }}" monasca_python_client_git_repo: "https://git.openstack.org/openstack/python-monascaclient" -monasca_python_client_git_install_branch: 4146e7e433d7c88ab5655625085ac21dfb994291 # master as of 25/09/2016 +monasca_python_client_git_install_branch: master monasca_python_client_git_dest: "/opt/monasca_{{ monasca_python_client_git_install_branch | replace('/', '_') }}" + +monasca_ui_git_repo: "https://git.openstack.org/openstack/monasca-ui" +monasca_ui_git_install_branch: master +monasca_ui_git_dest: "/opt/monasca_{{ monasca_ui_git_install_branch | replace('/', '_') }}" diff --git a/extras/user_haproxy_extras.yml b/extras/user_haproxy_extras.yml new file mode 100644 index 0000000..9636d7f --- /dev/null +++ b/extras/user_haproxy_extras.yml @@ -0,0 +1,78 @@ +--- +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +haproxy_extra_services: + - service: + haproxy_service_name: influxdb_admin + haproxy_backend_nodes: "{{ groups['monasca_influxdb'] | default([]) }}" + haproxy_ssl: "{{ haproxy_ssl }}" + haproxy_port: 8083 + haproxy_balance_type: tcp + haproxy_backend_options: + - tcp-check + haproxy_whitelist_networks: + - 192.168.0.0/16 + - 172.16.0.0/12 + - 10.0.0.0/8 + - service: + haproxy_service_name: influxdb + haproxy_backend_nodes: "{{ groups['monasca_influxdb'] | default([]) }}" + haproxy_ssl: "{{ haproxy_ssl }}" + haproxy_port: 8086 + haproxy_backend_port: 8086 + haproxy_balance_type: http + haproxy_backend_options: + - "httpchk HEAD /ping" + haproxy_whitelist_networks: + - 192.168.0.0/16 + - 172.16.0.0/12 + - 10.0.0.0/8 + haproxy_acls: + read_queries: + rule: "path_sub -i query" + write_queries: + rule: "path_sub -i write" + backend_name: "influxdb_relay" + - service: + haproxy_service_name: influxdb_relay + haproxy_backend_nodes: "{{ groups['monasca_influxdb'] | default([]) }}" + haproxy_ssl: "{{ haproxy_ssl }}" + haproxy_port: 8086 + haproxy_backend_port: 9096 + haproxy_balance_type: http + haproxy_backend_options: + - tcp-check + haproxy_whitelist_networks: + - 192.168.0.0/16 + - 172.16.0.0/12 + - 10.0.0.0/8 + haproxy_acls: + write_queries: + rule: "path_sub -i write" + read_queries: + rule: "path_sub -i query" + backend_name: "influxdb" + - service: + haproxy_service_name: grafana + haproxy_backend_nodes: "{{ groups['monasca_grafana'] | default([]) }}" + haproxy_ssl: "{{ haproxy_ssl }}" + haproxy_port: 3000 + haproxy_balance_type: http + - service: + haproxy_service_name: monasca_api + haproxy_backend_nodes: "{{ groups['monasca_api'] | default([]) }}" + haproxy_ssl: "{{ haproxy_ssl }}" + haproxy_port: 8070 + haproxy_balance_type: http + haproxy_backend_options: + - "httpchk /healthcheck" diff --git a/extras/user_secrets.yml b/extras/user_secrets.yml index 384e85b..c6ecda8 100644 --- a/extras/user_secrets.yml +++ b/extras/user_secrets.yml @@ -1,6 +1,8 @@ ---- -monasca_galera_password: -monasca_rabbitmq_password: -monasca_service_password: -monasca_admin_user_password: -monasca_regular_user_password: +grafana_admin_password: +grafana_galera_password: +monasca_container_mysql_password: +monasca_influxdb_admin_password: +monasca_api_influxdb_password: +monasca_persister_influxdb_password: +monasca_service_password: +monasca_agent_password: diff --git a/handlers/main.yml b/handlers/main.yml index 31b70a9..a4e1e7a 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -16,22 +16,30 @@ # (c) 2016 Donovan Francesco # (c) 2016 Paul Stevens -- name: Reload systemd daemon - command: "systemctl daemon-reload" - notify: - - Restart monasca services +- name: Setup monasca-thresh + command: "mvn clean {{ item.action }} -DskipTests" + args: + chdir: "/usr/share/{{ item.dir }}" + with_items: + - dir: "monasca-common" + action: "install" + - dir: "monasca-thresh/thresh" + action: "package" -- name: Reload upstart init scripts - command: initctl reload-configuration - notify: - - Restart monasca services +- name: Create monasca database schema + mysql_db: + login_host: "{{ monasca_galera_address }}" + login_user: "{{ monasca_galera_user }}" + login_password: "{{ monasca_container_mysql_password }}" + name: "{{ monasca_galera_database }}" + state: import + target: "/opt/mon_mysql.sql" - name: Restart monasca services service: name: "{{ item.value.service_name }}" + enabled: yes state: "restarted" - pattern: "{{ item.value.service_name }}" + daemon_reload: "{{ (ansible_service_mgr == 'systemd') | ternary('yes', omit) }}" with_dict: "{{ monasca_services }}" - when: - - inventory_hostname in groups[item.value.group] - - "{{ item.value.condition | default(True) }}" + when: inventory_hostname in groups[item.value.group] diff --git a/library/influxdb_user.py b/library/influxdb_user.py new file mode 100644 index 0000000..c6c386c --- /dev/null +++ b/library/influxdb_user.py @@ -0,0 +1,220 @@ +#!/usr/bin/python + +# (c) 2016, Adam Hamsik +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +from ansible.module_utils.basic import * +from ansible.module_utils.urls import * + +DOCUMENTATION = ''' +--- +module: influxdb_user +short_description: Manage InfluxDB users +description: + - Manage InfluxDB users +version_added: 2.2 +author: "Adam Hamsik (@haad)" +requirements: + - "python >= 2.6" + - "influxdb >= 0.9" +options: + hostname: + description: + - The hostname or IP address on which InfluxDB server is listening. + required: true + username: + description: + - Username used to authenticate against InfluxDB server. + default: root + required: false + password: + description: + - Password used to authenticate against InfluxDB server. + default: root + required: false + port: + description: + - The port on which InfluxDB server is listening. + default: 8086 + required: false + database_name: + description: + - Database name to work with. + required: true + user_name: + description: + - Name of the user that will be created/destroyed. + required: true + user_pass: + description: + - User password to create. + required: true + user_admin: + description: + - Determine if created user will be admin or not. + required: false + state: + description: + - Determines if the user should be created or destroyed. + choices: ['present', 'absent'] + default: present + required: false +''' + +EXAMPLES = ''' +# Example influxdb_user command from Ansible Playbooks +- name: Create user + influxdb_user: + database_name: influx + hostname: "{{ influxdb_ip_address }}" + user_name: "{{ influxdb_user_name }}" + user_pass: "{{ influxdb_user_pass }}" + user_admin: no + state: present + +- name: Destroy user + influxdb_user: + database_name: influx + hostname: "{{ influxdb_ip_address }}" + user_name: "{{ influxdb_user_name }}" + state: absent + +- name: Create admin user + influxdb_user: + database_name: influx + hostname: "{{ influxdb_ip_address }}" + username: "{{ influxdb_username }}" + password: "{{ influxdb_password }}" + user_name: "{{ influxdb_user_name }}" + user_pass: "{{ influxdb_user_pass }}" + user_admin: yes + state: present +''' + +RETURN = ''' +#only defaults +''' + +try: + from influxdb import InfluxDBClient + from influxdb import exceptions + HAS_INFLUXDB = True +except ImportError: + HAS_INFLUXDB = False + + +def influxdb_argument_spec(): + return dict( + hostname=dict(required=True, type='str'), + port=dict(default=8086, type='int'), + database_name=dict(required=True, type='str'), + username=dict(default='root', type='str'), + password=dict(default='root', type='str', no_log=True), + user_name=dict(required=True, type='str'), + user_pass=dict(required=True, type='str', no_log=True), + user_admin=dict(required=False, default=False, type='bool') + ) + + +def connect_to_influxdb(module): + hostname = module.params['hostname'] + port = module.params['port'] + username = module.params['username'] + password = module.params['password'] + database_name = module.params['database_name'] + + client = InfluxDBClient( + host=hostname, + port=port, + username=username, + password=password, + database=database_name + ) + return client + + +def find_user(module, client, user_name): + u = None + + try: + users = client.get_list_users() + for user in users: + if user['user'] == user_name: + u = user + break + except requests.exceptions.ConnectionError as e: + module.fail_json(msg=str(e)) + return u + + +def create_user(module, client, user_name, user_pass, user_admin): + if not module.check_mode: + try: + client.create_user(user_name, user_pass, user_admin) + except requests.exceptions.ConnectionError as e: + module.fail_json(msg=str(e)) + + module.exit_json(changed=True) + + +def drop_user(module, client, user_name): + if not module.check_mode: + try: + client.drop_user(user_name) + except exceptions.InfluxDBClientError as e: + module.fail_json(msg=e.content) + + module.exit_json(changed=True) + + +def main(): + argument_spec = influxdb_argument_spec() + argument_spec.update(state=dict(default='present', type='str', + choices=['present', 'absent'])) + module = AnsibleModule(argument_spec=argument_spec, + supports_check_mode=True) + + if not HAS_INFLUXDB: + module.fail_json(msg='influxdb python package \ + is required for this module') + + state = module.params['state'] + user_name = module.params['user_name'] + user_pass = module.params['user_pass'] + user_admin = module.params['user_admin'] + + try: + client = connect_to_influxdb(module) + user = find_user(module, client, user_name) + + if state == 'present': + if user: + module.exit_json(changed=False) + else: + create_user(module, client, user_name, user_pass, user_admin) + + if state == 'absent': + if user: + drop_user(module, client, user_name) + else: + module.exit_json(changed=False) + except Exception as e: + module.fail_json(msg="{}: {}".format(e.__class__.__name__, str(e))) + + +if __name__ == '__main__': + main() diff --git a/library/monasca_alarm_definition.py b/library/monasca_alarm_definition.py new file mode 100644 index 0000000..505ed8e --- /dev/null +++ b/library/monasca_alarm_definition.py @@ -0,0 +1,300 @@ +#!/usr/bin/python +# (C) Copyright 2015 Hewlett-Packard Development Company, L.P. + +DOCUMENTATION = ''' +--- +module: monasca_alarm_definition +short_description: crud operations on Monasca alarm definitions +description: + - Performs crud operations (create/update/delete) on monasca alarm + definitions + - Monasca project homepage - https://wiki.openstack.org/wiki/Monasca + - When relevant the alarm_definition_id is in the output and can be used + with the register action +author: Tim Kuhlman +requirements: [ python-monascaclient ] +options: + alarm_actions: + required: false + description: + - Array of notification method IDs that are invoked for the + transition to the ALARM state. + api_version: + required: false + default: '2_0' + description: + - The monasca api version. + description: + required: false + description: + - The description associated with the alarm + expression: + required: false + description: + - The alarm expression, required for create/update operations. + keystone_password: + required: false + description: + - Keystone password to use for authentication, required unless a + keystone_token is specified. + keystone_url: + required: false + description: + - Keystone url to authenticate against, required unless + keystone_token isdefined. + Example http://192.168.10.5:5000/v3 + keystone_token: + required: false + description: + - Keystone token to use with the monasca api. If this is specified + the monasca_api_url is required but + the keystone_user and keystone_password aren't. + keystone_user: + required: false + description: + - Keystone user to log in as, required unless a keystone_token + is specified. + keystone_project: + required: false + description: + - Keystone project name to obtain a token for, defaults to the + user's default project + match_by: + required: false + default: "[hostname]" + description: + - Alarm definition match by, see the monasca api documentation for + more detail. + monasca_api_url: + required: false + description: + - If unset the service endpoing registered with keystone will + be used. + name: + required: true + description: + - The alarm definition name + ok_actions: + required: false + description: + - Array of notification method IDs that are invoked for the + transition to the OK state. + severity: + required: false + default: "LOW" + description: + - The severity set for the alarm must be LOW, MEDIUM, HIGH or + CRITICAL + state: + required: false + default: "present" + choices: [ present, absent ] + description: + - Whether the account should exist. When C(absent), removes the + user account. + undetermined_actions: + required: false + description: + - Array of notification method IDs that are invoked for the + transition to the UNDETERMINED state. +''' + +EXAMPLES = ''' +- name: Host Alive Alarm + monasca_alarm_definition: + name: "Host Alive Alarm" + expression: "host_alive_status > 0" + keystone_url: "{{keystone_url}}" + keystone_user: "{{keystone_user}}" + keystone_password: "{{keystone_password}}" + tags: + - alarms + - system_alarms + register: out +- name: Create System Alarm Definitions + monasca_alarm_definition: + name: "{{item.name}}" + expression: "{{item.expression}}" + keystone_token: "{{out.keystone_token}}" + monasca_api_url: "{{out.monasca_api_url}}" + with_items: + - { name: "High CPU usage", expression: "avg(cpu.idle_perc) < 10 times 3" } + - { name: "Disk Inode Usage", expression: "disk.inode_used_perc > 90" } +''' + +from ansible.module_utils.basic import * # NOQA +import os # NOQA + +try: + from monascaclient import client + from monascaclient import ksclient +except ImportError: + # In many installs the python-monascaclient is available in a venv, switch + # to the most common location + activate_this = os.path.realpath( + '/opt/venvs/monasca-client/bin/activate_this.py') + try: + execfile(activate_this, dict(__file__=activate_this)) + from monascaclient import client + from monascaclient import ksclient + except ImportError: + monascaclient_found = False + else: + monascaclient_found = True +else: + monascaclient_found = True + + +# With Ansible modules including other files presents difficulties +# otherwise this would be in its own module +class MonascaAnsible(object): + """ A base class used to build Monasca Client based Ansible Modules + As input an ansible.module_utils.basic.AnsibleModule object is + expected. It should have at least these params defined: + - api_version + - keystone_token and monasca_api_url or keystone_url, keystone_user + and keystone_password and optionally + monasca_api_url + """ + + def __init__(self, module): + self.module = module + self._keystone_auth() + self.exit_data = { + 'keystone_token': self.token, + 'monasca_api_url': self.api_url} + self.monasca = client.Client( + self.module.params['api_version'], + self.api_url, + token=self.token) + + def _exit_json(self, **kwargs): + """ Exit with supplied kwargs combined with the self.exit_data + """ + kwargs.update(self.exit_data) + self.module.exit_json(**kwargs) + + def _keystone_auth(self): + """ Authenticate to Keystone and set self.token and self.api_url + """ + if self.module.params['keystone_token'] is None: + ks = ksclient.KSClient( + auth_url=self.module.params['keystone_url'], + username=self.module.params['keystone_user'], + password=self.module.params['keystone_password'], + project_name=self.module.params['keystone_project']) + + self.token = ks.token + if self.module.params['monasca_api_url'] is None: + self.api_url = ks.monasca_url + else: + self.api_url = self.module.params['monasca_api_url'] + else: + if self.module.params['monasca_api_url'] is None: + self.module.fail_json( + msg='Error: When specifying keystone_token, \ + monasca_api_url is required') + self.token = self.module.params['keystone_token'] + self.api_url = self.module.params['monasca_api_url'] + + +class MonascaDefinition(MonascaAnsible): + def run(self): + name = self.module.params['name'] + expression = self.module.params['expression'] + + # Find existing definitions + definitions = { + definition['name']: definition for definition in + self.monasca.alarm_definitions.list() + } + + if self.module.params['state'] == 'absent': + if name not in definitions.keys(): + self._exit_json(changed=False) + + if self.module.check_mode: + self._exit_json(changed=True) + resp = self.monasca.alarm_definitions.delete( + alarm_id=definitions[name]['id']) + if resp.status_code == 204: + self._exit_json(changed=True) + else: + self.module.fail_json(msg=str(resp.status_code) + resp.text) + else: # Only other option is state=present + def_kwargs = { + "name": name, + "description": self.module.params['description'], + "expression": expression, + "match_by": self.module.params['match_by'], + "severity": self.module.params['severity'], + "alarm_actions": self.module.params['alarm_actions'], + "ok_actions": self.module.params['ok_actions'], + "undetermined_actions": self.module.params[ + 'undetermined_actions']} + + if name in definitions.keys(): + if definitions[name]['expression'] == expression and \ + definitions[name]['alarm_actions'] == self.module.params[ + 'alarm_actions'] and \ + definitions[name]['ok_actions'] == self.module.params[ + 'ok_actions'] and \ + definitions[name][ + 'undetermined_actions'] == self.module.params[ + 'undetermined_actions']: + self._exit_json( + changed=False, + alarm_definition_id=definitions[name]['id'] + ) + def_kwargs['alarm_id'] = definitions[name]['id'] + + if self.module.check_mode: + self._exit_json( + changed=True, + alarm_definition_id=definitions[name]['id'] + ) + body = self.monasca.alarm_definitions.patch(**def_kwargs) + else: + if self.module.check_mode: + self._exit_json(changed=True) + body = self.monasca.alarm_definitions.create(**def_kwargs) + + if 'id' in body: + self._exit_json(changed=True, alarm_definition_id=body['id']) + else: + self.module.fail_json(msg=body) + + +def main(): + module = AnsibleModule( + argument_spec=dict( + alarm_actions=dict(required=False, default=[], type='list'), + api_version=dict(required=False, default='2_0', type='str'), + description=dict(required=False, type='str'), + expression=dict(required=False, type='str'), + keystone_password=dict(required=False, type='str'), + keystone_token=dict(required=False, type='str'), + keystone_url=dict(required=False, type='str'), + keystone_user=dict(required=False, type='str'), + keystone_project=dict(required=False, type='str'), + match_by=dict(default=['hostname'], type='list'), + monasca_api_url=dict(required=False, type='str'), + name=dict(required=True, type='str'), + ok_actions=dict(required=False, default=[], type='list'), + severity=dict(default='LOW', type='str'), + state=dict(default='present', choices=['present', 'absent'], + type='str'), + undetermined_actions=dict(required=False, default=[], type='list') + ), + supports_check_mode=True + ) + + if not monascaclient_found: + module.fail_json(msg="python-monascaclient >= 1.0.9 is required") + + definition = MonascaDefinition(module) + definition.run() + + +if __name__ == "__main__": + main() diff --git a/library/monasca_notification_method.py b/library/monasca_notification_method.py new file mode 100644 index 0000000..34dd622 --- /dev/null +++ b/library/monasca_notification_method.py @@ -0,0 +1,247 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# (C) Copyright 2015 Hewlett-Packard Development Company, L.P. + +DOCUMENTATION = ''' +--- +module: monasca_notification_method +short_description: crud operations for Monasca notifications methods +description: + - Performs crud operations (create/update/delete) on monasca notification + methods + - Monasca project homepage - https://wiki.openstack.org/wiki/Monasca + - When relevant the notification_id is in the output and can be used with + the register action +author: Tim Kuhlman +requirements: [ python-monascaclient ] +options: + address: + required: true + description: + - The notification method address corresponding to the type. + api_version: + required: false + default: '2_0' + description: + - The monasca api version. + keystone_password: + required: false + description: + - Keystone password to use for authentication, required unless a + keystone_token is specified. + keystone_url: + required: false + description: + - Keystone url to authenticate against, required unless + keystone_token isdefined. + Example http://192.168.10.5:5000/v3 + keystone_token: + required: false + description: + - Keystone token to use with the monasca api. If this is specified + the monasca_api_url is required but the keystone_user and + keystone_password aren't. + keystone_user: + required: false + description: + - Keystone user to log in as, required unless a keystone_token is + specified. + keystone_project: + required: false + description: + - Keystone project name to obtain a token for, defaults to the + user's default project + monasca_api_url: + required: false + description: + - If unset the service endpoing registered with keystone will be + used. + name: + required: true + description: + - The notification method name + state: + required: false + default: "present" + choices: [ present, absent ] + description: + - Whether the account should exist. When C(absent), removes the + user account. + type: + required: true + description: + - The notification type. This must be one of the types supported + by the Monasca API. +''' + +EXAMPLES = ''' +- name: Setup root email notification method + monasca_notification_method: + name: "Email Root" + type: 'EMAIL' + address: 'root@localhost' + keystone_url: "{{keystone_url}}" + keystone_user: "{{keystone_user}}" + keystone_password: "{{keystone_password}}" + register: out +- name: Create System Alarm Definitions + monasca_alarm_definition: + name: "Host Alive Alarm" + expression: "host_alive_status > 0" + keystone_token: "{{out.keystone_token}}" + monasca_api_url: "{{out.monasca_api_url}}" + alarm_actions: + - "{{out.notification_method_id}}" + ok_actions: + - "{{out.notification_method_id}}" + undetermined_actions: + - "{{out.notification_method_id}}" +''' + + +from ansible.module_utils.basic import * # NOQA +import os # NOQA + +try: + from monascaclient import client + from monascaclient import ksclient +except ImportError: + # In many installs the python-monascaclient is available in a venv, switch + # to the most common location + activate_this = os.path.realpath( + '/opt/venvs/monasca-client/bin/activate_this.py') + try: + execfile(activate_this, dict(__file__=activate_this)) + from monascaclient import client + from monascaclient import ksclient + except ImportError: + monascaclient_found = False + else: + monascaclient_found = True +else: + monascaclient_found = True + + +# With Ansible modules including other files presents difficulties +# otherwise this would be in its own module +class MonascaAnsible(object): + """ A base class used to build Monasca Client based Ansible Modules + As input an ansible.module_utils.basic.AnsibleModule object is + expected. It should have at least these params defined: + - api_version + - keystone_token and monasca_api_url or keystone_url, keystone_user + and keystone_password and optionally + monasca_api_url + """ + + def __init__(self, module): + self.module = module + self._keystone_auth() + self.exit_data = { + 'keystone_token': self.token, + 'monasca_api_url': self.api_url} + self.monasca = client.Client( + self.module.params['api_version'], + self.api_url, + token=self.token) + + def _exit_json(self, **kwargs): + """ Exit with supplied kwargs combined with the self.exit_data + """ + kwargs.update(self.exit_data) + self.module.exit_json(**kwargs) + + def _keystone_auth(self): + """ Authenticate to Keystone and set self.token and self.api_url + """ + if self.module.params['keystone_token'] is None: + ks = ksclient.KSClient( + auth_url=self.module.params['keystone_url'], + username=self.module.params['keystone_user'], + password=self.module.params['keystone_password'], + project_name=self.module.params['keystone_project']) + + self.token = ks.token + if self.module.params['monasca_api_url'] is None: + self.api_url = ks.monasca_url + else: + self.api_url = self.module.params['monasca_api_url'] + else: + if self.module.params['monasca_api_url'] is None: + self.module.fail_json( + msg='Error: When specifying keystone_token, \ + monasca_api_url is required') + self.token = self.module.params['keystone_token'] + self.api_url = self.module.params['monasca_api_url'] + + +class MonascaNotification(MonascaAnsible): + def run(self): + name = self.module.params['name'] + type = self.module.params['type'] + address = self.module.params['address'] + + notifications = { + notif['name']: notif for notif in + self.monasca.notifications.list() + } + if name in notifications.keys(): + notification = notifications[name] + else: + notification = None + + if self.module.params['state'] == 'absent': + if notification is None: + self._exit_json(changed=False) + else: + self.monasca.notifications.delete( + notification_id=notification['id']) + self._exit_json(changed=True) + else: # Only other option is present + if notification is None: + body = self.monasca.notifications.create( + name=name, type=type, address=address) + self._exit_json( + changed=True, + notification_method_id=body['id']) + else: + if (notification['type'] == type and + notification['address'] == address): + self._exit_json(changed=False, + notification_method_id=notification['id']) + else: + self.monasca.notifications.update( + notification_id=notification['id'], name=name, + type=type, address=address) + self._exit_json(changed=True, + notification_method_id=notification['id']) + + +def main(): + module = AnsibleModule( + argument_spec=dict( + address=dict(required=True, type='str'), + api_version=dict(required=False, default='2_0', type='str'), + keystone_password=dict(required=False, type='str', no_log=True), + keystone_token=dict(required=False, type='str'), + keystone_url=dict(required=False, type='str'), + keystone_user=dict(required=False, type='str'), + keystone_project=dict(required=False, type='str'), + monasca_api_url=dict(required=False, type='str'), + name=dict(required=True, type='str'), + state=dict(default='present', choices=['present', 'absent'], + type='str'), + type=dict(required=True, type='str') + ), + supports_check_mode=True + ) + + if not monascaclient_found: + module.fail_json(msg="python-monascaclient >= 1.0.9 is required") + + notification = MonascaNotification(module) + notification.run() + + +if __name__ == "__main__": + main() diff --git a/manual-test.rc b/manual-test.rc deleted file mode 100644 index 7016c45..0000000 --- a/manual-test.rc +++ /dev/null @@ -1,33 +0,0 @@ -export VIRTUAL_ENV=$(pwd) -export ANSIBLE_HOST_KEY_CHECKING=False -export ANSIBLE_SSH_CONTROL_PATH=/tmp/%%h-%%r - -# TODO (odyssey4me) These are only here as they are non-standard folder -# names for Ansible 1.9.x. We are using the standard folder names for -# Ansible v2.x. We can remove this when we move to Ansible 2.x. -export ANSIBLE_ACTION_PLUGINS=${HOME}/.ansible/plugins/action -export ANSIBLE_CALLBACK_PLUGINS=${HOME}/.ansible/plugins/callback -export ANSIBLE_FILTER_PLUGINS=${HOME}/.ansible/plugins/filter -export ANSIBLE_LOOKUP_PLUGINS=${HOME}/.ansible/plugins/lookup - -# This is required as the default is the current path or a path specified -# in ansible.cfg -export ANSIBLE_LIBRARY=${HOME}/.ansible/plugins/library - -# This is required as the default is '/etc/ansible/roles' or a path -# specified in ansible.cfg -export ANSIBLE_ROLES_PATH=${HOME}/.ansible/roles:$(pwd)/.. - -export ANSIBLE_SSH_ARGS="-o ControlMaster=no \ - -o UserKnownHostsFile=/dev/null \ - -o StrictHostKeyChecking=no \ - -o ServerAliveInterval=64 \ - -o ServerAliveCountMax=1024 \ - -o Compression=no \ - -o TCPKeepAlive=yes \ - -o VerifyHostKeyDNS=no \ - -o ForwardX11=no \ - -o ForwardAgent=yes" - -echo "Run manual functional tests by executing the following:" -echo "# ./.tox/functional/bin/ansible-playbook -i tests/inventory tests/test.yml" diff --git a/meta/main.yml b/meta/main.yml index 2905b63..1d1d2cf 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -15,7 +15,7 @@ # # (c) 2016 Donovan Francesco # (c) 2016 Paul Stevens -# + allow_duplicates: yes galaxy_info: @@ -27,11 +27,11 @@ galaxy_info: platforms: - name: Ubuntu versions: - - trusty - xenial categories: - cloud - python + - monasca - development - openstack @@ -43,20 +43,41 @@ dependencies: when: - ansible_pkg_mgr == 'apt' - role: ansible-zookeeper - tags: skip_ansible_lint + when: + - inventory_hostname in groups['monasca_zookeeper'] + tags: + - zookeeper + - skip_ansible_lint - role: ansible-kafka - tags: skip_ansible_lint + kafka_listen_address: "{{ ansible_host }}" + when: + - inventory_hostname in groups['monasca_kafka'] + tags: + - kafka + - skip_ansible_lint - role: ansible-storm - tags: skip_ansible_lint + storm_nimbus_enabled: True + storm_supervisor_enabled: True + nimbus_host: "{{ ansible_ssh_host }}" + when: + - inventory_hostname in groups['monasca_api'] + tags: + - storm + - skip_ansible_lint - role: ansible-influxdb - tags: skip_ansible_lint - - role: ansible-grafana - grafana_mysql_host: "{{ monasca_galera_address }}" - grafana_admin_password: "{{ monasca_grafana_admin_password }}" - grafana_mysql_db: "{{ monasca_grafana_galera_database }}" - grafana_mysql_user: "{{ monasca_grafana_galera_username }}" - grafana_mysql_password: "{{ monasca_grafana_galera_password }}" - grafana_keystone_url: "{{ keystone_service_internalurl }}" - tags: skip_ansible_lint - - role: ansible-monasca-schema - tags: skip_ansible_lint + when: + - inventory_hostname in groups['monasca_influxdb'] + tags: + - influxdb + - skip_ansible_lint + - role: grafana-ansible + grafana_mysql_host: "{{ galera_address }}" + grafana_mysql_root_user: "{{ galera_root_user }}" + grafana_mysql_root_password: "{{ galera_root_password }}" + grafana_mysql_password: "{{ grafana_galera_password }}" + grafana_keystone_url: "{{ keystone_service_internaluri }}" + when: + - inventory_hostname in groups['monasca_grafana'] + tags: + - grafana + - skip_ansible_lint diff --git a/tasks/main.yml b/tasks/main.yml index 3132bbe..4403355 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -15,7 +15,7 @@ # # (c) 2016 Donovan Francesco # (c) 2016 Paul Stevens -# + - name: Gather variables for each operating system include_vars: "{{ item }}" with_first_found: @@ -23,31 +23,49 @@ - "{{ ansible_distribution | lower }}-{{ ansible_distribution_major_version | lower }}.yml" - "{{ ansible_os_family | lower }}-{{ ansible_distribution_major_version | lower }}.yml" - "{{ ansible_distribution | lower }}.yml" + - "{{ ansible_os_family | lower }}-{{ ansible_distribution_version.split('.')[0] }}.yml" - "{{ ansible_os_family | lower }}.yml" tags: - always -- include: pre-install.yml +- include: monasca_pre_install.yml + when: inventory_hostname in groups['monasca_api'] tags: - monasca-install -- include: install.yml +- include: monasca_install.yml + when: inventory_hostname in groups['monasca_api'] tags: - monasca-install -- include: post-install.yml +- include: monasca_thresh_install.yml + when: inventory_hostname in groups['monasca_api'] + tags: + - monasca-install + +- include: monasca_post_install.yml + when: inventory_hostname in groups['monasca_api'] tags: - monasca-config -- include: monasca_init_common.yml +- include: monasca_init_{{ ansible_service_mgr }}.yml + when: inventory_hostname in groups['monasca_api'] + tags: + - monasca-config + +- include: monasca_db_setup.yml tags: - monasca-config - include: monasca_service_setup.yml - static: no when: inventory_hostname == groups['monasca_api'][0] tags: - monasca-config - name: Flush handlers meta: flush_handlers + +- include: monasca_alarms_setup.yml + when: inventory_hostname == groups['monasca_api'][0] + tags: + - monasca-alarms diff --git a/tasks/monasca_alarms_setup.yml b/tasks/monasca_alarms_setup.yml new file mode 100644 index 0000000..a8659a2 --- /dev/null +++ b/tasks/monasca_alarms_setup.yml @@ -0,0 +1,41 @@ +--- +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Setup default notification method + monasca_notification_method: + name: "{{ monasca_notification_name }}" + type: "{{ monasca_notification_type }}" + address: "{{ monasca_notification_address }}" + keystone_url: "{{ keystone_service_adminurl }}" + keystone_user: "{{ keystone_admin_user_name }}" + keystone_password: "{{ keystone_auth_admin_password }}" + keystone_project: "{{ keystone_admin_tenant_name }}" + monasca_api_url: "{{ monasca_service_internalurl }}" + register: default_notification + +- name: Create Default Alarm Definitions + monasca_alarm_definition: + name: "{{ item.name }}" + description: "{{ item.description | default('') }}" + expression: "{{ item.expression }}" + keystone_token: "{{ default_notification.keystone_token }}" + match_by: "{{ item.match_by | default(['hostname']) }}" + monasca_api_url: "{{ default_notification.monasca_api_url }}" + severity: "{{ item.severity | default('LOW') }}" + alarm_actions: + - "{{ default_notification.notification_method_id }}" + ok_actions: + - "{{ default_notification.notification_method_id }}" + undetermined_actions: + - "{{ default_notification.notification_method_id }}" + with_items: "{{ monasca_default_alarms }}" diff --git a/vars/ubuntu-14.04.yml b/tasks/monasca_db_setup.yml similarity index 64% rename from vars/ubuntu-14.04.yml rename to tasks/monasca_db_setup.yml index c301348..3ab3055 100644 --- a/vars/ubuntu-14.04.yml +++ b/tasks/monasca_db_setup.yml @@ -1,6 +1,4 @@ --- -# Copyright 2016 Internet Solutions (Pty) Ltd -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -12,14 +10,12 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# (c) 2016 Donovan Francesco -# (c) 2016 Paul Stevens -# -monasca_distro_packages: - - build-essential - - openjdk-7-jdk - - python-software-properties - - python-dev - - python-mysqldb - - python-pip + +- include: monasca_influxdb_setup.yml + when: inventory_hostname in groups['monasca_influxdb'] + +- include: monasca_mysql_setup.yml + when: inventory_hostname in groups['monasca_api'] + +- include: monasca_kafka_setup.yml + when: inventory_hostname in groups['monasca_kafka'] diff --git a/tasks/monasca_influxdb_setup.yml b/tasks/monasca_influxdb_setup.yml new file mode 100644 index 0000000..317407e --- /dev/null +++ b/tasks/monasca_influxdb_setup.yml @@ -0,0 +1,50 @@ +--- +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Install influxdb libs + pip: + name: influxdb + state: present + +- name: Create influxdb database + influxdb_database: + hostname: "{{ monasca_influxdb_host }}" + port: "{{ monasca_influxdb_port }}" + username: "{{ monasca_influxdb_admin }}" + password: "{{ monasca_influxdb_admin_password }}" + database_name: "{{ monasca_influxdb_database }}" + state: present + +- name: Create influxdb retention policy for database + influxdb_retention_policy: + hostname: "{{ monasca_influxdb_host }}" + port: "{{ monasca_influxdb_port }}" + database_name: "{{ monasca_influxdb_database }}" + username: "{{ monasca_influxdb_admin }}" + password: "{{ monasca_influxdb_admin_password }}" + policy_name: persister_all + duration: "{{ monasca_influxdb_retention_policy }}" + replication: "{{ monasca_influxdb_replication_factor }}" + +- name: Create influxdb users + influxdb_user: + hostname: "{{ monasca_influxdb_host }}" + port: "{{ monasca_influxdb_port }}" + database_name: "{{ monasca_influxdb_database }}" + username: "{{ monasca_influxdb_admin }}" + password: "{{ monasca_influxdb_admin_password }}" + user_name: "{{ item.username }}" + user_pass: "{{ item.password }}" + with_items: + - "{{ monasca_influxdb_users }}" + diff --git a/tasks/monasca_init_systemd.yml b/tasks/monasca_init_systemd.yml index a2cdedf..1a74dd9 100644 --- a/tasks/monasca_init_systemd.yml +++ b/tasks/monasca_init_systemd.yml @@ -33,15 +33,27 @@ with_dict: "{{ monasca_services }}" when: inventory_hostname in groups[item.value.group] -- name: Create tempfile.d entry +# TODO: +# Remove this in Pike as it only needed to handle upgrades +# from Newton->Newton and Newton->Ocata +- name: Cleanup old tmpfiles.d entry + file: + path: "/etc/tmpfiles.d/{{ item.value.service_name }}.conf" + state: absent + with_dict: "{{ monasca_services }}" + when: inventory_hostname in groups[item.value.group] + +- name: Create tmpfiles.d entry template: - src: "monasca-systemd-tempfiles.j2" - dest: "/etc/tmpfiles.d/{{ item.value.service_name }}.conf" + src: "monasca-systemd-tmpfiles.j2" + dest: "/etc/tmpfiles.d/openstack-{{ item.value.service_name }}.conf" mode: "0644" owner: "root" group: "root" with_dict: "{{ monasca_services }}" when: inventory_hostname in groups[item.value.group] + notify: + - Restart monasca services - name: Place the systemd init script config_template: @@ -55,4 +67,4 @@ with_dict: "{{ monasca_services }}" when: inventory_hostname in groups[item.value.group] notify: - - Reload systemd daemon + - Restart monasca services diff --git a/tasks/install.yml b/tasks/monasca_install.yml similarity index 92% rename from tasks/install.yml rename to tasks/monasca_install.yml index a8ce7ef..fb5ee9c 100644 --- a/tasks/install.yml +++ b/tasks/monasca_install.yml @@ -34,7 +34,8 @@ {% for item in monasca_developer_constraints %} {{ item }} {% endfor %} - when: monasca_developer_mode | bool + when: + - monasca_developer_mode | bool - name: Install requires pip packages pip: @@ -100,7 +101,16 @@ retries: 5 delay: 2 when: monasca_get_venv | failed or monasca_get_venv | skipped - notify: Restart monasca services + notify: + - Restart monasca services + +- name: CentOS remove python from path first + file: + path: "{{ monasca_bin | dirname }}/bin/python2.7" + state: "absent" + when: + - ansible_pkg_mgr == 'yum' + - monasca_get_venv | changed - name: Update virtualenv path command: > diff --git a/tasks/monasca_kafka_setup.yml b/tasks/monasca_kafka_setup.yml new file mode 100644 index 0000000..8150dcc --- /dev/null +++ b/tasks/monasca_kafka_setup.yml @@ -0,0 +1,33 @@ +--- +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Create kafka topics logs dir + file: + path: "/opt/kafka/logs" + state: directory + owner: "kafka" + group: "kafka" + mode: "0766" + +- name: Check kafka topics + shell: "/opt/kafka/bin/kafka-topics.sh --list --zookeeper {{ zookeeper_hosts }} --topic {{ item.key }} | grep {{ item.key }}" + with_dict: "{{ kafka_topics }}" + ignore_errors: yes + register: check_result + changed_when: False + +- name: create topics + command: "/opt/kafka/bin/kafka-topics.sh --create --zookeeper {{ zookeeper_hosts }} --replication-factor {{ item.value.replicas }} --partitions {{ item.value.partitions }} --topic {{ item.key }}" + with_dict: "{{ kafka_topics }}" + when: + - check_result | failed diff --git a/tasks/monasca_init_upstart.yml b/tasks/monasca_mysql_setup.yml similarity index 60% rename from tasks/monasca_init_upstart.yml rename to tasks/monasca_mysql_setup.yml index 3e5a4f7..fc1760e 100644 --- a/tasks/monasca_init_upstart.yml +++ b/tasks/monasca_mysql_setup.yml @@ -1,6 +1,4 @@ --- -# Copyright 2016 Internet Solutions (Pty) Ltd -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -13,14 +11,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -- name: Place the init script +- name: Copy mysql schema script to host template: - src: "monasca-upstart-init.j2" - dest: "/etc/init/{{ item.value.service_name }}.conf" - mode: "0644" - owner: "root" - group: "root" - with_dict: "{{ monasca_services }}" - when: inventory_hostname in groups[item.value.group] - notify: - - Reload upstart init scripts + dest: "/opt/mon_mysql.sql" + owner: root + group: root + mode: 0640 + src: mon_mysql.sql.j2 + notify: Create monasca database schema diff --git a/tasks/monasca_post_install.yml b/tasks/monasca_post_install.yml new file mode 100644 index 0000000..9fa381e --- /dev/null +++ b/tasks/monasca_post_install.yml @@ -0,0 +1,53 @@ +--- +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Drop Monasca Config(s) + config_template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: "{{ monasca_system_user_name }}" + group: "{{ monasca_system_group_name }}" + mode: "0644" + config_overrides: "{{ item.config_overrides }}" + config_type: "{{ item.config_type }}" + with_items: + - src: "monasca-api/api-config.conf.j2" + dest: "/etc/monasca/api-config.conf" + config_overrides: "{{ monasca_api_config_overrides }}" + config_type: "ini" + - src: "monasca-api/api-config.ini.j2" + dest: "/etc/monasca/api-config.ini" + config_overrides: "{{ monasca_api_config_ini_overrides }}" + config_type: "ini" + - src: "monasca-api/api-logging.conf.j2" + dest: "/etc/monasca/api-logging.conf" + config_overrides: "{{ monasca_api_logging_config_overrides }}" + config_type: "ini" + - src: "monasca-persister/persister.conf.j2" + dest: "/etc/monasca/persister.conf" + config_overrides: "{{ monasca_persister_config_overrides }}" + config_type: "ini" + - src: "monasca-persister/persister-logging.conf.j2" + dest: "/etc/monasca/persister-logging.conf" + config_overrides: "{{ monasca_persister_logging_config_overrides }}" + config_type: "ini" + - src: "monasca-thresh/thresh-config.yml.j2" + dest: "/etc/monasca/thresh-config.yml" + config_overrides: "{{ monasca_thresh_config_overrides }}" + config_type: "yaml" + - src: "monasca-notification/notification.yaml.j2" + dest: "/etc/monasca/notification.yaml" + config_overrides: "{{ monasca_notification_config_overrides }}" + config_type: "yaml" + notify: + - Restart monasca services diff --git a/tasks/pre-install.yml b/tasks/monasca_pre_install.yml similarity index 53% rename from tasks/pre-install.yml rename to tasks/monasca_pre_install.yml index 137dc58..a5361a5 100644 --- a/tasks/pre-install.yml +++ b/tasks/monasca_pre_install.yml @@ -1,22 +1,17 @@ --- -# Copyright 2016 Internet Solutions (Pty) Ltd -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# -# (c) 2016 Donovan Francesco -# (c) 2016 Paul Stevens -- name: Create the monasca system group +- name: Create the system group group: name: "{{ monasca_system_group_name }}" state: "present" @@ -26,33 +21,30 @@ user: name: "{{ monasca_system_user_name }}" group: "{{ monasca_system_group_name }}" - groups: sudo - shell: "{{ monasca_system_user_shell }}" + comment: "{{ monasca_system_comment }}" + shell: "{{ monasca_system_shell }}" system: "yes" createhome: "yes" home: "{{ monasca_system_user_home }}" - register: create_monasca_user - until: create_monasca_user | success - retries: 5 - delay: 2 -- name: Create monasca's directories +- name: Create monasca dir file: path: "{{ item.path }}" - state: "directory" - owner: "{{ item.owner |default(monasca_system_user_name) }}" - group: "{{ item.group |default(monasca_system_group_name) }}" - mode: "{{ item.mode |default('0750') }}" + state: directory + owner: "{{ item.owner|default(monasca_system_user_name) }}" + group: "{{ item.group|default(monasca_system_group_name) }}" + mode: "{{ item.mode|default('0755') }}" with_items: - - path: "{{ monasca_conf_directory }}" - - path: "{{ monasca_system_user_home }}" - - path: "{{ monasca_lock_path }}" + - { path: "/openstack/venvs", mode: "0755", owner: "root", group: "root" } + - { path: "/etc/monasca" } + - { path: "/var/cache/monasca" } + - { path: "{{ monasca_system_user_home }}" } -- name: Test for monasca log directory or link +- name: Test for log directory or link shell: | - if [ -h "{{ monasca_log_directory }}" ]; then - chown -h {{ monasca_system_user_name }}:{{ monasca_system_group_name }} {{ monasca_log_directory }} - chown -R {{ monasca_system_user_name }}:{{ monasca_system_group_name }} "$(readlink {{ monasca_log_directory }})" + if [ -h "/var/log/monasca" ]; then + chown -h {{ monasca_system_user_name }}:{{ monasca_system_group_name }} "/var/log/monasca" + chown -R {{ monasca_system_user_name }}:{{ monasca_system_group_name }} "$(readlink /var/log/monasca)" else exit 1 fi @@ -60,11 +52,11 @@ failed_when: false changed_when: log_dir.rc != 0 -- name: Create monasca log directory +- name: Create monasca log dir file: - path: "{{ monasca_log_directory }}" - state: "directory" + path: "/var/log/monasca" + state: directory owner: "{{ monasca_system_user_name }}" group: "{{ monasca_system_group_name }}" - mode: "0750" + mode: "0755" when: log_dir.rc != 0 diff --git a/tasks/monasca_service_setup.yml b/tasks/monasca_service_setup.yml index b54c395..28d7f57 100644 --- a/tasks/monasca_service_setup.yml +++ b/tasks/monasca_service_setup.yml @@ -15,86 +15,44 @@ # # (c) 2016 Donovan Francesco # (c) 2016 Paul Stevens -- name: Ensure the service for monasca exists + +# Create a service +- name: Ensure monasca service keystone: command: "ensure_service" endpoint: "{{ keystone_service_adminurl }}" login_user: "{{ keystone_admin_user_name }}" login_password: "{{ keystone_auth_admin_password }}" login_project_name: "{{ keystone_admin_tenant_name }}" - insecure: "{{ keystone_service_adminuri_insecure }}" service_name: "{{ monasca_service_name }}" service_type: "{{ monasca_service_type }}" description: "{{ monasca_service_description }}" - register: add_monasca_service - until: add_monasca_service |success + insecure: "{{ keystone_service_adminuri_insecure }}" + register: add_service + until: add_service|success retries: 5 delay: 2 - tags: - - monasca-api-setup - - monasca-service-add - - monasca-setup -- name: Ensure the monasca user exists +# Create an admin user +- name: Ensure monasca user keystone: command: "ensure_user" endpoint: "{{ keystone_service_adminurl }}" login_user: "{{ keystone_admin_user_name }}" login_password: "{{ keystone_auth_admin_password }}" login_project_name: "{{ keystone_admin_tenant_name }}" - insecure: "{{ keystone_service_adminuri_insecure }}" user_name: "{{ monasca_service_user_name }}" tenant_name: "{{ monasca_service_project_name }}" - password: "{{ monasca_service_password | default('changeme') }}" - register: add_monasca_user - until: add_monasca_user |success - retries: 5 - delay: 2 - tags: - - monasca-api-setup - - monasca-service-add - - monasca-user-add - - monasca-setup - -- name: Ensure the monasca read only user exists - keystone: - command: "ensure_user" - endpoint: "{{ keystone_service_adminurl }}" - login_user: "{{ keystone_admin_user_name }}" - login_password: "{{ keystone_auth_admin_password }}" - login_project_name: "{{ keystone_admin_tenant_name }}" + password: "{{ monasca_service_password }}" insecure: "{{ keystone_service_adminuri_insecure }}" - user_name: "{{ monasca_readonly_user_name }}" - tenant_name: "{{ monasca_service_project_name }}" - password: "{{ monasca_readonly_password }}" - register: add_monasca_readonly_user - until: add_monasca_readonly_user |success + register: add_user + when: not monasca_service_in_ldap | bool + until: add_user|success retries: 5 - delay: 2 - tags: - - monasca-api-setup - - monasca-service-add - - monasca-user-add - - monasca-setup + delay: 10 -- name: Ensure the monasca role exists - keystone: - command: "ensure_role" - endpoint: "{{ keystone_service_adminurl }}" - login_user: "{{ keystone_admin_user_name }}" - login_password: "{{ keystone_auth_admin_password }}" - login_project_name: "{{ keystone_admin_tenant_name }}" - user_name: "{{ monasca_service_user_name }}" - tenant_name: "{{ monasca_service_project_name }}" - role_name: "{{ item }}" - insecure: "{{ keystone_service_adminuri_insecure }}" - register: ensure_monasca_roles - until: ensure_monasca_roles |success - retries: 5 - delay: 2 - with_items: "{{ monasca_role_names }}" - -- name: Ensure the monasca user has the admin role +# Add a role to the user +- name: Ensure monasca user to admin role keystone: command: "ensure_user_role" endpoint: "{{ keystone_service_adminurl }}" @@ -103,25 +61,102 @@ login_project_name: "{{ keystone_admin_tenant_name }}" user_name: "{{ monasca_service_user_name }}" tenant_name: "{{ monasca_service_project_name }}" + role_name: "{{ monasca_role_name }}" + insecure: "{{ keystone_service_adminuri_insecure }}" + register: add_user_role + when: not monasca_service_in_ldap | bool + until: add_user_role|success + retries: 5 + delay: 10 + +# Create monasca roles +- name: Ensure monasca user, agent and read only roles + keystone: + command: "ensure_role" + endpoint: "{{ keystone_service_adminurl }}" + login_user: "{{ keystone_admin_user_name }}" + login_password: "{{ keystone_auth_admin_password }}" + login_project_name: "{{ keystone_admin_tenant_name }}" role_name: "{{ item }}" insecure: "{{ keystone_service_adminuri_insecure }}" - register: ensure_monasca_service_roles - until: ensure_monasca_service_roles |success + register: add_roles + when: not monasca_service_in_ldap | bool + until: add_roles|success retries: 5 - delay: 2 - with_items: "{{ monasca_service_role_names }}" + delay: 10 + with_flattened: + - "{{ monasca_user_roles }}" + - "{{ monasca_agent_roles }}" + - "{{ monasca_read_only_user_roles }}" -- name: Ensure the monasca endpoint is registered +# Create an monasca-agent user +- name: Ensure monasca-agent user + keystone: + command: "ensure_user" + endpoint: "{{ keystone_service_adminurl }}" + login_user: "{{ keystone_admin_user_name }}" + login_password: "{{ keystone_auth_admin_password }}" + login_project_name: "{{ keystone_admin_tenant_name }}" + user_name: "{{ monasca_agent_user_name }}" + tenant_name: "{{ monasca_agent_project_name }}" + password: "{{ monasca_agent_password }}" + insecure: "{{ keystone_service_adminuri_insecure }}" + register: add_user + when: not monasca_service_in_ldap | bool + until: add_user|success + retries: 5 + delay: 10 + +# Add a role to the user +- name: Ensure monasca-agent user to monasca-agent roles + keystone: + command: "ensure_user_role" + endpoint: "{{ keystone_service_adminurl }}" + login_user: "{{ keystone_admin_user_name }}" + login_password: "{{ keystone_auth_admin_password }}" + login_project_name: "{{ keystone_admin_tenant_name }}" + user_name: "{{ monasca_agent_user_name }}" + tenant_name: "{{ monasca_agent_project_name }}" + role_name: "{{ item }}" + insecure: "{{ keystone_service_adminuri_insecure }}" + register: add_user_role + when: not monasca_service_in_ldap | bool + until: add_user_role|success + retries: 5 + delay: 10 + with_items: "{{ monasca_agent_roles }}" + +# Add a role to the user +- name: Ensure admin user to monasca-user roles + keystone: + command: "ensure_user_role" + endpoint: "{{ keystone_service_adminurl }}" + login_user: "{{ keystone_admin_user_name }}" + login_password: "{{ keystone_auth_admin_password }}" + login_project_name: "{{ keystone_admin_tenant_name }}" + user_name: "{{ keystone_admin_user_name }}" + tenant_name: "{{ keystone_admin_tenant_name }}" + role_name: "{{ item }}" + insecure: "{{ keystone_service_adminuri_insecure }}" + register: add_user_role + when: not monasca_service_in_ldap | bool + until: add_user_role|success + retries: 5 + delay: 10 + with_items: "{{ monasca_user_roles }}" + +# Create an endpoint +- name: Ensure monasca endpoint keystone: command: "ensure_endpoint" endpoint: "{{ keystone_service_adminurl }}" login_user: "{{ keystone_admin_user_name }}" login_password: "{{ keystone_auth_admin_password }}" login_project_name: "{{ keystone_admin_tenant_name }}" - insecure: "{{ keystone_service_adminuri_insecure }}" region_name: "{{ monasca_service_region }}" service_name: "{{ monasca_service_name }}" service_type: "{{ monasca_service_type }}" + insecure: "{{ keystone_service_adminuri_insecure }}" endpoint_list: - url: "{{ monasca_service_publicurl }}" interface: "public" @@ -129,7 +164,7 @@ interface: "internal" - url: "{{ monasca_service_adminurl }}" interface: "admin" - register: add_monasca_endpoints - until: add_monasca_endpoints |success + register: add_endpoint + until: add_endpoint|success retries: 5 - delay: 2 + delay: 10 diff --git a/tasks/monasca_thresh_install.yml b/tasks/monasca_thresh_install.yml new file mode 100644 index 0000000..90a8d454 --- /dev/null +++ b/tasks/monasca_thresh_install.yml @@ -0,0 +1,39 @@ +--- +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Get package from git + git: + repo: "{{ item.repo }}" + dest: "/usr/share/{{ item.dest }}" + clone: "yes" + update: "yes" + version: "{{ item.version }}" + force: yes + accept_hostkey: yes + register: git_clone + until: git_clone|success + retries: 5 + delay: 2 + with_items: + - repo: "{{ monasca_common_git_repo }}" + version: "{{ monasca_common_git_install_branch }}" + dest: "monasca-common" + - repo: "{{ monasca_thresh_git_repo }}" + version: "{{ monasca_thresh_git_install_branch }}" + dest: "monasca-thresh" + notify: Setup monasca-thresh + +- name: Get monasca-thresh version + shell: "grep -m 1 version /usr/share/monasca-thresh/thresh/pom.xml | awk -F '[<>]' '{print $3}'" + register: _monasca_thresh_version + changed_when: false diff --git a/tasks/post-install.yml b/tasks/post-install.yml deleted file mode 100644 index d4a3469..0000000 --- a/tasks/post-install.yml +++ /dev/null @@ -1,68 +0,0 @@ ---- -# Copyright 2016 Internet Solutions (Pty) Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# (c) 2016 Donovan Francesco -# (c) 2016 Paul Stevens -- name: Drop monasca api Config(s) - config_template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: "{{ monasca_system_user_name }}" - group: "{{ monasca_system_group_name }}" - mode: "0644" - config_overrides: "{{ item.config_overrides }}" - config_type: "{{ item.config_type }}" - with_items: - - src: "monasca-api-paste.ini.j2" - dest: "/etc/monasca/api-config.ini" - config_overrides: "{{ monasca_api_paste_ini_overrides }}" - config_type: "ini" - - src: "monasca-api.conf.j2" - dest: "/etc/monasca/api-config.conf" - config_overrides: "{{ monasca_api_config_overrides }}" - config_type: "ini" - - src: "monasca-api-logging.conf.j2" - dest: "/etc/monasca/api-logging.conf" - config_overrides: "{{ monasca_api_config_overrides }}" - config_type: "ini" - notify: - - Restart monasca services - when: inventory_hostname in groups['monasca_api'] - -- name: Drop monasca-log-api Config(s) - config_template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: "{{ monasca_system_user_name }}" - group: "{{ monasca_system_group_name }}" - mode: "0644" - config_overrides: "{{ item.config_overrides }}" - config_type: "{{ item.config_type }}" - with_items: - - src: "monasca-log-api-paste.ini.j2" - dest: "/etc/monasca/log-api-config.ini" - config_overrides: "{{ monasca_log_api_paste_ini_overrides }}" - config_type: "ini" - - src: "monasca-log-api.conf.j2" - dest: "/etc/monasca/log-api-config.conf" - config_overrides: "{{ monasca_log_api_config_overrides }}" - config_type: "ini" - - src: "monasca-log-api-logging.conf.j2" - dest: "/etc/monasca/log-api-logging.conf" - config_overrides: "{{ monasca_log_api_logging_overrides }}" - config_type: "ini" - notify: - - Restart monasca services - when: inventory_hostname in groups['monasca_log_api'] diff --git a/templates/mon_mysql.sql.j2 b/templates/mon_mysql.sql.j2 new file mode 100644 index 0000000..0a8458c --- /dev/null +++ b/templates/mon_mysql.sql.j2 @@ -0,0 +1,212 @@ +/* +* (C) Copyright 2015,2016 Hewlett Packard Enterprise Development LP +* Copyright 2016 FUJITSU LIMITED +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +*    http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +* implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +DROP DATABASE IF EXISTS `{{ monasca_galera_database }}`; + +CREATE DATABASE IF NOT EXISTS `{{ monasca_galera_database }}` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE `{{ monasca_galera_database }}`; + +SET foreign_key_checks = 0; + +/* + * Enum tables + */ +CREATE TABLE `alarm_state` ( + `name` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `alarm_definition_severity` ( + `name` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `notification_method_type` ( + `name` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `alarm` ( + `id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `alarm_definition_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', + `state` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, + `lifecycle_state` varchar(50) DEFAULT NULL, + `link` varchar(512) DEFAULT NULL, + `created_at` datetime NOT NULL, + `state_updated_at` datetime, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `alarm_definition_id` (`alarm_definition_id`), + CONSTRAINT `fk_alarm_definition_id` FOREIGN KEY (`alarm_definition_id`) REFERENCES `alarm_definition` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_alarm_alarm_state` FOREIGN KEY (`state`) REFERENCES `alarm_state` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `alarm_action` ( + `alarm_definition_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `alarm_state` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, + `action_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`alarm_definition_id`,`alarm_state`,`action_id`), + CONSTRAINT `fk_alarm_action_alarm_definition_id` FOREIGN KEY (`alarm_definition_id`) REFERENCES `alarm_definition` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_alarm_action_notification_method_id` FOREIGN KEY (`action_id`) REFERENCES `notification_method` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_alarm_action_alarm_state` FOREIGN KEY (`alarm_state`) REFERENCES `alarm_state` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `alarm_definition` ( + `id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `tenant_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', + `description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `expression` longtext COLLATE utf8mb4_unicode_ci NOT NULL, + `severity` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, + `match_by` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '', + `actions_enabled` tinyint(1) NOT NULL DEFAULT '1', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `deleted_at` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `tenant_id` (`tenant_id`), + KEY `deleted_at` (`deleted_at`), + CONSTRAINT `fk_alarm_definition_severity` FOREIGN KEY (`severity`) REFERENCES `alarm_definition_severity` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `alarm_metric` ( + `alarm_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `metric_definition_dimensions_id` binary(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', + PRIMARY KEY (`alarm_id`,`metric_definition_dimensions_id`), + KEY `alarm_id` (`alarm_id`), + KEY `metric_definition_dimensions_id` (`metric_definition_dimensions_id`), + CONSTRAINT `fk_alarm_id` FOREIGN KEY (`alarm_id`) REFERENCES `alarm` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `metric_definition` ( + `id` binary(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `tenant_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `region` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `metric_definition_dimensions` ( + `id` binary(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', + `metric_definition_id` binary(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', + `metric_dimension_set_id` binary(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', + KEY `metric_definition_id` (`metric_definition_id`), + KEY `metric_dimension_set_id` (`metric_dimension_set_id`), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +/* + * mysql limits the size of a unique key to 767 bytes. The utf8mb4 charset requires + * 4 bytes to be allocated for each character while the utf8 charset requires 3 bytes. + * The utf8 charset should be sufficient for any reasonable characters, see the definition + * of supplementary characters for what it doesn't support. + * Even with utf8, the unique key length would be 785 bytes so only a subset of the + * name is used. Potentially the size of the name should be limited to 250 characters + * which would resolve this issue. + * + * The unique key is required to allow high performance inserts without doing a select by using + * the "insert into metric_dimension ... on duplicate key update dimension_set_id=dimension_set_id + * syntax + */ +CREATE TABLE `metric_dimension` ( + `dimension_set_id` binary(20) NOT NULL DEFAULT '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', + `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', + `value` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', + UNIQUE KEY `metric_dimension_key` (`dimension_set_id`,`name`(252)), + KEY `dimension_set_id` (`dimension_set_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='PRIMARY KEY (`id`)'; + +CREATE TABLE `notification_method` ( + `id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `tenant_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(250) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `type` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL, + `address` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `period` int NOT NULL DEFAULT 0, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_alarm_noticication_method_type` FOREIGN KEY (`type`) REFERENCES `notification_method_type` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `sub_alarm_definition` ( + `id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `alarm_definition_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', + `function` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL, + `metric_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `operator` varchar(5) COLLATE utf8mb4_unicode_ci NOT NULL, + `threshold` double NOT NULL, + `period` int(11) NOT NULL, + `periods` int(11) NOT NULL, + `is_deterministic` tinyint(1) NOT NULL DEFAULT '0', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `fk_sub_alarm_definition` (`alarm_definition_id`), + CONSTRAINT `fk_sub_alarm_definition` FOREIGN KEY (`alarm_definition_id`) REFERENCES `alarm_definition` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `sub_alarm_definition_dimension` ( + `sub_alarm_definition_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', + `dimension_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', + `value` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + CONSTRAINT `fk_sub_alarm_definition_dimension` FOREIGN KEY (`sub_alarm_definition_id`) REFERENCES `sub_alarm_definition` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +CREATE TABLE `sub_alarm` ( + `id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `alarm_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', + `sub_expression_id` varchar(36) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', + `expression` longtext COLLATE utf8mb4_unicode_ci NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `state` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'OK', + PRIMARY KEY (`id`), + KEY `fk_sub_alarm` (`alarm_id`), + KEY `fk_sub_alarm_expr` (`sub_expression_id`), + CONSTRAINT `fk_sub_alarm` FOREIGN KEY (`alarm_id`) REFERENCES `alarm` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_sub_alarm_state` FOREIGN KEY (`state`) REFERENCES `alarm_state` (`name`), + CONSTRAINT `fk_sub_alarm_expr` FOREIGN KEY (`sub_expression_id`) REFERENCES `sub_alarm_definition` (`id`) +); + +/* + * To require ssl connections add 'REQUIRE SSL' to the end of all grant statements + */ +{% if mysql_users is defined %} +{% for user in mysql_users %} +GRANT ALL ON {{ monasca_mysql_db }} .* TO '{{ user.name }}'@'%' IDENTIFIED BY '{{ user.pass }}'; +GRANT ALL ON {{ monasca_mysql_db }} .* TO '{{ user.name }}'@'localhost' IDENTIFIED BY '{{ user.pass }}'; +{% endfor %} +{% endif %} + +SET foreign_key_checks = 1; + +/* provide data for enum tables */ +insert into `alarm_state` values ('UNDETERMINED'); +insert into `alarm_state` values ('OK'); +insert into `alarm_state` values ('ALARM'); + +insert into `alarm_definition_severity` values ('LOW'); +insert into `alarm_definition_severity` values ('MEDIUM'); +insert into `alarm_definition_severity` values ('HIGH'); +insert into `alarm_definition_severity` values ('CRITICAL'); + +insert into `notification_method_type` values ('EMAIL'); +insert into `notification_method_type` values ('WEBHOOK'); +insert into `notification_method_type` values ('PAGERDUTY'); +/* provide data for enum tables */ diff --git a/templates/monasca-api.conf.j2 b/templates/monasca-api.conf.j2 deleted file mode 100644 index b76b899..0000000 --- a/templates/monasca-api.conf.j2 +++ /dev/null @@ -1,90 +0,0 @@ -[DEFAULT] -debug={{ debug }} -log_config_append=/etc/monasca/api-logging.conf -region = {{ keystone_service_region }} - -[dispatcher] -versions = monasca_api.v2.reference.versions:Versions -version_2_0 = monasca_api.v2.reference.version_2_0:Version2 -metrics = monasca_api.v2.reference.metrics:Metrics -metrics_measurements = monasca_api.v2.reference.metrics:MetricsMeasurements -metrics_statistics = monasca_api.v2.reference.metrics:MetricsStatistics -metrics_names = monasca_api.v2.reference.metrics:MetricsNames -alarm_definitions = monasca_api.v2.reference.alarm_definitions:AlarmDefinitions -alarms = monasca_api.v2.reference.alarms:Alarms -alarms_count = monasca_api.v2.reference.alarms:AlarmsCount -alarms_state_history = monasca_api.v2.reference.alarms:AlarmsStateHistory -notification_methods = monasca_api.v2.reference.notifications:Notifications -dimension_values = monasca_api.v2.reference.metrics:DimensionValues -dimension_names = monasca_api.v2.reference.metrics:DimensionNames -notification_method_types = monasca_api.v2.reference.notificationstype:NotificationsType - -[security] -default_authorized_roles = user, domainuser, domainadmin, {{ monasca_service_role_names | join(', ') }}, {{ monasca_role_names | join(', ') }} -agent_authorized_roles = {{ monasca_service_user_name }} -read_only_authorized_roles = {{ monasca_readonly_user_name }} -delegate_authorized_roles = admin - -[messaging] -driver = monasca_api.common.messaging.kafka_publisher:KafkaPublisher - -# Concurrency (locking mechanisms) -[oslo_concurrency] -lock_path = {{ monasca_lock_path }} - -[repositories] -metrics_driver = {{ monasca_api_metrics_driver }} -alarm_definitions_driver = monasca_api.common.repositories.sqla.alarm_definitions_repository:AlarmDefinitionsRepository -alarms_driver = monasca_api.common.repositories.sqla.alarms_repository:AlarmsRepository -notifications_driver = monasca_api.common.repositories.sqla.notifications_repository:NotificationsRepository -notification_method_type_driver = monasca_api.common.repositories.sqla.notification_method_type_repository:NotificationMethodTypeRepository - -[dispatcher] -driver = v2_reference - -[kafka] -uri = {{ kafka_hosts }} -metrics_topic = metrics -group = api -max_retry = 1 -wait_time = 1 -async = False -compact = False -partitions = 0 - -{% if monasca_backend_database == 'influxdb' %} -[influxdb] -ip_address = {{ influxdb_host }} -port = {{ influxdb_port }} -user = {{ influxdb_admin }} -password = {{ influxdb_admin_password }} -database_name = {{ influxdb_dbname }} -{% elif monasca_backend_database == 'cassandra' %} -[cassandra] -cluster_ip_addresses: 127.0.0.1 -keyspace: monasca -{% else %} -[mysql] -database_name = {{ monasca_galera_database }} -hostname = {{ monasca_galera_address }} -username = {{ monasca_galera_user }} -password = {{ monasca_galera_password }} -{% endif %} - -[database] -url = "mysql+pymysql://{{ monasca_galera_user }}:{{ monasca_galera_password }}@{{ monasca_galera_address }}/{{ monasca_galera_database }}" - -[keystone_authtoken] -auth_uri = {{ keystone_service_internalurl }} -auth_version = v3 -insecure = {{ keystone_service_internaluri_insecure | bool }} -memcached_servers = {{ memcached_servers }} -token_cache_time = 300 -identity_uri = {{ keystone_service_adminuri }} -auth_type = {{ monasca_keystone_auth_plugin }} -auth_url = {{ keystone_service_internaluri }} -project_domain_name = {{ monasca_service_project_domain_name }} -user_domain_name = {{ monasca_service_user_domain_name }} -project_name = {{ monasca_service_project_name }} -username = {{ monasca_service_user_name }} -password = {{ monasca_service_password }} diff --git a/templates/monasca-api/api-config.conf.j2 b/templates/monasca-api/api-config.conf.j2 new file mode 100644 index 0000000..1aefd8a --- /dev/null +++ b/templates/monasca-api/api-config.conf.j2 @@ -0,0 +1,139 @@ +# {{ ansible_managed }} + +[DEFAULT] +log_config_append = /etc/monasca/api-logging.conf + +# Identifies the region that the Monasca API is running in. +region = {{ keystone_service_region }} + +# Dispatchers to be loaded to serve restful APIs +[dispatcher] +versions = monasca_api.v2.reference.versions:Versions +version_2_0 = monasca_api.v2.reference.version_2_0:Version2 +metrics = monasca_api.v2.reference.metrics:Metrics +metrics_measurements = monasca_api.v2.reference.metrics:MetricsMeasurements +metrics_statistics = monasca_api.v2.reference.metrics:MetricsStatistics +metrics_names = monasca_api.v2.reference.metrics:MetricsNames +alarm_definitions = monasca_api.v2.reference.alarm_definitions:AlarmDefinitions +alarms = monasca_api.v2.reference.alarms:Alarms +alarms_count = monasca_api.v2.reference.alarms:AlarmsCount +alarms_state_history = monasca_api.v2.reference.alarms:AlarmsStateHistory +notification_methods = monasca_api.v2.reference.notifications:Notifications +dimension_values = monasca_api.v2.reference.metrics:DimensionValues +dimension_names = monasca_api.v2.reference.metrics:DimensionNames +notification_method_types = monasca_api.v2.reference.notificationstype:NotificationsType +healthchecks = monasca_api.healthchecks:HealthChecks + +[security] +# The roles that are allowed full access to the API. +default_authorized_roles = {{ monasca_user_roles | join(', ') }} + +# The roles that are allowed to only POST metrics to the API. This role would be used by the Monasca Agent. +agent_authorized_roles = {{ monasca_agent_roles | join(', ') }} + +# The roles that are allowed to only GET metrics from the API. +read_only_authorized_roles = {{ monasca_read_only_user_roles | join(', ') }} + +# The roles that are allowed to access the API on behalf of another tenant. +# For example, a service can POST metrics to another tenant if they are a member of the "delegate" role. +delegate_authorized_roles = admin + +[messaging] +# The message queue driver to use +driver = monasca_api.common.messaging.kafka_publisher:KafkaPublisher + +[repositories] +# The driver to use for the metrics repository +metrics_driver = monasca_api.common.repositories.influxdb.metrics_repository:MetricsRepository + +# The driver to use for the alarm definitions repository +alarm_definitions_driver = monasca_api.common.repositories.sqla.alarm_definitions_repository:AlarmDefinitionsRepository + +# The driver to use for the alarms repository +alarms_driver = monasca_api.common.repositories.sqla.alarms_repository:AlarmsRepository + +# The driver to use for the notifications repository +notifications_driver = monasca_api.common.repositories.sqla.notifications_repository:NotificationsRepository + +# The driver to use for the notification method type repository +notification_method_type_driver = monasca_api.common.repositories.sqla.notification_method_type_repository:NotificationMethodTypeRepository + +[dispatcher] +driver = v2_reference + +[kafka] +# The endpoint to the kafka server +uri = {{ kafka_hosts }} + +# The topic that metrics will be published too +metrics_topic = metrics + +# The topic that events will be published too +events_topic = events + +# The topic that alarm state will be published too +alarm_state_transitions_topic = alarm-state-transitions + +# consumer group name +group = api + +# how many times to try when error occurs +max_retry = 3 + +# wait time between tries when kafka goes down +wait_time = 1 + +# use synchronous or asynchronous connection to kafka +async = False + +# send messages in bulk or send messages one by one. +compact = False + +# How many partitions this connection should listen messages on, this +# parameter is for reading from kafka. If listens on multiple partitions, +# For example, if the client should listen on partitions 1 and 3, then the +# configuration should look like the following: +# partitions = 1 +# partitions = 3 +# default to listen on partition 0. +partitions = 0 + +[influxdb] +# The IP address of the InfluxDB service. +ip_address = {{ monasca_influxdb_host }} + +# The port number that the InfluxDB service is listening on. +port = {{ monasca_influxdb_port }} + +# The username to authenticate with. +user = {{ monasca_api_influxdb_user }} + +# The password to authenticate with. +password = {{ monasca_api_influxdb_password }} + +# The name of the InfluxDB database to use. +database_name = {{ monasca_influxdb_database }} + +[database] +connection = "mysql+pymysql://{{ monasca_galera_user }}:{{ monasca_container_mysql_password }}@{{ monasca_galera_address }}/{{ monasca_galera_database }}?charset=utf8mb4" + +[keystone_authtoken] +insecure = {{ keystone_service_internaluri_insecure | bool }} +auth_type = {{ monasca_keystone_auth_plugin }} +auth_url = {{ keystone_service_adminuri }} +auth_uri = {{ keystone_service_internaluri }} +project_domain_id = {{ monasca_service_project_domain_id }} +user_domain_id = {{ monasca_service_user_domain_id }} +project_name = {{ monasca_service_project_name }} +username = {{ monasca_service_user_name }} +password = {{ monasca_service_password }} +region_name = {{ keystone_service_region }} +service_token_roles_required = True + +memcached_servers = {{ memcached_servers }} + +token_cache_time = 300 + +# if your memcached server is shared, use these settings to avoid cache poisoning +memcache_security_strategy = ENCRYPT +memcache_secret_key = {{ memcached_encryption_key }} diff --git a/templates/monasca-api-paste.ini.j2 b/templates/monasca-api/api-config.ini.j2 similarity index 59% rename from templates/monasca-api-paste.ini.j2 rename to templates/monasca-api/api-config.ini.j2 index 9503c7e..01d9a52 100644 --- a/templates/monasca-api-paste.ini.j2 +++ b/templates/monasca-api/api-config.ini.j2 @@ -1,3 +1,5 @@ +# {{ ansible_managed }} + [DEFAULT] name = monasca_api @@ -8,7 +10,7 @@ pipeline = request_id auth api paste.app_factory = monasca_api.api.server:launch [filter:auth] -paste.filter_factory = keystonemiddleware.auth_token:filter_factory +paste.filter_factory = monasca_api.healthcheck.keystone_protocol:filter_factory [filter:request_id] paste.filter_factory = oslo_middleware.request_id:RequestId.factory @@ -16,6 +18,8 @@ paste.filter_factory = oslo_middleware.request_id:RequestId.factory [server:main] use = egg:gunicorn#main host = 0.0.0.0 -port = {{ monasca_bind_port }} -workers = 1 +port = {{ monasca_api_service_port }} +workers = {{ monasca_api_workers }} +worker-connections = 2000 +backlog = 1000 proc_name = monasca_api diff --git a/templates/monasca-api-logging.conf.j2 b/templates/monasca-api/api-logging.conf.j2 similarity index 60% rename from templates/monasca-api-logging.conf.j2 rename to templates/monasca-api/api-logging.conf.j2 index 1f97733..fd7637c 100644 --- a/templates/monasca-api-logging.conf.j2 +++ b/templates/monasca-api/api-logging.conf.j2 @@ -1,3 +1,5 @@ +# {{ ansible_managed }} + [loggers] keys = root, sqlalchemy, kafka @@ -5,11 +7,10 @@ keys = root, sqlalchemy, kafka keys = console, file [formatters] -keys = generic +keys = context [logger_root] -level = DEBUG -formatter = default +level = {{ monasca_log_level }} handlers = console, file [logger_sqlalchemy] @@ -17,30 +18,28 @@ qualname = sqlalchemy.engine # "level = INFO" logs SQL queries. # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) -level = DEBUG -formatter = default +level = {{ monasca_log_level }} handlers = console, file -propagate=0 +propagate = 0 [logger_kafka] qualname = kafka -level = DEBUG -formatter = default +level = {{ monasca_log_level }} handlers = console, file propagate = 0 [handler_console] class = logging.StreamHandler args = (sys.stderr,) -level = DEBUG -formatter = generic +level = {{ monasca_log_level }} +formatter = context [handler_file] class = logging.handlers.RotatingFileHandler -level = DEBUG -formatter = generic +level = {{ monasca_log_level }} +formatter = context # store up to 5*100MB of logs -args = ('/var/log/{{ monasca_service_name }}/monasca-api.log', 'a', 104857600, 5) +args = ('/var/log/{{ monasca_service_name }}/api.log', 'a', 104857600, 5) -[formatter_generic] -format = %(asctime)s %(levelname)s [%(name)s][%(threadName)s] %(message)s +[formatter_context] +class = oslo_log.formatters.ContextFormatter diff --git a/templates/monasca-log-api-paste.ini.j2 b/templates/monasca-log-api-paste.ini.j2 deleted file mode 100644 index 043a54b..0000000 --- a/templates/monasca-log-api-paste.ini.j2 +++ /dev/null @@ -1,24 +0,0 @@ -[DEFAULT] -name = monasca_log_api - -[pipeline:main] -pipeline = request_id auth roles api - -[app:api] -paste.app_factory = monasca_log_api.server:launch - -[filter:auth] -paste.filter_factory = monasca_log_api.healthcheck.keystone_protocol:filter_factory - -[filter:roles] -paste.filter_factory = monasca_log_api.middleware.role_middleware:RoleMiddleware.factory - -[filter:request_id] -paste.filter_factory = oslo_middleware.request_id:RequestId.factory - -[server:main] -use = egg:gunicorn#main -host = 0.0.0.0 -port = {{ monasca_log_api_bind_port }} -workers = 1 -proc_name = monasca_log_api diff --git a/templates/monasca-log-api.conf.j2 b/templates/monasca-log-api.conf.j2 deleted file mode 100644 index 7037587..0000000 --- a/templates/monasca-log-api.conf.j2 +++ /dev/null @@ -1,45 +0,0 @@ -[DEFAULT] -log_config_append=/etc/monasca/log-api-logging.conf -debug={{ debug }} -[service] -max_log_size = 1048576 -region = {{ keystone_service_region }} - -[log_publisher] -topics = logs -kafka_url = {{ kafka_hosts }} - -[kafka_healthcheck] -kafka_url = {{ kafka_hosts }} -kafka_topics = log - -[roles_middleware] -path = /v2.0/log -path = /v3.0/logs -default_roles = user, domainuser, domainadmin, {{ monasca_service_role_names | join(', ') }}, {{ monasca_role_names | join(', ') }} -agent_roles = {{ monasca_service_user_name }}, admin - -[dispatcher] -logs = monasca_log_api.reference.v2.logs:Logs -logs_v3 = monasca_log_api.reference.v3.logs:Logs -versions = monasca_log_api.reference.versions:Versions -healthchecks = monasca_log_api.reference.healthchecks:HealthChecks - -# Concurrency (locking mechanisms) -[oslo_concurrency] -lock_path = {{ monasca_lock_path }} - -[keystone_authtoken] -auth_uri = {{ keystone_service_internalurl }} -auth_version = v3 -insecure = {{ keystone_service_internaluri_insecure | bool }} -memcached_servers = {{ memcached_servers }} -token_cache_time = 300 -identity_uri = {{ keystone_service_adminuri }} -auth_type = {{ monasca_keystone_auth_plugin }} -auth_url = {{ keystone_service_internaluri }} -project_domain_name = {{ monasca_service_project_domain_name }} -user_domain_name = {{ monasca_service_user_domain_name }} -project_name = {{ monasca_service_project_name }} -username = {{ monasca_service_user_name }} -password = {{ monasca_service_password }} diff --git a/templates/monasca-notification/notification.yaml.j2 b/templates/monasca-notification/notification.yaml.j2 new file mode 100644 index 0000000..3af26bc --- /dev/null +++ b/templates/monasca-notification/notification.yaml.j2 @@ -0,0 +1,120 @@ +# {{ ansible_managed }} + +# +# (C) Copyright 2015,2016 Hewlett Packard Enterprise Development Company LP +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +#    http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +kafka: + url: "{{ kafka_hosts }}" + group: "monasca-notification" + alarm_topic: "alarm-state-transitions" + notification_topic: "alarm-notifications" + notification_retry_topic: "retry-notifications" + periodic: + 60: 60-seconds-notifications + max_offset_lag: 600 # In seconds, undefined for none + +database: + repo_driver: "monasca_notification.common.repositories.mysql.mysql_repo:MysqlRepo" + +mysql: + host: "{{ monasca_galera_address }}" + user: "{{ monasca_galera_user }}" + passwd: "{{ monasca_container_mysql_password }}" + db: "{{ monasca_galera_database }}" + +notification_types: + + email: + server: "localhost" + port: 25 + user: "" + password: "" + timeout: 15 + from_addr: "monasca-notification@{{ ansible_hostname }}" + + webhook: + timeout: 5 + + pagerduty: + timeout: 5 + url: "https://events.pagerduty.com/generic/2010-04-15/create_event.json" + + hipchat: + timeout: 5 + insecure: False + ca_certs: "/etc/ssl/certs/ca-certificates.crt" + + slack: + timeout: 5 + insecure: False + ca_certs: "/etc/ssl/certs/ca-certificates.crt" + +processors: + alarm: + number: 2 + ttl: 14400 # In seconds, undefined for none. Alarms older than this are not processed + notification: + number: 4 + +retry: + interval: 30 + max_attempts: 5 + +queues: + alarms_size: 256 + finished_size: 256 + notifications_size: 256 + sent_notifications_size: 50 # limiting this size reduces potential # of re-sent notifications after a failure + +zookeeper: + url: "{{ zookeeper_hosts }}" + notification_path: "/notification/alarms" + notification_retry_path: "/notification/retry" + periodic_path: + 60: /notification/60_seconds + +logging: # Used in logging.dictConfig + version: 1 + disable_existing_loggers: False + formatters: + default: + format: "%(asctime)s %(levelname)s %(name)s %(message)s" + handlers: + console: + class: logging.StreamHandler + formatter: default + file: + class: logging.handlers.RotatingFileHandler + filename: "/var/log/monasca/notification.log" + formatter: default + maxBytes: 10485760 # Rotate at file size ~10MB + backupCount: 5 # Keep 5 older logs around + loggers: + kazoo: + level: {{ monasca_log_level }} + kafka: + level: {{ monasca_log_level }} + statsd: + level: {{ monasca_log_level }} + root: + handlers: + - file + level: {{ monasca_log_level }} + +statsd: + host: 'localhost' + port: 8125 diff --git a/templates/monasca-log-api-logging.conf.j2 b/templates/monasca-persister/persister-logging.conf.j2 similarity index 58% rename from templates/monasca-log-api-logging.conf.j2 rename to templates/monasca-persister/persister-logging.conf.j2 index 9e1a3b7..ef5e335 100644 --- a/templates/monasca-log-api-logging.conf.j2 +++ b/templates/monasca-persister/persister-logging.conf.j2 @@ -1,5 +1,7 @@ +# {{ ansible_managed }} + [loggers] -keys = root, kafka +keys = root, kafka, influxdb [handlers] keys = console, file @@ -8,13 +10,20 @@ keys = console, file keys = generic [logger_root] -level = DEBUG +level = {{ monasca_log_level }} formatter = default handlers = console, file [logger_kafka] qualname = kafka -level = DEBUG +level = {{ monasca_log_level }} +formatter = default +handlers = console, file +propagate = 0 + +[logger_influxdb] +qualname = influxdb +level = {{ monasca_log_level }} formatter = default handlers = console, file propagate = 0 @@ -22,15 +31,15 @@ propagate = 0 [handler_console] class = logging.StreamHandler args = (sys.stderr,) -level = DEBUG +level = {{ monasca_log_level }} formatter = generic [handler_file] class = logging.handlers.RotatingFileHandler -level = DEBUG +level = {{ monasca_log_level }} formatter = generic # store up to 5*100MB of logs -args = ('/var/log/{{ monasca_service_name }}/monasca-log-api.log', 'a', 104857600, 5) +args = ('/var/log/monasca/persister.log', 'a', 104857600, 5) [formatter_generic] format = %(asctime)s %(levelname)s [%(name)s][%(threadName)s] %(message)s diff --git a/templates/monasca-persister/persister.conf.j2 b/templates/monasca-persister/persister.conf.j2 new file mode 100644 index 0000000..125da42 --- /dev/null +++ b/templates/monasca-persister/persister.conf.j2 @@ -0,0 +1,63 @@ +# {{ ansible_managed }} + +[DEFAULT] +log_config_append=/etc/monasca/persister-logging.conf + +# Default log level is WARNING +# Show debugging output in logs (sets DEBUG log level output) +debug = {{ debug }} + +[repositories] +# The driver to use for the metrics repository +metrics_driver = monasca_persister.repositories.influxdb.metrics_repository:MetricInfluxdbRepository + +# The driver to use for the alarm state history repository +alarm_state_history_driver = monasca_persister.repositories.influxdb.alarm_state_history_repository:AlarmStateHistInfluxdbRepository + +[zookeeper] +# Comma separated list of host:port +uri = {{ zookeeper_hosts }} +partition_interval_recheck_seconds = {{ monasca_partition_interval_recheck_seconds }} + +[kafka_alarm_history] +# Comma separated list of Kafka broker host:port. +uri = {{ kafka_hosts }} +group_id = 1_alarm-state-transitions +topic = alarm-state-transitions +consumer_id = 1 +client_id = 1 +database_batch_size = 3000 +max_wait_time_seconds = 15 +# The following 3 values are set to the kakfa-python defaults +fetch_size_bytes = 4096 +buffer_size = 4096 +# 8 times buffer size +max_buffer_size = 32768 +# Path in zookeeper for kafka consumer group partitioning algo +zookeeper_path = /persister_partitions/alarm-state-transitions +num_processors = {{ monasca_persister_workers|int // 2 }} + +[kafka_metrics] +# Comma separated list of Kafka broker host:port +uri = {{ kafka_hosts }} +group_id = 1_metrics +topic = metrics +consumer_id = 1 +client_id = 1 +database_batch_size = 3000 +max_wait_time_seconds = 15 +# The following 3 values are set to the kakfa-python defaults +fetch_size_bytes = 4096 +buffer_size = 4096 +# 8 times buffer size +max_buffer_size = 32768 +# Path in zookeeper for kafka consumer group partitioning algo +zookeeper_path = /persister_partitions/metrics +num_processors = {{ monasca_persister_workers|int // 2 }} + +[influxdb] +database_name = {{ monasca_influxdb_database }} +ip_address = {{ monasca_influxdb_host }} +port = {{ monasca_influxdb_port }} +user = {{ monasca_persister_influxdb_user }} +password = {{ monasca_persister_influxdb_password }} diff --git a/templates/monasca-systemd-init.j2 b/templates/monasca-systemd-init.j2 index 3b03332..151c8d0 100644 --- a/templates/monasca-systemd-init.j2 +++ b/templates/monasca-systemd-init.j2 @@ -11,9 +11,9 @@ User={{ monasca_system_user_name }} Group={{ monasca_system_group_name }} {% if item.value.service_init_bin is defined %} -ExecStart={{ item.value.service_init_bin }} {{ item.value.service_init_options |default('') }} --log-file=/var/log/monasca/{{ item.value.service_name }}.log +ExecStart={{ item.value.service_init_bin }} {{ item.value.service_init_options |default('') }} {% else %} -ExecStart={{ monasca_bin }}/{{ item.value.service_name }} {{ program_config_options|default('') }} --log-file=/var/log/monasca/{{ item.value.service_name }}.log +ExecStart={{ monasca_bin }}/{{ item.value.service_name }} {{ program_config_options|default('') }} {% endif %} # Give a reasonable amount of time for the server to start up/shut down diff --git a/templates/monasca-systemd-tempfiles.j2 b/templates/monasca-systemd-tmpfiles.j2 similarity index 72% rename from templates/monasca-systemd-tempfiles.j2 rename to templates/monasca-systemd-tmpfiles.j2 index 48d0318..055d540 100644 --- a/templates/monasca-systemd-tempfiles.j2 +++ b/templates/monasca-systemd-tmpfiles.j2 @@ -2,4 +2,3 @@ D /var/lock/{{ item.value.service_name }} 2755 {{ monasca_system_user_name }} {{ monasca_system_group_name }} D /var/run/{{ item.value.service_name }} 2755 {{ monasca_system_user_name }} {{ monasca_system_group_name }} -D {{ monasca_lock_path }} 2755 {{ monasca_system_user_name }} {{ monasca_system_group_name }} diff --git a/templates/monasca-thresh/thresh-config.yml.j2 b/templates/monasca-thresh/thresh-config.yml.j2 new file mode 100644 index 0000000..61c8b1f --- /dev/null +++ b/templates/monasca-thresh/thresh-config.yml.j2 @@ -0,0 +1,146 @@ +# {{ ansible_managed }} + +# +# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +#    http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +metricSpoutThreads: 2 +metricSpoutTasks: 2 + +statsdConfig: + host: 0.0.0.0 + port: 8125 + prefix: monasca.storm. + dimensions: !!map + service : monitoring + component : storm + + +metricSpoutConfig: + kafkaConsumerConfiguration: + # See http://kafka.apache.org/documentation.html#api for semantics and defaults. + topic: "metrics" + numThreads: 1 + groupId: "thresh-metric" + zookeeperConnect: "{{ zookeeper_hosts }}" + consumerId: 1 + socketTimeoutMs: 30000 + socketReceiveBufferBytes : 65536 + fetchMessageMaxBytes: 1048576 + autoCommitEnable: true + autoCommitIntervalMs: 60000 + queuedMaxMessageChunks: 10 + rebalanceMaxRetries: 4 + fetchMinBytes: 1 + fetchWaitMaxMs: 100 + rebalanceBackoffMs: 2000 + refreshLeaderBackoffMs: 200 + autoOffsetReset: largest + consumerTimeoutMs: -1 + clientId : 1 + zookeeperSessionTimeoutMs : 60000 + zookeeperConnectionTimeoutMs : 60000 + zookeeperSyncTimeMs: 2000 + + +eventSpoutConfig: + kafkaConsumerConfiguration: + # See http://kafka.apache.org/documentation.html#api for semantics and defaults. + topic: "events" + numThreads: 1 + groupId: "thresh-event" + zookeeperConnect: "{{ zookeeper_hosts }}" + consumerId: 1 + socketTimeoutMs: 30000 + socketReceiveBufferBytes : 65536 + fetchMessageMaxBytes: 1048576 + autoCommitEnable: true + autoCommitIntervalMs: 60000 + queuedMaxMessageChunks: 10 + rebalanceMaxRetries: 4 + fetchMinBytes: 1 + fetchWaitMaxMs: 100 + rebalanceBackoffMs: 2000 + refreshLeaderBackoffMs: 200 + autoOffsetReset: largest + consumerTimeoutMs: -1 + clientId : 1 + zookeeperSessionTimeoutMs : 60000 + zookeeperConnectionTimeoutMs : 60000 + zookeeperSyncTimeMs: 2000 + + +kafkaProducerConfig: + # See http://kafka.apache.org/documentation.html#api for semantics and defaults. + topic: "alarm-state-transitions" + metadataBrokerList: "{{ kafka_hosts }}" + serializerClass: kafka.serializer.StringEncoder + partitionerClass: + requestRequiredAcks: 1 + requestTimeoutMs: 10000 + producerType: sync + keySerializerClass: + compressionCodec: none + compressedTopics: + messageSendMaxRetries: 3 + retryBackoffMs: 100 + topicMetadataRefreshIntervalMs: 600000 + queueBufferingMaxMs: 5000 + queueBufferingMaxMessages: 10000 + queueEnqueueTimeoutMs: -1 + batchNumMessages: 200 + sendBufferBytes: 102400 + clientId : Threshold_Engine + + +sporadicMetricNamespaces: + - foo + +database: + driverClass: "com.mysql.jdbc.jdbc2.optional.MysqlDataSource" + url: "jdbc:mysql://{{ monasca_galera_address }}/{{ monasca_galera_database }}?useSSL=true" + user: "{{ monasca_galera_user }}" + password: "{{ monasca_container_mysql_password }}" + properties: + ssl: false + # the maximum amount of time to wait on an empty pool before throwing an exception + maxWaitForConnection: 1s + + # the SQL query to run when validating a connection's liveness + validationQuery: "/* mysql Health Check */ SELECT 1" + + # the minimum number of connections to keep open + minSize: 8 + + # the maximum number of connections to keep open + maxSize: 41 + + # flag indicates if Hibernate support enabled + hibernateSupport: false + + # hibernate provider class + providerClass: com.zaxxer.hikari.hibernate.HikariConnectionProvider + + # database name + databaseName: {{ monasca_galera_database }} + + # server name/address + serverName: {{ monasca_galera_address }} + + # server port number + portNumber: 3306 + + # hibernate auto configuretion parameter + autoConfig: validate diff --git a/templates/monasca-upstart-init.j2 b/templates/monasca-upstart-init.j2 deleted file mode 100644 index 5072734..0000000 --- a/templates/monasca-upstart-init.j2 +++ /dev/null @@ -1,42 +0,0 @@ -# {{ ansible_managed }} - - -description "{{ item.value.service_name }}" -author "Kevin Carter " - -start on runlevel [2345] -stop on runlevel [016] - -respawn -respawn limit 10 5 - -# Set the RUNBIN environment variable -env RUNBIN="{{ monasca_bin }}/{{ item.value.service_name }}" -# Change directory to service users home -chdir "{{ monasca_system_user_home }}" - -# Pre start actions -pre-start script - mkdir -p "/var/run/{{ item.value.service_name }}" - chown {{ monasca_system_user_name }}:{{ monasca_system_group_name }} "/var/run/{{ item.value.service_name }}" - - mkdir -p "/var/lock/{{ item.value.service_name }}" - chown {{ monasca_system_user_name }}:{{ monasca_system_group_name }} "/var/lock/{{ item.value.service_name }}" - - . {{ monasca_bin }}/activate - -end script - -# Post stop actions -post-stop script - rm "/var/run/{{ item.value.service_name }}/{{ item.value.service_name }}.pid" -end script - -# Run the start up job -exec start-stop-daemon --start \ - --chuid {{ monasca_system_user_name }} \ - --make-pidfile \ - --pidfile /var/run/{{ item.value.service_name }}/{{ item.value.service_name }}.pid \ - --exec "{{ item.value.service_init_bin|default('$RUNBIN') }}" \ - -- {{ item.value.service_init_options|default('') }} \ - --log-file=/var/log/{{ monasca_service_name }}/{{ item.value.service_name }}.log diff --git a/tests/ansible-role-requirements.yml b/tests/ansible-role-requirements.yml index 6a5a6f7..69b94c3 100644 --- a/tests/ansible-role-requirements.yml +++ b/tests/ansible-role-requirements.yml @@ -22,10 +22,6 @@ src: https://git.openstack.org/openstack/openstack-ansible-lxc_container_create scm: git version: master -- name: memcached_server - src: https://git.openstack.org/openstack/openstack-ansible-memcached_server - scm: git - version: master - name: galera_client src: https://git.openstack.org/openstack/openstack-ansible-galera_client scm: git @@ -46,10 +42,6 @@ src: https://git.openstack.org/openstack/openstack-ansible-os_keystone scm: git version: master -- name: openstack_hosts - src: https://github.com/openstack/openstack-ansible-openstack_hosts - scm: git - version: master - name: os_tempest src: https://git.openstack.org/openstack/openstack-ansible-os_tempest scm: git @@ -59,22 +51,18 @@ scm: git version: master - name: ansible-kafka - src: https://github.com/Chillisystems/ansible-kafka + src: https://github.com/flaviodsr/ansible-kafka scm: git version: master - name: ansible-storm - src: https://github.com/Chillisystems/ansible-storm + src: https://github.com/flaviodsr/ansible-storm scm: git version: master - name: ansible-influxdb - src: https://github.com/Chillisystems/ansible-influxdb + src: https://github.com/flaviodsr/ansible-influxdb scm: git version: master -- name: ansible-grafana - src: https://github.com/Chillisystems/ansible-grafana - scm: git - version: master -- name: ansible-monasca-schema - src: https://github.com/Chillisystems/ansible-monasca-schema +- name: grafana-ansible + src: https://github.com/flaviodsr/grafana-ansible scm: git version: master diff --git a/tasks/monasca_init_common.yml b/tests/group_vars/monasca_all.yml similarity index 55% rename from tasks/monasca_init_common.yml rename to tests/group_vars/monasca_all.yml index eae82a6..ab4b393 100644 --- a/tasks/monasca_init_common.yml +++ b/tests/group_vars/monasca_all.yml @@ -1,6 +1,4 @@ --- -# Copyright 2016 Internet Solutions (Pty) Ltd -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -13,19 +11,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -- include: monasca_init_upstart.yml - when: - - ansible_service_mgr == 'upstart' +influxdb_host: "{{ internal_lb_vip_address }}" +influxdb_port: 8086 -- include: monasca_init_systemd.yml - when: - - ansible_service_mgr == 'systemd' +zookeeper_hosts: "{% for host in groups['monasca_zookeeper'] %}{{ hostvars[host]['ansible_host'] }}:{{ zookeeper_client_port }}{% if not loop.last %},{% endif %}{% endfor %}" -- name: Load service - service: - name: "{{ item.value.service_name }}" - enabled: "yes" - with_dict: "{{ monasca_services }}" - when: inventory_hostname in groups[item.value.group] - notify: - - Restart monasca services +kafka_hosts: "{% for host in groups['monasca_kafka'] %}{{ hostvars[host]['ansible_host'] }}:{{ kafka_port }}{% if not loop.last %},{% endif %}{% endfor %}" diff --git a/tests/host_vars/infra1.yml b/tests/host_vars/infra1.yml new file mode 100644 index 0000000..bfdc135 --- /dev/null +++ b/tests/host_vars/infra1.yml @@ -0,0 +1,18 @@ +--- +# Copyright 2016, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ansible_host: 10.1.1.101 +ansible_become: True +ansible_user: root diff --git a/tests/host_vars/localhost.yml b/tests/host_vars/localhost.yml index 65ddeaa..4384b96 100644 --- a/tests/host_vars/localhost.yml +++ b/tests/host_vars/localhost.yml @@ -13,7 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -bridges: - - "br-mgmt" - +ansible_host: 127.0.0.1 ansible_python_interpreter: "/usr/bin/python2" +bridges: + - name: "br-mgmt" + ip_addr: "10.1.1.1" diff --git a/tests/host_vars/monasca1.yml b/tests/host_vars/monasca1.yml new file mode 100644 index 0000000..1f172ba --- /dev/null +++ b/tests/host_vars/monasca1.yml @@ -0,0 +1,18 @@ +--- +# Copyright 2016, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ansible_host: 10.1.1.103 +ansible_become: True +ansible_user: root diff --git a/tests/host_vars/openstack1.yml b/tests/host_vars/openstack1.yml new file mode 100644 index 0000000..e50c238 --- /dev/null +++ b/tests/host_vars/openstack1.yml @@ -0,0 +1,18 @@ +--- +# Copyright 2016, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ansible_host: 10.1.1.102 +ansible_become: True +ansible_user: root diff --git a/tests/inventory b/tests/inventory index a2c80b0..e84da62 100644 --- a/tests/inventory +++ b/tests/inventory @@ -1,11 +1,13 @@ [all] localhost -infra1 ansible_host=10.100.100.2 ansible_become=True ansible_user=root -openstack1 ansible_host=10.100.100.3 ansible_become=True ansible_user=root +infra1 +openstack1 +monasca1 [all_containers] infra1 openstack1 +monasca1 [rabbitmq_all] infra1 @@ -17,7 +19,7 @@ infra1 infra1 [utility_all] -openstack1 +infra1 [service_all:children] rabbitmq_all @@ -28,14 +30,43 @@ memcached_all openstack1 [monasca_api] -openstack1 +monasca1 -[monasca_events_api] -openstack1 +[monasca_persister] +monasca1 -[monasca_log_api] -openstack1 +[monasca_thresh] +monasca1 + +[monasca_notification] +monasca1 + +[monasca_agent] +monasca1 + +[monasca_zookeeper] +monasca1 + +[monasca_kafka] +monasca1 + +[monasca_storm] +monasca1 + +[monasca_influxdb] +monasca1 + +[monasca_grafana] +monasca1 [monasca_all:children] monasca_api -monasca_log_api +monasca_persister +monasca_thresh +monasca_notification +monasca_agent +monasca_zookeeper +monasca_kafka +monasca_storm +monasca_influxdb +monasca_grafana diff --git a/tests/os_monasca-overrides.yml b/tests/os_monasca-overrides.yml index f77f384..84368f2 100644 --- a/tests/os_monasca-overrides.yml +++ b/tests/os_monasca-overrides.yml @@ -16,88 +16,43 @@ # (c) 2016 Donovan Francesco # (c) 2016 Paul Stevens +# Monasca vars +test_monasca_group: "{{ ((groups['monasca_all'] is defined) and (groups['monasca_all'] | length > 0)) | ternary('monasca_all', 'all_containers') }}" +test_monasca_host: "{{ hostvars[groups[test_monasca_group][0]]['ansible_host'] }}" monasca_venv_tag: "testing" -monasca_developer_mode: True -monasca_galera_address: "{{ hostvars[groups['galera_all'][0]]['ansible_host'] }}" -external_lb_vip_address: "{{ hostvars[groups['keystone_all'][0]]['ansible_host'] }}" -internal_lb_vip_address: "{{ hostvars[groups['keystone_all'][0]]['ansible_host'] }}" +monasca_developer_mode: true +monasca_git_install_branch: master +monasca_service_password: "secrete" +monasca_galera_address: "{{ test_galera_host }}" monasca_galera_database: monasca monasca_galera_user: monasca -monasca_galera_password: "secrete" -monasca_keystone_auth_plugin: password -monasca_rabbitmq_port: "{{ rabbitmq_port }}" -monasca_rabbitmq_servers: "{{ rabbitmq_servers }}" -monasca_rabbitmq_use_ssl: "{{ rabbitmq_use_ssl }}" -monasca_rabbitmq_password: "secrete" -monasca_rabbitmq_userid: monasca -monasca_rabbitmq_vhost: /monasca -monasca_api_requirements_git_install_branch: master -monasca_log_api_requirements_git_install_branch: master -monasca_ceilometer_requirements_git_install_branch: master -monasca_common_requirements_git_install_branch: master -monasca_transform_requirements_git_install_branch: master -monasca_notification_requirements_git_install_branch: master -monasca_persister_requirements_git_install_branch: master -monasca_python_client_requirements_git_install_branch: master -monasca_service_password: "secrete" -monasca_readonly_password: "secrete" -monasca_role_names: - - monasca-user - - anotherrole -monasca_service_user_domain_name: default -monasca_service_project_domain_name: Default -monasca_service_project_name: service -monasca_service_region: RegionOne -monasca_service_user_name: monasca -monasca_readonly_user_name: monasca-read-only -monasca_bind_port: 8070 -monasca_log_api_bind_port: 5607 +monasca_service_port: 8070 +monasca_service_publicuri: "http://{{ test_monasca_host }}:{{ monasca_service_port }}" +monasca_service_publicurl: "{{ monasca_service_publicuri }}/v2.0" +monasca_service_internaluri: "http://{{ test_monasca_host }}:{{ monasca_service_port }}" +monasca_service_internalurl: "{{ monasca_service_internaluri }}/v2.0" +monasca_service_adminuri: "http://{{ test_monasca_host }}:{{ monasca_service_port }}" +monasca_service_adminurl: "{{ monasca_service_adminuri }}/v2.0" +monasca_container_mysql_password: "SuperSecrete" monasca_bin: "/openstack/venvs/monasca-{{ monasca_venv_tag }}/bin" -storm_nimbus_enabled: true -storm_supervisor_enabled: true -nimbus_host: "{{ zookeeper_hosts }}" -monasca_mysql_host: "{{ monasca_galera_address }}" -monasca_mysql_admin: "{{ monasca_galera_user }}" -monasca_mysql_admin_password: "{{ monasca_galera_password }}" -monasca_mysql_db: "{{ monasca_galera_database }}" -influxdb_admin: "monasca" -influxdb_admin_password: "secrete" -monasca_grafana_admin_password: "secrete" -monasca_grafana_galera_password: "secrete" -monasca_grafana_galera_database: grafana -monasca_grafana_galera_username: grafana + grafana_mysql_host: "{{ monasca_galera_address }}" -grafana_admin_password: "{{ monasca_grafana_admin_password }}" -grafana_mysql_db: "{{ monasca_grafana_galera_database }}" -grafana_mysql_user: "{{ monasca_grafana_galera_username }}" -grafana_mysql_password: "{{ monasca_grafana_galera_password }}" -grafana_keystone_url: "{{ keystone_service_internalurl }}" +grafana_admin_password: "secrete" +grafana_galera_password: "secrete" +monasca_influxdb_admin_password: "secrete" +monasca_api_influxdb_password: "secrete" +monasca_persister_influxdb_password: "secrete" +monasca_agent_password: "secrete" +monasca_agent_roles: + - monasca-agent + - anotherrole + tempest_run: yes -tempest_venv_tag: "{{ tempest_git_install_branch }}" -tempest_venv_bin: "/opt/tempest_{{ tempest_venv_tag }}/bin" -tempest_log_dir: "/var/log/" + tempest_plugins: - name: monasca-api repo: https://git.openstack.org/openstack/monasca-api branch: master + tempest_test_whitelist: - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_alarm_actions_exceeds_max_length - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_description_exceeds_max_length - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_invalid_severity - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_multiple_notifications - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_name_exceeds_max_length - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_notification - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_ok_actions_exceeds_max_length - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_special_chars_in_expression - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_undeterm_actions_exceeds_max_length - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_alarm_definition_with_url_in_expression - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_and_delete_alarm_definition - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_deterministic_alarm_definition - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_create_deterministic_alarm_definition_compound_expr - - monasca_tempest_tests.tests.api.test_alarm_definitions.TestAlarmDefinitions.test_update_notification_in_alarm_definition - - monasca_tempest_tests.tests.api.test_versions.TestVersions.* -neutron_provider_networks: - network_types: "vxlan,flat" - network_mappings: "flat:eth12" - network_vxlan_ranges: "1:1000" + - monasca_tempest_tests.tests.api.* diff --git a/tests/test-install-monasca.yml b/tests/test-install-monasca.yml index e94fd83..f205ce6 100644 --- a/tests/test-install-monasca.yml +++ b/tests/test-install-monasca.yml @@ -18,69 +18,13 @@ - name: Install monasca server hosts: monasca_all - max_fail_percentage: 20 - user: root + remote_user: root + become: true gather_facts: true pre_tasks: - - name: Ensure rabbitmq vhost - rabbitmq_vhost: - name: "{{ monasca_rabbitmq_vhost }}" - state: "present" - delegate_to: "{{ hostvars[groups['rabbitmq_all'][0]]['ansible_host'] }}" - when: inventory_hostname == groups['monasca_all'][0] - - name: Ensure rabbitmq user - rabbitmq_user: - user: "{{ monasca_rabbitmq_userid }}" - password: "{{ monasca_rabbitmq_password }}" - vhost: "{{ monasca_rabbitmq_vhost }}" - configure_priv: ".*" - read_priv: ".*" - write_priv: ".*" - state: "present" - delegate_to: "{{ hostvars[groups['rabbitmq_all'][0]]['ansible_host'] }}" - when: inventory_hostname == groups['monasca_all'][0] - - name: Create DB for service - mysql_db: - login_user: "{{ galera_root_user }}" - login_password: "{{ galera_root_password }}" - login_host: "{{ monasca_galera_address }}" - name: "{{ item }}" - state: "present" - with_items: - - "{{ monasca_galera_database }}" - - "{{ monasca_grafana_galera_database }}" - delegate_to: "{{ hostvars[groups['galera_all'][0]]['ansible_host'] }}" - when: inventory_hostname == groups['monasca_all'][0] - - name: Grant access to the DB for the monasca service - mysql_user: - login_user: "{{ galera_root_user }}" - login_password: "{{ galera_root_password }}" - login_host: "{{ monasca_galera_address }}" - name: "{{ monasca_galera_database }}" - password: "{{ monasca_galera_password }}" - host: "{{ item }}" - state: "present" - priv: "{{ monasca_galera_database }}.*:ALL" - with_items: - - "localhost" - - "%" - delegate_to: "{{ hostvars[groups['galera_all'][0]]['ansible_host'] }}" - when: inventory_hostname == groups['monasca_all'][0] - - name: Grant access to the DB for the monasca grafana service - mysql_user: - login_user: "{{ galera_root_user }}" - login_password: "{{ galera_root_password }}" - login_host: "{{ monasca_galera_address }}" - name: "{{ monasca_grafana_galera_username }}" - password: "{{ monasca_grafana_galera_password }}" - host: "{{ item }}" - state: "present" - priv: "{{ monasca_grafana_galera_database }}.*:ALL" - with_items: - - "localhost" - - "%" - delegate_to: "{{ hostvars[groups['galera_all'][0]]['ansible_host'] }}" - when: inventory_hostname == groups['monasca_all'][0] + - include: common/create-grant-db.yml + db_name: "{{ monasca_galera_database }}" + db_password: "{{ monasca_container_mysql_password }}" roles: - role: "os_monasca" vars_files: diff --git a/vars/ubuntu-16.04.yml b/vars/ubuntu-16.04.yml index a504a53..ad3e5bd 100644 --- a/vars/ubuntu-16.04.yml +++ b/vars/ubuntu-16.04.yml @@ -16,10 +16,17 @@ # (c) 2016 Donovan Francesco # (c) 2016 Paul Stevens # + +## APT Cache options +cache_timeout: 600 + +## Common apt packages monasca_distro_packages: - build-essential + - git + - mailutils + - maven - openjdk-8-jdk - python-software-properties - python-dev - python-mysqldb - - python-pip