solar/doc/source/examples.rst
venkatamahesh 08d463d220 Fix misspellings
Change-Id: I7f250d89efb204dc3e232e1e10c0382deb04eec8
2016-02-04 09:21:04 +05:30

138 lines
5.7 KiB
ReStructuredText

.. _examples:
Examples
========
Create resource for the puppet handler
--------------------------------------
Let's create an example :ref:`resource-term` for the puppet
:ref:`res-handler-term` version 1 [#]_. The resource should install and
configure OpenStack Nova API service.
.. [#] There is also puppet handler version 2 but it is out of the scope
of this example.
Step 1: Find an appropriate puppet module
+++++++++++++++++++++++++++++++++++++++++
The `Puppet OpenStack <https://wiki.openstack.org/wiki/Puppet>`_
module for `Nova <https://github.com/openstack/puppet-nova>`_
provides all of the required functionality.
Step 2: Define granularity level for a resource
+++++++++++++++++++++++++++++++++++++++++++++++
One may want to implement resources as atomic entities doing their only single
task, like running one and only puppet manifest [#]_. Other option might be
single entity doing all required tasks instead. In order to configure and run
the Nova API service at least two manifests should be executed:
`init.pp <https://github.com/openstack/puppet-nova/blob/master/manifests/init.pp>`_
and
`api.pp <https://github.com/openstack/puppet-nova/blob/master/manifests/api.pp>`_ [#]_.
.. [#] Puppet manifests may contain references to externally defined classess
or services in the catalog. Keep that in mind then designing the resource.
.. [#] This assumes configuring DB and messaging entities like user, password
database, vhost, access rights are left out of the scope of this example.
Assuming the atomic tasks approach, the example resource for Nova API service
should only use the `api.pp` manifest. Note that the puppet handler is normally
executed in its own isolated puppet catalog with its specific hiera data only.
This assumes every puppet manifest called by every action to be executed as a
separate puppet run and shares nothing with other tasks.
Step 3: Define resource inputs
++++++++++++++++++++++++++++++
Once the granularity level of the resource is clearly defined, one should
define the resource's :ref:`res-input-term` data. The puppet class `nova::api`
contains lots of parameters. It looks reasonable to use them as the resource
inputs as is.
.. note ::
There is a `helper script <https://github.com/bogdando/convert_puppet_parameters>`_
to convert a puppet class parameters into the format expected by the
`meta.yaml` inputs file.
Step 4: Implement basic action run
++++++++++++++++++++++++++++++++++++++
Each resource should have all of the mandatory actions defined. In this example
we define only the :ref:`ref-action-term` `run`. With the example of Nova API
resource, the action run should:
- fetch the resource inputs from the hiera [#]_ ::
$resource = hiera($::resource_name)
$ensure_package = $resource['input']['ensure_package']
$auth_strategy = $resource['input']['auth_strategy']
.. [#] The syntax is the puppet handler v1 specific. The v2 allows to query
the hiera directly, like `$public_vip = hiera('public_vip')`
- call the `class { 'nova::api': }` with the required parameters
- implement workarounds for externally referenced entities, like ::
exec { 'post-nova_config':
command => '/bin/echo "Nova config has changed"',
}
include nova::params
package { 'nova-common':
name => $nova::params::common_package_name,
ensure => $ensure_package,
}
.. note ::
Otherwise, called class would assume the package and exec are
already included in the catalog by the `init.pp`. And would fail as
there is no `class { 'nova': }` call expected for the Nova API resource
action run.
In order to implement the resource without such workarounds, one should
rethink the granularity scope for the resource. And make sure the resource
contains required inputs for the main `nova` and `nova::api` classes and
call them both in the resource action run.
Step 5: Think of the rest of the resource actions
+++++++++++++++++++++++++++++++++++++++++++++++++
One should also design other actions for the resource. Mandatory are only
`run`, `update` and `remove`. There might be additional ones like `on-fail`,
`on-retry` or whichever are actually required to implement expected behavior.
For the given API resource there are no specific actions expected and there
is nothing to do for the action remove. For the action update, it is likely
the same steps should be done as for the action run.
Step 6: Design the high level functional test
+++++++++++++++++++++++++++++++++++++++++++++
TODO(bogdando) provide details about test.py and writing tests for Nova API
in order to verify if it works on the app level.
Step 7: Think of the deployment composition
+++++++++++++++++++++++++++++++++++++++++++
The deployment composition is which resources should be used and in which order
it should be executed to achieve the expected result, which is a successful
:ref:`deploy-plan-term`. For the given example, the composition may be as
following:
- Install and configure MySQL DB [#]_
- Install and configure RabbitMQ node
- Install and configure dependency components like OpenStack Keystone
- Create all of the required user/tenant/db/vhost entities and assign rights
- Install and configure Nova main components, like packages, db sync, configs.
- Install and configure Nova API. BINGO! A job for our resource, at last!
.. [#] Omitted host related steps like OS provisioning, disks and network
configuration.
Besides the execution plan, there is also data :ref:`res-connection-term`
to be considered. For example, one might want to have all of the OpenStack
services to use the common RabbitMQ virtualhost and user. Or have them
separated instead. Or use the clustered RabbitMQ nodes. These decisions
will directly impact how resources' inputs should be connected.