-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add os_ratings role for registering resources in Cloudkitty #30
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this going to be redundant once this gets pushed as the way to configure and run the CloudKitty playbook is with the role via
openstack-config
&openstack-config.yml
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally I like roles to provide an example in their readme. openstack-config is a separate project and you don't need to use it to use this collection or role. I don't think we even link to it from this collection.