
Currently, CloudKitty only allows creating rating rules as "99.999999999999999999999999". Therefore, for prices equal to or higher than 100, we would not be able to use them. This patch will enable operators to use any value between 0 and 999999999999 (in the integer part of the number), which will provide more flexibility. Change-Id: I2ff4a09ce3b0fdf0b08a7e565b58794b25ac5ade Story: 2009947 Task: 44865
16 KiB
Hashmap rating module
CloudKitty is shipped with core rating modules.
Hashmap composition
HashMap is composed of different resources and groups.
Group
A group is a way to group calculations of mappings. For example you might want to apply a set of rules to rate instance uptime and another set to block storage volume. You don't want the two to be linked so you'll create one group for each calculation.
See mappings for information about how groups impact rating.
Service
A service is a way to map a rule to the type of data collected. One
hashmap service must be created for each metric type you want to rate.
If the metric has an alt_name
, the name of the hashmap
service must match the alt_name
. If no
alt_name
is provided, use the name of the metric.
Example with the default configuration:
metrics:
cpu:
unit: instance
alt_name: instance
# [...]
image.size:
unit: MiB
# [...]
In this case, cpu
has an alt_name and
image.size
hasn't. Thus, the hashmap service for the cpu
metric must be called instance
and the service for images
must be called image.size
.
Field
A field is referring to a metadata field of a resource. For example
on an instance object (in the instance
service), you can
use the flavor to define specific rules.
Each groupby
and metadata
attribute
specified in the configuration can be used for a field:
metrics:
cpu:
unit: instance
alt_name: instance
groupby:
- id
- project_id
metadata:
- flavor_id
# [...]
volume.size:
unit: GiB
groupby:
- id
- project_id
metadata:
- volume_type
# [...]
With the configuration above, the instance
service could
have the following fields:
- id
- project_id
- flavor_id
The volume.size
service could have the following
fields:
- id
- project_id
- volume_type
In this case, flavor_id
and volume_type
can
be used to apply a different pricing based on the flavor of an instance
or the type of a volume.
Mapping
A mapping is the final object, it's what triggers calculation, for example a specific value of flavor on an instance.
There are two kinds of mappings: field and service mappings.
Field mappings
A field mapping is used to match the attributes/metadata of a resource. For example, if you have three volume types on which you want to apply distinct rating rules, you must proceed in the following way:
- Create a hashmap service matching the name or
alt_name
of the volume metric (volume.size
with default gnocchi). - In that service, create a field with the name of the volume type
metadata (
volume_type
with default gnocchi). - In that field, create one mapping per possible value of the
volume_type
metadata. Example:SSD_gold
: 0.03SSD_silver
: 0.02HDD_bronze
: 0.01
Each element of the volume metric will now be based on its
volume_type
metadata. A 10GiB SSD_gold
volume
will be rated 0.3 per collect period, a 1GiB HDD_bronze
volume will be rated 0.01, a 0.5GiB SSD_silver
will be
0.01...
Service mappings
A service mapping is not associated with a field, but directly with a
service. If a mapping is created directly on the
volume.size
service, each volume will be rated based on
this mapping, with no metadata-based distinction.
Flat and Rate
A mapping can have two types: flat
or rate
.
A flat mapping is simply added to the total for a given item, whereas a
rate multiplies the total. See the examples below use cases.
Note
If several flat mappings of the same group match, only the most expensive one is applied.
Scope
It is possible to tie a mapping to a specific scope/tenant_id.
Threshold
A threshold entry is used to apply rating rules only after a specific level. Apart from that, it works the same way as a mapping.
As for mappings, a threshold can be tied to a specific scope/project.
Cost
The cost option is the actual cost for the rating period. It has a precision of 28 decimal digits (on the right side of the decimal point), and 12 digits on the left side of the decimal point (the integer part of the number).
Examples
Instance uptime
Apply rating rules to rate instances based on their flavor_id and uptime:
Create an instance_uptime_flavor_id
group:
$ cloudkitty hashmap group create instance_uptime_flavor_id
+---------------------------+--------------------------------------+
| Name | Group ID |
+---------------------------+--------------------------------------+
| instance_uptime_flavor_id | 9a2ff37d-be86-4642-8b7d-567bace61f06 |
+---------------------------+--------------------------------------+
$ cloudkitty hashmap group list
+---------------------------+--------------------------------------+
| Name | Group ID |
+---------------------------+--------------------------------------+
| instance_uptime_flavor_id | 9a2ff37d-be86-4642-8b7d-567bace61f06 |
+---------------------------+--------------------------------------+
Create the service matching rule:
$ cloudkitty hashmap service create instance
+----------+--------------------------------------+
| Name | Service ID |
+----------+--------------------------------------+
| instance | b19d801d-e7d4-46f9-970b-3e6d60fc07b5 |
+----------+--------------------------------------+
Create a field matching rule:
$ cloudkitty hashmap field create b19d801d-e7d4-46f9-970b-3e6d60fc07b5 flavor_id
+-----------+--------------------------------------+--------------------------------------+
| Name | Field ID | Service ID |
+-----------+--------------------------------------+--------------------------------------+
| flavor_id | 18aa50b6-6da8-4c47-8a1f-43236b971625 | b19d801d-e7d4-46f9-970b-3e6d60fc07b5 |
+-----------+--------------------------------------+--------------------------------------+
Create a mapping in the instance_uptime_flavor
group
that will map m1.tiny instance to a cost of 0.01:
$ openstack flavor show m1.tiny
+----------------------------+----------------------------------------+
| Field | Value |
+----------------------------+----------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| access_project_ids | None |
| disk | 20 |
| id | 93195dd4-bbf3-4b13-929d-8293ae72e056 |
| name | m1.tiny |
| os-flavor-access:is_public | True |
| properties | baremetal='false', flavor-type='small' |
| ram | 512 |
| rxtx_factor | 1.0 |
| swap | |
| vcpus | 1 |
+----------------------------+----------------------------------------+
$ cloudkitty hashmap mapping create 0.01 \
--field-id 18aa50b6-6da8-4c47-8a1f-43236b971625 \
--value 93195dd4-bbf3-4b13-929d-8293ae72e056 \
-g 9a2ff37d-be86-4642-8b7d-567bace61f06 \
-t flat
+--------------------------------------+--------------------------------------+------------+------+--------------------------------------+------------+--------------------------------------+------------+
| Mapping ID | Value | Cost | Type | Field ID | Service ID | Group ID | Project ID |
+--------------------------------------+--------------------------------------+------------+------+--------------------------------------+------------+--------------------------------------+------------+
| 9c2418dc-99d3-44b6-8fdf-e9fa02f3ceb5 | 93195dd4-bbf3-4b13-929d-8293ae72e056 | 0.01000000 | flat | 18aa50b6-6da8-4c47-8a1f-43236b971625 | None | 9a2ff37d-be86-4642-8b7d-567bace61f06 | None |
+--------------------------------------+--------------------------------------+------------+------+--------------------------------------+------------+--------------------------------------+------------+
In this example every machine in any project with the flavor m1.tiny will be rated 0.01 per collection period.
Volume per GiB with discount
Now let's do some threshold based rating.
Create a volume_thresholds
group:
$ cloudkitty hashmap group create volume_thresholds
+-------------------+--------------------------------------+
| Name | Group ID |
+-------------------+--------------------------------------+
| volume_thresholds | 9736bbc0-8888-4700-96fc-58db5fded493 |
+-------------------+--------------------------------------+
$ cloudkitty hashmap group list
+-------------------+--------------------------------------+
| Name | Group ID |
+-------------------+--------------------------------------+
| volume_thresholds | 9736bbc0-8888-4700-96fc-58db5fded493 |
+-------------------+--------------------------------------+
Create the service matching rule:
$ cloudkitty hashmap service create volume.size
+-------------+--------------------------------------+
| Name | Service ID |
+-------------+--------------------------------------+
| volume.size | 74ad7e4e-9cae-45a8-884b-368a92803afe |
+-------------+--------------------------------------+
Now let's setup the price per gigabyte:
$ cloudkitty hashmap mapping create 0.001 \
-s 74ad7e4e-9cae-45a8-884b-368a92803afe \
-t flat -g 9736bbc0-8888-4700-96fc-58db5fded493
+--------------------------------------+-------+------------+------+----------+--------------------------------------+--------------------------------------+------------+
| Mapping ID | Value | Cost | Type | Field ID | Service ID | Group ID | Project ID |
+--------------------------------------+-------+------------+------+----------+--------------------------------------+--------------------------------------+------------+
| 09e36b13-ce89-4bd0-bbf1-1b80577031e8 | None | 0.00100000 | flat | None | 74ad7e4e-9cae-45a8-884b-368a92803afe | 9736bbc0-8888-4700-96fc-58db5fded493 | None |
+--------------------------------------+-------+------------+------+----------+--------------------------------------+--------------------------------------+------------+
We have the basic price per gigabyte be we now want to apply a discount on huge data volumes. Create the thresholds in the group volume_thresholds that will map different volume quantities to costs:
Here we set a threshold when going past 50GiB, and apply a 2% discount (0.98):
$ cloudkitty hashmap threshold create 50 0.98 \
-s 74ad7e4e-9cae-45a8-884b-368a92803afe \
-t rate -g 9736bbc0-8888-4700-96fc-58db5fded493
+--------------------------------------+-------------+------------+------+----------+--------------------------------------+--------------------------------------+------------+
| Threshold ID | Level | Cost | Type | Field ID | Service ID | Group ID | Project ID |
+--------------------------------------+-------------+------------+------+----------+--------------------------------------+--------------------------------------+------------+
| ae02175d-beff-4b01-bb3a-00907b05fe66 | 50.00000000 | 0.98000000 | rate | None | 74ad7e4e-9cae-45a8-884b-368a92803afe | 9736bbc0-8888-4700-96fc-58db5fded493 | None |
+--------------------------------------+-------------+------------+------+----------+--------------------------------------+--------------------------------------+------------+
Here we set the same threshold for project 2d5b39657dc542d4b2a14b685335304e but with a 3% discount (0.97):
$ cloudkitty hashmap threshold create 50 0.97 \
-s 74ad7e4e-9cae-45a8-884b-368a92803afe \
-t rate -g 9736bbc0-8888-4700-96fc-58db5fded493 \
-p 2d5b39657dc542d4b2a14b685335304e
+--------------------------------------+-------------+------------+------+----------+--------------------------------------+--------------------------------------+----------------------------------+
| Threshold ID | Level | Cost | Type | Field ID | Service ID | Group ID | Project ID |
+--------------------------------------+-------------+------------+------+----------+--------------------------------------+--------------------------------------+----------------------------------+
| b20504bf-da34-434c-909d-46c2168c6166 | 50.00000000 | 0.97000000 | rate | None | 74ad7e4e-9cae-45a8-884b-368a92803afe | 9736bbc0-8888-4700-96fc-58db5fded493 | 2d5b39657dc542d4b2a14b685335304e |
+--------------------------------------+-------------+------------+------+----------+--------------------------------------+--------------------------------------+----------------------------------+
Here we set a threshold when going past 200GiB, and apply a 5% discount (0.95):
$ cloudkitty hashmap threshold create 200 0.95 \
-s 74ad7e4e-9cae-45a8-884b-368a92803afe \
-t rate -g 9736bbc0-8888-4700-96fc-58db5fded493
+--------------------------------------+--------------+------------+------+----------+--------------------------------------+--------------------------------------+------------+
| Threshold ID | Level | Cost | Type | Field ID | Service ID | Group ID | Project ID |
+--------------------------------------+--------------+------------+------+----------+--------------------------------------+--------------------------------------+------------+
| ed9fd297-37d4-4d9c-8f65-9919d554617b | 200.00000000 | 0.95000000 | rate | None | 74ad7e4e-9cae-45a8-884b-368a92803afe | 9736bbc0-8888-4700-96fc-58db5fded493 | None |
+--------------------------------------+--------------+------------+------+----------+--------------------------------------+--------------------------------------+------------+
In this example every volume is rated 0.001 per GiB but if the size goes past 50GiB you'll get a 2% discount, if you even go further you'll get 5% discount (only one level apply at a time).
For project 2d5b39657dc542d4b2a14b685335304e only, you'll get a 3% discount instead of 2% when the size goes past 50GiB and the same %5 discount it goes further.
- 20GiB
-
0.02 per collection period.
- 50GiB
-
0.049 per collection period (0.0485 for project 2d5b39657dc542d4b2a14b685335304e).
- 80GiB
-
0.0784 per collection period (0.0776 for project 2d5b39657dc542d4b2a14b685335304e).
- 250GiB
-
0.2375 per collection period.