1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
=======================
PyScripts rating module
=======================
The PyScripts module allows you to create your own rating module.
A script is supposed to process the given data and to set the
different prices.
CAUTION: If you add several PyScripts, the order in which they will be executed
is not guaranteed.
Custom module example
=====================
Price definitions
-----------------
.. code-block:: python
import decimal
# Price for each flavor. These are equivalent to hashmap field mappings.
flavors = {
'm1.micro': decimal.Decimal(0.65),
'm1.nano': decimal.Decimal(0.35),
'm1.large': decimal.Decimal(2.67)
}
# Price per MB / GB for images and volumes. These are equivalent to
# hashmap service mappings.
image_mb_price = decimal.Decimal(0.002)
volume_gb_price = decimal.Decimal(0.35)
Price calculation functions
---------------------------
.. code-block:: python
# These functions return the price of a service usage on a collect period.
# The price is always equivalent to the price per unit multiplied by
# the quantity.
def get_instance_price(item):
if not item['metadata']['flavor_name'] in flavors:
return 0
else:
return (decimal.Decimal(item['vol']['qty'])
* flavors[item['metadata']['flavor_name']])
def get_image_price(item):
if not item['vol']['qty']:
return 0
else:
return decimal.Decimal(item['vol']['qty']) * image_mb_price
def get_volume_price(item):
if not item['vol']['qty']:
return 0
else:
return decimal.Decimal(item['vol']['qty']) * volume_gb_price
# Mapping each service to its price calculation function
services = {
'instance': get_instance_price,
'volume': get_volume_price,
'image': get_image_price
}
Processing the data
-------------------
.. code-block:: python
def process(data):
# The 'data' is a dictionary with the usage entries for each service
# in a given period.
usage_data = data['usage']
for service_name, service_data in usage_data.items():
# Do not calculate the price if the service has no
# price calculation function
if service_name in services.keys():
# A service can have several items. For example,
# each running instance is an item of the compute service
for item in service_data:
item['rating'] = {'price': services[service_name](item)}
return data
# 'data' is passed as a global variable. The script is supposed to set the
# 'rating' element of each item in each service
data = process(data)
Using your Script for rating
============================
Enabling the PyScripts module
-----------------------------
To use your script for rating, you will need to enable the pyscripts module
.. code-block:: console
$ cloudkitty module enable pyscripts
+-----------+---------+----------+
| Module | Enabled | Priority |
+-----------+---------+----------+
| pyscripts | True | 1 |
+-----------+---------+----------+
Adding the script to CloudKitty
-------------------------------
Create the script and specify its name, description, start and end dates.
If the ``start`` and ``end`` are not given, the ``start`` will be set as the
creation date and the ``end`` as ``None``. The script is valid from the
``start`` time until the ``end`` time, if the ``end`` time is ``None``, the
script is endless.
.. code-block:: console
$ cloudkitty pyscript create my_awesome_script script.py
+-------------------+--------------------------------------+---------------------+---------------------+------+-------------+---------+----------------------------------+------------+------------+------------------------------------------+---------------------------------------+
| Name | Script ID | Created At | Start | End | Description | Deleted | Created By | Updated By | Deleted By | Checksum | Data |
+-------------------+--------------------------------------+---------------------+---------------------+------+-------------+---------+----------------------------------+------------+------------+------------------------------------------+---------------------------------------+
| my_awesome_script | 78e1955a-4e7e-47e3-843c-524d8e6ad4c4 | 2023-01-01T10:00:00 | 2023-01-01T10:00:00 | None | None | None | 7977999e2e2511e6a8b2df30b233ffcb | None | None | 49e889018eb86b2035437ebb69093c0b6379f18c | from __future__ import print_function |
| | | | | | | | | | | | from cloudkitty import rating |
| | | | | | | | | | | | |
| | | | | | | | | | | | import decimal |
| | | | | | | | | | | | |
| | | | | | | | | | | | {...} |
| | | | | | | | | | | | |
| | | | | | | | | | | | data = process(data) |
| | | | | | | | | | | | |
+-------------------+--------------------------------------+---------------------+---------------------+------+-------------+---------+----------------------------------+------------+------------+------------------------------------------+---------------------------------------+
|