almanach/doc/source/index.rst
Marc Aubry 51d6364b07 Add devstack plugin
Change-Id: I47be86218a744f3b7937380b7adbe5268c04abf0
2016-09-09 16:48:08 -04:00

263 lines
6.4 KiB
ReStructuredText

..
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
======================================
Welcome to the Almanach documentation!
======================================
Almanach stores the utilization of OpenStack resources (instances and volumes) for each tenant.
What is Almanach?
-----------------
The main purpose of this software is to bill customers based on their usage of the cloud infrastructure.
Almanach is composed of two parts:
- **Collector**: Listen for OpenStack events and store the relevant information in the database.
- **REST API**: Expose the information collected to external systems.
Requirements
------------
- OpenStack infrastructure installed (Nova, Cinder...)
- MongoDB
- Python 2.7
Command line usage
------------------
Usage:
.. code:: bash
usage: almanach [-h] [--logging LOGGING] {api,collector} config_file
Start the API daemon:
.. code:: bash
almanach api /path/to/almanach.cfg
Start the collector:
.. code:: bash
almanach collector /path/to/almanach.cfg
Custom logging configuration:
.. code:: bash
almanach collector /path/to/almanach.cfg --logging /path/to/logging.cfg
The syntax of the logging configuration file is available in the official [Python documentation](https://docs.python.org/2/library/logging.config.html).
Authentication
--------------
Protocol
~~~~~~~~
The authentication mechanism use the HTTP header :code:`X-Auth-Token` to send a token.
This token is validated through Keystone or with the config file (private secret key).
::
GET /volume_types HTTP/1.1
X-Auth-Token: secret
Content-Type: application/json
{}
If the token is not valid, you will receive a :code:`401 Not Authorized` response.
Private Key Authentication
~~~~~~~~~~~~~~~~~~~~~~~~~~
The private secret key authentication is the default method.
In your config file, you have to define your private key in the field :code:`auth_token`:
::
[ALMANACH]
auth_token=my secret token
Keystone Authentication
~~~~~~~~~~~~~~~~~~~~~~~
The token will be validated with Keystone.
To use this authentication backend you have to define the authentication strategy to :code:`keystone`.
::
[ALMANACH]
auth_strategy=keystone
[KEYSTONE]
username=my_service_username
password=my_service_password
tenant_name=my_service_tenant_name
auth_url=http://keystone_url:5000/v2.0
Environment variables
---------------------
You can override the configuration parameters by using environment variables:
.. code:: bash
export RABBITMQ_URL="amqp://openstack:openstack@hostname:5672"
almanach collector /path/to/almanach.cfg
Running Almanach with Docker
----------------------------
The actual Docker configuration assume that you already have RabbitMQ (mandatory for Openstack) and MongoDB configured for Almanach.
.. code:: bash
export RABBITMQ_URL="amqp://guest:guest@messaging:5672/"
export MONGODB_URL="mongodb://almanach:almanach@database:27017/almanach"
docker-compose build
docker-compose up
The command :code:`docker-compose up` starts 2 containers: the collector and the API server.
The environment variables :code:`RABBITMQ_URL` and :code:`MONGODB_URL` are mandatory.
RabbitMQ configuration
----------------------
Each OpenStack services (Nova, Cinder, Neutron) need to be configured to send notifications to the Almanach queue.
For example with Nova, add the topic "almanach" in the config file :code:`/etc/nova.conf`:
.. code:: bash
notification_topics=almanach
Database configuration
----------------------
Almanach requires a specific user to connect to the database.
To create a new user, open a new MongoDB shell:
.. code:: javascript
m = new Mongo()
m.getDB("almanach").createUser({user: "almanach", pwd: "almanach", roles: [{role: "readWrite", db: "almanach"}]})
Devstack configuration
----------------------
.. code:: bash
[[local|localrc]]
ADMIN_PASSWORD=secret
DATABASE_PASSWORD=$ADMIN_PASSWORD
RABBIT_PASSWORD=$ADMIN_PASSWORD
SERVICE_PASSWORD=$ADMIN_PASSWORD
enable_plugin almanach https://git.openstack.org/openstack/almanach
[[post-config|$NOVA_CONF]]
[DEFAULT]
notification_topics=almanach,notifications
[[post-config|$CINDER_CONF]]
[DEFAULT]
notification_topics=almanach,notifications
Database entities
-----------------
Each entity have at least these properties:
- :code:`entity_id`: Unique id for the entity (UUID)
- :code:`entity_type`: "instance" or "volume"
- :code:`project_id`: Tenant unique ID (UUID)
- :code:`start`: Start date of the resource usage
- :code:`end`: End date of the resource usage or :code:`null` if the resource still in use by the tenant
- :code:`name`: Resource name
Compute Object
~~~~~~~~~~~~~~
.. code:: json
{
"entity_id": "UUID",
"entity_type": "instance",
"project_id": "UUID",
"start": "2014-01-01T06:00:00.000Z",
"end": null,
"last_event": "2014-01-01T06:00:00.000Z",
"flavor": "MyFlavor1",
"os": {
"distro": "ubuntu",
"version": "14.04"
},
"name": "my-virtual-machine.domain.tld"
}
Block Storage Object
~~~~~~~~~~~~~~~~~~~~
.. code:: json
{
"entity_id": "UUID",
"entity_type": "volume",
"project_id": "UUID",
"start": "2014-01-01T06:00:00.000Z",
"end": null,
"last_event": "2014-01-01T06:00:00.000Z",
"volume_type": "MyVolumeType",
"size": 50,
"name": "my-virtual-machine.domain.tld-volume",
"attached_to": "UUID"
}
List of events handled
----------------------
Almanach will process those events:
- :code:`compute.instance.create.end`
- :code:`compute.instance.delete.end`
- :code:`compute.instance.resize.confirm.end`
- :code:`compute.instance.rebuild.end`
- :code:`volume.create.end`
- :code:`volume.delete.end`
- :code:`volume.resize.end`
- :code:`volume.attach.end`
- :code:`volume.detach.end`
- :code:`volume.update.end`
- :code:`volume.exists`
- :code:`volume_type.create`