Storage backend (v2)

Storage backend (v2)

Warning

This backend is considered unstable and should be used for upstream development only.

In order to implement a storage backend for cloudkitty, you’ll have to implement the following abstract class:

class cloudkitty.storage.v2.BaseStorage(*args, **kwargs)[source]

Abstract class for v2 storage objects.

static get_retention()[source]

Returns the retention period defined in the configuration.

Return type:datetime.timedelta
init()[source]

Called for storage backend initialization

push(dataframes, scope_id)[source]

Pushes dataframes to the storage backend

A dataframe has the following format:

{
    "usage": {
        "bananas": [ # metric name
            {
                "vol": {
                    "unit": "banana",
                    "qty": 1
                },
                "rating": {
                    "price": 1
                },
                "groupby": {
                    "xxx_id": "hello",
                    "yyy_id": "bye",
                },
                "metadata": {
                    "flavor": "chocolate",
                    "eaten_by": "gorilla",
                },
           }
        ],
        "metric_name2": [...],
    }
   "period": {
        "begin": "1239781290", # timestamp
        "end": "1239793490", # timestamp
    }
}
Parameters:
  • dataframes (list) – List of dataframes
  • scope_id (str) – ID of the scope (A project ID for example).
retrieve(begin=None, end=None, filters=None, group_filters=None, metric_types=None, offset=0, limit=1000, paginate=True)[source]

Returns the following dict:

{
   'total': int, # total amount of measures found
   'dataframes': list of dataframes,
}
Parameters:
  • begin (datetime) – Start date
  • end (datetime) – End date
  • filters (dict) – Metadata to filter on. ex: {‘flavor_id’: ‘42’}
  • group_filters (dict) – Groupby to filter on. ex: {‘project_id’: ‘123ab’}
  • metric_types (str or list) – Metric type to filter on.
  • offset (int) – Offset for pagination
  • limit (int) – Maximum amount of elements to return
  • paginate – Defaults to True. If False, all found results will be returned.
Return type:

dict

total(groupby=None, begin=None, end=None, metric_types=None, filters=None, group_filters=None)[source]

Returns a grouped total for given groupby.

Parameters:
  • groupby (list of strings) – Attributes on which to group by. These attributes must be part of the ‘groupby’ section for the given metric type in metrics.yml. In order to group by metric type, add ‘type’ to the groupby list.
  • begin (datetime) – Start date
  • end (datetime) – End date
  • filters (dict) – Metadata to filter on. ex: {‘flavor_id’: ‘42’}
  • group_filters (dict) – Groupby to filter on. ex: {‘project_id’: ‘123ab’}
  • metric_types (str or list) – Metric type to filter on.
Return type:

list of dicts

returns a list of dicts with the following format:

{
    'begin': XXX,
    'end': XXX,
    'type': XXX,
    'rate': XXX,
    'groupby1': XXX,
    'groupby2': XXX
}

You’ll then need to register an entrypoint corresponding to your storage backend in the cloudkitty.storage.v2.backends section of the setup.cfg file.

Testing

There is a generic test class for v2 storage backends. It allows to run a functional test suite against a new v2 storage backend.

$ tree cloudkitty/tests/storage/v2
cloudkitty/tests/storage/v2
├── base_functional.py
├── __init__.py
└── test_gnocchi_functional.py

In order to use the class, add a file called test_mybackend_functional.py to the cloudkitty/tests/storage/v2 directory. You will then need to write a class inheriting from BaseFunctionalStorageTest. Specify the storage version and the backend name as class attributes

Example:

import testtools

from cloudkitty.tests.storage.v2 import base_functional
from cloudkitty.tests.utils import is_functional_test


@testtools.skipUnless(is_functional_test(), 'Test is not a functional test')
class GnocchiBaseFunctionalStorageTest(
        base_functional.BaseFunctionalStorageTest):

    storage_backend = 'gnocchi'
    storage_version = 2

Two methods need to be implemented:

  • wait_for_backend. This method is called once data has been once dataframes have been pushed to the storage backend (in gnocchi’s case, it waits for all measures to have been processed). It is a classmethod.
  • cleanup_backend: This method is called at the end of the test suite in order to delete all data from the storage backend. It is a classmethod.
Creative Commons Attribution 3.0 License

Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.