EfficientMetering/APIProposalv1

= Ceilometer External API =

This page defines the External API that Ceilometer will offer for queries to other system such as billing or rating engine.

/!\ This page is a design spec. The effective implementation is described at http://ceilometer.readthedocs.org/en/latest/api.html

Design
The following criterias were us to define the API:


 * Database can only be queried via a REST API (i.e. the database schema is not a supported API and can change in a non backward compatible way from one version to the other).
 * Requests must be authenticated (separate from keystone, or only linked to accounting type account)
 * API Server must be able to be redundant
 * Requests allow to
 * Discover the sorts of things the server can provide:
 * list the components providing metering data
 * list the meters for a given component
 * list the known users
 * list the known projects
 * list the known sources
 * list the types of meters known
 * Fetch raw event data, without aggregation:
 * per user
 * per project
 * per source
 * per user and project
 * Produce aggregate views of the data:
 * sum "volume" field for meter type over a time period
 * per user
 * per project
 * per source
 * sum "duration" field for meter type over a period of time
 * per user
 * per project
 * per source

Note: here is a list of additional items. Some of these items may be better handled in the consumer of this API (the system that actually bills the user) Note: the aggregation of values is done by the API and is not stored in the database. It may be cached for performance reasons but the caching strategy is outside of the scope of this blueprint.
 * list discrete events that may not have a duration (instance creation, IP allocation, etc.)
 * list raw event data for a resource ("what happened with a specific instance?")
 * aggregate event data per meter type for a resource over a period of time ("what costs are related to this instance?")
 * sum volume for meter type over a time period for a specific resource ("how much total bandwidth was used by a VIF?")
 * sum duration for meter type over a time period for a specific resource ("how long did an instance run?")
 * metadata for resources (such as location of instances)
 * aggregating averages in addition to sums

Note: At the Folsom design session, the SET account_id call designed to change the status of the tenant in keystone was pointed more as a wart at this stage, since the billing system will need to talk to Keystone API anyway to make sense of the account id.

Limitations
Please note that the /VOLUME and /DURATION functions have some intrinsic limitation due to the nature of the collected data, as for a given Instance ID, a given meter may have to be interpreted as if the Instance ID was changing over time. The following example tries to explains this.

Example:
 * t1: Instance A - Has 1 CPU - 64G ram - runs in zone 1
 * t2: Instance A - Has 2 CPU - 64G ram - runs in zone 1
 * t3: Instance A - Has 2 CPU - 128G ram - runs in zone 1
 * t4: Instance A - Has 2 CPU - 128G ram - runs in zone 3
 * t5: Instance A is stopped

From a billing point of view, what is important here is that even though the Instance ID remains the same, we have in fact 4 different segments of time which could lead to 4 different pricing being applied to the same instance:


 * t1->t2: price 1
 * t2->t3: price 2
 * t3->t4: price 3
 * t4->t5: price 4

Full billing or rating engines need to be informed that these events have occurred so that it does not uniformly apply a billing price to from a sum of a given meter volume, so we advise them not to rely on /SUM or /DURATION calls, but rather fetch complete history to provide detailed billing.

/SUM or /DURATION calls are summaries that would be safe to use in simple scenarios such as:
 * In a simple amazon type billing model where instances cannot change zone, add CPU or add ram,
 * In a Private cloud scenario where you only need simple usage stats to inform your users,
 * in a horizon plugin to give a quick summary of use.

The intent of Ceilometer is to be a central point to collect information to be used by rating and billing engines, not to act as a rating engine. We can hope that our current API will be able to evolve to simplify rating engines requests over time, and we should be ready to accept extension of it to do so. However I do think we do not have the necessary experience with rating to propose a universal solution that will effectively work at this time, and therefore am proposing that we postpone that until we do have the experience.

REST API
Notes:
 * All results are provided JSON or XML format.
 * [] denotes optional information
 * date_time is assumed to use ISO format and to use UTC
 * [start_time and end_time] are optional date_times for most of the request. It has previously been agreed that the range is exclusive for start and inclusive for end.

{| border="1" cellpadding="2" cellspacing="0"
 * Verb
 * URL
 * Parameters
 * Expected result
 * GET
 * v1
 * Returns detailed information about this specific version of the API.
 * GET
 * v1/EXTENSIONS
 * Returns list of all available extensions
 * GET
 * v1/EXTENSIONS/
 * Gets details about a specific extension. Extensions enable the introduction of new features in the API without requiring a version change and they allow the introduction of vendor-specific functionality
 * GET
 * v1/SOURCES
 * [start_time and end_time]
 * Returns list of sources which are known
 * GET
 * v1/[SOURCES//]LIST
 * Returns list of information topic the server can provide
 * GET
 * v1/[SOURCES//]LIST/COMPONENTS
 * Returns list of components which provide metering data
 * GET
 * v1/[SOURCES//]LIST//METERS
 * Returns list of meters which are provided for a given component
 * GET
 * v1/[SOURCES//]LIST/METERS
 * Returns list of meters type which are known
 * GET
 * v1/[SOURCES//]LIST/RESOURCES
 * [start_time and end_time]
 * Returns list of resource_ID type which are known along with meta data info for the last occurrence of this ressource
 * GET
 * v1/[SOURCES//]USERS
 * [start_time and end_time]
 * Returns list of USERS_ID which are known
 * GET
 * v1/[SOURCES//]USERS/
 * [start_time and end_time]
 * Returns list of raw events for given user
 * GET
 * v1/[SOURCES//]USERS//
 * [start_time and end_time]
 * Returns list of raw events for given user and a given meter
 * GET
 * v1/[SOURCES//]USERS///VOLUME
 * [start_time and end_time]
 * Return sum of meter_volume for the given user and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]USERS/<USER_ID>/<METER>/DURATION
 * [start_time and end_time]
 * Return sum of meter_duration for the given use and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]USERS/<USER_ID>/RESOURCES
 * [start_time and end_time]
 * Returns list of resources for a given user along with meta data info for the last occurrence of this ressource
 * GET
 * v1/[SOURCES/<SOURCE>/]USERS/<USER_ID>/RESOURCES/<RESOURCE_ID>/
 * [start_time and end_time]
 * Returns list of events for given user and a given resource
 * GET
 * v1/[SOURCES/<SOURCE>/]USERS/<USER_ID>/RESOURCES/<RESOURCE_ID>/<METER>
 * [start_time and end_time]
 * Returns list of events for given user, resource and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]USERS/<USER_ID>/RESOURCES/<RESOURCE_ID>/<METER>/VOLUME
 * [start_time and end_time]
 * Return sum of meter_volume for the given user, resource and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]USERS/<USER_ID>/RESOURCES/<RESOURCE_ID>/<METER>/DURATION
 * [start_time and end_time]
 * Return sum of meter_duration for the given user, resource and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS
 * [start_time and end_time]
 * Returns list of PROJECT_ID which are known
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>
 * [start_time and end_time]
 * Returns list of raw events for given project
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/<METER>
 * [start_time and end_time]
 * Returns list of raw events for given project and a given meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/<METER>/VOLUME
 * [start_time and end_time]
 * Return sum of meter_volume for the given project and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/<METER>/DURATION
 * [start_time and end_time]
 * Return sum of meter_duration for the given project and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES
 * [start_time and end_time]
 * Returns list of resources for a given project along with meta data info for the last occurrence of this ressource
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES/<RESOURCE_ID>/
 * [start_time and end_time]
 * Returns list of events for given project and a given resource
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES/<RESOURCE_ID>/<METER>
 * [start_time and end_time]
 * Returns list of events for given project, resource and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES/<RESOURCE_ID>/<METER>/VOLUME
 * [start_time and end_time]
 * Return sum of meter_volume for the project, resource and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES/<RESOURCE_ID>/<METER>/DURATION
 * [start_time and end_time]
 * Return sum of meter_duration for the project, resource and meter
 * Returns list of raw events for given project and a given meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/<METER>/VOLUME
 * [start_time and end_time]
 * Return sum of meter_volume for the given project and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/<METER>/DURATION
 * [start_time and end_time]
 * Return sum of meter_duration for the given project and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES
 * [start_time and end_time]
 * Returns list of resources for a given project along with meta data info for the last occurrence of this ressource
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES/<RESOURCE_ID>/
 * [start_time and end_time]
 * Returns list of events for given project and a given resource
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES/<RESOURCE_ID>/<METER>
 * [start_time and end_time]
 * Returns list of events for given project, resource and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES/<RESOURCE_ID>/<METER>/VOLUME
 * [start_time and end_time]
 * Return sum of meter_volume for the project, resource and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES/<RESOURCE_ID>/<METER>/DURATION
 * [start_time and end_time]
 * Return sum of meter_duration for the project, resource and meter
 * [start_time and end_time]
 * Return sum of meter_volume for the project, resource and meter
 * GET
 * v1/[SOURCES/<SOURCE>/]PROJECTS/<PROJECT_ID>/RESOURCES/<RESOURCE_ID>/<METER>/DURATION
 * [start_time and end_time]
 * Return sum of meter_duration for the project, resource and meter
 * Return sum of meter_duration for the project, resource and meter