Charm Interface - Neutron Plugin API Subordinate
Go to file
Hervé Beraud 33bcde1011 Use unittest.mock instead of mock
The mock third party library was needed for mock support in py2
runtimes. Since we now only support py36 and later, we can use the
standard lib unittest.mock module instead.

Note that https://github.com/openstack/charms.openstack is used during tests
and he need `mock`, unfortunatelly it doesn't declare `mock` in its
requirements so it retrieve mock from other charm project (cross dependency).
So we depend on charms.openstack first and when
Ib1ed5b598a52375e29e247db9ab4786df5b6d142 will be merged then CI
will pass without errors.

Depends-On: Ib1ed5b598a52375e29e247db9ab4786df5b6d142
Change-Id: I0550ad77a072d7edb083f24b260cbe034c8b9c75
2021-12-15 09:52:37 +00:00
unit_tests Use unittest.mock instead of mock 2021-12-15 09:52:37 +00:00
.gitignore Add unit tests 2019-09-24 16:21:54 +02:00
.gitreview OpenDev Migration Patch 2019-04-19 19:33:54 +00:00
.stestr.conf Add unit tests 2019-09-24 16:21:54 +02:00
.zuul.yaml [ussuri][goal] Updates for python 2.7 drop 2020-03-24 18:29:01 -05:00
copyright Generl tidy, docstrings, copyright, tox.ini etc 2016-09-12 15:02:22 +00:00
interface.yaml Add unit tests 2019-09-24 16:21:54 +02:00
provides.py Support database migrations 2019-09-30 08:21:45 +02:00
README.md Support database migrations 2019-09-30 08:21:45 +02:00
test-requirements.txt Use unittest.mock instead of mock 2021-12-15 09:52:37 +00:00
tox.ini Migrate unit tests from testr to stestr 2021-02-10 11:12:34 +00:00

Overview

This interface is used for a charm to send configuration information to the neutron-api principle charm, request a restart of a service managed by that charm, and request database migration to be performed.

Usage

Flags and States

The interface provides the {relation-name}.connected and {relation_name}.available flags and states.

The charm may set the {relation-name}.db_migration flag to instruct the interface code to gate the {relation_name}.available flag/state on completion of any in-flight database migration requests.

neutron_config_data

The neutron_config_data property allows the charm author to introspect a subset of the principle charm context values prior to applying the context provided by this relation.

This enables the subordinate charm to make informed decisions about how it should configure Neutron based on how the deployment is configured.

@reactive.when('neutron-plugin-api-subordinate.connected')
def configure_principle():
    api_principle = reactive.endpoint_from_flag(
        'neutron-plugin-api-subordinate.connected')
    if 'dns' in api_principle.neutron_config_data['extension_drivers']:
        ...

## configure\_plugin

The configure\_plugin method allows the following to be configured in the
principle charm:

* **neutron\_plugin**: Name of the plugin type eg 'ovs', 'ovn' etc. This is not
                       currently used in the principle but should be set to
                       something representitve of the plugin type.
* **core\_plugin**:    Value of core\_plugin to be set in neutron.conf
* **neutron\_plugin\_config**: File containing plugin config. This config file
                               is appended to the list of configs the neutron
                               services read on startup.
* **service\_plugins**: Value of service\_plugins to be set in neutron.conf
* **subordinate\_configuration**: Config to be inserted into a configuration
                                  file that the principle manages.
* **extension\_drivers**: Value of extension\_drivers to be set in
                          ml2\_conf.ini
* **neutron\_security\_groups**: Toggle whether the Neutron security group
                                 feature should be enabled or not.

Request `foo = bar` is inserted into the `DEFAULT` section of neutron.conf

```python
@reactive.when('neutron-plugin-api-subordinate.connected')
def configure_principle(api_principle):
    ...
    inject_config = {
        "neutron-api": {
            "/etc/neutron/neutron.conf": {
                "sections": {
                    'DEFAULT': [
                        ('foo', 'bar')
                    ],
                }
            }
        }
    }
    service_plugins = ','.join((
        api_principle.neutron_config_data.get('service_plugins', ''),
        'networking_ovn.l3.l3_ovn.OVNL3RouterPlugin'),
    )
    api_principle.configure_plugin(
        neutron_plugin='ovn',
        core_plugin='neutron.plugins.ml2.plugin.Ml2Plugin',
        neutron_plugin_config='/etc/neutron/plugins/ml2/ml2_conf.ini',
        service_plugins=service_plugins,
        subordinate_configuration=inject_config)

request_restart

Requesting a restart of all remote services:

@reactive.when('neutron-plugin-api-subordinate.connected')
def remote_restart(api_principle):
    ...
    api_principle.request_restart()

Requesting a restart of a specific type of remote services:

@reactive.when('neutron-plugin-api-subordinate.connected')
def remote_restart(api_principle):
    ...
    api_principle.request_restart(service_type='neutron')

request_db_migration

Request principle charm to perform a DB migration. This is useful both at initial deploy time and at subsequent changes as the lifecycle of the subordinate may be independent of the principle charm.

An example of how to request db migration upon initial deployment:

@reactive.when_none('neutron-plugin-api-subordinate.db_migration',
                    'neutron-plugin-api-subordinate.available')
@reactive.when('charm.installed')
def flag_db_migration():
    reactive.set_flag('neutron-plugin-api-subordinate.db_migration')


@reactive.when_none('neutron-plugin-api-subordinate.available',
                    'run-default-update-status')
@reactive.when('neutron-plugin-api-subordinate.connected')
def request_db_migration():
    neutron = reactive.endpoint_from_flag(
        'neutron-plugin-api-subordinate.connected')
    neutron.request_db_migration()

An example of usage in conjunction with post deployment change:

@reactive.when('config.changed')
def handle_change():
    ...
    if config_change_added_package_which_requires_db_migration:
        neutron = reactive.endpoint_from_flag(
            'neutron-plugin-api-subordinate.connected')
        neutron.request_db_migration()


@reactive.when('neutron-plugin-api-subordinate.available')
def do_something():
    ...
    # After requesting the DB migration above, you will not get here until it
    # is done.
    use_new_feature()

Metadata

To consume this interface in your charm or layer, add the following to layer.yaml:

includes: ['interface:neutron-plugin-api-subordinate']

and add a provides interface of type neutron-plugin-api-subordinate to your charm or layers metadata.yaml eg:

provides:
  neutron-plugin-api-subordinate:
    interface: neutron-plugin-api-subordinate
    scope: container

Bugs

Please report bugs on Launchpad.

For development questions please refer to the OpenStack Charm Guide.