From d8ab00fa3c6ec3aba440ac50beb32c8e18e42337 Mon Sep 17 00:00:00 2001 From: Doug Szumski Date: Fri, 7 May 2021 18:49:31 +0100 Subject: [PATCH] Add role to deploy cASO cASO is an OpenStack accounting extractor. For more detail see: https://github.com/IFCA/caso By default, cASO is configured to output to Fluentd via TCP. The accounting information can then be shipped off to ElasticSearch. --- ansible/group_vars/all.yml | 3 + ansible/inventory/all-in-one | 4 + ansible/inventory/multinode | 4 + ansible/roles/caso/defaults/main.yml | 40 +++++++++ ansible/roles/caso/handlers/main.yml | 24 +++++ ansible/roles/caso/meta/main.yml | 3 + ansible/roles/caso/tasks/check.yml | 1 + ansible/roles/caso/tasks/config.yml | 90 +++++++++++++++++++ ansible/roles/caso/tasks/deploy.yml | 12 +++ ansible/roles/caso/tasks/main.yml | 2 + ansible/roles/caso/tasks/precheck.yml | 1 + ansible/roles/caso/tasks/pull.yml | 11 +++ ansible/roles/caso/tasks/reconfigure.yml | 2 + ansible/roles/caso/tasks/register.yml | 14 +++ ansible/roles/caso/tasks/upgrade.yml | 5 ++ ansible/roles/caso/templates/caso.conf.j2 | 23 +++++ ansible/roles/caso/templates/caso.crontab.j2 | 1 + ansible/roles/caso/templates/caso.json.j2 | 41 +++++++++ ansible/roles/caso/templates/voms.json.j2 | 9 ++ ansible/roles/common/tasks/config.yml | 2 + .../conf/filter/00-record_transformer.conf.j2 | 9 ++ .../templates/conf/input/99-caso.conf.j2 | 8 ++ .../templates/conf/output/01-es.conf.j2 | 16 ++++ .../templates/cron-logrotate-caso.conf.j2 | 3 + ansible/site.yml | 10 +++ etc/kolla/passwords.yml | 5 ++ 26 files changed, 343 insertions(+) create mode 100644 ansible/roles/caso/defaults/main.yml create mode 100644 ansible/roles/caso/handlers/main.yml create mode 100644 ansible/roles/caso/meta/main.yml create mode 100644 ansible/roles/caso/tasks/check.yml create mode 100644 ansible/roles/caso/tasks/config.yml create mode 100644 ansible/roles/caso/tasks/deploy.yml create mode 100644 ansible/roles/caso/tasks/main.yml create mode 100644 ansible/roles/caso/tasks/precheck.yml create mode 100644 ansible/roles/caso/tasks/pull.yml create mode 100644 ansible/roles/caso/tasks/reconfigure.yml create mode 100644 ansible/roles/caso/tasks/register.yml create mode 100644 ansible/roles/caso/tasks/upgrade.yml create mode 100644 ansible/roles/caso/templates/caso.conf.j2 create mode 100644 ansible/roles/caso/templates/caso.crontab.j2 create mode 100644 ansible/roles/caso/templates/caso.json.j2 create mode 100644 ansible/roles/caso/templates/voms.json.j2 create mode 100644 ansible/roles/common/templates/conf/input/99-caso.conf.j2 create mode 100644 ansible/roles/common/templates/cron-logrotate-caso.conf.j2 diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index 921e0613df..7bab619df2 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -256,6 +256,8 @@ barbican_api_listen_port: "{{ barbican_api_port }}" blazar_api_port: "1234" +caso_tcp_output_port: "24224" + cinder_internal_fqdn: "{{ kolla_internal_fqdn }}" cinder_external_fqdn: "{{ kolla_external_fqdn }}" cinder_api_port: "8776" @@ -568,6 +570,7 @@ enable_haproxy_memcached: "no" enable_aodh: "no" enable_barbican: "no" enable_blazar: "no" +enable_caso: "no" enable_ceilometer: "no" enable_ceilometer_ipmi: "no" enable_cells: "no" diff --git a/ansible/inventory/all-in-one b/ansible/inventory/all-in-one index bc0022f76e..5382f278c7 100644 --- a/ansible/inventory/all-in-one +++ b/ansible/inventory/all-in-one @@ -18,6 +18,10 @@ localhost ansible_connection=local [deployment] localhost ansible_connection=local +# Caso +[caso:children] +monitoring + # You can explicitly specify which hosts run each project by updating the # groups in the sections below. Common services are grouped together. [chrony-server:children] diff --git a/ansible/inventory/multinode b/ansible/inventory/multinode index 19b9fe2590..51e0848499 100644 --- a/ansible/inventory/multinode +++ b/ansible/inventory/multinode @@ -42,6 +42,10 @@ monitoring [tls-backend:children] control +# Caso +[caso:children] +monitoring + # You can explicitly specify which hosts run each project by updating the # groups in the sections below. Common services are grouped together. [chrony-server:children] diff --git a/ansible/roles/caso/defaults/main.yml b/ansible/roles/caso/defaults/main.yml new file mode 100644 index 0000000000..462c9f5b36 --- /dev/null +++ b/ansible/roles/caso/defaults/main.yml @@ -0,0 +1,40 @@ +--- +caso_services: + caso: + container_name: caso + group: caso + enabled: true + image: "{{ caso_image_full }}" + volumes: + - "{{ node_config_directory }}/caso/:{{ container_config_directory }}/" + - "/etc/localtime:/etc/localtime:ro" + - "caso_spool:/var/lib/caso" + - "caso_ssm_outgoing:/var/spool/apel/outgoing/openstack" + - "kolla_logs:/var/log/kolla/" + dimensions: "{{ caso_dimensions }}" + +#################### +# caso +#################### +caso_site_name: "kolla_caso" +caso_projects: [] +caso_logging_debug: "{{ openstack_logging_debug }}" +caso_log_dir: "/var/log/kolla/caso" +caso_cron_table: "10 * * * *" +caso_messengers: + - caso.messenger.logstash.LogstashMessenger + +#################### +# OpenStack +#################### +caso_openstack_auth: "{{ openstack_auth }}" +caso_keystone_user: "caso" + +#################### +# Docker +#################### +caso_install_type: "{{ kolla_install_type }}" +caso_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ caso_install_type }}-caso" +caso_tag: "{{ openstack_release }}" +caso_image_full: "{{ caso_image }}:{{ caso_tag }}" +caso_dimensions: "{{ default_container_dimensions }}" diff --git a/ansible/roles/caso/handlers/main.yml b/ansible/roles/caso/handlers/main.yml new file mode 100644 index 0000000000..07cd0f24d4 --- /dev/null +++ b/ansible/roles/caso/handlers/main.yml @@ -0,0 +1,24 @@ +--- +- name: Restart caso container + vars: + service_name: "caso" + service: "{{ caso_services[service_name] }}" + config_json: "{{ caso_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}" + caso_container: "{{ check_caso_containers.results|selectattr('item.key', 'equalto', service_name)|first }}" + become: true + kolla_docker: + action: "recreate_or_restart_container" + common_options: "{{ docker_common_options }}" + name: "{{ service.container_name }}" + image: "{{ service.image }}" + volumes: "{{ service.volumes }}" + dimensions: "{{ service.dimensions }}" + when: + - kolla_action != "config" + - inventory_hostname in groups[service.group] + - service.enabled | bool + - config_json.changed | bool + or caso_conf.changed | bool + or caso_vom_conf.changed | bool + or caso_crontab.changed | bool + or caso_container.changed | bool diff --git a/ansible/roles/caso/meta/main.yml b/ansible/roles/caso/meta/main.yml new file mode 100644 index 0000000000..6b4fff8fef --- /dev/null +++ b/ansible/roles/caso/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - { role: common } diff --git a/ansible/roles/caso/tasks/check.yml b/ansible/roles/caso/tasks/check.yml new file mode 100644 index 0000000000..ed97d539c0 --- /dev/null +++ b/ansible/roles/caso/tasks/check.yml @@ -0,0 +1 @@ +--- diff --git a/ansible/roles/caso/tasks/config.yml b/ansible/roles/caso/tasks/config.yml new file mode 100644 index 0000000000..7e4d7eec3a --- /dev/null +++ b/ansible/roles/caso/tasks/config.yml @@ -0,0 +1,90 @@ +--- +- name: Ensuring config directories exist + file: + path: "{{ node_config_directory }}/{{ item.key }}" + state: "directory" + owner: "{{ config_owner_user }}" + group: "{{ config_owner_group }}" + mode: "0770" + become: true + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ caso_services }}" + +- name: Copying over config.json files for services + template: + src: "{{ item.key }}.json.j2" + dest: "{{ node_config_directory }}/{{ item.key }}/config.json" + mode: "0660" + become: true + register: caso_config_jsons + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ caso_services }}" + notify: + - Restart caso container + +- name: Copying over caso config + merge_configs: + sources: + - "{{ role_path }}/templates/caso.conf.j2" + - "{{ node_custom_config }}//caso/caso.conf" + - "{{ node_custom_config }}/{{ item.key }}/{{ inventory_hostname }}/caso.conf" + dest: "{{ node_config_directory }}/{{ item.key }}/caso.conf" + mode: "0660" + become: true + register: caso_conf + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ caso_services }}" + notify: + - Restart caso container + +- name: Copying over caso crontab + template: + src: "{{ role_path }}/templates/caso.crontab.j2" + dest: "{{ node_config_directory }}/{{ item.key }}/caso.crontab" + mode: "0660" + become: true + register: caso_crontab + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ caso_services }}" + notify: + - Restart caso container + +- name: Copying over caso voms file + template: + src: "{{ role_path }}/templates/voms.json.j2" + dest: "{{ node_config_directory }}/{{ item.key }}/voms.json" + mode: "0660" + become: true + register: caso_vom_conf + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ caso_services }}" + notify: + - Restart caso container + +- name: Check caso containers + become: true + kolla_docker: + action: "compare_container" + common_options: "{{ docker_common_options }}" + name: "{{ item.value.container_name }}" + image: "{{ item.value.image }}" + volumes: "{{ item.value.volumes }}" + dimensions: "{{ item.value.dimensions }}" + register: check_caso_containers + when: + - kolla_action != "config" + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ caso_services }}" + notify: + - Restart caso container diff --git a/ansible/roles/caso/tasks/deploy.yml b/ansible/roles/caso/tasks/deploy.yml new file mode 100644 index 0000000000..27c275b7a4 --- /dev/null +++ b/ansible/roles/caso/tasks/deploy.yml @@ -0,0 +1,12 @@ +--- +- include_tasks: register.yml + when: inventory_hostname in groups['caso'] + +- include_tasks: config.yml + when: inventory_hostname in groups['caso'] + +- name: Flush handlers + meta: flush_handlers + +- include_tasks: check.yml + when: inventory_hostname in groups['caso'] diff --git a/ansible/roles/caso/tasks/main.yml b/ansible/roles/caso/tasks/main.yml new file mode 100644 index 0000000000..bc5d1e6257 --- /dev/null +++ b/ansible/roles/caso/tasks/main.yml @@ -0,0 +1,2 @@ +--- +- include_tasks: "{{ kolla_action }}.yml" diff --git a/ansible/roles/caso/tasks/precheck.yml b/ansible/roles/caso/tasks/precheck.yml new file mode 100644 index 0000000000..ed97d539c0 --- /dev/null +++ b/ansible/roles/caso/tasks/precheck.yml @@ -0,0 +1 @@ +--- diff --git a/ansible/roles/caso/tasks/pull.yml b/ansible/roles/caso/tasks/pull.yml new file mode 100644 index 0000000000..5b08cc879a --- /dev/null +++ b/ansible/roles/caso/tasks/pull.yml @@ -0,0 +1,11 @@ +--- +- name: Pulling caso images + become: true + kolla_docker: + action: "pull_image" + common_options: "{{ docker_common_options }}" + image: "{{ item.value.image }}" + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ caso_services }}" diff --git a/ansible/roles/caso/tasks/reconfigure.yml b/ansible/roles/caso/tasks/reconfigure.yml new file mode 100644 index 0000000000..f670a5b78d --- /dev/null +++ b/ansible/roles/caso/tasks/reconfigure.yml @@ -0,0 +1,2 @@ +--- +- include_tasks: deploy.yml diff --git a/ansible/roles/caso/tasks/register.yml b/ansible/roles/caso/tasks/register.yml new file mode 100644 index 0000000000..b0b2049be9 --- /dev/null +++ b/ansible/roles/caso/tasks/register.yml @@ -0,0 +1,14 @@ +--- +- name: Configure cASO user + kolla_toolbox: + module_name: "kolla_keystone_user" + module_args: + project: "{{ item }}" + user: "{{ caso_keystone_user }}" + password: "{{ caso_keystone_password }}" + region_name: "{{ openstack_region_name }}" + role: admin + auth: "{{ caso_openstack_auth }}" + endpoint_type: "{{ openstack_interface }}" + with_items: "{{ caso_projects }}" + run_once: True diff --git a/ansible/roles/caso/tasks/upgrade.yml b/ansible/roles/caso/tasks/upgrade.yml new file mode 100644 index 0000000000..375dcad19b --- /dev/null +++ b/ansible/roles/caso/tasks/upgrade.yml @@ -0,0 +1,5 @@ +--- +- include_tasks: config.yml + +- name: Flush handlers + meta: flush_handlers diff --git a/ansible/roles/caso/templates/caso.conf.j2 b/ansible/roles/caso/templates/caso.conf.j2 new file mode 100644 index 0000000000..81502116df --- /dev/null +++ b/ansible/roles/caso/templates/caso.conf.j2 @@ -0,0 +1,23 @@ +[DEFAULT] +messengers = {{ caso_messengers|join(', ') }} +site_name = {{ caso_site_name }} +projects = {{ caso_projects|join(', ') }} +debug = {{ caso_logging_debug }} +log_file = caso.log +log_dir = {{ caso_log_dir }} +log_rotation_type = none +spooldir = /var/lib/caso + +[keystone_auth] +auth_type = password +auth_url = {{ admin_protocol }}://{{ kolla_internal_fqdn }}:{{ keystone_admin_port }} +project_domain_id = {{ default_project_domain_id }} +username = {{ caso_keystone_user }} +user_domain_id = {{ default_user_domain_id }} +password = {{ caso_keystone_password }} + +[logstash] +port = {{ caso_tcp_output_port }} + +[ssm] +output_path = /var/spool/apel/outgoing/openstack diff --git a/ansible/roles/caso/templates/caso.crontab.j2 b/ansible/roles/caso/templates/caso.crontab.j2 new file mode 100644 index 0000000000..f406d808eb --- /dev/null +++ b/ansible/roles/caso/templates/caso.crontab.j2 @@ -0,0 +1 @@ +{{ caso_cron_table }} caso-extract --config-file /etc/caso/caso.conf diff --git a/ansible/roles/caso/templates/caso.json.j2 b/ansible/roles/caso/templates/caso.json.j2 new file mode 100644 index 0000000000..949c4ca022 --- /dev/null +++ b/ansible/roles/caso/templates/caso.json.j2 @@ -0,0 +1,41 @@ +{% set cron_cmd = 'cron -f' if kolla_base_distro in ['ubuntu', 'debian'] else 'crond -s -n' %} +{ + "command": "{{ cron_cmd }}", + "config_files": [ + { + "source": "{{ container_config_directory }}/caso.crontab", + "dest": "/var/spool/cron/caso", + "owner": "caso", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/caso.conf", + "dest": "/etc/caso/caso.conf", + "owner": "caso", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/voms.json", + "dest": "/etc/caso/voms.json", + "owner": "caso", + "perm": "0600" + } + ], + "permissions": [ + { + "path": "/var/log/kolla/caso", + "owner": "caso:caso", + "recurse": true + }, + { + "path": "/var/spool/apel/outgoing/openstack", + "owner": "caso:caso", + "recurse": true + }, + { + "path": "/var/lib/caso", + "owner": "caso:caso", + "recurse": true + } + ] +} diff --git a/ansible/roles/caso/templates/voms.json.j2 b/ansible/roles/caso/templates/voms.json.j2 new file mode 100644 index 0000000000..559eccb765 --- /dev/null +++ b/ansible/roles/caso/templates/voms.json.j2 @@ -0,0 +1,9 @@ +{ + "VO FQAN": { + "projects": ["local tenant 1", "local tenant 2"] + }, + "VO NAME": { + "projects": ["local tenant 3"] + } +} + diff --git a/ansible/roles/common/tasks/config.yml b/ansible/roles/common/tasks/config.yml index 6cf1c3d36b..544c503c17 100644 --- a/ansible/roles/common/tasks/config.yml +++ b/ansible/roles/common/tasks/config.yml @@ -111,6 +111,7 @@ # Inputs fluentd_input_files: "{{ default_input_files | customise_fluentd(customised_input_files) }}" default_input_files: + - "conf/input/99-caso.conf.j2" - "conf/input/00-global.conf.j2" - "conf/input/01-syslog.conf.j2" - "conf/input/02-mariadb.conf.j2" @@ -168,6 +169,7 @@ - { name: "barbican", enabled: "{{ enable_barbican | bool }}" } - { name: "blazar", enabled: "{{ enable_blazar | bool }}" } - { name: "ceilometer", enabled: "{{ enable_ceilometer | bool }}" } + - { name: "caso", enabled: "{{ enable_caso | bool }}" } - { name: "chrony", enabled: "{{ enable_chrony | bool }}" } - { name: "cinder", enabled: "{{ enable_cinder | bool }}" } - { name: "cloudkitty", enabled: "{{ enable_cloudkitty | bool }}" } diff --git a/ansible/roles/common/templates/conf/filter/00-record_transformer.conf.j2 b/ansible/roles/common/templates/conf/filter/00-record_transformer.conf.j2 index 238efee3de..3c06d38814 100644 --- a/ansible/roles/common/templates/conf/filter/00-record_transformer.conf.j2 +++ b/ansible/roles/common/templates/conf/filter/00-record_transformer.conf.j2 @@ -85,3 +85,12 @@ {% endif %} + +{% if enable_caso | bool and inventory_hostname in groups['caso'] %} + + @type parser + format json + key_name Payload + reserve_data true + +{% endif %} diff --git a/ansible/roles/common/templates/conf/input/99-caso.conf.j2 b/ansible/roles/common/templates/conf/input/99-caso.conf.j2 new file mode 100644 index 0000000000..5c577de410 --- /dev/null +++ b/ansible/roles/common/templates/conf/input/99-caso.conf.j2 @@ -0,0 +1,8 @@ + + @type tcp + tag apel.events + port {{ caso_tcp_output_port }} + bind 127.0.0.1 + format /^(?.*)$/ + emit_unmatched_lines true + diff --git a/ansible/roles/common/templates/conf/output/01-es.conf.j2 b/ansible/roles/common/templates/conf/output/01-es.conf.j2 index c586938668..1ea388bf2a 100644 --- a/ansible/roles/common/templates/conf/output/01-es.conf.j2 +++ b/ansible/roles/common/templates/conf/output/01-es.conf.j2 @@ -1,3 +1,19 @@ +{% if enable_caso | bool and inventory_hostname in groups['caso'] %} + + @type copy + + @type elasticsearch + host {% raw %}{{ elasticsearch_address }} +{% endraw %} + port {% raw %}{{ elasticsearch_port }} +{% endraw %} + logstash_format true + logstash_prefix apel + flush_interval 15s + + +{% endif %} + @type copy diff --git a/ansible/roles/common/templates/cron-logrotate-caso.conf.j2 b/ansible/roles/common/templates/cron-logrotate-caso.conf.j2 new file mode 100644 index 0000000000..2d4642e4b5 --- /dev/null +++ b/ansible/roles/common/templates/cron-logrotate-caso.conf.j2 @@ -0,0 +1,3 @@ +"/var/log/kolla/caso/*.log" +{ +} diff --git a/ansible/site.yml b/ansible/site.yml index 73a872fbb1..2a4df3d64f 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -1242,3 +1242,13 @@ - { role: masakari, tags: masakari, when: enable_masakari | bool } + +- name: Apply role caso + gather_facts: false + hosts: + - caso + serial: '{{ kolla_serial|default("0") }}' + roles: + - { role: caso, + tags: caso, + when: enable_caso | bool } diff --git a/etc/kolla/passwords.yml b/etc/kolla/passwords.yml index f4d4928c17..cf8dba5e8f 100644 --- a/etc/kolla/passwords.yml +++ b/etc/kolla/passwords.yml @@ -9,6 +9,11 @@ rbd_secret_uuid: cinder_rbd_secret_uuid: +############ +# cASO +############ +caso_keystone_password: + ################### # Database options ####################