#!/usr/bin/env python3
#
# Copyright 2016 Canonical Ltd
#
# 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.

import sys

from copy import deepcopy

from charmhelpers.contrib.openstack.utils import (
    pausable_restart_on_change as restart_on_change,
)

from charmhelpers.core.hookenv import (
    Hooks,
    UnregisteredHookError,
    config,
    log,
    relation_set,
    relation_ids,
)

from neutron_ovs_utils import (
    DHCP_PACKAGES,
    DVR_PACKAGES,
    METADATA_PACKAGES,
    OVS_DEFAULT,
    configure_ovs,
    configure_sriov,
    configure_ipfix,
    get_shared_secret,
    register_configs,
    restart_map,
    use_dvr,
    enable_nova_metadata,
    enable_local_dhcp,
    install_packages,
    purge_packages,
    assess_status,
)

hooks = Hooks()
CONFIGS = register_configs()


@hooks.hook()
def install():
    install_packages()


# NOTE(wolsen): Do NOT add restart_on_change decorator without consideration
# for the implications of modifications to the /etc/default/openvswitch-switch.
@hooks.hook('upgrade-charm')
def upgrade_charm():
    # In the 16.10 release of the charms, the code changed from managing the
    # /etc/default/openvswitch-switch file only when dpdk was enabled to always
    # managing this file. Thus, an upgrade of the charm from a release prior
    # to 16.10 or higher will always cause the contents of the file to change
    # and will trigger a restart of the openvswitch-switch service, which in
    # turn causes a temporary network outage. To prevent this outage, determine
    # if the /etc/default/openvswitch-switch file needs to be migrated and if
    # so, migrate the file but do NOT restart the openvswitch-switch service.
    # See bug LP #1712444
    with open(OVS_DEFAULT, 'r') as f:
        # The 'Service restart triggered ...' line was added to the OVS_DEFAULT
        # template in the 16.10 version of the charm to allow restarts so we
        # use this as the key to see if the file needs migrating.
        if 'Service restart triggered' not in f.read():
            CONFIGS.write(OVS_DEFAULT)


@hooks.hook('neutron-plugin-relation-changed')
@hooks.hook('config-changed')
@restart_on_change(restart_map())
def config_changed():
    install_packages()

    configure_ovs()
    CONFIGS.write_all()
    # NOTE(fnordahl): configure_sriov must be run after CONFIGS.write_all()
    # to allow us to enable boot time execution of init script
    configure_ipfix()
    configure_sriov()
    for rid in relation_ids('neutron-plugin'):
        neutron_plugin_joined(relation_id=rid)


@hooks.hook('neutron-plugin-api-relation-changed')
@restart_on_change(restart_map())
def neutron_plugin_api_changed():
    if use_dvr():
        install_packages()
    else:
        purge_packages(DVR_PACKAGES)
    configure_ovs()
    CONFIGS.write_all()
    # If dvr setting has changed, need to pass that on
    for rid in relation_ids('neutron-plugin'):
        neutron_plugin_joined(relation_id=rid)


@hooks.hook('neutron-plugin-relation-joined')
def neutron_plugin_joined(relation_id=None):
    if enable_local_dhcp():
        install_packages()
    else:
        pkgs = deepcopy(DHCP_PACKAGES)
        # NOTE: only purge metadata packages if dvr is not
        #       in use as this will remove the l3 agent
        #       see https://pad.lv/1515008
        if not use_dvr():
            pkgs.extend(METADATA_PACKAGES)
        purge_packages(pkgs)
    secret = get_shared_secret() if enable_nova_metadata() else None
    rel_data = {
        'metadata-shared-secret': secret,
    }
    relation_set(relation_id=relation_id, **rel_data)


@hooks.hook('amqp-relation-joined')
def amqp_joined(relation_id=None):
    relation_set(relation_id=relation_id,
                 username=config('rabbit-user'),
                 vhost=config('rabbit-vhost'))


@hooks.hook('amqp-relation-changed')
@hooks.hook('amqp-relation-departed')
@restart_on_change(restart_map())
def amqp_changed():
    if 'amqp' not in CONFIGS.complete_contexts():
        log('amqp relation incomplete. Peer not ready?')
        return
    CONFIGS.write_all()


@hooks.hook('neutron-control-relation-changed')
@restart_on_change(restart_map(), stopstart=True)
def restart_check():
    CONFIGS.write_all()


def main():
    try:
        hooks.execute(sys.argv)
    except UnregisteredHookError as e:
        log('Unknown hook {} - skipping.'.format(e))
    assess_status(CONFIGS)


if __name__ == '__main__':
    main()

#!/usr/bin/env python3
#
# Copyright 2016 Canonical Ltd
#
# 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.

import sys

from copy import deepcopy

from charmhelpers.contrib.openstack.utils import (
    pausable_restart_on_change as restart_on_change,
)

from charmhelpers.core.hookenv import (
    Hooks,
    UnregisteredHookError,
    config,
    log,
    relation_set,
    relation_ids,
)

from neutron_ovs_utils import (
    DHCP_PACKAGES,
    DVR_PACKAGES,
    METADATA_PACKAGES,
    OVS_DEFAULT,
    configure_ovs,
    configure_sriov,
    configure_ipfix,
    get_shared_secret,
    register_configs,
    restart_map,
    use_dvr,
    enable_nova_metadata,
    enable_local_dhcp,
    install_packages,
    purge_packages,
    assess_status,
)

hooks = Hooks()
CONFIGS = register_configs()


@hooks.hook()
def install():
    install_packages()


# NOTE(wolsen): Do NOT add restart_on_change decorator without consideration
# for the implications of modifications to the /etc/default/openvswitch-switch.
@hooks.hook('upgrade-charm')
def upgrade_charm():
    # In the 16.10 release of the charms, the code changed from managing the
    # /etc/default/openvswitch-switch file only when dpdk was enabled to always
    # managing this file. Thus, an upgrade of the charm from a release prior
    # to 16.10 or higher will always cause the contents of the file to change
    # and will trigger a restart of the openvswitch-switch service, which in
    # turn causes a temporary network outage. To prevent this outage, determine
    # if the /etc/default/openvswitch-switch file needs to be migrated and if
    # so, migrate the file but do NOT restart the openvswitch-switch service.
    # See bug LP #1712444
    with open(OVS_DEFAULT, 'r') as f:
        # The 'Service restart triggered ...' line was added to the OVS_DEFAULT
        # template in the 16.10 version of the charm to allow restarts so we
        # use this as the key to see if the file needs migrating.
        if 'Service restart triggered' not in f.read():
            CONFIGS.write(OVS_DEFAULT)


@hooks.hook('neutron-plugin-relation-changed')
@hooks.hook('config-changed')
@restart_on_change(restart_map())
def config_changed():
    install_packages()

    configure_ovs()
    CONFIGS.write_all()
    # NOTE(fnordahl): configure_sriov must be run after CONFIGS.write_all()
    # to allow us to enable boot time execution of init script
    configure_ipfix()
    configure_sriov()
    for rid in relation_ids('neutron-plugin'):
        neutron_plugin_joined(relation_id=rid)


@hooks.hook('neutron-plugin-api-relation-changed')
@restart_on_change(restart_map())
def neutron_plugin_api_changed():
    if use_dvr():
        install_packages()
    else:
        purge_packages(DVR_PACKAGES)
    configure_ovs()
    CONFIGS.write_all()
    # If dvr setting has changed, need to pass that on
    for rid in relation_ids('neutron-plugin'):
        neutron_plugin_joined(relation_id=rid)


@hooks.hook('neutron-plugin-relation-joined')
def neutron_plugin_joined(relation_id=None):
    if enable_local_dhcp():
        install_packages()
    else:
        pkgs = deepcopy(DHCP_PACKAGES)
        # NOTE: only purge metadata packages if dvr is not
        #       in use as this will remove the l3 agent
        #       see https://pad.lv/1515008
        if not use_dvr():
            pkgs.extend(METADATA_PACKAGES)
        purge_packages(pkgs)
    secret = get_shared_secret() if enable_nova_metadata() else None
    rel_data = {
        'metadata-shared-secret': secret,
    }
    relation_set(relation_id=relation_id, **rel_data)


@hooks.hook('amqp-relation-joined')
def amqp_joined(relation_id=None):
    relation_set(relation_id=relation_id,
                 username=config('rabbit-user'),
                 vhost=config('rabbit-vhost'))


@hooks.hook('amqp-relation-changed')
@hooks.hook('amqp-relation-departed')
@restart_on_change(restart_map())
def amqp_changed():
    if 'amqp' not in CONFIGS.complete_contexts():
        log('amqp relation incomplete. Peer not ready?')
        return
    CONFIGS.write_all()


@hooks.hook('neutron-control-relation-changed')
@restart_on_change(restart_map(), stopstart=True)
def restart_check():
    CONFIGS.write_all()


def main():
    try:
        hooks.execute(sys.argv)
    except UnregisteredHookError as e:
        log('Unknown hook {} - skipping.'.format(e))
    assess_status(CONFIGS)


if __name__ == '__main__':
    main()

#!/usr/bin/env python3 # # Copyright 2016 Canonical Ltd # # 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. # NOTE(wolsen): Do NOT add restart_on_change decorator without consideration # for the implications of modifications to the /etc/default/openvswitch-switch. # In the 16.10 release of the charms, the code changed from managing the # /etc/default/openvswitch-switch file only when dpdk was enabled to always # managing this file. Thus, an upgrade of the charm from a release prior # to 16.10 or higher will always cause the contents of the file to change # and will trigger a restart of the openvswitch-switch service, which in # turn causes a temporary network outage. To prevent this outage, determine # if the /etc/default/openvswitch-switch file needs to be migrated and if # so, migrate the file but do NOT restart the openvswitch-switch service. # See bug LP #1712444 # The 'Service restart triggered ...' line was added to the OVS_DEFAULT # template in the 16.10 version of the charm to allow restarts so we # use this as the key to see if the file needs migrating. # NOTE(fnordahl): configure_sriov must be run after CONFIGS.write_all() # to allow us to enable boot time execution of init script # If dvr setting has changed, need to pass that on # NOTE: only purge metadata packages if dvr is not #       in use as this will remove the l3 agent #       see https://pad.lv/1515008