From 6a087ad8c6c8fc38a2ae6ed70392ea4612bf8228 Mon Sep 17 00:00:00 2001 From: David Ames Date: Mon, 23 Apr 2018 13:12:01 -0700 Subject: [PATCH] Upgrade OpenStack Fix upgrade openstack Update README Update docstrings Clean up for final review --- .gitignore | 1 + .stestr.conf | 3 ++ src/HACKING.md | 5 +- src/README.md | 28 ++++++++++ src/lib/charm/openstack/dragent.py | 84 +++++++++++++++++++++--------- src/reactive/dragent_handlers.py | 25 ++++----- test-requirements.txt | 1 + tox.ini | 11 ++-- 8 files changed, 105 insertions(+), 53 deletions(-) create mode 100644 .stestr.conf diff --git a/.gitignore b/.gitignore index a0b2628..04d133b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ interfaces .testrepository *__pycache__* *.pyc +.stestr/ diff --git a/.stestr.conf b/.stestr.conf new file mode 100644 index 0000000..5fcccac --- /dev/null +++ b/.stestr.conf @@ -0,0 +1,3 @@ +[DEFAULT] +test_path=./unit_tests +top_dir=./ diff --git a/src/HACKING.md b/src/HACKING.md index 38bed01..dddf231 100644 --- a/src/HACKING.md +++ b/src/HACKING.md @@ -4,7 +4,4 @@ This charm is developed as part of the OpenStack Charms project, and as such you should refer to the [OpenStack Charm Development Guide](https://github.com/openstack/charm-guide) for details on how to contribute to this charm. -You can find its source code here: . - - - +You can find its source code here: . diff --git a/src/README.md b/src/README.md index 8b13789..3340915 100644 --- a/src/README.md +++ b/src/README.md @@ -1 +1,29 @@ +# Overview +This charm provides the BGP speaker, dynamic routing agent, feature for OpenStack + +# Charm Usage + +Neutron dynamic routing relies on services from the rabbitmq-server charm and assumes a functioning neutron stack: + + # The neutron-dynamic-routing charm only requires a relationship to rabbitmq-server + juju deploy neutron-dyanmic-routing + juju deploy rabbitmq-server + juju add-relation neutron-dyanmic-routing rabbitmq-server + + # For minimum functionality a full neutron stack is required: + juju deploy keystone + juju deploy neutron-api + juju deploy percona-cluster + juju add-relation keystone percona-cluster + juju add-relation keystone neutron-api + +# Feature Usage + +For utilizing the dynamic routing feature of OpenStack see upstream documentation for [neutron dynamic routing](https://docs.openstack.org/neutron-dynamic-routing/latest/). + +# Bugs + +Please report bugs on [Launchpad](https://bugs.launchpad.net/charm-neutron-dynamic-routing/+filebug). + +For general questions please refer to the OpenStack [Charm Guide](https://docs.openstack.org/charm-guide/latest/). diff --git a/src/lib/charm/openstack/dragent.py b/src/lib/charm/openstack/dragent.py index 8003c51..a762e26 100644 --- a/src/lib/charm/openstack/dragent.py +++ b/src/lib/charm/openstack/dragent.py @@ -44,37 +44,72 @@ charms_openstack.charm.use_defaults('charm.default-select-release') def render_configs(interfaces_list): """Using a list of interfaces, render the configs and, if they have changes, restart the services on the unit. + + :returns: None """ - # Starting out with just amqp + try: [i for i in interfaces_list] except TypeError: interfaces_list = [interfaces_list] + # TODO: Add bgp-speaker as an optional interface. + # Currently, charms.openstack does not understand endpoints and will need + # to be updated for this functionality. DRAgentCharm.singleton.render_with_interfaces(interfaces_list) def assess_status(): """Just call the DRAgentCharm.singleton.assess_status() command to update status on the unit. + + :returns: None """ + DRAgentCharm.singleton.assess_status() -def bgp_speaker_bindings(): - """Speaker bindings for bgp interface +def upgrade_if_available(interfaces_list): + """Just call the DRAgentCharm.singleton.upgrade_if_available() command to + update OpenStack package if upgrade is available - :return: list of bindings + @returns: None """ + + DRAgentCharm.singleton.upgrade_if_available(interfaces_list) + + +def bgp_speaker_bindings(): + """Return BGP speaker bindings for the bgp interface + + :returns: list of bindings + """ + return [SPEAKER_BINDING] @os_adapters.config_property def provider_ip(cls): + """Return the provider binding network IP + + Use the extra binding, provider, to determine the correct provider network + IP. + + :returns: string IP address + """ + return ch_ip.get_relation_ip(PROVIDER_BINDING) @os_adapters.config_property def speaker_ip(cls): + """Return the BGP speaker binding network IP + + Use the interface-bgp relation binding, to determine the correct bgp + network IP. + + :returns: string IP address + """ + return ch_ip.get_relation_ip(SPEAKER_BINDING) @@ -85,6 +120,10 @@ class TransportURLAdapter(os_adapters.RabbitMQRelationAdapter): @property def transport_url(self): + """Return the transport URL for communicating with rabbitmq + + :returns: string transport URL + """ hosts = self.hosts or [self.host] if hosts: transport_url_hosts = ','.join([ @@ -97,6 +136,10 @@ class TransportURLAdapter(os_adapters.RabbitMQRelationAdapter): @property def port(self): + """Return the port for commuicating with rabbitmq + + :returns: int port number + """ return self.ssl_port or 5672 @@ -109,9 +152,7 @@ class DRAgentCharm(charms_openstack.charm.OpenStackCharm): name = 'neutron-dynamic-routing' packages = PACKAGES default_service = 'neutron-bgp-dragent' - services = ['neutron-bgp-dragent'] - - # Note that the hsm interface is optional - defined in config.yaml + services = [default_service] required_relations = ['amqp'] adapters_class = os_adapters.OpenStackRelationAdapters @@ -137,28 +178,19 @@ class DRAgentCharm(charms_openstack.charm.OpenStackCharm): } def install(self): + """Configure openstack-origin and install packages + + :returns: None + """ + self.configure_source() super().install() - def get_amqp_credentials(self): - """Provide the default amqp username and vhost as a tuple. + def do_openstack_upgrade_db_migration(self, *args): + """Override the default do_openstack_upgrade_db_migration function. + DRAgentCharm has no database to migrate. - :returns (username, host): two strings to send to the amqp provider. + :returns: None """ - return (self.config['rabbit-user'], self.config['rabbit-vhost']) - def states_to_check(self, required_relations=None): - """Override the default states_to_check() for the assess_status - functionality so that, if we have to have an HSM relation, then enforce - it on the assess_status() call. - - If param required_relations is not None then it overrides the - instance/class variable self.required_relations. - - :param required_relations: [list of state names] - :returns: [states{} as per parent method] - """ - if required_relations is None: - required_relations = self.required_relations - return super(DRAgentCharm, self).states_to_check( - required_relations=required_relations) + pass diff --git a/src/reactive/dragent_handlers.py b/src/reactive/dragent_handlers.py index cfc78ab..aa9b02f 100644 --- a/src/reactive/dragent_handlers.py +++ b/src/reactive/dragent_handlers.py @@ -22,7 +22,7 @@ import charms_openstack.charm as charm # This charm's library contains all of the handler code associated with # dragent -- we need to import it to get the definitions for the charm. -import charm.openstack.dragent as dragent # noqa +import charm.openstack.dragent as dragent # Use the charms.openstack defaults for common states and hooks @@ -30,23 +30,18 @@ charm.use_defaults( 'charm.installed', 'amqp.connected', 'config.changed', - 'update-status') + 'update-status', + 'upgrade-charm') -@reactive.when('charm.installed') -def debug(): - if not hookenv.config('debug'): - return - for key, value in reactive.get_states().items(): - print(key, value) - - -# Use for testing with the quagga charm -@reactive.when('endpoint.bgp-speaker.joined') +@reactive.when('endpoint.bgp-speaker.changed') def publish_bgp_info(endpoint): + """Publish BGP information about this unit to interface-bgp peers + """ endpoint.publish_info(asn=hookenv.config('asn'), passive=True, bindings=dragent.bgp_speaker_bindings()) + dragent.assess_status() @reactive.when('amqp.connected') @@ -60,10 +55,10 @@ def setup_amqp_req(amqp): @reactive.when('amqp.available') -def render_stuff(*args): - """Render the configuration for dyanmic routing when all the interfaces are +def render_configs(*args): + """Render the configuration for dynamic routing when all the interfaces are available. """ - hookenv.log("about to call the render_configs with {}".format(args)) + dragent.upgrade_if_available(args) dragent.render_configs(args) dragent.assess_status() diff --git a/test-requirements.txt b/test-requirements.txt index 368dbf2..7875895 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -3,5 +3,6 @@ flake8 os-testr>=0.4.1 charms.reactive mock>=1.2 +nose>=1.3.7 coverage>=3.6 git+https://github.com/openstack/charms.openstack.git#egg=charms-openstack diff --git a/tox.ini b/tox.ini index 3ba2b23..d3a870d 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ # within individual charm repos. [tox] skipsdist = True -envlist = pep8,py34,py35 +envlist = pep8,py3 skip_missing_interpreters = True [testenv] @@ -32,13 +32,8 @@ basepython = python2.7 whitelist_externals = true commands = true -[testenv:py34] -basepython = python3.4 -deps = -r{toxinidir}/test-requirements.txt -commands = ostestr {posargs} - -[testenv:py35] -basepython = python3.5 +[testenv:py3] +basepython = python3 deps = -r{toxinidir}/test-requirements.txt commands = ostestr {posargs}