-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add os_ratings role for registering resources in Cloudkitty
- Loading branch information
1 parent
147f216
commit 0290447
Showing
7 changed files
with
309 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
OpenStack Cloudkitty Ratings | ||
============================ | ||
|
||
This role can be used to register ratings in OpenStack Cloudkitty. | ||
|
||
Requirements | ||
------------ | ||
|
||
The OpenStack Cloudkitty API should be accessible from the target host. | ||
|
||
Role Variables | ||
-------------- | ||
|
||
`os_ratings_venv` is a path to a directory in which to create a | ||
virtual environment. | ||
|
||
`os_ratings_upper_constraints_file` is a file or URL containing Python | ||
upper constraints. | ||
|
||
`os_ratings_environment` is a dict of environment variables for use with | ||
OpenStack CLI. Default is empty. | ||
|
||
`os_ratings_hashmap_field_mappings` is a list of mappings associated with a | ||
field. Each item is a dict with the following fields: | ||
* `service` | ||
* `name` | ||
* `mappings` | ||
The mappings field is a list, where each item is a dict with the following | ||
fields: | ||
* `value` | ||
* `cost` | ||
* `group` (optional) | ||
* `type` | ||
|
||
`os_ratings_hashmap_service_mappings` is a list of mappings not associated with | ||
a field. Each item is a dict with the following fields: | ||
* `service` | ||
* `cost` | ||
* `group` (optional) | ||
* `type` | ||
|
||
Dependencies | ||
------------ | ||
|
||
This role depends on the `stackhpc.openstack.os_openstackclient` role. | ||
|
||
Example Playbook | ||
---------------- | ||
|
||
The following playbook registers a Cloudkitty flavor field with two mappings | ||
for different Nova flavors. It also registers a service mapping based on the | ||
size of images stored in Glance. | ||
|
||
``` | ||
--- | ||
- name: Ensure Cloudkitty ratings are registered | ||
hosts: os-client | ||
tasks: | ||
- import_role: | ||
name: stackhpc.openstack.os_ratings | ||
vars: | ||
os_ratings_venv: "~/os-ratings-venv" | ||
os_ratings_environment: | ||
OS_AUTH_URL: "{{ lookup('env', 'OS_AUTH_URL') }}" | ||
... | ||
os_ratings_hashmap_field_mappings: | ||
- service: instance | ||
name: flavor_id | ||
mappings: | ||
- value: small | ||
cost: 1.0 | ||
group: instance_uptime_flavor_id | ||
type: flat | ||
- value: large | ||
cost: 2.0 | ||
group: instance_uptime_flavor_id | ||
type: flat | ||
os_ratings_hashmap_service_mappings: | ||
- service: image.size | ||
cost: 0.1 | ||
group: volume_ceph | ||
type: flat | ||
``` | ||
|
||
Author Information | ||
------------------ | ||
|
||
- Mark Goddard (<[email protected]>) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
--- | ||
# Path to a directory in which to create a virtualenv. | ||
os_ratings_venv: | ||
# Upper constraints file for installation of Python dependencies. | ||
os_ratings_upper_constraints_file: https://releases.openstack.org/constraints/upper/2023.1 | ||
|
||
# Environment variables for use with OpenStack CLI. | ||
os_ratings_environment: {} | ||
# Mappings associated with a field. | ||
# Each item is a dict with the following fields: | ||
# * service | ||
# * name | ||
# * mappings | ||
# The mappings field is a list, where each item is a dict with the following fields: | ||
# * value | ||
# * cost | ||
# * group (optional) | ||
# * type | ||
# For example, for per-instance rating: | ||
# - service: instance | ||
# name: flavor_id | ||
# mappings: | ||
# - value: small | ||
# cost: 1.0 | ||
# group: instance_uptime_flavor_id | ||
# type: flat | ||
# - value: large | ||
# cost: 2.0 | ||
# group: instance_uptime_flavor_id | ||
# type: flat | ||
os_ratings_hashmap_field_mappings: [] | ||
# Mappings not associated with a field. | ||
# Each item is a dict with the following fields: | ||
# * service | ||
# * cost | ||
# * group (optional) | ||
# * type | ||
# For example, for image image storage (MB) | ||
# - service: image.size | ||
# cost: 0.1 | ||
# group: volume_ceph | ||
# type: flat | ||
os_ratings_hashmap_service_mappings: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
dependencies: | ||
- role: stackhpc.openstack.os_openstackclient | ||
os_openstackclient_venv: "{{ os_ratings_venv }}" | ||
os_openstackclient_upper_constraints_file: "{{ os_ratings_upper_constraints_file | default(None) }}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--- | ||
# Task file for a single field and its mappings. | ||
|
||
- name: Create hashmap field | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap field create {{ service_id }} {{ field.name }} | ||
when: field.name not in fields | map(attribute='Name') | list | ||
changed_when: true | ||
|
||
# List again to get ID of created mapping. | ||
- name: List hashmap fields | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap field list -f json {{ service_id }} | ||
register: hashmap_field | ||
changed_when: false | ||
|
||
- name: List hashmap field mappings | ||
vars: | ||
field_id: "{{ (hashmap_field.stdout | from_json | selectattr('Name', 'equalto', field.name) | first)['Field ID'] }}" | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap mapping list -f json --field-id {{ field_id }} | ||
register: hashmap_mappings | ||
changed_when: false | ||
|
||
- name: Create hashmap field mappings | ||
vars: | ||
field_id: "{{ (hashmap_field.stdout | from_json | selectattr('Name', 'equalto', field.name) | first)['Field ID'] }}" | ||
group_id: >- | ||
{{ (hashmap_groups.stdout | from_json | selectattr('Name', 'equalto', item.group) | first)['Group ID'] | default('') if item.group is defined else '' }} | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap mapping create | ||
{{ item.cost }} | ||
--field-id {{ field_id }} | ||
--value {{ item.value }} | ||
{% if group_id | length > 0 %}--group-id {{ group_id }}{% endif %} | ||
--type {{ item.type }} | ||
loop: "{{ field.mappings }}" | ||
# Condition could be better, but should work with current values. | ||
when: item.value not in (hashmap_mappings.stdout | from_json | map(attribute='Value') | list) | ||
changed_when: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
- name: Ensure Cloudkitty client is installed # noqa package-latest | ||
ansible.builtin.pip: | ||
name: | ||
- python-cloudkittyclient | ||
state: latest | ||
extra_args: "{% if os_ratings_upper_constraints_file %}-c {{ os_ratings_upper_constraints_file }}{% endif %}" | ||
virtualenv: "{{ os_ratings_venv }}" | ||
run_once: true | ||
|
||
- name: Set a fact about the Ansible python interpreter | ||
ansible.builtin.set_fact: | ||
old_ansible_python_interpreter: "{{ ansible_python_interpreter | default('/usr/bin/python3') }}" | ||
|
||
- name: Import ratings.yml | ||
ansible.builtin.import_tasks: ratings.yml | ||
vars: | ||
ansible_python_interpreter: "{{ os_ratings_venv ~ '/bin/python' if os_ratings_venv != None else old_ansible_python_interpreter }}" | ||
openstack: "{{ os_ratings_venv ~ '/bin/' if os_ratings_venv else '' }}openstack" | ||
os_ratings_hashmap_field_mapping_services: "{{ os_ratings_hashmap_field_mappings | map(attribute='service') | list }}" | ||
os_ratings_hashmap_service_mapping_services: "{{ os_ratings_hashmap_service_mappings | map(attribute='service') | list }}" | ||
environment: "{{ os_ratings_environment }}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
--- | ||
- name: List modules | ||
ansible.builtin.command: > | ||
{{ openstack }} rating module list -f json | ||
register: modules | ||
changed_when: false | ||
|
||
- name: Enable hashmap module | ||
ansible.builtin.command: > | ||
{{ openstack }} rating module enable hashmap | ||
when: not (modules.stdout | from_json | selectattr('Module', 'equalto', 'hashmap') | first)['Enabled'] | bool | ||
changed_when: true | ||
|
||
- name: List hashmap services | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap service list -f json | ||
register: hashmap_services | ||
changed_when: false | ||
|
||
- name: Create hashmap services | ||
vars: | ||
existing_services: "{{ hashmap_services.stdout | from_json | map(attribute='Name') | list }}" | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap service create {{ item }} | ||
loop: "{{ (os_ratings_hashmap_field_mapping_services + os_ratings_hashmap_service_mapping_services) | unique | list }}" | ||
when: item not in existing_services | ||
changed_when: true | ||
|
||
- name: List hashmap groups | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap group list -f json | ||
register: hashmap_groups | ||
changed_when: false | ||
|
||
- name: Create hashmap groups | ||
vars: | ||
existing_groups: "{{ hashmap_groups.stdout | from_json | map(attribute='Name') | list }}" | ||
field_mapping_groups: "{{ query('subelements', os_ratings_hashmap_field_mappings, 'mappings') | map(attribute='1.group') | select('defined') | list }}" | ||
service_mapping_groups: "{{ os_ratings_hashmap_service_mappings | map(attribute='group') | select('defined') | list }}" | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap group create {{ item }} | ||
loop: "{{ (field_mapping_groups + service_mapping_groups) | unique | list }}" | ||
when: | ||
- item is not none and item | length > 0 | ||
- item not in existing_groups | ||
changed_when: true | ||
|
||
# List again to get IDs of created services. | ||
- name: List hashmap services | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap service list -f json | ||
register: hashmap_services | ||
changed_when: false | ||
|
||
# List again to get IDs of created groups. | ||
- name: List hashmap groups | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap group list -f json | ||
register: hashmap_groups | ||
changed_when: false | ||
|
||
- name: List hashmap fields | ||
vars: | ||
service_id: "{{ (hashmap_services.stdout | from_json | selectattr('Name', 'equalto', item) | first)['Service ID'] }}" | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap field list {{ service_id }} -f json | ||
loop: "{{ os_ratings_hashmap_field_mapping_services }}" | ||
register: hashmap_fields | ||
changed_when: false | ||
|
||
# Field mappings | ||
|
||
- name: Include field mappings | ||
ansible.builtin.include_tasks: field-mappings.yml | ||
vars: | ||
fields_result: "{{ hashmap_fields.results | selectattr('item', 'equalto', field.service) | first }}" | ||
fields: "{{ fields_result.stdout | from_json }}" | ||
service_id: "{{ (hashmap_services.stdout | from_json | selectattr('Name', 'equalto', field.service) | first)['Service ID'] }}" | ||
loop: "{{ os_ratings_hashmap_field_mappings }}" | ||
loop_control: | ||
loop_var: field | ||
|
||
# Service mappings | ||
|
||
- name: List hashmap service mappings | ||
vars: | ||
service_id: "{{ (hashmap_services.stdout | from_json | selectattr('Name', 'equalto', item) | first)['Service ID'] }}" | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap mapping list -f json --service-id {{ service_id }} | ||
loop: "{{ os_ratings_hashmap_service_mapping_services }}" | ||
register: hashmap_mappings | ||
changed_when: false | ||
|
||
- name: Create hashmap service mappings | ||
vars: | ||
mappings_result: "{{ hashmap_mappings.results | selectattr('item', 'equalto', item.service) | first }}" | ||
mappings: "{{ mappings_result.stdout | from_json }}" | ||
service_id: "{{ (hashmap_services.stdout | from_json | selectattr('Name', 'equalto', item.service) | first)['Service ID'] }}" | ||
group_id: "{{ (hashmap_groups.stdout | from_json | selectattr('Name', 'equalto', item.group) | first)['Group ID'] | default('') if item.group is defined else | ||
'' }}" | ||
ansible.builtin.command: > | ||
{{ openstack }} rating hashmap mapping create | ||
{{ item.cost }} | ||
--service-id {{ service_id }} | ||
{% if group_id | length > 0 %}--group-id {{ group_id }}{% endif %} | ||
--type {{ item.type }} | ||
loop: "{{ os_ratings_hashmap_service_mappings }}" | ||
# Condition could be better, but should work with current values. | ||
when: mappings | length == 0 | ||
changed_when: true |