Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions ansible/group_vars/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -953,13 +953,16 @@ cinder_backup_mount_options_nfs: ""
#######################
# Valid option is gnocchi
cloudkitty_collector_backend: "gnocchi"
# Valid options are 'sqlalchemy' or 'influxdb'. The default value is
# Valid options are 'sqlalchemy', 'elasticsearch' or 'influxdb'. The default value is
# 'influxdb', which matches the default in Cloudkitty since the Stein release.
# When the backend is "influxdb", we also enable Influxdb.
# Also, when using 'influxdb' as the backend, we trigger the configuration/use
# Also, when using 'influxdb' or 'elasticsearch' as the backend, we trigger the configuration/use
# of Cloudkitty storage backend version 2.
cloudkitty_storage_backend: "influxdb"

# Elasticsearch index alias name when cloudkitty_storage_backend is 'elasticsearch'.
cloudkitty_elasticsearch_alias_name: "cloudkitty"

#######################
# Designate options
#######################
Expand Down
17 changes: 15 additions & 2 deletions ansible/roles/cloudkitty/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,21 @@ cloudkitty_storage_backend: "influxdb"

cloudkitty_influxdb_name: "cloudkitty"

# Set the elasticsearch index name.
cloudkitty_elasticsearch_index_name: "cloudkitty"
# Set the elasticsearch index alias name.
cloudkitty_elasticsearch_alias_name: "cloudkitty"

# Set the elasticsearch index name, will be URI encoded. eg, <cloudkitty-{now/d}-000001>.
cloudkitty_elasticsearch_index_name: "<{{ cloudkitty_elasticsearch_alias_name }}-{now/d}-000001>"

# Set the name of the elasticsearch component template to be created.
cloudkitty_elasticsearch_component_template_name: "{{ cloudkitty_elasticsearch_alias_name }}_settings"

# Set the elasticsearch component templates to include in the cloudkitty provided template.
cloudkitty_elasticsearch_component_templates:
- "{{ cloudkitty_elasticsearch_component_template_name }}"

# Set the number of replicas for cloudkitty indices.
cloudkitty_elasticsearch_index_replicas: "{{ groups['elasticsearch'] | length -1 }}"

# Set the elasticsearch host URL.
cloudkitty_elasticsearch_url: "{{ internal_protocol }}://{{ elasticsearch_address }}:{{ elasticsearch_port }}"
Expand Down
80 changes: 71 additions & 9 deletions ansible/roles/cloudkitty/tasks/bootstrap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,34 +45,96 @@
delegate_to: "{{ groups['cloudkitty-api'][0] }}"
when: cloudkitty_storage_backend == 'influxdb'

- name: Checking if Cloudkitty elasticsearch index exists
- name: Creating Cloudkitty elasticsearch index settings component template
become: true
kolla_toolbox:
module_name: uri
module_args:
url: "{{ cloudkitty_elasticsearch_url }}/{{ cloudkitty_elasticsearch_index_name }}"
url: "{{ cloudkitty_elasticsearch_url }}/_component_template/{{ cloudkitty_elasticsearch_component_template_name }}"
method: PUT
status_code: 200
return_content: yes
body: "{{ lookup('template', item) | to_json }}"
body_format: json
run_once: True
delegate_to: "{{ groups['cloudkitty-api'][0] }}"
when: cloudkitty_storage_backend == 'elasticsearch'
with_first_found:
- "{{ node_custom_config }}/cloudkitty/cloudkitty_elasticsearch_component_template.json"
- "templates/cloudkitty_elasticsearch_component_template.json.j2"

- name: Checking if Cloudkitty elasticsearch index alias name exists
become: true
kolla_toolbox:
module_name: uri
module_args:
url: "{{ cloudkitty_elasticsearch_url }}/{{ cloudkitty_elasticsearch_alias_name }}"
status_code: 200, 404
run_once: true
delegate_to: "{{ groups['cloudkitty-api'][0] }}"
register: cloudkitty_index
when: cloudkitty_storage_backend == 'elasticsearch'

- name: Creating Cloudkitty elasticsearch index
- name: Checking if Cloudkitty elasticsearch index alias name is an alias
become: true
kolla_toolbox:
module_name: uri
module_args:
url: "{{ cloudkitty_elasticsearch_url }}/{{ cloudkitty_elasticsearch_index_name }}"
method: PUT
url: "{{ cloudkitty_elasticsearch_url }}/_alias/{{ cloudkitty_elasticsearch_alias_name }}"
method: HEAD
status_code: 200, 404
run_once: true
delegate_to: "{{ groups['cloudkitty-api'][0] }}"
register: cloudkitty_index_alias
when:
- cloudkitty_index is not skipped
- cloudkitty_index.get('status') == 200

- name: Reindexing old Cloudkitty index to new index name
become: true
kolla_toolbox:
module_name: uri
module_args:
url: "{{ cloudkitty_elasticsearch_url }}/_reindex"
method: POST
status_code: 200
body: "{{ lookup('template', 'cloudkitty_elasticsearch_reindex.json.j2') | to_json }}"
body_format: json
run_once: true
delegate_to: "{{ groups['cloudkitty-api'][0] }}"
register: cloudkitty_reindex
when:
- cloudkitty_index_alias is not skipped
- cloudkitty_index_alias.get('status') == 404

- name: Deleting old Cloudkitty index
become: true
kolla_toolbox:
module_name: uri
module_args:
url: "{{ cloudkitty_elasticsearch_url }}/{{ cloudkitty_elasticsearch_alias_name }}"
method: DELETE
status_code: 200
run_once: true
delegate_to: "{{ groups['cloudkitty-api'][0] }}"
register: cloudkitty_delete
when:
- cloudkitty_reindex is not skipped

- name: Adding alias to new Cloudkitty elasticsearch index
become: true
kolla_toolbox:
module_name: uri
module_args:
url: "{{ cloudkitty_elasticsearch_url }}/{{ cloudkitty_elasticsearch_index_name | urlencode | regex_replace('/','%2F') }}/_alias/{{ cloudkitty_elasticsearch_alias_name }}"
method: POST
status_code: 200
return_content: yes
body: |
{}
body: '{ "is_write_index": true }'
body_format: json
run_once: True
delegate_to: "{{ groups['cloudkitty-api'][0] }}"
when:
- cloudkitty_storage_backend == 'elasticsearch'
- cloudkitty_index.get('status') != 200
- cloudkitty_delete is not skipped

- import_tasks: bootstrap_service.yml
3 changes: 2 additions & 1 deletion ansible/roles/cloudkitty/templates/cloudkitty.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ cafile = {{ cloudkitty_influxdb_cafile }}
{% if cloudkitty_storage_backend == 'elasticsearch' %}
[storage_elasticsearch]
host = {{ cloudkitty_elasticsearch_url }}
index_name = {{ cloudkitty_elasticsearch_index_name }}
index_name = {{ cloudkitty_elasticsearch_alias_name }}
component_templates = {{ cloudkitty_elasticsearch_component_templates | join(',') }}
insecure = {{ cloudkitty_elasticsearch_insecure_connections }}

{% if cloudkitty_elasticsearch_cafile is defined %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"template": {
"settings": {
"index" : {
"number_of_replicas": {{ cloudkitty_elasticsearch_index_replicas }}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"source": {
"index": "{{ cloudkitty_elasticsearch_alias_name }}"
},
"dest": {
"index": "{{ cloudkitty_elasticsearch_index_name }}"
}
}
26 changes: 25 additions & 1 deletion ansible/roles/elasticsearch/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,15 @@ elasticsearch_curator_cron_schedule: "0 {{ elasticsearch_curator_instance_id }}
# useful way of checking that Curator actions are working as expected.
elasticsearch_curator_dry_run: false

# List of elasticsearch index names to be managed by Curator.
elasticsearch_curator_index_names:
- "{{ kibana_log_prefix }}"
- "{{ (enable_monasca | bool) | ternary('monasca', '') }}"
- "{{ (cloudkitty_storage_backend == 'elasticsearch') | ternary(cloudkitty_elasticsearch_alias_name, '') }}"

# Index prefix pattern. Any indices matching this regex will
# be managed by Curator.
elasticsearch_curator_index_pattern: "^{{ '(monasca|' + kibana_log_prefix + ')' if enable_monasca|bool else kibana_log_prefix }}-.*"
elasticsearch_curator_index_pattern: "^({{ elasticsearch_curator_index_names | reject('eq', '') | unique | join('|') }})-.*"

# Duration after which an index is staged for deletion. This is
# implemented by closing the index. Whilst in this state the index
Expand All @@ -75,6 +81,24 @@ elasticsearch_curator_soft_retention_period_days: 30
# Duration after which an index is permanently erased from the cluster.
elasticsearch_curator_hard_retention_period_days: 60

# Enable rollover of elasticsearch indices.
elasticsearch_curator_rollover: "{{ cloudkitty_storage_backend == 'elasticsearch' }}"

# Dict containing elasticsearch rollover options.
# For help with options see curator docs:
# https://www.elastic.co/guide/en/elasticsearch/client/curator/5.8/rollover.html
elasticsearch_curator_rollover_options:
- name: "{{ cloudkitty_elasticsearch_alias_name }}"
conditions:
max_age: "{{ elasticsearch_curator_rollover_default_max_age }}"
max_docs: "{{ elasticsearch_curator_rollover_default_max_docs }}"

# Elasticsearch index max age before rollover.
elasticsearch_curator_rollover_default_max_age: "1d"

# Elasticsearch index max number of docs before rollover.
elasticsearch_curator_rollover_default_max_docs: "100000"

####################
# Keystone
####################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,13 @@ actions:
timestring: '%Y.%m.%d'
unit: days
unit_count: "{{ elasticsearch_curator_hard_retention_period_days }}"
{% if elasticsearch_curator_rollover | bool %}
{% for index in elasticsearch_curator_rollover_options %}
{{ 2 + loop.index }}:
action: rollover
description: >-
Rollover index associated with {{ index.name }} alias
options:
{{ index | to_nice_yaml | indent(6, false) }}
{% endfor %}
{% endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
features:
- |
Improves support for elasticsearch as the cloudkitty storage backend.
Enforces using an elasticsearch index alias with cloudkitty.
Provides an elasticsearch index component template to manage replicas.
Adds elasicsearch curator config to prune cloudkitty indices.
upgrade:
- |
Enforces using an elasticsearch index alias with cloudkitty.
If elasticsearch is used as the cloudkitty storage backend this will
reindex the data into a dated index and delete the old copy. The old index
name is used as an alias for the dated indices.