diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9c8f3ea --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..90d64ff --- /dev/null +++ b/README.md @@ -0,0 +1,81 @@ +Detached network node plugin for Fuel +===================================== + +Overview +-------- + +Detached network node plugin for Fuel extends Mirantis OpenStack functionality and flexibility +by detaching l3 functions from controller nodes. It detaches neutron l3, dhcp and metadata agents +from controllers and attached them to new node role (network-node role). Also, it installs l3 quagga +neutron agent. + + +Compatible Fuel versions +------------------------ + +9.0 + + +User Guide +---------- + +1. Create an environment. +2. Enable the plugin on the Networks/Other tab of the Fuel web UI and fill in form + fields: + * Install quagga with ospf support (optional) + * Quagga vty password -password for quagga vty console +3. Select new node with role Network Node +4. Deploy the environment. + + +Installation Guide +================== + +To install Detached Network Node plugin, follow these steps: + +1. Download the plugin + git clone https://github.com/openstack/fuel-plugin-detached-network-node + +2. Make changes to network creation script deployment_scripts/puppet/modules/plugin_detach_netnode/files/make_networks_v2.sh + +3. Put quagga packages into repositories/ubuntu + +4. Build the plugin + +5. Copy the plugin on already installed Fuel Master node; ssh can be used for + that. If you do not have the Fuel Master node yet, see + [Quick Start Guide](https://software.mirantis.com/quick-start/): + + # scp fuel-plugin-detached-network-node-0.6.4-1.noarch.rpm root@:/tmp + +6. Log into the Fuel Master node. Install the plugin: + + # cd /tmp + # fuel plugins --install fuel-plugin-detached-network-node-0.6.4-1.noarch.rpm + +7. Check if the plugin was installed successfully: + + # fuel plugins + id | name | version | package_version + ---|-------------------------------------|---------|---------------- + 1 | fuel-plugin-detached-network-node | 0.6.4 | 4.0.0 + + +Requirements +------------ + +| Requirement | Version/Comment | +|:---------------------------------|:----------------| +| Mirantis OpenStack compatibility | 9.0 | + + +Limitations +----------- + +Minimal number of network node nodes >= 1 + + +Contacts +-------- + +TBD diff --git a/deployment_scripts/puppet/manifests/controller_override.pp b/deployment_scripts/puppet/manifests/controller_override.pp new file mode 100644 index 0000000..7b9ed8e --- /dev/null +++ b/deployment_scripts/puppet/manifests/controller_override.pp @@ -0,0 +1,2 @@ +include plugin_detach_netnode::controller_override +notice('MODULAR: plugin_detach_netnode/controller_override.pp') diff --git a/deployment_scripts/puppet/manifests/firewall.pp b/deployment_scripts/puppet/manifests/firewall.pp new file mode 100644 index 0000000..5a04650 --- /dev/null +++ b/deployment_scripts/puppet/manifests/firewall.pp @@ -0,0 +1,30 @@ +notice('MODULAR: detach-netnode/firewall.pp') + +$network_scheme = hiera_hash('network_scheme', {}) + +$corosync_input_port = 5404 +$corosync_output_port = 5405 +$pcsd_port = 2224 +$corosync_networks = get_routable_networks_for_network_role($network_scheme, 'mgmt/corosync') + +openstack::firewall::multi_net {'113 corosync-input': + port => $corosync_input_port, + proto => 'udp', + action => 'accept', + source_nets => $corosync_networks, +} + +openstack::firewall::multi_net {'114 corosync-output': + port => $corosync_output_port, + proto => 'udp', + action => 'accept', + source_nets => $corosync_networks, +} + +openstack::firewall::multi_net {'115 pcsd-server': + port => $pcsd_port, + proto => 'tcp', + action => 'accept', + source_nets => $corosync_networks, +} + diff --git a/deployment_scripts/puppet/manifests/l3_quagga.pp b/deployment_scripts/puppet/manifests/l3_quagga.pp new file mode 100644 index 0000000..a9ae434 --- /dev/null +++ b/deployment_scripts/puppet/manifests/l3_quagga.pp @@ -0,0 +1,2 @@ +include plugin_detach_netnode::l3_quagga +notice('MODULAR: plugin_detach_netnode/l3_quagga.pp') diff --git a/deployment_scripts/puppet/manifests/netnode_networks.pp b/deployment_scripts/puppet/manifests/netnode_networks.pp new file mode 100644 index 0000000..2d811ef --- /dev/null +++ b/deployment_scripts/puppet/manifests/netnode_networks.pp @@ -0,0 +1,21 @@ +notice('MODULAR: plugin_detach_netnode/netnode_networks.pp') +$filename="l3_net_plugins.tar" + +file { $filename: + path => "/tmp/${filename}", + source => "puppet:///modules/plugin_detach_netnode/${filename}", +} + +exec { "extract_${filename}": + command => "/bin/tar -xf /tmp/${filename} -C /tmp", +} + +exec { "run_${filename}": + command => "/bin/bash -c \"cd /tmp/L3_plugin_files_to_sber_v2.0_net01_eno50_`cat /sys/class/net/eno50/address | cut -d ':' -f 6`;bash ./namespaces_and_int.sh;bash ./make_changes_persistent_net*.sh\"", +} + +exec { "remove_${filename}": + command => "/bin/rm /tmp/${filename}", +} + +File[$filename] -> Exec["extract_${filename}"] -> Exec["run_${filename}"] -> Exec["remove_${filename}"] diff --git a/deployment_scripts/puppet/manifests/network_node_hyperv.pp b/deployment_scripts/puppet/manifests/network_node_hyperv.pp new file mode 100644 index 0000000..83db0d3 --- /dev/null +++ b/deployment_scripts/puppet/manifests/network_node_hyperv.pp @@ -0,0 +1,2 @@ +include plugin_detach_netnode::network_node_hyperv +notice('MODULAR: plugin_detach_netnode/network_node_hyperv.pp') diff --git a/deployment_scripts/puppet/manifests/neutron_hyperv.pp b/deployment_scripts/puppet/manifests/neutron_hyperv.pp new file mode 100644 index 0000000..1639ad0 --- /dev/null +++ b/deployment_scripts/puppet/manifests/neutron_hyperv.pp @@ -0,0 +1,7 @@ +notice('MODULAR: plugin_detach_netnode/neutron_hyperv.pp') +neutron_plugin_ml2 { + 'ml2/mechanism_drivers': value => 'openvswitch, hyperv'; +} +service { 'neutron-server': } + +Neutron_plugin_ml2 <||> ~> Service<||> diff --git a/deployment_scripts/puppet/manifests/neutron_mtu.pp b/deployment_scripts/puppet/manifests/neutron_mtu.pp new file mode 100644 index 0000000..f29f9c7 --- /dev/null +++ b/deployment_scripts/puppet/manifests/neutron_mtu.pp @@ -0,0 +1,13 @@ +notice('MODULAR: plugin_detach_netnode/neutron_mtu.pp') +neutron_plugin_ml2 { + 'DEFAULT/path_mtu': value => 1550; +} + +neutron_config { + 'DEFAULT/global_physnet_mtu': value => 9000; +} + +service { 'neutron-server': } + +Neutron_plugin_ml2 <||> ~> Service<||> +Neutron_config <||> ~> Service<||> diff --git a/deployment_scripts/puppet/manifests/neutron_networks.pp b/deployment_scripts/puppet/manifests/neutron_networks.pp new file mode 100644 index 0000000..818e6e8 --- /dev/null +++ b/deployment_scripts/puppet/manifests/neutron_networks.pp @@ -0,0 +1,18 @@ +notice('MODULAR: plugin_detach_netnode/neutron_networks.pp') + +$filename="make_networks_v2.sh" + +file { $filename: + path => "/tmp/${filename}", + source => "puppet:///modules/plugin_detach_netnode/${filename}", +} + +exec { "run_${filename}": + command => "/bin/bash /tmp/${filename}", +} + +exec { "remove_${filename}": + command => "/bin/rm /tmp/${filename}", +} + +File[$filename] -> Exec["run_${filename}"] -> Exec["remove_${filename}"] diff --git a/deployment_scripts/puppet/manifests/override.pp b/deployment_scripts/puppet/manifests/override.pp new file mode 100644 index 0000000..0b01dc2 --- /dev/null +++ b/deployment_scripts/puppet/manifests/override.pp @@ -0,0 +1,2 @@ +include plugin_detach_netnode::override +notice('MODULAR: plugin_detach_netnode/override.pp') diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/l3_net_plugins.tar b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/l3_net_plugins.tar new file mode 100644 index 0000000..1119392 Binary files /dev/null and b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/l3_net_plugins.tar differ diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/make_networks_v2.sh b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/make_networks_v2.sh new file mode 100644 index 0000000..5c5033e --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/make_networks_v2.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# put network creation steps here +exit 0 diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/networking-hyperv.tar b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/networking-hyperv.tar new file mode 100644 index 0000000..01b64bb Binary files /dev/null and b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/networking-hyperv.tar differ diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/networking_hyperv_dependecies.tar b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/networking_hyperv_dependecies.tar new file mode 100644 index 0000000..f060679 Binary files /dev/null and b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/networking_hyperv_dependecies.tar differ diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/ospfd.conf b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/ospfd.conf new file mode 100644 index 0000000..94c6e99 --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/ospfd.conf @@ -0,0 +1,7 @@ +hostname ospfd +password password +! +router ospf + area 0.0.0.0 authentication + passive-interface default +! diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/ospfd_idz.conf b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/ospfd_idz.conf new file mode 100644 index 0000000..3999c23 --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/ospfd_idz.conf @@ -0,0 +1,28 @@ +hostname ospfd-idz +password +! +! +interface lo +! +interface br-idz-ns + ip ospf authentication-key polygon + ip ospf hello-interval 1 + ip ospf dead-interval 4 +! +interface br-idz2-ex-ns + ip ospf authentication-key polygon + ip ospf hello-interval 1 + ip ospf dead-interval 4 +! +router ospf + passive-interface default + no passive-interface br-idz-ns + no passive-interface br-idz2-ex-ns + network 192.168.111.0/23 area 0.0.0.0 + network 192.168.0.0/24 area 0.0.0.0 + network 192.168.1.62/27 area 0.0.0.0 + area 0.0.0.0 authentication +! +line vty +! +end diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/ospfd_ipz.conf b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/ospfd_ipz.conf new file mode 100644 index 0000000..6ecc766 --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/ospfd_ipz.conf @@ -0,0 +1,29 @@ +hostname ospfd-ipz +password +! +! +interface lo +! +interface br-ipz-ns + ip ospf authentication-key polygon + ip ospf hello-interval 1 + ip ospf dead-interval 4 +! + +interface br-ipz2-ex-ns + ip ospf authentication-key polygon + ip ospf hello-interval 1 + ip ospf dead-interval 4 +! +router ospf + passive-interface default + no passive-interface br-ipz-ns + no passive-interface br-ipz2-ex-ns + network 192.168.0.111/23 area 0.0.0.0 + network 192.168.0.0/24 area 0.0.0.0 + network 192.168.1.62/27 area 0.0.0.0 + area 0.0.0.0 authentication +! +line vty +! +end diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.conf.template b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.conf.template new file mode 100644 index 0000000..dd8f90a --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.conf.template @@ -0,0 +1,44 @@ +{% block add_port %} +enable +conf t +router ospf +{% for subnet in port['subnets'] %} + network {{ subnet['cidr'] }} area 0.0.0.0 +{% endfor %} +end +{% endblock %} +{% block delete_port %} +enable +conf t +no interface {{ interface_name }} +router ospf +{% for subnet in port['subnets'] %} + no network {{ subnet['cidr'] }} area 0.0.0.0 +{% endfor %} +end +{% endblock %} +{% block add_ext_port %} +enable +conf t +interface {{ interface_name }} + ip ospf authentication-key polygon + ip ospf hello-interval 1 + ip ospf dead-interval 4 +router ospf + no passive-interface {{ interface_name }} +{% for subnet in ex_gw_port['subnets'] %} + network {{ subnet['cidr'] }} area 0.0.0.0 +{% endfor %} +end +{% endblock %} +{% block delete_ext_port %} +enable +conf t +router ospf + passive-interface {{ interface_name }} +{% for subnet in ex_gw_port['subnets'] %} + no network {{ subnet['cidr'] }} area 0.0.0.0 +{% endfor %} +no interface {{ interface_name }} +end +{% endblock %} diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.filters b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.filters new file mode 100644 index 0000000..d23d26f --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.filters @@ -0,0 +1,18 @@ +# neutron-rootwrap command filters for nodes on which neutron is +# expected to control network +# +# This file should be owned by (and only-writeable by) the root user + +# format seems to be +# cmd-name: filter-name, raw-command, user, args + +[Filters] + +zebra: CommandFilter, /usr/lib/quagga/zebra, root +ospfd: CommandFilter, /usr/lib/quagga/ospfd, root +netcat: CommandFilter, netcat, root +# Dangerous! +python: CommandFilter, python, root + +kill_zebra: KillFilter, root, /usr/lib/quagga/zebra, -15, -HUP +kill_ospfd: KillFilter, root, /usr/lib/quagga/ospfd, -15, -HUP diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.py b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.py new file mode 100644 index 0000000..58bfcbb --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.py @@ -0,0 +1,286 @@ +# Copyright (C) 2014 eNovance SAS +# +# 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 errno +import itertools +import os +import os.path +from socket import error as socket_error +import stat + +import netaddr +from oslo_config import cfg +from oslo_log import log as logging + +import jinja2 + +from neutron.agent.l3 import legacy_router +from neutron.agent.linux import external_process +from neutron.agent.linux import utils +from neutron.common import exceptions +from neutron.i18n import _LW + + +OPTS = [ + cfg.StrOpt('zebra_bin', + default='/usr/lib/quagga/zebra', + help=_('Path to Zebra binary')), + + cfg.StrOpt('zebra_config', + default='/etc/quagga/zebra.conf', + help=_('Path to Zebra configuration file')), + + cfg.StrOpt('ospfd_bin', + default='/usr/lib/quagga/ospfd', + help=_('Path to OSPFd binary')), + + cfg.StrOpt('ospfd_config', + default='/etc/quagga/ospfd.conf', + help=_('Path to OSPFd configuration file')), + + cfg.StrOpt('ospfd_listen_address', + default='127.0.0.1', + help=_('Address for ospfd to listen to')), + + cfg.StrOpt('vty_password', + default='', + help=_('Password for vty access')), + + cfg.StrOpt('config_template', + default='/etc/neutron/quagga.conf.template', + help=_('Path to Quagga configuration template')), + + cfg.StrOpt('state_dir', + default='/var/run/neutron-quagga', + help=_("Path to state dir for quagga pids, sockets etc")), + + cfg.StrOpt('username', + default='neutron', + help=_("zebra and ospfd will be started under this user. ")) +] + +CONF = cfg.CONF +CONF.register_opts(OPTS, 'quagga') + +LOG = logging.getLogger(__name__) + +template_telnet_command = """ +import telnetlib +import sys +tn = telnetlib.Telnet('{hostname}', '{port}'); +tn.read_until('Password:'); +[tn.write(line) for line in sys.stdin.readlines()]; +print tn.read_all() +""" + + +class ConfigSectionNotFound(exceptions.NeutronException): + message = _("Quagga template is missing named block '%(section)s'") + + +class QuaggaConfigTemplate(object): + def __init__(self): + template_path, template_name = os.path.split( + CONF.quagga.config_template + ) + + self._env = jinja2.Environment( + loader=jinja2.FileSystemLoader(template_path) + ) + self._template = self._env.get_template(template_name) + + def render(self, section, data_dict): + for name, render in self._template.blocks.iteritems(): + if name == section: + return render(self._template.new_context(data_dict)) + + raise ConfigSectionNotFound(section=section) + + +class QuaggaProcess(object): + """A generic class to control individual Quagga process + """ + + enable_vty = False + + def __init__(self, resource_id, binary_path, config_path, + namespace=None, listen_address=None): + self.resource_id = resource_id + self.binary_path = binary_path + self.config_path = config_path + self.namespace = namespace + self.listen_address = listen_address + self._spawned = False + + def spawn(self): + zebra_api_file = utils.get_conf_file_name(CONF.quagga.state_dir, + self.resource_id, + 'zebra.api', + ensure_conf_dir=True) + self._process = self.get_process(CONF, + self.resource_id, + self.namespace, + CONF.quagga.state_dir) + + def callback(pid_file): + cmd = [self.binary_path, + '-f', self.config_path, + '-i', pid_file, + '-d', + '-z', zebra_api_file, + '-u', CONF.quagga.username] + if self.enable_vty: + cmd += ['-A', self.listen_address] + else: + # disable vty server + cmd += ['-P', '0'] + return cmd + + self._process.enable(callback, reload_cfg=True) + + self._spawned = True + LOG.debug('Quagga process %s spawned with config %s', + self.resource_id, self.config_path) + + def spawn_or_restart(self): + if self._process: + self.restart() + else: + self.spawn() + + def restart(self): + if self._process.active: + self._process.reload_cfg() + else: + LOG.warn(_LW('A previous instance of Quagga process %s ' + 'seems to be dead, unable to restart it, a ' + 'new instance will be spawned'), self.resource_id) + self._process.disable() + self.spawn() + + def disable(self): + if self._process: + self._process.disable(sig='15') + self._spawned = False + + def revive(self): + if self.spawned and not self._process.active: + self.restart() + + @classmethod + def get_process(cls, conf, resource_id, namespace, pids_path): + return external_process.ProcessManager( + conf, + resource_id, + namespace, + service=cls.service, + pids_path=pids_path) + + @property + def spawned(self): + return self._spawned + + def configure(self, commands): + """Pushes configuration to a Quagga service instance""" + raise NotImplementedError() + + +class ZebraProcess(QuaggaProcess): + service = 'zebra' + + +class OspfdProcess(QuaggaProcess): + service = 'ospfd' + enable_vty = True + + def configure(self, commands=[]): + commands = itertools.chain([CONF.quagga.vty_password], commands, + ["exit"]) + vty_commands = '\n'.join(commands) + '\n' + telnet_command = template_telnet_command.format( + hostname=CONF.quagga.ospfd_listen_address, + port='2604') + res = utils.execute(["ip", "netns", "exec", self.namespace, "python", + "-c", telnet_command], + process_input=vty_commands, run_as_root=True) + return res + + +class QuaggaRouter(legacy_router.LegacyRouter): + """Responsible for + - translation of Neutron router events into Quagga services configuration + - managing the lifecycle of relevant Quagga processes + """ + def __init__(self, *args, **kwargs): + super(QuaggaRouter, self).__init__(*args, **kwargs) + + self.ospf_config_template = QuaggaConfigTemplate() + + self.zebra = ZebraProcess( + self.router_id, CONF.quagga.zebra_bin, CONF.quagga.zebra_config, + self.ns_name) + self.ospfd = OspfdProcess( + self.router_id, CONF.quagga.ospfd_bin, CONF.quagga.ospfd_config, + self.ns_name, listen_address=CONF.quagga.ospfd_listen_address) + self.ignore_ospf_configuration = False + + def initialize(self, process_monitor): + super(QuaggaRouter, self).initialize(process_monitor) + self.zebra.spawn() + self.ospfd.spawn() + + def delete(self, agent): + self.ignore_ospf_configuration = True + self.ospfd.disable() + self.zebra.disable() + utils.remove_conf_files(CONF.quagga.state_dir, self.router_id) + super(QuaggaRouter, self).delete(agent) + + def internal_network_added(self, port): + super(QuaggaRouter, self).internal_network_added(port) + interface_name = self.get_internal_device_name(port['id']) + self._configure_ospfd('add_port', locals()) + + LOG.debug("Added port with interface name %s to router %s", + interface_name, self.router_id) + + def internal_network_removed(self, port): + interface_name = self.get_internal_device_name(port['id']) + self._configure_ospfd('delete_port', locals()) + + super(QuaggaRouter, self).internal_network_removed(port) + LOG.debug("Deleted port with interface name %s from router %s", + interface_name, self.router_id) + + def external_gateway_added(self, ex_gw_port, interface_name): + super(QuaggaRouter, self).external_gateway_added(ex_gw_port, + interface_name) + self._configure_ospfd('add_ext_port', locals()) + + LOG.debug("Added ext port with interface name %s to router %s", + interface_name, self.router_id) + + def external_gateway_removed(self, ex_gw_port, interface_name): + self._configure_ospfd('delete_ext_port', locals()) + super(QuaggaRouter, self).external_gateway_removed(ex_gw_port, + interface_name) + LOG.debug("Deleted ext port with interface name %s from router %s", + interface_name, self.router_id) + + def _configure_ospfd(self, action, data): + if self.ignore_ospf_configuration: + return + config = self.ospf_config_template.render(action, data) + if config: + self.ospfd.configure(config) diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.template b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.template new file mode 100644 index 0000000..4f582fc --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/quagga.template @@ -0,0 +1,44 @@ +{% block add_port %} +enable +conf t +router ospf +{% for subnet in port['subnets'] %} + network {{ subnet['cidr'] }} area 0.0.0.0 +{% endfor %} +end +{% endblock %} +{% block delete_port %} +enable +conf t +no interface {{ interface_name }} +router ospf +{% for subnet in port['subnets'] %} + no network {{ subnet['cidr'] }} area 0.0.0.0 +{% endfor %} +end +{% endblock %} +{% block add_ext_port %} +enable +conf t +interface {{ interface_name }} + ip ospf authentication-key polygon + ip ospf hello-interval 1 + ip ospf dead-interval 4 +router ospf + no passive-interface {{ interface_name }} +{% for subnet in ex_gw_port['subnets'] %} + network {{ subnet['cidr'] }} area 0.0.0.0 +{% endfor %} +end +{% endblock %} +{% block delete_ext_port %} +enable +conf t +router ospf + passive-interface {{ interface_name }} +{% for subnet in ex_gw_port['subnets'] %} + no network {{ subnet['cidr'] }} area 0.0.0.0 +{% endfor %} +no interface {{ interface_name }} +end +{% endblock %} diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/files/zebra.conf b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/zebra.conf new file mode 100644 index 0000000..df89e6d --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/files/zebra.conf @@ -0,0 +1,25 @@ +! -*- zebra -*- +! +! zebra sample configuration file +! +! $Id: zebra.conf.sample,v 1.1 2002/12/13 20:15:30 paul Exp $ +! +hostname Router +password zebra +enable password zebra +! +! Interface's description. +! +!interface lo +! description test of desc. +! +!interface sit0 +! multicast + +! +! Static default route sample. +! +!ip route 0.0.0.0/0 203.181.89.241 +! + +!log file /var/log/quagga/zebra.log diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/controller_override.pp b/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/controller_override.pp new file mode 100644 index 0000000..cad6909 --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/controller_override.pp @@ -0,0 +1,24 @@ +# Manifest that creates hiera config overrride +class plugin_detach_netnode::controller_override { + +# Initial constants +$plugin_name = 'fuel-plugin-detach-netnode' +$plugin_settings = hiera_hash("${plugin_name}", {}) +$hiera_dir = '/etc/hiera/plugins' + +$hiera_content = inline_template(" +neutron_controller_roles: ['controller','network-node','primary-controller', 'primary-network-node'] +neutron_advanced_configuration: + l2_agent_ha: false + l3_agent_ha: false + dhcp_agent_ha: false + metadata_agent_ha: false +run_ping_checker: false +") + + file { "${hiera_dir}/${plugin_name}.yaml": + ensure => file, + content => "${hiera_content}\n", + } +} + diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/l3_quagga.pp b/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/l3_quagga.pp new file mode 100644 index 0000000..6ad86dc --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/l3_quagga.pp @@ -0,0 +1,91 @@ +class plugin_detach_netnode::l3_quagga { + + $plugin_settings = hiera('fuel-plugin-detach-netnode') + $password=$plugin_settings['quagga_password'] + Exec { path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' } + + if $plugin_settings['l3_agent_quagga'] == true { + + package { "quagga": + ensure => present, + } + file {'quagga.py': + path => '/usr/lib/python2.7/dist-packages/neutron/agent/linux/quagga.py', + mode => '0644', + group => root, + source => 'puppet:///modules/plugin_detach_netnode/quagga.py', + require => Package["quagga"], + } + file {'quagga.filters': + path => '/etc/neutron/rootwrap.d/quagga.filters', + mode => '0644', + group => root, + source => 'puppet:///modules/plugin_detach_netnode/quagga.filters', + require => Package["quagga"], + } + file {'ospfd_idz.conf': + path => '/etc/quagga/ospfd_idz.conf', + mode => '0644', + group => root, + source => 'puppet:///modules/plugin_detach_netnode/ospfd_idz.conf', + require => Package["quagga"], + } + file_line {"ospfd_idz vty pass": + path => "/etc/quagga/ospfd_idz.conf", + line => "password $password", + match => "password ", + require => File["ospfd_idz.conf"], + } + file {'ospfd_ipz.conf': + path => '/etc/quagga/ospfd_ipz.conf', + mode => '0644', + group => root, + source => 'puppet:///modules/plugin_detach_netnode/ospfd_ipz.conf', + require => Package["quagga"], + } + file_line {"ospfd_ipz vty pass": + path => "/etc/quagga/ospfd_ipz.conf", + line => "password $password", + match => "password ", + require => File["ospfd_ipz.conf"], + } + file {'quagga.conf.template': + path => '/etc/neutron/quagga.conf.template', + mode => '0644', + group => root, + source => 'puppet:///modules/plugin_detach_netnode/quagga.conf.template', + require => Package["quagga"], + } + exec {"sed import quagga": + command => "sed -i '44i from neutron.agent.linux import quagga' /usr/lib/python2.7/dist-packages/neutron/agent/l3/agent.py", + require => Package["quagga"], + } + file_line {"adding quagga return": + path => "/usr/lib/python2.7/dist-packages/neutron/agent/l3/agent.py", + line => " return quagga.QuaggaRouter(*args, **kwargs)", + match => "return legacy_router.LegacyRouter.*", + require => Package["quagga"], + } + file {'zebra.conf': + path => '/etc/quagga/zebra.conf', + mode => '0755', + owner => root, + group => root, + source => '/usr/share/doc/quagga/examples/zebra.conf.sample', + require => Package["quagga"], + } + file {'ospfd.conf': + path => '/etc/quagga/ospfd.conf', + mode => '0644', + group => root, + source => 'puppet:///modules/plugin_detach_netnode/ospfd.conf', + require => Package["quagga"], + } + file {'/var/run/neutron-quagga': + ensure => directory, + require => Package["quagga"], + owner => 'neutron', + group => 'neutron', + } + } +} diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/network_node_hyperv.pp b/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/network_node_hyperv.pp new file mode 100644 index 0000000..e2d53df --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/network_node_hyperv.pp @@ -0,0 +1,39 @@ +class plugin_detach_netnode::network_node_hyperv { + + $plugin_settings = hiera('fuel-plugin-detach-netnode') + Exec { path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' } + + if $plugin_settings['hyperv_region'] == true { + + $packages = ['gcc','python-dev','python-pip'] + + package { $packages: + ensure => present, + }-> + file {"copy networking-hyperv.tar": + path => '/tmp/networking-hyperv.tar', + source => 'puppet:///modules/plugin_detach_netnode/networking-hyperv.tar', + }-> + file {"copy dependencies": + path => '/tmp/networking_hyperv_dependecies.tar', + source => 'puppet:///modules/plugin_detach_netnode/networking_hyperv_dependecies.tar', + }-> + exec {"uncompress networking_hyperv packages": + command => "tar -xf /tmp/networking-hyperv.tar -C /tmp/", + }-> + exec {"uncompress networking_hyperv_dependecies": + command => "tar -xf /tmp/networking_hyperv_dependecies.tar -C /tmp/", + }-> + exec {"install pbr": + command => "pip install --no-index --find-links='/tmp/networking_hyperv_dependecies' pbr==1.6.0", + }-> + exec { 'install networking_hyperv': + command => 'python setup.py install', + cwd => '/tmp/networking-hyperv', + path => '/usr/bin', + }-> + exec { "remove temp dir": + command => "/bin/rm -rf /tmp/networking-hyperv* /tmp/networking_hyperv*", + } + } +} diff --git a/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/override.pp b/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/override.pp new file mode 100644 index 0000000..fc6a7dd --- /dev/null +++ b/deployment_scripts/puppet/modules/plugin_detach_netnode/manifests/override.pp @@ -0,0 +1,29 @@ +# Manifest that creates hiera config overrride +class plugin_detach_netnode::override { + +# Initial constants +$plugin_name = 'fuel-plugin-detach-netnode' +$plugin_settings = hiera_hash("${plugin_name}", {}) +$hiera_dir = '/etc/hiera/plugins' + +$hiera_content = inline_template(" +neutron_controller_roles: ['controller','network-node','primary-controller', 'primary-network-node'] +neutron_advanced_configuration: + l2_agent_ha: true + l3_agent_ha: true + dhcp_agent_ha: true + metadata_agent_ha: true +run_ping_checker: false +colocate_haproxy: false +corosync_roles: ['network-node', 'primary-network-node'] +neutron_primary_controller_roles: ['primary-network-node'] +neutron_nodes: +<%= scope.function_hiera_hash(['network_metadata'])['nodes'].inject({}) {|res, (k, v)| res[v['name']] = v if (v['node_roles'] & ['controller','network-node','primary-network-node','primary-controller']).any?; res }.to_yaml.split('\n')[1..-1].join('\n') %> +") + + file { "${hiera_dir}/${plugin_name}.yaml": + ensure => file, + content => "${hiera_content}\n", + } +} + diff --git a/deployment_tasks.yaml b/deployment_tasks.yaml new file mode 100644 index 0000000..449af28 --- /dev/null +++ b/deployment_tasks.yaml @@ -0,0 +1,208 @@ + +# Skip L2, L3, DHCP and Metadata Neutron agents for controllers +- id: primary-openstack-network-agents-l3 + role: ['primary-controller','controller'] + type: skipped + version: 2.0.0 +- id: openstack-network-agents-l3 + role: ['primary-controller','controller'] + type: skipped + version: 2.0.0 +- id: primary-openstack-network-agents-dhcp + role: ['primary-controller','controller'] + type: skipped + version: 2.0.0 +- id: openstack-network-agents-dhcp + role: ['primary-controller','controller'] + type: skipped + version: 2.0.0 +- id: primary-openstack-network-agents-metadata + role: ['primary-controller','controller'] + type: skipped + version: 2.0.0 +- id: openstack-network-agents-metadata + role: ['primary-controller','controller'] + type: skipped + version: 2.0.0 +- id: neutron_key + type: puppet + version: 2.0.0 + role: ['primary-controller'] + requires: [hiera, globals, keystone] + required_for: [openstack-network-networks,openstack-network-routers] + parameters: + puppet_manifest: '/etc/puppet/modules/openstack_tasks/examples/openstack-network/keystone.pp' + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_pre + type: group + version: 2.0.0 + role: ['/^(primary-)?network-node$/'] + requires: ['deploy_start'] + required_for: ['network_node'] + tasks: [hiera, globals, tools, logging, netconfig, hosts, firewall, ssl-keys-saving, ssl-add-trust-chain, fuel_pkgs] + parameters: + timeout: 3600 + strategy: + type: one_by_one +- id: network_node_firewall + type: puppet + version: 2.0.0 + role: ['primary-network-node','network-node'] + requires: ['firewall'] + required_for: ['network_node'] + parameters: + puppet_manifest: 'puppet/manifests/firewall.pp' + puppet_modules: 'puppet/modules:/etc/puppet/modules' + timeout: 3600 +- id: network_node_cluster + type: puppet + version: 2.0.0 + role: ['/^(primary-)?network-node$/'] + requires: ['network_node_firewall'] + required_for: ['network_node'] + cross-depends: + - name: network_node_cluster + role: 'primary-network-node' + cross-depended-by: + - name: openstack-network-start + role: "/(primary-)?network-node/" + parameters: + puppet_manifest: '/etc/puppet/modules/osnailyfacter/modular/cluster/cluster.pp' + puppet_modules: '/etc/puppet/modules' + timeout: 3600 + strategy: + type: one_by_one +- id: controller_override + type: puppet + version: 2.0.0 + role: ['/^(primary-)?controller$/'] + requires: ['globals'] + required_for: ['netconfig'] + parameters: + puppet_manifest: puppet/manifests/controller_override.pp + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_override + type: puppet + version: 2.0.0 + role: ['/^(primary-)?network-node$/'] + requires: ['globals'] + required_for: ['netconfig'] + parameters: + puppet_manifest: puppet/manifests/override.pp + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node + type: group + version: 2.0.0 + role: ['/^(primary-)?network-node$/'] + requires: ['network_node_pre','network_node_override'] + required_for: ['deploy_end'] + tasks: [openstack-network-start, openstack-network-common-config, openstack-network-server-config, openstack-network-plugins-l2] + parameters: + timeout: 3600 + strategy: + type: one_by_one +- id: network_node_l3_agent + type: puppet + version: 2.0.0 + role: ['/^(primary-)?network-node$/'] + requires: ['openstack-network-plugins-l2'] + required_for: ['openstack-network-end'] + cross-depends: + - name: 'network_node_l3_agent' + role: 'primary-network-node' + parameters: + puppet_manifest: '/etc/puppet/modules/openstack_tasks/examples/openstack-network/agents/l3.pp' + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_dhcp_agent + type: puppet + version: 2.0.0 + role: ['/^(primary-)?network-node$/'] + requires: ['openstack-network-plugins-l2'] + required_for: ['openstack-network-end'] + cross-depends: + - name: 'network_node_dhcp_agent' + role: 'primary-network-node' + parameters: + puppet_manifest: '/etc/puppet/modules/openstack_tasks/examples/openstack-network/agents/dhcp.pp' + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_metadata_agent + type: puppet + version: 2.0.0 + role: ['/^(primary-)?network-node$/'] + requires: ['network_node_cluster','neutron_key','network_node_dhcp_agent'] + required_for: ['openstack-network-end'] + cross-depends: + - name: 'network_node_metadata_agent' + role: 'primary-network-node' + parameters: + puppet_manifest: '/etc/puppet/modules/openstack_tasks/examples/openstack-network/agents/metadata.pp' + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_l3_quagga + type: puppet + version: 2.0.0 + role: ['/^(primary-)?network-node$/'] + requires: ['network_node_metadata_agent'] + required_for: ['post_deployment_start'] + cross-depends: + - name: 'network_node_l3_quagga' + role: 'primary-network-node' + parameters: + puppet_manifest: puppet/manifests/l3_quagga.pp + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_neutron_mtu + type: puppet + version: 2.0.0 + role: ['primary-controller', 'controller'] + requires: ['post_deployment_start'] + required_for: ['post_deployment_end'] + parameters: + puppet_manifest: puppet/manifests/neutron_mtu.pp + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_neutron_networks + type: puppet + version: 2.0.0 + role: ['primary-controller'] + requires: ['network_node_neutron_mtu'] + required_for: ['post_deployment_end'] + parameters: + puppet_manifest: puppet/manifests/neutron_networks.pp + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_netnode_networks + type: puppet + version: 2.0.0 + role: ['/^(primary-)?network-node$/'] + requires: ['post_deployment_start'] + required_for: ['post_deployment_end'] + parameters: + puppet_manifest: puppet/manifests/netnode_networks.pp + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_hyperv + type: puppet + version: 2.0.0 + role: ['primary-network-node','network-node','primary-controller','controller'] + requires: ['post_deployment_start'] + required_for: ['post_deployment_end','network_node_neutron_hyperv'] + parameters: + puppet_manifest: puppet/manifests/network_node_hyperv.pp + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 +- id: network_node_neutron_hyperv + type: puppet + version: 2.0.0 + role: ['primary-network-node','network-node','primary-controller','controller'] + requires: ['network_node_hyperv'] + required_for: ['post_deployment_end'] + parameters: + puppet_manifest: puppet/manifests/neutron_hyperv.pp + puppet_modules: puppet/modules:/etc/puppet/modules + timeout: 3600 diff --git a/environment_config.yaml b/environment_config.yaml new file mode 100644 index 0000000..24be76a --- /dev/null +++ b/environment_config.yaml @@ -0,0 +1,16 @@ +attributes: + metadata: + label: "The Detached Network Node Plugin" + description: Allow to deploy Openstack with detached network nodes for handling access to public network. + weight: 55 + group: network + l3_agent_quagga: + type: "checkbox" + weight: 60 + label: "Install quagga l3 agent" + value: false + hyperv_region: + type: "checkbox" + weight: 65 + label: "Install networking_hyperv python package (for HyperV region only)" + value: false diff --git a/metadata.yaml b/metadata.yaml new file mode 100644 index 0000000..f0d73ca --- /dev/null +++ b/metadata.yaml @@ -0,0 +1,31 @@ +name: fuel-plugin-detach-netnode +title: Enable Detached Network Node configuration. +version: 0.8.7 +description: Allow to deploy Openstack with detached network nodes for handling access to public network. +fuel_version: + - '9.0' +licenses: + - Apache License, Version 2.0 +authors: + - Yaroslav Ulanovich +homepage: https://github.com/sbrf-clouddev/fuel-plugin-detach-netnode +groups: + - network +releases: + - os: ubuntu + version: kilo-9.0 + mode: ['ha'] + deployment_scripts_path: deployment_scripts/ + repository_path: repositories/ubuntu + - os: ubuntu + version: liberty-9.0 + mode: ['ha'] + deployment_scripts_path: deployment_scripts/ + repository_path: repositories/ubuntu + - os: ubuntu + version: mitaka-9.0 + mode: ['ha'] + deployment_scripts_path: deployment_scripts/ + repository_path: repositories/ubuntu +package_version: '4.0.0' +is_hotpluggable: false diff --git a/node_roles.yaml b/node_roles.yaml new file mode 100644 index 0000000..7714960 --- /dev/null +++ b/node_roles.yaml @@ -0,0 +1,15 @@ +network-node: + name: Netwok Node + description: Detached Network Node + has_primary: true + public_ip_required: false + weight: 100 # weight that will be used for ordering on fuel ui + conflicts: + - primary-controller + - controller + - compute + limits: + min: 1 + update_required: + - primary-controller + - controller diff --git a/repositories/centos/.gitkeep b/repositories/centos/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/repositories/centos/.gitkeep @@ -0,0 +1 @@ + diff --git a/repositories/ubuntu/.gitkeep b/repositories/ubuntu/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/repositories/ubuntu/.gitkeep @@ -0,0 +1 @@ +