QuantumUsage

Summary
Quantum administrators want data on system usage for billing, chargeback, or monitoring purposes.

Release Note
System usage data is emitted from Quantum in the form of usage events from Quantum's Notifications system. The notifications system can be configured to emit events either through Quantum's logging facility, or send them to a series of AMQP queues (one per notification priority). System usages are emitted as notification events with the INFO priority. Different types of usage events are distinguished via the notifications' event_type, which is a hierarchical dotted string such as ip_block.address.create, which allows usages to be easily grouped for aggregation. Usage notifications can be immediate, created when a specific increment of usage occurs (such as creation of an instance) or periodic, generated by a periodic task, like a cron job, and covering usage for a certain period of time. Besides the standard Quantum Notification priority, notification timestamp, and event_type, usage notifications contain a payload of data that will vary depending on the event_type. This is presented as a json-formatted hash of key-value pairs. Some of the keys, such as tenant_id will always be present in any usage notification, others will be data relevent to that event_type (For example, instance related notifications will contain data describing the instance.)

An external application (https://github.com/Cerberus98/yagi) is available that can read notifications from AMQP queues and provide an Atom API. This application generates Atom feeds of the notifications, and can publish feeds via PubSubHubbub (PSH) for efficient distribution of data to subscribers.

Rationale
As a systems integrator, we need the ability for 3rd party systems to query usage information from Quantum to determine how to charge customers for use of the platform.

Enterprise customers also need the ability to determine usage data, though for different reasons. For example, a cloud administrator may want to determine VMs that have not been used in several month so that they can be reclaimed and the resources reallocated. Some IT departments may implement a quota system for their users.

Note that Quantum itself should not be concerned with billing, but it needs to present a feed of usage data that an external application could use to aggregate the billing data for a requested time period.

User stories

 * 1) As a systems integrator, I need to retrieve usage data so that I can properly bill my customers.
 * 2) As a systems integrator or enterprise cloud administrator, I want to monitor usage data over time so that I can optimize the utilization of my resources.
 * 3) As an business or agency that supports multiple projects, I need to account for the resources consumed by each project so that I can properly meet accounting and budget standards.
 * 4) As a systems integrator, I need to provide usage data to multiple third-party systems without building custom interfaces to each one so that I can efficiently utilize my manpower.

Assumptions
Usage data can be aggregated by Tenant ID (as defined in the openstack-accounting blueprint).(i.e. Tenant ID is always present)

There is a billing system that is not a part of OpenStack. Invoicing, billing, and customer management are handled externally to OpenStack/Quantum. Quantum only has knowledge of an "tenant ID" (as per the openstack-accounting blueprint).

The Tenant ID is the same as the tenant id concept in Keystone, and is known internally to Quantum as the "Project ID".

If Quantum is installed in multiple regions (aka "zones"), usage data will not span zones; even if the same tenant ID is used in multiple zones, that data must be aggregated external to Quantum.

network.create:

 * Usage notification upon creation of a new network
 * tenant_id:  Tenant ID that owns the this instance (string)
 * network_id: Quantum network ID  (string)
 * created_at: Timestamp for when this network's record was created in Quantum (string, formatted  "YYYY-MM-DD hh:mm:ss.ssssss")

network.delete:

 * Usage notification upon deletion of a network
 * tenant_id:  Tenant ID that owns the this instance (string)
 * network_id: Quantum network ID  (string)
 * created_at: Timestamp for when this network's record was created in Quantum (string, formatted  "YYYY-MM-DD hh:mm:ss.ssssss")
 * deleted_at: Timestamp for when this network's record was deleted in Quantum (string, formatted  "YYYY-MM-DD hh:mm:ss.ssssss")

network.port.create:

 * Usage notification upon the creation of an port
 * tenant_id:  Tenant ID that owns the this instance (string)
 * network_id: Quantum network ID  (string)
 * port_id: Quantum port ID (string)
 * instance__id: ID of connected instance  (string)
 * created_at: Timestamp for when this port's record was created in Quantum (string, formatted  "YYYY-MM-DD hh:mm:ss.ssssss")

network.port.delete:

 * Usage notification when a port is deleted
 * tenant_id:  Tenant ID that owns the this instance (string)
 * network_id: Quantum network ID  (string)
 * port_id: Quantum port ID (string)
 * instance__id: ID of connected instance  (string)
 * created_at: Timestamp for when this port's record was created in Quantum (string, formatted  "YYYY-MM-DD hh:mm:ss.ssssss")
 * deleted_at: Timestamp for when this port's record was deleted in Quantum (string, formatted  "YYYY-MM-DD hh:mm:ss.ssssss")

network.port.exists:

 * Periodic usage notification generated by the network-usage-audit cron job. These usages are generated for each instance that has been neither created not deleted during the specified audit period. Aggregating these usages with the network.port.create and network.port.delete usages for the audit period will give a complete account of instance usage for each tenant during the audit period.
 * tenant_id:  Tenant ID that owns the this instance (string)
 * network_id: Quantum network ID (string)
 * port_id: Port ID (string)
 * instance__id: ID of assigned instance  (string)
 * created_at: Timestamp for when this port's record was created in Quantum (string, formatted  "YYYY-MM-DD hh:mm:ss.ssssss")
 * audit_period_begining: Timestamp of beginning of audit period. (string, formatted "YYYY-MM-DD  hh:mm:ss.ssssss")
 * audit_period_ending: Timestamp of end of audit period. (string, formatted "YYYY-MM-DD  hh:mm:ss.ssssss")