From 11ed9236217725146942e99c2606d54be61fefd4 Mon Sep 17 00:00:00 2001 From: Andreas Jaeger Date: Wed, 18 Dec 2019 19:40:33 +0100 Subject: [PATCH] Retire repository Fuel repositories are all retired in openstack namespace, retire remaining fuel repos in x namespace since they are unused now. This change removes all content from the repository and adds the usual README file to point out that the repository is retired following the process from https://docs.openstack.org/infra/manual/drivers.html#retiring-a-project See also http://lists.openstack.org/pipermail/openstack-discuss/2019-December/011675.html A related change is: https://review.opendev.org/699752 . Change-Id: I58cefc49ce851e159b15919aac6e08082ed5fd2a --- .gitignore | 89 -- LICENSE | 201 ---- README.rst | 57 +- components.yaml | 14 - ...install_midonet_common_modules_and_gems.sh | 13 - ...tall_midonet_common_modules_and_gems_54.sh | 17 - .../install_midonet_openstack_package.sh | 17 - .../install_midonet_package_from_source.sh | 16 - deployment_scripts/override_neutron_module.sh | 43 - deployment_scripts/puppet/files/midonet.yaml | 11 - .../puppet/files/startup-static.conf | 6 - deployment_scripts/puppet/files/startup.conf | 6 - .../manifests/midonet-bgp-interfaces.pp | 38 - .../manifests/midonet-cleanup-masquerade.pp | 69 -- .../midonet-cleanup-static-per-host.pp | 24 - .../manifests/midonet-cleanup-static.pp | 120 --- .../puppet/manifests/midonet-compute-nova.pp | 136 --- .../manifests/midonet-define-repositories.pp | 81 -- .../manifests/midonet-disable-services.pp | 116 --- .../midonet-edge-router-cleanup-bgp-gw.pp | 20 - .../midonet-edge-router-cleanup-bgp.pp | 116 --- .../midonet-edge-router-setup-bgp-gw.pp | 79 -- .../midonet-edge-router-setup-bgp.pp | 81 -- ...donet-edge-router-setup-static-per-host.pp | 64 -- .../midonet-edge-router-setup-static.pp | 53 - .../manifests/midonet-edge-router-setup.pp | 49 - .../manifests/midonet-enable-ip-forward.pp | 23 - .../manifests/midonet-ensure-rootwrap.pp | 8 - .../midonet-gateway-static-router-ifaces.pp | 56 - .../manifests/midonet-gateway-static.pp | 47 - .../midonet-generate-openrc-for-gw.pp | 57 - .../manifests/midonet-horizon-lb-firewall.pp | 35 - .../puppet/manifests/midonet-host-registry.pp | 47 - .../puppet/manifests/midonet-install-agent.pp | 93 -- .../manifests/midonet-install-analytics.pp | 93 -- .../manifests/midonet-install-cluster.pp | 129 --- .../manifests/midonet-install-haveged.pp | 18 - .../puppet/manifests/midonet-install-java8.pp | 17 - .../puppet/manifests/midonet-install-mem.pp | 273 ----- .../manifests/midonet-mem-horizon-override.pp | 72 -- .../manifests/midonet-neutron-configure.pp | 161 --- .../manifests/midonet-neutron-networks.pp | 84 -- .../puppet/manifests/midonet-nsdb.pp | 88 -- .../manifests/midonet-override-hiera.pp | 22 - .../manifests/midonet-replace-guess-func.pp | 22 - .../puppet/manifests/midonet-restart-agent.pp | 26 - .../manifests/midonet-restart-cluster.pp | 22 - .../puppet/parser/functions/filter_nodes.rb | 9 - .../functions/generate_api_zookeeper_ips.rb | 27 - .../functions/generate_bgp_edge_port_hash.rb | 36 - .../generate_bgp_edge_subnet_hash.rb | 37 - .../generate_bgp_neighbors_for_gateway_bgp.rb | 42 - .../generate_cidr_from_ip_netlength.rb | 25 - .../parser/functions/generate_fqdn_list.rb | 30 - .../generate_port_bindings_to_delete.rb | 33 - .../generate_router_interfaces_list.rb | 32 - .../generate_router_interfaces_to_delete.rb | 32 - .../functions/generate_zookeeper_hash.rb | 36 - .../parser/functions/get_node_by_fqdn.rb | 19 - .../lib/puppet/parser/functions/loadyamlv2.rb | 34 - .../parser/functions/public_network_hash.rb | 29 - .../puppet/templates/cleanup_masquerade.erb | 29 - .../templates/cleanup_static_gateway.sh.erb | 47 - .../templates/create_router_interfaces.sh.erb | 43 - .../create_router_interfaces_static.sh.erb | 43 - .../delete_router_interfaces_bgp.sh.erb | 31 - .../templates/remove_router_interfaces.sh.erb | 28 - .../puppet/templates/vhost_mem_manager.erb | 46 - deployment_tasks.yaml | 977 ------------------ doc/Makefile | 184 ---- doc/TestPlanforMidoNetFuelPlugin9.2.0.pdf | Bin 127706 -> 0 bytes doc/TestReportforMidoNetFuelPlugin9.2.0.pdf | Bin 143924 -> 0 bytes doc/images/bgp_params.png | Bin 17036 -> 0 bytes doc/images/floating_network.png | Bin 34519 -> 0 bytes doc/images/fuelml2gre.png | Bin 236508 -> 0 bytes doc/images/mem.png | Bin 26525 -> 0 bytes doc/images/mem_credentials.png | Bin 15823 -> 0 bytes doc/images/midonet_fuel.png | Bin 35598 -> 0 bytes doc/images/nodes_to_roles.png | Bin 99158 -> 0 bytes doc/images/other.png | Bin 77959 -> 0 bytes doc/images/plugin_config.png | Bin 65394 -> 0 bytes doc/images/static_gw_params.png | Bin 35062 -> 0 bytes doc/images/tunnel_type.png | Bin 8072 -> 0 bytes doc/images/tunneling.png | Bin 62089 -> 0 bytes doc/source/appendix.rst | 16 - doc/source/appendixes.rst | 9 - doc/source/bgp-peer.rst | 343 ------ doc/source/conf.py | 82 -- doc/source/description.rst | 62 -- doc/source/guide.rst | 321 ------ doc/source/index.rst | 22 - doc/source/installation.rst | 34 - doc/source/licenses.rst | 77 -- doc/source/revisions.rst | 39 - doc/source/terms.rst | 0 environment_config.yaml | 204 ---- metadata.yaml | 22 - node_roles.yaml | 33 - pre_build_hook | 6 - repositories/centos/.gitkeep | 0 repositories/ubuntu/.gitkeep | 0 specs/fuel-plugin-midonet.rst | 154 --- volumes.yaml | 8 - 103 files changed, 8 insertions(+), 6202 deletions(-) delete mode 100644 .gitignore delete mode 100644 LICENSE delete mode 100644 components.yaml delete mode 100755 deployment_scripts/install_midonet_common_modules_and_gems.sh delete mode 100644 deployment_scripts/install_midonet_common_modules_and_gems_54.sh delete mode 100644 deployment_scripts/install_midonet_openstack_package.sh delete mode 100644 deployment_scripts/install_midonet_package_from_source.sh delete mode 100644 deployment_scripts/override_neutron_module.sh delete mode 100644 deployment_scripts/puppet/files/midonet.yaml delete mode 100644 deployment_scripts/puppet/files/startup-static.conf delete mode 100644 deployment_scripts/puppet/files/startup.conf delete mode 100644 deployment_scripts/puppet/manifests/midonet-bgp-interfaces.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-cleanup-masquerade.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-cleanup-static-per-host.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-cleanup-static.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-compute-nova.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-define-repositories.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-disable-services.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-edge-router-cleanup-bgp-gw.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-edge-router-cleanup-bgp.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-edge-router-setup-bgp-gw.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-edge-router-setup-bgp.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-edge-router-setup-static-per-host.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-edge-router-setup-static.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-edge-router-setup.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-enable-ip-forward.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-ensure-rootwrap.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-gateway-static-router-ifaces.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-gateway-static.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-generate-openrc-for-gw.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-horizon-lb-firewall.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-host-registry.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-install-agent.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-install-analytics.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-install-cluster.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-install-haveged.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-install-java8.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-install-mem.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-mem-horizon-override.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-neutron-configure.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-neutron-networks.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-nsdb.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-override-hiera.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-replace-guess-func.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-restart-agent.pp delete mode 100644 deployment_scripts/puppet/manifests/midonet-restart-cluster.pp delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/filter_nodes.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_api_zookeeper_ips.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_edge_port_hash.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_edge_subnet_hash.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_neighbors_for_gateway_bgp.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_cidr_from_ip_netlength.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_fqdn_list.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_port_bindings_to_delete.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_router_interfaces_list.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_router_interfaces_to_delete.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_zookeeper_hash.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/get_node_by_fqdn.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/loadyamlv2.rb delete mode 100644 deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/public_network_hash.rb delete mode 100644 deployment_scripts/puppet/templates/cleanup_masquerade.erb delete mode 100644 deployment_scripts/puppet/templates/cleanup_static_gateway.sh.erb delete mode 100644 deployment_scripts/puppet/templates/create_router_interfaces.sh.erb delete mode 100644 deployment_scripts/puppet/templates/create_router_interfaces_static.sh.erb delete mode 100644 deployment_scripts/puppet/templates/delete_router_interfaces_bgp.sh.erb delete mode 100644 deployment_scripts/puppet/templates/remove_router_interfaces.sh.erb delete mode 100644 deployment_scripts/puppet/templates/vhost_mem_manager.erb delete mode 100644 deployment_tasks.yaml delete mode 100644 doc/Makefile delete mode 100644 doc/TestPlanforMidoNetFuelPlugin9.2.0.pdf delete mode 100644 doc/TestReportforMidoNetFuelPlugin9.2.0.pdf delete mode 100644 doc/images/bgp_params.png delete mode 100644 doc/images/floating_network.png delete mode 100644 doc/images/fuelml2gre.png delete mode 100644 doc/images/mem.png delete mode 100644 doc/images/mem_credentials.png delete mode 100644 doc/images/midonet_fuel.png delete mode 100644 doc/images/nodes_to_roles.png delete mode 100644 doc/images/other.png delete mode 100644 doc/images/plugin_config.png delete mode 100644 doc/images/static_gw_params.png delete mode 100644 doc/images/tunnel_type.png delete mode 100644 doc/images/tunneling.png delete mode 100644 doc/source/appendix.rst delete mode 100644 doc/source/appendixes.rst delete mode 100644 doc/source/bgp-peer.rst delete mode 100644 doc/source/conf.py delete mode 100644 doc/source/description.rst delete mode 100644 doc/source/guide.rst delete mode 100644 doc/source/index.rst delete mode 100644 doc/source/installation.rst delete mode 100644 doc/source/licenses.rst delete mode 100644 doc/source/revisions.rst delete mode 100644 doc/source/terms.rst delete mode 100644 environment_config.yaml delete mode 100644 metadata.yaml delete mode 100644 node_roles.yaml delete mode 100755 pre_build_hook delete mode 100644 repositories/centos/.gitkeep delete mode 100644 repositories/ubuntu/.gitkeep delete mode 100644 specs/fuel-plugin-midonet.rst delete mode 100644 volumes.yaml diff --git a/.gitignore b/.gitignore deleted file mode 100644 index adc8dfc..0000000 --- a/.gitignore +++ /dev/null @@ -1,89 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover -.hypothesis/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py - -# Flask instance folder -instance/ - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ -doc/build/ - -# PyBuilder -target/ - -# IPython Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# dotenv -.env - -# virtualenv -venv/ -ENV/ - -# Spyder project settings -.spyderproject -*.swp -.build/ -midonet-*.rpm diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 648acb8..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ -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 2017 Midokura - - 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. diff --git a/README.rst b/README.rst index c9b0b9b..86e34d6 100644 --- a/README.rst +++ b/README.rst @@ -1,51 +1,10 @@ -Mirantis Fuel MidoNet plugin -============================ +This project is no longer maintained. -Compatible versions: +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". -- Mirantis Fuel 9.0 , Fuel 9.1 and Fuel 9.2 -- MidoNet v5.2 / v5.4 -- Midokura Enterprise MidoNet 5.2 & 5.4 - -How to build the plugin ------------------------ - -- Install Fuel plugin builder (fpb) - - :: - - # pip install fuel-plugin-builder - -- Clone the plugin repo and run fpb there: - - :: - - $ git clone https://github.com/openstack/fuel-plugin-midonet - $ cd fuel-plugin-midonet - $ fpb --build . - -A *rpm* called `midonet-9.2-9.2.0-1.noarch.rpm` should be created in -the same directory. - -Follow the documentation to install and configure the plugin. You can read the -`rst` files in this very repository, or you can build a documentation file. - -How to build the documentation ------------------------------- - -You need to have **Sphinx** installed in your computer. Hint; for full Latex -Sphinx support on Ubuntu one needs **python-sphinx**, **rst2pdf**, **texlive** -and **texlive-latex-extra** packages. The Makefile provides several target -formats to do so. Go to the `doc` directory and run: - - make latexpdf - -or: - - make html - -or: - - make pdf - -You will need `rst2pdf` to run the last one. +For any further questions, please email +openstack-discuss@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/components.yaml b/components.yaml deleted file mode 100644 index 14d4c2b..0000000 --- a/components.yaml +++ /dev/null @@ -1,14 +0,0 @@ -- name: 'network:neutron:midonet' - label: 'Neutron with MidoNet' - description: 'MidoNet is a production grade network virtualization software' - bind: !!pairs - - "cluster:net_provider": "neutron" - - "cluster:net_segment_type": "tun" - compatible: - - name: 'hypervisor:kvm' - - name: 'hypervisor:qemu' - incompatible: - - name: 'hypervisor:vmware' - description: 'MidoNet plugin is not compatible with VMware' - - name: 'additional_service:ironic' - description: 'MidoNet plugin is not compatible with Ironic' diff --git a/deployment_scripts/install_midonet_common_modules_and_gems.sh b/deployment_scripts/install_midonet_common_modules_and_gems.sh deleted file mode 100755 index c8c209c..0000000 --- a/deployment_scripts/install_midonet_common_modules_and_gems.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -puppet module install puppetlabs-java --version=1.6.0 --ignore-dependencies --force -puppet module install locp-cassandra --version=1.25.2 --ignore-dependencies --force -puppet module install deric-zookeeper --version=0.6.1 --ignore-dependencies --force -puppet module install TubeMogul-curator --version=1.0.1 --ignore-dependencies --force -puppet module install elasticsearch-elasticsearch --version=0.13.2 --ignore-dependencies --force -puppet module install elasticsearch-logstash --version=0.6.4 --ignore-dependencies --force -puppet module install electrical-file_concat --version=1.0.1 --ignore-dependencies --force -puppet module install richardc-datacat --version=0.6.2 --ignore-dependencies --force - -gem install faraday # This is needed by the midonet providers -gem install netaddr # This is needed to calculate cidrs diff --git a/deployment_scripts/install_midonet_common_modules_and_gems_54.sh b/deployment_scripts/install_midonet_common_modules_and_gems_54.sh deleted file mode 100644 index 982b291..0000000 --- a/deployment_scripts/install_midonet_common_modules_and_gems_54.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -puppet module install puppetlabs-java --version=1.6.0 --ignore-dependencies --force -puppet module install locp-cassandra --version=1.25.2 --ignore-dependencies --force -puppet module install deric-zookeeper --version=0.6.1 --ignore-dependencies --force -puppet module install TubeMogul-curator --version=1.0.1 --ignore-dependencies --force -puppet module install elasticsearch-elasticsearch --version=0.15.1 --ignore-dependencies --force -puppet module install elastic-logstash --version=5.0.3 --ignore-dependencies --force -puppet module install electrical-file_concat --version=1.0.1 --ignore-dependencies --force -puppet module install richardc-datacat --version=0.6.2 --ignore-dependencies --force - -# Dirty sed because elk packages and fuel use different sysctl packages - -sed -i "s| sysctl { 'vm| sysctl::value { 'vm|g" /etc/puppet/modules/elasticsearch/manifests/config.pp - -gem install faraday # This is needed by the midonet providers -gem install netaddr # This is needed to calculate cidrs diff --git a/deployment_scripts/install_midonet_openstack_package.sh b/deployment_scripts/install_midonet_openstack_package.sh deleted file mode 100644 index 8c18ffc..0000000 --- a/deployment_scripts/install_midonet_openstack_package.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -#install git -apt-get install -y git -#install unzip -apt-get install -y unzip - -cd /tmp -git clone https://github.com/midonet/puppet-midonet_openstack.git -cd puppet-midonet_openstack -git fetch -git checkout stable/mitaka -puppet module build -puppet module install $(find . | grep .tar.gz) --ignore-dependencies --force - -#cleanup -rm -rf /tmp/puppet-midonet_openstack diff --git a/deployment_scripts/install_midonet_package_from_source.sh b/deployment_scripts/install_midonet_package_from_source.sh deleted file mode 100644 index 69945c9..0000000 --- a/deployment_scripts/install_midonet_package_from_source.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -#install git -apt-get install -y git - - -cd /tmp -git clone https://github.com/openstack/puppet-midonet.git -cd puppet-midonet -git fetch -git checkout stable/mitaka -puppet module build -puppet module install $(find . | grep .tar.gz) --ignore-dependencies --force - -#cleanup -rm -rf /tmp/puppet-midonet diff --git a/deployment_scripts/override_neutron_module.sh b/deployment_scripts/override_neutron_module.sh deleted file mode 100644 index 5f23182..0000000 --- a/deployment_scripts/override_neutron_module.sh +++ /dev/null @@ -1,43 +0,0 @@ -if [[ -e /etc/puppet/modules/neutron/lib/puppet/type/neutron_plugin_midonet.rb ]]; then - # Apply the released patch of Neutron Puppet to allow midonet manifests - wget https://github.com/openstack/puppet-neutron/commit/dfd4662347bec58644c6f22bf9ba2a433c23b4d9.diff -O /etc/puppet/modules/neutron/midonet.diff - cd /etc/puppet/modules/neutron && patch -p1 --force --forward < midonet.diff && cd - -fi - -# Dirty way of checking if the neutron type is already patched. It is not possible to get -# version Of the current fuel version from a node. -NEUTRONTYPEPATCHED=$(cat /etc/puppet/modules/neutron/lib/puppet/type/neutron_port.rb | grep binding_host_id | head -n1) -if [[ -z ${NEUTRONTYPEPATCHED} ]]; then - if [[ -e /etc/puppet/modules/neutron/lib/puppet/provider/neutron_port/neutron.rb ]]; then - # Apply the released patch of Neutron Puppet to allow midonet manifests - wget https://github.com/openstack/puppet-neutron/commit/dcfb3dd946cbc6f6083afa35f023917dfe0369e4.diff -O /etc/puppet/modules/neutron/midonet2.diff - cd /etc/puppet/modules/neutron && patch -p1 --force --forward < midonet2.diff && cd - - fi -fi - -if [[ -e /etc/puppet/modules/neutron/lib/puppet/type/neutron_network.rb ]]; then - # Apply the released patch of Neutron Puppet to allow midonet manifests - wget https://github.com/openstack/puppet-neutron/commit/95f0514a8ef6f5491d7e5775553d234435354cf8.diff -O /etc/puppet/modules/neutron/midonet3.diff - cd /etc/puppet/modules/neutron && patch -p1 --force --forward < midonet3.diff && cd - -fi - - -if [[ -e /etc/puppet/modules/neutron/lib/puppet/provider/neutron.rb ]]; then - # Apply the released patch of Neutron Puppet to allow midonet manifests - wget https://github.com/openstack/puppet-neutron/commit/46e2d7acdcd5319bbc73483ff24cbafa0409d302.diff -O /etc/puppet/modules/neutron/midonet4.diff - cd /etc/puppet/modules/neutron && patch -p1 --force --forward < midonet4.diff && cd - -fi - -if [[ -e /etc/puppet/modules/neutron/manifests/plugins/midonet.pp ]]; then - # Apply the released patch of Neutron Puppet to allow midonet manifests - wget https://github.com/openstack/puppet-neutron/commit/e4a79e348d110e7a80e042a045a671359f31c103.diff -O /etc/puppet/modules/neutron/midonet5.diff - cd /etc/puppet/modules/neutron && patch -p1 --force --forward < midonet5.diff && cd - -fi - -if [[ -e /etc/puppet/modules/neutron/manifests/plugins/midonet.pp ]]; then - # Apply the released patch of Neutron Puppet to allow midonet manifests - wget https://github.com/openstack/puppet-neutron/commit/3af5e9a40400bc7dc47cd7c265b5f126637c4ba3.diff -O /etc/puppet/modules/neutron/midonet6.diff - cd /etc/puppet/modules/neutron && patch -p1 --force --forward < midonet6.diff && cd - -fi - -exit 0 diff --git a/deployment_scripts/puppet/files/midonet.yaml b/deployment_scripts/puppet/files/midonet.yaml deleted file mode 100644 index 72b0679..0000000 --- a/deployment_scripts/puppet/files/midonet.yaml +++ /dev/null @@ -1,11 +0,0 @@ -neutron::core_plugin: 'midonet.neutron.plugin_v2.MidonetPluginV2' -neutron::service_plugins: - - midonet.neutron.services.firewall.plugin.MidonetFirewallPlugin - - lbaas - - midonet.neutron.services.l3.l3_midonet.MidonetL3ServicePlugin -horizon::neutron_options: - - enable_lb: true - - enable_firewall: true - -neutron::server::service_providers: - - LOADBALANCER:Midonet:midonet.neutron.services.loadbalancer.driver.MidonetLoadbalancerDriver:default diff --git a/deployment_scripts/puppet/files/startup-static.conf b/deployment_scripts/puppet/files/startup-static.conf deleted file mode 100644 index b60f249..0000000 --- a/deployment_scripts/puppet/files/startup-static.conf +++ /dev/null @@ -1,6 +0,0 @@ -start on runlevel [123456] -stop on shutdown - -script - puppet apply --modulepath=/etc/fuel/plugins/midonet-9.2/puppet/modules:/etc/puppet/modules /etc/fuel/plugins/midonet-9.2/puppet/manifests/midonet-gateway-static.pp -end script diff --git a/deployment_scripts/puppet/files/startup.conf b/deployment_scripts/puppet/files/startup.conf deleted file mode 100644 index 136caee..0000000 --- a/deployment_scripts/puppet/files/startup.conf +++ /dev/null @@ -1,6 +0,0 @@ -start on runlevel [123456] -stop on shutdown - -script - puppet apply --modulepath=/etc/fuel/plugins/midonet-9.2/puppet/modules:/etc/puppet/modules /etc/fuel/plugins/midonet-9.2/puppet/manifests/midonet-bgp-interfaces.pp -end script diff --git a/deployment_scripts/puppet/manifests/midonet-bgp-interfaces.pp b/deployment_scripts/puppet/manifests/midonet-bgp-interfaces.pp deleted file mode 100644 index 36e4d51..0000000 --- a/deployment_scripts/puppet/manifests/midonet-bgp-interfaces.pp +++ /dev/null @@ -1,38 +0,0 @@ -notice('MODULAR: midonet-bgp-interfaces.pp') - - -exec {'add veth interface': - path => '/usr/bin:/usr/sbin:/sbin', - command => 'ip link add gw-veth-br type veth peer name gw-veth-mn', - unless => 'ip l | /bin/grep gw-veth-br' -} -> - -exec {'set gw-veth-br interface up': - path => '/usr/bin:/usr/sbin:/sbin', - command => 'ip l set dev gw-veth-br up' -} -> - -exec {'set gw-veth-mn interface up': - path => '/usr/bin:/usr/sbin:/sbin', - command => 'ip l set dev gw-veth-mn up' -} -> - -exec {'add veth to bridge': - path => '/usr/bin:/usr/sbin:/sbin', - command => 'brctl addif br-ex gw-veth-br', - unless => 'brctl show br-ex | /bin/grep gw-veth-br' -} -> - -file {'/etc/sysconfig/network-scripts/ifcfg-p_br-floating-0': - ensure => absent, -} -> - -exec {'set up external bridge': - path => '/usr/bin:/usr/sbin:/sbin', - command => 'ip link set dev br-ex up' -} -> - -file {'/etc/init/midonet-network.conf': - ensure => present, - source => '/etc/fuel/plugins/midonet-9.2/puppet/files/startup.conf' -} diff --git a/deployment_scripts/puppet/manifests/midonet-cleanup-masquerade.pp b/deployment_scripts/puppet/manifests/midonet-cleanup-masquerade.pp deleted file mode 100644 index 51b2583..0000000 --- a/deployment_scripts/puppet/manifests/midonet-cleanup-masquerade.pp +++ /dev/null @@ -1,69 +0,0 @@ - -notice('MODULAR: midonet-cleanup-masquerade.pp') -include ::stdlib - -$old_config = loadyamlv2('/etc/fuel/cluster/astute.yaml.old','notfound') - -# If it's a redeploy and the file exists we can proceed -if($old_config != 'notfound') -{ - $old_gw_type = $old_config['midonet']['gateway_type'] - if ($old_gw_type == 'static') { - - # Extract data from hiera - $access_data = $old_config['access'] - $keystone_admin_tenant = $access_data['tenant'] - $net_metadata = $old_config['network_metadata'] - $neutron_settings = $old_config['quantum_settings'] - $external_net_name = $neutron_settings['default_floating_net'] - $tenant_net_name = $neutron_settings['default_private_net'] - $predefined_nets = $neutron_settings['predefined_networks'] - $tenant_net = $predefined_nets[$tenant_net_name] - $external_net = $predefined_nets[$external_net_name] - - $old_midonet_settings = $old_config['midonet'] - $old_net_metadata = $old_config['network_metadata'] - $controllers_map = get_nodes_hash_by_roles($old_net_metadata, ['controller', 'primary-controller']) - - - $management_address = hiera('management_vip') - $username = $access_data['user'] - $password = $access_data['password'] - $tenant_name = $access_data['tenant'] - - $midonet_settings = $old_config['midonet'] - $floating_cidr = $midonet_settings['floating_cidr'] - $f_net_cidr = split($midonet_settings['floating_cidr'], '/') - - $static_linux_bridge_ip_netl = $midonet_settings['static_linux_bridge_address'] - $static_fake_edge_router_ip_netl = $midonet_settings['static_fake_edge_router_address'] - $static_use_masquerade = $midonet_settings['static_use_masquerade'] - - $static_linux_bridge_ip_address = split($static_linux_bridge_ip_netl,'/') - $static_fake_edge_router_ip_address = split($static_fake_edge_router_ip_netl,'/') - - $slbip_without_netl = $static_linux_bridge_ip_address[0] - - $gw_hash = get_nodes_hash_by_roles($net_metadata, ['midonet-gw']) - $gw_mgmt_ip_hash = get_node_to_ipaddr_map_by_network_role($gw_hash, 'management') - $gw_mgmt_ip_list = values($gw_mgmt_ip_hash) - $gw_keys = keys($gw_hash) - - $nic = 'br-ex' - $fip = $old_midonet_settings['floating_cidr'] - - file { 'delete masquerade script': - ensure => present, - path => '/tmp/remove_router_interfaces.sh', - content => template('/etc/fuel/plugins/midonet-9.2/puppet/templates/cleanup_masquerade.sh.erb'), - } -> - - # Finally, execute the script - exec { 'run delete masquerade script': - command => '/bin/bash -x /tmp/cleanup_masquerade.sh 2>&1 | tee /tmp/cleanup_masq.out', - returns => ['0', '7'], - } - - - } -} diff --git a/deployment_scripts/puppet/manifests/midonet-cleanup-static-per-host.pp b/deployment_scripts/puppet/manifests/midonet-cleanup-static-per-host.pp deleted file mode 100644 index 2da2b75..0000000 --- a/deployment_scripts/puppet/manifests/midonet-cleanup-static-per-host.pp +++ /dev/null @@ -1,24 +0,0 @@ - -notice('MODULAR: midonet-cleanup-static-per-host.pp') - - exec {'drop the veth pair': - path => '/usr/bin:/usr/sbin:/sbin', - command => 'ip link delete veth0', - onlyif => 'ip l | /bin/grep -e veth0 -e veth1' - } -> - - exec {'shut off the uplinkbridge': - path => '/usr/bin:/usr/sbin:/sbin', - command => 'ifconfig uplinkbridge down', - onlyif => 'ip l | /bin/grep -e uplinkbridge' - } -> - - exec {'delete the uplinkbridge': - path => '/usr/bin:/usr/sbin:/sbin', - command => 'brctl delbr uplinkbridge', - onlyif => 'ip l | /bin/grep -e uplinkbridge' - } -> - - file {'/etc/init/midonet-network-static.conf': - ensure => absent, - } diff --git a/deployment_scripts/puppet/manifests/midonet-cleanup-static.pp b/deployment_scripts/puppet/manifests/midonet-cleanup-static.pp deleted file mode 100644 index 63b26c5..0000000 --- a/deployment_scripts/puppet/manifests/midonet-cleanup-static.pp +++ /dev/null @@ -1,120 +0,0 @@ - -notice('MODULAR: midonet-cleanup-static.pp') -include ::stdlib - -$old_config = loadyamlv2('/etc/fuel/cluster/astute.yaml.old','notfound') - -# If it's a redeploy and the file exists we can proceed -if($old_config != 'notfound') -{ - $old_gw_type = $old_config['midonet']['gateway_type'] - if ($old_gw_type == 'static') { - - # Extract data from hiera - $access_data = $old_config['access'] - $keystone_admin_tenant = $access_data['tenant'] - $net_metadata = $old_config['network_metadata'] - $neutron_settings = $old_config['quantum_settings'] - $external_net_name = $neutron_settings['default_floating_net'] - $tenant_net_name = $neutron_settings['default_private_net'] - $predefined_nets = $neutron_settings['predefined_networks'] - $tenant_net = $predefined_nets[$tenant_net_name] - $external_net = $predefined_nets[$external_net_name] - - $old_midonet_settings = $old_config['midonet'] - $old_net_metadata = $old_config['network_metadata'] - $controllers_map = get_nodes_hash_by_roles($old_net_metadata, ['controller', 'primary-controller']) - - - $management_address = hiera('management_vip') - $username = $access_data['user'] - $password = $access_data['password'] - $tenant_name = $access_data['tenant'] - - $midonet_settings = $old_config['midonet'] - $floating_cidr = $midonet_settings['floating_cidr'] - $f_net_cidr = split($midonet_settings['floating_cidr'], '/') - - $static_linux_bridge_ip_netl = $midonet_settings['static_linux_bridge_address'] - $static_fake_edge_router_ip_netl = $midonet_settings['static_fake_edge_router_address'] - $static_use_masquerade = $midonet_settings['static_use_masquerade'] - - $static_linux_bridge_ip_address = split($static_linux_bridge_ip_netl,'/') - $static_fake_edge_router_ip_address = split($static_fake_edge_router_ip_netl,'/') - - $slbip_without_netl = $static_linux_bridge_ip_address[0] - - $gw_hash = get_nodes_hash_by_roles($old_net_metadata, ['midonet-gw']) - $gw_mgmt_ip_hash = get_node_to_ipaddr_map_by_network_role($gw_hash, 'management') - $gw_mgmt_ip_list = values($gw_mgmt_ip_hash) - $gw_keys = keys($gw_hash) - - $gw_fqdn = $gw_hash[$gw_keys[0]]['fqdn'] - - $nic = 'br-ex' - $fip = $old_midonet_settings['floating_cidr'] - $edge_router = 'edge-router' - $veth0_ip = $static_linux_bridge_ip_address[0] - $veth1_ip = $static_fake_edge_router_ip_address[0] - $veth_network = generate_cidr_from_ip_netlength($static_linux_bridge_ip_netl) - $myhostname = $gw_mgmt_ip_list[0] - - package { 'python-neutronclient': - ensure => latest - } - - file { 'cleanup static script': - ensure => present, - path => '/tmp/cleanup_static_gateway.sh', - content => template('/etc/fuel/plugins/midonet-9.2/puppet/templates/cleanup_static_gateway.sh.erb'), - } - - # Finally, execute the script - exec { 'run gateway static cleanup script': - command => '/bin/bash -x /tmp/cleanup_static_gateway.sh 2>&1 | tee /tmp/cleanup.out', - returns => ['0', '7'], - } - - $ports_to_unbind = generate_router_interfaces_to_delete($gw_hash) - - file { 'delete router interfaces script': - ensure => present, - path => '/tmp/remove_router_interfaces.sh', - content => template('/etc/fuel/plugins/midonet-9.2/puppet/templates/remove_router_interfaces.sh.erb'), - } - - # Finally, execute the script - exec { 'run delete router interfaces script': - command => '/bin/bash -x /tmp/remove_router_interfaces.sh 2>&1 | tee /tmp/ri-delete.out', - returns => ['0', '7'], - } - - neutron_port { "port-static-${gw_fqdn}": - - ensure => absent, - network_name => 'edge-net', - binding_host_id => $gw_fqdn, - binding_profile => { - 'interface_name' => 'veth1' - }, - ip_address => [[$static_fake_edge_router_ip_address[0]],['0.0.0.0']], - } - - neutron_subnet { 'edge-subnet': - ensure => absent, - enable_dhcp => false, - cidr => generate_cidr_from_ip_netlength($static_linux_bridge_ip_netl), - tenant_id => $external_net['tenant'], - network_name => 'edge-net', - } - - Package['python-neutronclient'] - -> File['cleanup static script'] - -> Exec['run gateway static cleanup script'] - -> File['delete router interfaces script'] - -> Exec['run delete router interfaces script'] - -> Neutron_port<||> - -> Neutron_subnet['edge-subnet'] - - } -} diff --git a/deployment_scripts/puppet/manifests/midonet-compute-nova.pp b/deployment_scripts/puppet/manifests/midonet-compute-nova.pp deleted file mode 100644 index 0cf286f..0000000 --- a/deployment_scripts/puppet/manifests/midonet-compute-nova.pp +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: neutron-compute-nova.pp') - -$network_scheme = hiera_hash('network_scheme', {}) -prepare_network_config($network_scheme) - -$use_neutron = hiera('use_neutron', false) - -include nova::params -$neutron_config = hiera_hash('neutron_config', {}) -$neutron_integration_bridge = 'br-int' -$nova_hash = hiera_hash('nova', {}) -$libvirt_vif_driver = pick($nova_hash['libvirt_vif_driver'], 'nova.virt.libvirt.vif.LibvirtGenericVIFDriver') - -$management_vip = hiera('management_vip') -$service_endpoint = hiera('service_endpoint', $management_vip) -$admin_password = try_get_value($neutron_config, 'keystone/admin_password') -$admin_tenant_name = try_get_value($neutron_config, 'keystone/admin_tenant', 'services') -$admin_username = try_get_value($neutron_config, 'keystone/admin_user', 'neutron') -$region_name = hiera('region', 'RegionOne') -$auth_api_version = 'v3' -$ssl_hash = hiera_hash('use_ssl', {}) - -$admin_identity_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'protocol', 'http') -$admin_identity_address = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'hostname', [$service_endpoint, $management_vip]) - -$neutron_internal_protocol = get_ssl_property($ssl_hash, {}, 'neutron', 'internal', 'protocol', 'http') -$neutron_endpoint = get_ssl_property($ssl_hash, {}, 'neutron', 'internal', 'hostname', [hiera('neutron_endpoint', ''), $management_vip]) - -$admin_identity_uri = "${admin_identity_protocol}://${admin_identity_address}:35357" -$admin_auth_url = "${admin_identity_uri}/${auth_api_version}" -$neutron_url = "${neutron_internal_protocol}://${neutron_endpoint}:9696" - -$nova_migration_ip = get_network_role_property('nova/migration', 'ipaddr') - -service { 'libvirt' : - ensure => 'running', - enable => true, - # Workaround for bug LP #1469308 - # also service name for Ubuntu and Centos is the same. - name => 'libvirtd', - provider => $nova::params::special_service_provider, -} - -firewall { '999 accept all to metadata interface': - proto => 'all', - iniface => 'metadata', - action => 'accept', -} - -exec { 'destroy_libvirt_default_network': - command => 'virsh net-destroy default', - onlyif => 'virsh net-info default | grep -qE "Active:.* yes"', - path => [ '/bin', '/sbin', '/usr/bin', '/usr/sbin' ], - tries => 3, - require => Service['libvirt'], -} - -exec { 'undefine_libvirt_default_network': - command => 'virsh net-undefine default', - onlyif => 'virsh net-info default 2>&1 > /dev/null', - path => [ '/bin', '/sbin', '/usr/bin', '/usr/sbin' ], - tries => 3, - require => Exec['destroy_libvirt_default_network'], -} - -Service['libvirt'] ~> Exec['destroy_libvirt_default_network'] - -# script called by qemu needs to manipulate the tap device -file_line { 'clear_emulator_capabilities': - path => '/etc/libvirt/qemu.conf', - line => 'clear_emulator_capabilities = 0', - notify => Service['libvirt'] -} - -class { 'nova::compute::neutron': - libvirt_vif_driver => $libvirt_vif_driver, -} - -nova_config { - 'DEFAULT/linuxnet_interface_driver': value => 'nova.network.linux_net.LinuxOVSInterfaceDriver'; - 'DEFAULT/linuxnet_ovs_integration_bridge': value => $neutron_integration_bridge; - 'DEFAULT/network_device_mtu': value => '65000'; - 'DEFAULT/my_ip': value => $nova_migration_ip; - 'DEFAULT/force_config_drive': value => 'False'; -} - -class { 'nova::network::neutron' : - neutron_admin_password => $admin_password, - neutron_admin_tenant_name => $admin_tenant_name, - neutron_region_name => $region_name, - neutron_admin_username => $admin_username, - neutron_admin_auth_url => $admin_auth_url, - neutron_url => $neutron_url, - neutron_ovs_bridge => $neutron_integration_bridge, -} - -augeas { 'sysctl-net.bridge.bridge-nf-call-arptables': - context => '/files/etc/sysctl.conf', - changes => "set net.bridge.bridge-nf-call-arptables '1'", - before => Service['libvirt'], -} -augeas { 'sysctl-net.bridge.bridge-nf-call-iptables': - context => '/files/etc/sysctl.conf', - changes => "set net.bridge.bridge-nf-call-iptables '1'", - before => Service['libvirt'], -} -augeas { 'sysctl-net.bridge.bridge-nf-call-ip6tables': - context => '/files/etc/sysctl.conf', - changes => "set net.bridge.bridge-nf-call-ip6tables '1'", - before => Service['libvirt'], -} - -service { 'nova-compute': - ensure => 'running', - name => $::nova::params::compute_service_name, -} -Nova_config<| |> ~> Service['nova-compute'] - -if($::operatingsystem == 'Ubuntu') { - tweaks::ubuntu_service_override { 'nova-network': - package_name => 'nova-network', - } -} diff --git a/deployment_scripts/puppet/manifests/midonet-define-repositories.pp b/deployment_scripts/puppet/manifests/midonet-define-repositories.pp deleted file mode 100644 index 7670d51..0000000 --- a/deployment_scripts/puppet/manifests/midonet-define-repositories.pp +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-define-repositories.pp') - -$midonet_settings = hiera('midonet') -$mem = $midonet_settings['mem'] -$mem_version = $midonet_settings['midonet_version'] -$mem_user = $midonet_settings['mem_repo_user'] -$mem_password = $midonet_settings['mem_repo_password'] -$midonet_version = $midonet_settings['midonet_version'] -$openstack_release = 'mitaka' - -include apt -include apt::update -include midonet::params - - -if $mem { - $midonet_repo_url = "http://${mem_user}:${mem_password}@${midonet::params::midonet_repo_baseurl}/mem-${mem_version}" -} -else { - $midonet_repo_url = "http://${midonet::params::midonet_repo_baseurl}/midonet-${midonet_version}" -} - -apt::key { 'midorepo': - id => 'E9996503AEB005066261D3F38DDA494E99143E75', - source => $midonet::params::midonet_key_url -} -> - -apt::source {'midonet': - comment => 'Midonet apt repository', - location => $midonet_repo_url, - release => 'unstable', - key => { - 'id' => 'E9996503AEB005066261D3F38DDA494E99143E75', - 'server' => 'subkeys.pgp.net', - }, - include => { - 'src' => false, - } -} -> - -apt::source {'midonet-openstack-integration': - comment => 'Midonet apt plugin repository', - location => "http://${midonet::params::midonet_repo_baseurl}/openstack-${openstack_release}", - release => 'stable', - include => { - 'src' => false, - } -} -> - -apt::source {'midonet-openstack-misc': - comment => 'Midonet 3rd party tools and libraries', - location => "http://${midonet::params::midonet_repo_baseurl}/misc", - release => 'stable', - include => { - 'src' => false, - } -} - -# Dummy exec to wrap apt_update -exec {'update-midonet-repos': - command => '/bin/true', - require => [Exec['apt_update'], - Apt::Source['midonet'], - Apt::Source['midonet-openstack-integration']] - -} - -Apt::Source<| |> -> Exec<| title == 'update-midonet-repos' |> diff --git a/deployment_scripts/puppet/manifests/midonet-disable-services.pp b/deployment_scripts/puppet/manifests/midonet-disable-services.pp deleted file mode 100644 index f524c22..0000000 --- a/deployment_scripts/puppet/manifests/midonet-disable-services.pp +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-disable-services.pp') -include ::stdlib - -# Extract hiera data -$net_metadata = hiera_hash('network_metadata') - -$node = get_node_by_fqdn($net_metadata, $::fqdn) - -$roles = $node['node_roles'] - -$ovs_agent_name = $operatingsystem ? { - 'CentOS' => 'neutron-openvswitch-agent', - 'Ubuntu' => 'neutron-plugin-openvswitch-agent', -} - -$l3_agent_name = $operatingsystem ? { - 'CentOS' => 'neutron-l3-agent', - 'Ubuntu' => 'neutron-l3-agent' -} - -$dhcp_agent_name = $operatingsystem ? { - 'CentOS' => 'neutron-dhcp-agent', - 'Ubuntu' => 'neutron-dhcp-agent' -} - -$metadata_agent_name = $operatingsystem ? { - 'CentOS' => 'neutron-metadata-agent', - 'Ubuntu' => 'neutron-metadata-agent' -} - -if member($roles, 'primary-controller') { - - exec {'stop-dhcp-agent': - command => 'crm resource stop clone_neutron-dhcp-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status clone_neutron-dhcp-agent' - } -> - exec {'stop-metadata-agent': - command => 'crm resource stop clone_neutron-metadata-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status clone_neutron-metadata-agent' - } -> - exec {'delete-metadata-agent': - command => 'crm configure delete clone_neutron-metadata-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status clone_neutron-metadata-agent' - }-> - exec {'delete-dhcp-agent': - command => 'crm configure delete clone_neutron-dhcp-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status clone_neutron-dhcp-agent' - }-> - exec {'stop-dhcp-agent-N': - command => 'crm resource stop neutron-dhcp-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status neutron-dhcp-agent' - } -> - exec {'stop-metadata-agent-N': - command => 'crm resource stop neutron-metadata-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status neutron-metadata-agent' - } -> - exec {'delete-metadata-agent-N': - command => 'crm configure delete neutron-metadata-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status neutron-metadata-agent' - }-> - exec {'delete-dhcp-agent-N': - command => 'crm configure delete neutron-dhcp-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status neutron-dhcp-agent' - }-> - exec {'stop-l3-agent': - command => 'crm resource stop p_neutron-l3-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status p_neutron-l3-agent' - } -> - exec {'delete-l3-agent': - command => 'crm configure delete p_neutron-l3-agent', - path => '/usr/bin:/usr/sbin', - onlyif => 'crm resource status p_neutron-l3-agent' - }-> - service {$dhcp_agent_name: - ensure => stopped, - enable => false - }-> - - service {$metadata_agent_name: - ensure => stopped, - enable => false - } -} else { - - service {$dhcp_agent_name: - ensure => stopped, - enable => false - } - - service {$metadata_agent_name: - ensure => stopped, - enable => false - } -} diff --git a/deployment_scripts/puppet/manifests/midonet-edge-router-cleanup-bgp-gw.pp b/deployment_scripts/puppet/manifests/midonet-edge-router-cleanup-bgp-gw.pp deleted file mode 100644 index d4854f7..0000000 --- a/deployment_scripts/puppet/manifests/midonet-edge-router-cleanup-bgp-gw.pp +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-edge-router-cleanup-bgp-gw.pp') - - - file {'/etc/init/midonet-network.conf': - ensure => absent, - source => '/etc/fuel/plugins/midonet-9.2/puppet/files/startup.conf' - } diff --git a/deployment_scripts/puppet/manifests/midonet-edge-router-cleanup-bgp.pp b/deployment_scripts/puppet/manifests/midonet-edge-router-cleanup-bgp.pp deleted file mode 100644 index 461312f..0000000 --- a/deployment_scripts/puppet/manifests/midonet-edge-router-cleanup-bgp.pp +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-edge-router-cleanup-bgp.pp') - -include ::stdlib - -$old_config = loadyamlv2('/etc/fuel/cluster/astute.yaml.old','notfound') - -# If it's a redeploy and the file exists we can proceed -if($old_config != 'notfound') -{ - $old_gw_type = $old_config['midonet']['gateway_type'] - if ($old_gw_type == 'bgp') { - # Extract data from hiera - $access_data = $old_config['access'] - $management_address = hiera('management_vip') - $keystone_admin_tenant = $access_data['tenant'] - $net_metadata = $old_config['network_metadata'] - $gw_hash = get_nodes_hash_by_roles($net_metadata, ['midonet-gw']) - $gw_keys = keys($gw_hash) - $neutron_settings = $old_config['quantum_settings'] - $external_net_name = $neutron_settings['default_floating_net'] - $tenant_net_name = $neutron_settings['default_private_net'] - $predefined_nets = $neutron_settings['predefined_networks'] - $tenant_net = $predefined_nets[$tenant_net_name] - $external_net = $predefined_nets[$external_net_name] - - $username = $access_data['user'] - $password = $access_data['password'] - $tenant_name = $access_data['tenant'] - - # Plugin settings data (overrides $external_net l3 values) - $midonet_settings = $old_config['midonet'] - $tz_type = $midonet_settings['tunnel_type'] - $floating_range_start = $midonet_settings['floating_ip_range_start'] - $floating_range_end = $midonet_settings['floating_ip_range_end'] - $floating_cidr = $midonet_settings['floating_cidr'] - $floating_gateway_ip = $midonet_settings['gateway'] - $bgp_local_as = $midonet_settings['bgp_local_as'] - $bgp_neighbors = $midonet_settings['bgp_neighbors'] - - $edge_router = 'edge-router' - - $allocation_pools = "start=${floating_range_start},end=${floating_range_end}" - - $myhostname = $gw_keys[0] - - $ports_to_unbind = generate_router_interfaces_list($bgp_neighbors) - - - file { 'delete router interfaces script': - ensure => present, - path => '/tmp/delete_router_interfaces_bgp.sh', - content => template('/etc/fuel/plugins/midonet-9.2/puppet/templates/delete_router_interfaces_bgp.sh.erb'), - } - - # Finally, execute the script - exec { 'run delete router interfaces script': - command => '/bin/bash -x /tmp/delete_router_interfaces_bgp.sh 2>&1 | tee /tmp/ri-delete-bgp.out', - returns => ['0', '7'], - } - - $defaults_for_subnet = { - ensure => absent, - enable_dhcp => false, - network_name => 'edge-net', - tenant_id => $external_net['tenant'] - } - - create_resources('neutron_subnet', - generate_bgp_edge_subnet_hash($bgp_neighbors), - $defaults_for_subnet) - - $defaults_for_port = { - ensure => absent, - network_name => 'edge-net', - binding_host_id => $gw_hash[$gw_keys[0]]['fqdn'], - binding_profile => { - 'interface_name' => 'gw-veth-mn' - }, - } - - create_resources('neutron_port', - generate_bgp_edge_port_hash($bgp_neighbors), - $defaults_for_port) - - midonet_gateway_bgp { 'edge-router': - ensure => absent, - bgp_local_as_number => $bgp_local_as, - username => $username, - password => $password, - tenant_name => $tenant_name, - midonet_api_url => "http://${management_address}:8181/midonet-api", - bgp_advertised_networks => $floating_cidr, - bgp_neighbors => generate_bgp_neighbors_for_gateway_bgp($bgp_neighbors) - } - - File['delete router interfaces script'] - -> Exec['run delete router interfaces script'] - -> Neutron_subnet<||> - -> Neutron_port<||> - -> Midonet_gateway_bgp['edge-router'] - } - -} diff --git a/deployment_scripts/puppet/manifests/midonet-edge-router-setup-bgp-gw.pp b/deployment_scripts/puppet/manifests/midonet-edge-router-setup-bgp-gw.pp deleted file mode 100644 index a7a198e..0000000 --- a/deployment_scripts/puppet/manifests/midonet-edge-router-setup-bgp-gw.pp +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-edge-router-setup-bgp-gw.pp') - -include ::stdlib -# Extract data from hiera -$access_data = hiera_hash('access') -$management_address = hiera('management_vip') -$keystone_admin_tenant = $access_data['tenant'] -$net_metadata = hiera_hash('network_metadata') -$gw_hash = get_nodes_hash_by_roles($net_metadata, ['midonet-gw']) -$gw_keys = keys($gw_hash) -$neutron_settings = hiera('neutron_config') -$external_net_name = $neutron_settings['default_floating_net'] -$tenant_net_name = $neutron_settings['default_private_net'] -$predefined_nets = $neutron_settings['predefined_networks'] -$tenant_net = $predefined_nets[$tenant_net_name] -$external_net = $predefined_nets[$external_net_name] - -$username = $access_data['user'] -$password = $access_data['password'] -$tenant_name = $access_data['tenant'] - -# Plugin settings data (overrides $external_net l3 values) -$midonet_settings = hiera_hash('midonet') -$tz_type = $midonet_settings['tunnel_type'] -$floating_range_start = $midonet_settings['floating_ip_range_start'] -$floating_range_end = $midonet_settings['floating_ip_range_end'] -$floating_cidr = $midonet_settings['floating_cidr'] -$floating_gateway_ip = $midonet_settings['gateway'] -$bgp_local_as = $midonet_settings['bgp_local_as'] -$bgp_neighbors = $midonet_settings['bgp_neighbors'] - -$edge_router = 'edge-router' - -$allocation_pools = "start=${floating_range_start},end=${floating_range_end}" - -# Create one subnet per each network used. -$myhostname = $::fqdn - -$ports_to_bind = generate_router_interfaces_list($bgp_neighbors) - -package { 'python-neutronclient': - ensure => latest -} -> - -file { 'create router interfaces script': - ensure => present, - path => '/tmp/create_router_interfaces.sh', - content => template('/etc/fuel/plugins/midonet-9.2/puppet/templates/create_router_interfaces.sh.erb'), -} -> - -# Finally, execute the script -exec { 'run create router interfaces script': - command => '/bin/bash -x /tmp/create_router_interfaces.sh 2>&1 | tee /tmp/ri-create.out', - returns => ['0', '7'], -} -> - -midonet_gateway_bgp { 'edge-router': - ensure => present, - bgp_local_as_number => $bgp_local_as, - username => $username, - password => $password, - tenant_name => $tenant_name, - midonet_api_url => "http://${management_address}:8181/midonet-api", - bgp_advertised_networks => $floating_cidr, - bgp_neighbors => generate_bgp_neighbors_for_gateway_bgp($bgp_neighbors) -} diff --git a/deployment_scripts/puppet/manifests/midonet-edge-router-setup-bgp.pp b/deployment_scripts/puppet/manifests/midonet-edge-router-setup-bgp.pp deleted file mode 100644 index 856ff69..0000000 --- a/deployment_scripts/puppet/manifests/midonet-edge-router-setup-bgp.pp +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-edge-router-setup-bgp.pp') - -include ::stdlib -# Extract data from hiera -$access_data = hiera_hash('access') -$keystone_admin_tenant = $access_data['tenant'] -$net_metadata = hiera_hash('network_metadata') -$gw_hash = get_nodes_hash_by_roles($net_metadata, ['midonet-gw']) -$gw_keys = keys($gw_hash) -$neutron_settings = hiera('neutron_config') -$external_net_name = $neutron_settings['default_floating_net'] -$tenant_net_name = $neutron_settings['default_private_net'] -$predefined_nets = $neutron_settings['predefined_networks'] -$tenant_net = $predefined_nets[$tenant_net_name] -$external_net = $predefined_nets[$external_net_name] - -$username = $access_data['user'] -$password = $access_data['password'] -$tenant_name = $access_data['tenant'] - -# Plugin settings data (overrides $external_net l3 values) -$midonet_settings = hiera_hash('midonet') -$tz_type = $midonet_settings['tunnel_type'] -$floating_range_start = $midonet_settings['floating_ip_range_start'] -$floating_range_end = $midonet_settings['floating_ip_range_end'] -$floating_cidr = $midonet_settings['floating_cidr'] -$floating_gateway_ip = $midonet_settings['gateway'] -$bgp_local_as = $midonet_settings['bgp_local_as'] -$bgp_neighbors = $midonet_settings['bgp_neighbors'] - -$edge_router = 'edge-router' - -$allocation_pools = "start=${floating_range_start},end=${floating_range_end}" - -# Create one subnet per each network used. - -if size($gw_keys) < 1 { - fail('A Midonet Gateway node is required to run on BGP mode') -} - -$defaults_for_subnet = { - ensure => present, - enable_dhcp => false, - network_name => 'edge-net', - tenant_id => $external_net['tenant'] -} - -create_resources('neutron_subnet', - generate_bgp_edge_subnet_hash($bgp_neighbors), - $defaults_for_subnet) - -$defaults_for_port = { - ensure => present, - network_name => 'edge-net', - binding_host_id => $gw_hash[$gw_keys[0]]['fqdn'], - binding_profile => { - 'interface_name' => 'gw-veth-mn' - }, -} - -create_resources('neutron_port', - generate_bgp_edge_port_hash($bgp_neighbors), - $defaults_for_port) - - - -Neutron_subnet<||> --> Neutron_port<||> diff --git a/deployment_scripts/puppet/manifests/midonet-edge-router-setup-static-per-host.pp b/deployment_scripts/puppet/manifests/midonet-edge-router-setup-static-per-host.pp deleted file mode 100644 index 08fb0dd..0000000 --- a/deployment_scripts/puppet/manifests/midonet-edge-router-setup-static-per-host.pp +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-edge-router-setup-static-per-host.pp') - -include ::stdlib - -# Extract data from hiera -$access_data = hiera_hash('access') -$keystone_admin_tenant = $access_data['tenant'] -$net_metadata = hiera_hash('network_metadata') -$neutron_settings = hiera('neutron_config') -$external_net_name = $neutron_settings['default_floating_net'] -$tenant_net_name = $neutron_settings['default_private_net'] -$predefined_nets = $neutron_settings['predefined_networks'] -$tenant_net = $predefined_nets[$tenant_net_name] -$external_net = $predefined_nets[$external_net_name] - -# Plugin settings data (overrides $external_net l3 values) -$midonet_settings = hiera_hash('midonet') -$tz_type = $midonet_settings['tunnel_type'] -$floating_range_start = $midonet_settings['floating_ip_range_start'] -$floating_range_end = $midonet_settings['floating_ip_range_end'] -$floating_cidr = $midonet_settings['floating_cidr'] -$floating_gateway_ip = $midonet_settings['gateway'] -$bgp_subnets = $midonet_settings['bgp_cidr'] -$static_linux_bridge_ip_netl = $midonet_settings['static_linux_bridge_address'] -$static_fake_edge_router_ip_netl = $midonet_settings['static_fake_edge_router_address'] -$static_use_masquerade = $midonet_settings['static_use_masquerade'] - -$static_linux_bridge_ip_address = split($static_linux_bridge_ip_netl,'/') -$static_fake_edge_router_ip_address = split($static_fake_edge_router_ip_netl,'/') - -$allocation_pools = "start=${floating_range_start},end=${floating_range_end}" - -$gw_hash = get_nodes_hash_by_roles($net_metadata, ['midonet-gw']) -$gw_mgmt_ip_hash = get_node_to_ipaddr_map_by_network_role($gw_hash, 'management') -$gw_mgmt_ip_list = values($gw_mgmt_ip_hash) -$gw_keys = keys($gw_hash) - -$gw_fqdn = $gw_hash[$gw_keys[0]]['fqdn'] - -# Warning: The 0.0.0.0 is there just to get away with a bug in puppet-neutron. -# It doesnt get evaluated but forces the type to get the correct value -neutron_port { "port-static-${gw_fqdn}": - - ensure => present, - network_name => 'edge-net', - binding_host_id => $gw_fqdn, - binding_profile => { - 'interface_name' => 'veth1' - }, - ip_address => [[$static_fake_edge_router_ip_address[0]],['0.0.0.0']], -} diff --git a/deployment_scripts/puppet/manifests/midonet-edge-router-setup-static.pp b/deployment_scripts/puppet/manifests/midonet-edge-router-setup-static.pp deleted file mode 100644 index 5977474..0000000 --- a/deployment_scripts/puppet/manifests/midonet-edge-router-setup-static.pp +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-edge-router-setup-static.pp') - -include ::stdlib -# Extract data from hiera -$access_data = hiera_hash('access') -$keystone_admin_tenant = $access_data['tenant'] -$neutron_settings = hiera('neutron_config') -$external_net_name = $neutron_settings['default_floating_net'] -$tenant_net_name = $neutron_settings['default_private_net'] -$predefined_nets = $neutron_settings['predefined_networks'] -$tenant_net = $predefined_nets[$tenant_net_name] -$external_net = $predefined_nets[$external_net_name] - -# Plugin settings data (overrides $external_net l3 values) -$midonet_settings = hiera_hash('midonet') -$tz_type = $midonet_settings['tunnel_type'] -$floating_range_start = $midonet_settings['floating_ip_range_start'] -$floating_range_end = $midonet_settings['floating_ip_range_end'] -$floating_cidr = $midonet_settings['floating_cidr'] -$floating_gateway_ip = $midonet_settings['gateway'] -$static_linux_bridge_ip_netl = $midonet_settings['static_linux_bridge_address'] -$static_fake_edge_router_ip_netl = $midonet_settings['static_fake_edge_router_address'] -$static_use_masquerade = $midonet_settings['static_use_masquerade'] - -$static_linux_bridge_ip_address = split($static_linux_bridge_ip_netl,'/') -$static_fake_edge_router_ip_address = split($static_fake_edge_router_ip_netl,'/') - -$allocation_pools = "start=${floating_range_start},end=${floating_range_end}" - -package { 'python-neutronclient': - ensure => latest -} -> - -neutron_subnet { 'edge-subnet': - ensure => present, - enable_dhcp => false, - cidr => generate_cidr_from_ip_netlength($static_linux_bridge_ip_netl), - tenant_id => $external_net['tenant'], - network_name => 'edge-net', -} diff --git a/deployment_scripts/puppet/manifests/midonet-edge-router-setup.pp b/deployment_scripts/puppet/manifests/midonet-edge-router-setup.pp deleted file mode 100644 index 6b6c87f..0000000 --- a/deployment_scripts/puppet/manifests/midonet-edge-router-setup.pp +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-edge-router-setup.pp') - -# Extract data from hiera -$access_data = hiera_hash('access') -$keystone_admin_tenant = $access_data['tenant'] -$neutron_settings = hiera('neutron_config') -$external_net_name = $neutron_settings['default_floating_net'] -$tenant_net_name = $neutron_settings['default_private_net'] -$predefined_nets = $neutron_settings['predefined_networks'] -$tenant_net = $predefined_nets[$tenant_net_name] -$external_net = $predefined_nets[$external_net_name] - -# Plugin settings data (overrides $external_net l3 values) -$midonet_settings = hiera_hash('midonet') -$tz_type = $midonet_settings['tunnel_type'] -$floating_range_start = $midonet_settings['floating_ip_range_start'] -$floating_range_end = $midonet_settings['floating_ip_range_end'] -$floating_cidr = $midonet_settings['floating_cidr'] -$floating_gateway_ip = $midonet_settings['gateway'] - - -$allocation_pools = "start=${floating_range_start},end=${floating_range_end}" - -neutron_router { 'edge-router': - ensure => present, -} - -neutron_router_interface { "edge-router:${external_net_name}__subnet": - ensure => present, -} - -neutron_network { 'edge-net': - ensure => present, - tenant_id => $external_net['tenant'], - provider_network_type => 'uplink', -} diff --git a/deployment_scripts/puppet/manifests/midonet-enable-ip-forward.pp b/deployment_scripts/puppet/manifests/midonet-enable-ip-forward.pp deleted file mode 100644 index 163fffa..0000000 --- a/deployment_scripts/puppet/manifests/midonet-enable-ip-forward.pp +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-enable-ip.forward.pp') - -sysctl::value { 'net.ipv4.ip_forward': - value => '1' -} -> - -exec { 'load-sysctl': - command => '/sbin/sysctl -p /etc/sysctl.conf', - refreshonly => true -} diff --git a/deployment_scripts/puppet/manifests/midonet-ensure-rootwrap.pp b/deployment_scripts/puppet/manifests/midonet-ensure-rootwrap.pp deleted file mode 100644 index ffdbbbd..0000000 --- a/deployment_scripts/puppet/manifests/midonet-ensure-rootwrap.pp +++ /dev/null @@ -1,8 +0,0 @@ -if $::osfamily == 'Debian' { - - package { 'nova-network': - ensure => installed - } - -} - diff --git a/deployment_scripts/puppet/manifests/midonet-gateway-static-router-ifaces.pp b/deployment_scripts/puppet/manifests/midonet-gateway-static-router-ifaces.pp deleted file mode 100644 index 51976db..0000000 --- a/deployment_scripts/puppet/manifests/midonet-gateway-static-router-ifaces.pp +++ /dev/null @@ -1,56 +0,0 @@ - -notice('MODULAR: midonet-gateway-static-router-ifaces.pp') - -$management_address = hiera('management_vip') -$access_data = hiera_hash('access') -$username = $access_data['user'] -$password = $access_data['password'] -$tenant_name = $access_data['tenant'] - -$midonet_settings = hiera_hash('midonet') -$floating_cidr = $midonet_settings['floating_cidr'] -$f_net_cidr = split($midonet_settings['floating_cidr'], '/') - -$nodes_hash = hiera('nodes') -$node = filter_nodes($nodes_hash, 'fqdn', $::fqdn) -$gw_ip = $node[0]['public_address'] -$gw_mask = $node[0]['public_netmask'] -$net_hash = public_network_hash($gw_ip, $gw_mask) - -$static_linux_bridge_ip_netl = $midonet_settings['static_linux_bridge_address'] -$static_fake_edge_router_ip_netl = $midonet_settings['static_fake_edge_router_address'] -$static_use_masquerade = $midonet_settings['static_use_masquerade'] - -$static_linux_bridge_ip_address = split($static_linux_bridge_ip_netl,'/') -$static_fake_edge_router_ip_address = split($static_fake_edge_router_ip_netl,'/') - -$slbip_without_netl = $static_linux_bridge_ip_address[0] - -$net_metadata = hiera_hash('network_metadata') - -$gw_hash = get_nodes_hash_by_roles($net_metadata, ['midonet-gw']) -$gw_keys = keys($gw_hash) - -$gw_fqdn = $gw_hash[$gw_keys[0]]['fqdn'] - -$ports_to_bind = "port-static-${gw_fqdn}" - -$edge_router = 'edge-router' - -$myhostname = $::fqdn - -package { 'python-neutronclient': - ensure => latest -} -> - -file { 'create router interfaces script': - ensure => present, - path => '/tmp/create_router_interfaces_static.sh', - content => template('/etc/fuel/plugins/midonet-9.2/puppet/templates/create_router_interfaces_static.sh.erb'), -} -> - -# Finally, execute the script -exec { 'run create router interfaces script': - command => '/bin/bash -x /tmp/create_router_interfaces_static.sh 2>&1 | tee /tmp/ri-create.out', - returns => ['0', '7'], -} diff --git a/deployment_scripts/puppet/manifests/midonet-gateway-static.pp b/deployment_scripts/puppet/manifests/midonet-gateway-static.pp deleted file mode 100644 index 228275e..0000000 --- a/deployment_scripts/puppet/manifests/midonet-gateway-static.pp +++ /dev/null @@ -1,47 +0,0 @@ - -notice('MODULAR: midonet-gateway-static.pp') - -$management_address = hiera('management_vip') -$access_data = hiera_hash('access') -$username = $access_data['user'] -$password = $access_data['password'] -$tenant_name = $access_data['tenant'] - -$midonet_settings = hiera_hash('midonet') -$floating_cidr = $midonet_settings['floating_cidr'] -$f_net_cidr = split($midonet_settings['floating_cidr'], '/') - -$nodes_hash = hiera('nodes') -$node = filter_nodes($nodes_hash, 'fqdn', $::fqdn) -$gw_ip = $node[0]['public_address'] -$gw_mask = $node[0]['public_netmask'] -$net_hash = public_network_hash($gw_ip, $gw_mask) - -$static_linux_bridge_ip_netl = $midonet_settings['static_linux_bridge_address'] -$static_fake_edge_router_ip_netl = $midonet_settings['static_fake_edge_router_address'] -$static_use_masquerade = $midonet_settings['static_use_masquerade'] - -$static_linux_bridge_ip_address = split($static_linux_bridge_ip_netl,'/') -$static_fake_edge_router_ip_address = split($static_fake_edge_router_ip_netl,'/') - -$slbip_without_netl = $static_linux_bridge_ip_address[0] - -class { 'midonet::gateway::static': - nic => 'br-ex', - fip => $floating_cidr, - edge_router => 'edge-router', - veth0_ip => $static_linux_bridge_ip_address[0], - veth1_ip => $static_fake_edge_router_ip_address[0], - veth_network => generate_cidr_from_ip_netlength($static_linux_bridge_ip_netl), - scripts_dir => '/tmp', - uplink_script => 'create_fake_uplink_l2.sh', - ensure_scripts => 'present', - masquerade => $static_use_masquerade? {true => 'on' ,default => 'off' } -} -contain ::midonet::gateway::static - -file {'/etc/init/midonet-network-static.conf': - ensure => present, - source => '/etc/fuel/plugins/midonet-9.2/puppet/files/startup-static.conf', - require => Exec['run gateway static creation script'] -} diff --git a/deployment_scripts/puppet/manifests/midonet-generate-openrc-for-gw.pp b/deployment_scripts/puppet/manifests/midonet-generate-openrc-for-gw.pp deleted file mode 100644 index 5d278e9..0000000 --- a/deployment_scripts/puppet/manifests/midonet-generate-openrc-for-gw.pp +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2015 Midokura SARL. -# -# 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. -notice('MODULAR: midonet-generate-openrc-for-gw.pp') - -$access_hash = hiera_hash('access', {}) -$keystone_hash = hiera_hash('keystone', {}) -$admin_tenant = $access_hash['tenant'] -$admin_email = $access_hash['email'] -$admin_user = $access_hash['user'] -$admin_password = $access_hash['password'] -$ssl_hash = hiera_hash('use_ssl', {}) -$management_vip = hiera('management_vip') -$service_endpoint = hiera('service_endpoint', $management_vip) -$internal_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'protocol', 'http') -$internal_address = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'hostname', [$service_endpoint, $management_vip]) -$internal_port = '5000' -$internal_url = "${internal_protocol}://${internal_address}:${internal_port}" -$region = hiera('region', 'RegionOne') -$auth_suffix = pick($keystone_hash['auth_suffix'], '/') -$auth_url = "${internal_url}${auth_suffix}" - - -$murano_settings_hash = hiera_hash('murano_settings', {}) -if has_key($murano_settings_hash, 'murano_repo_url') { - $murano_repo_url = $murano_settings_hash['murano_repo_url'] -} else { - $murano_repo_url = 'http://storage.apps.openstack.org' -} - -$murano_hash = hiera_hash('murano', {}) -$murano_plugins = pick($murano_hash['plugins'], {}) -if has_key($murano_plugins, 'glance_artifacts_plugin') { - $murano_glare_plugin = $murano_plugins['glance_artifacts_plugin']['enabled'] -} else { - $murano_glare_plugin = false -} - -osnailyfacter::credentials_file { '/root/openrc': - admin_user => $admin_user, - admin_password => $admin_password, - admin_tenant => $admin_tenant, - region_name => $region, - auth_url => $auth_url, - murano_repo_url => $murano_repo_url, - murano_glare_plugin => $murano_glare_plugin, -} diff --git a/deployment_scripts/puppet/manifests/midonet-horizon-lb-firewall.pp b/deployment_scripts/puppet/manifests/midonet-horizon-lb-firewall.pp deleted file mode 100644 index a787602..0000000 --- a/deployment_scripts/puppet/manifests/midonet-horizon-lb-firewall.pp +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-horizon-lb-firewall.pp') -include ::stdlib - -service { 'apache2': - ensure => running, - enable => true, - hasrestart => true, - hasstatus => true, -} - -file_line { 'firewall enable horizon': - path => '/etc/openstack-dashboard/local_settings.py', - line => " 'enable_firewall': True,", - match => '^\ \ \ \ \'enable_firewall.*$', -} -> - -file_line { 'lb enable horizon': - path => '/etc/openstack-dashboard/local_settings.py', - line => " 'enable_lb': True,", - match => '^\ \ \ \ \'enable_lb.*$', - notify => Service['apache2'] -} diff --git a/deployment_scripts/puppet/manifests/midonet-host-registry.pp b/deployment_scripts/puppet/manifests/midonet-host-registry.pp deleted file mode 100644 index 459caaf..0000000 --- a/deployment_scripts/puppet/manifests/midonet-host-registry.pp +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2015 Midokura SARL. -# -# 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. -notice('MODULAR: midonet-host-registry.pp') - -# Extract data from hiera -$api_ip = hiera('management_vip') -$access_data = hiera_hash('access') -$username = $access_data['user'] -$password = $access_data['password'] -$tenant_name = $access_data['tenant'] - -# Plugin settings data -$midonet_settings = hiera_hash('midonet') -$tz_type = $midonet_settings['tunnel_type'] - -$service_path = $operatingsystem ? { - 'CentOS' => '/sbin', - 'Ubuntu' => '/usr/bin:/usr/sbin:/sbin' -} - -# Somehow, there are times where the hosts don't register -# to NSDB. Restarting midolman forces the registration -exec {'service midolman restart': - path => $service_path -} -> - -midonet_host_registry {$::fqdn: - ensure => present, - midonet_api_url => "http://${api_ip}:8181", - username => $username, - password => $password, - tenant_name => $tenant_name, - underlay_ip_address => $::ipaddress_br_mesh, - tunnelzone_type => $tz_type, - tunnelzone_name => 'tzonefuel' -} diff --git a/deployment_scripts/puppet/manifests/midonet-install-agent.pp b/deployment_scripts/puppet/manifests/midonet-install-agent.pp deleted file mode 100644 index 704331c..0000000 --- a/deployment_scripts/puppet/manifests/midonet-install-agent.pp +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-install-agent.pp') - -# Extract data from hiera -$midonet_settings = hiera('midonet') -$net_metadata = hiera_hash('network_metadata') -$neutron_config = hiera_hash('quantum_settings') -$segmentation_type = $neutron_config['L2']['segmentation_type'] -$nsdb_hash = get_nodes_hash_by_roles($net_metadata, ['nsdb']) -$nsdb_mgmt_ips = get_node_to_ipaddr_map_by_network_role($nsdb_hash, 'management') -$zoo_ips_hash = generate_api_zookeeper_ips(values($nsdb_mgmt_ips)) -$api_ip = hiera('management_vip') -$access_data = hiera_hash('access') -$username = $access_data['user'] -$password = $access_data['password'] -$tenant_name = $access_data['tenant'] -$mem = $midonet_settings['mem'] -$mem_user = $midonet_settings['mem_repo_user'] -$mem_password = $midonet_settings['mem_repo_password'] -$metadata_hash = hiera_hash('quantum_settings', {}) -$metadata_secret = pick($metadata_hash['metadata']['metadata_proxy_shared_secret'], 'root') - - -$ovsdb_service_name = $operatingsystem ? { - 'CentOS' => 'openvswitch', - 'Ubuntu' => 'openvswitch-switch' -} - -$openvswitch_package_neutron = $operatingsystem ? { - 'CentOS' => 'openstack-neutron-openvswitch', - 'Ubuntu' => 'neutron-plugin-openvswitch-agent' -} - -$openvswitch_package = $operatingsystem ? { - 'CentOS' => 'openvswitch', - 'Ubuntu' => 'openvswitch-switch' -} - -package {$openvswitch_package_neutron: - ensure => purged -} -> - -package {$openvswitch_package: - ensure => purged -} -> - -class {'::midonet::agent': - zookeeper_hosts => $zoo_ips_hash, - is_mem => $mem, - mem_username => $mem_user, - mem_password => $mem_password, - metadata_port => '8775', - shared_secret => $metadata_secret, - controller_host => $api_ip -} -> - -class {'::midonet::cli': - api_endpoint => "http://${api_ip}:8181/midonet-api", - username => $username, - password => $password, - tenant_name => $tenant_name, -} - -# Firewall rule to allow the udp port used for vxlan tunnelling of overlay -# traffic from midolman hosts to other midolman hosts. - -class { 'firewall': } - -if $segmentation_type =='tun' { - firewall {'6677 vxlan port': - port => '6677', - proto => 'udp', - action => 'accept', - } -} - -exec {'/usr/bin/mm-dpctl --delete-dp ovs-system': - path => '/usr/bin:/usr/sbin:/bin', - onlyif => '/usr/bin/mm-dpctl --show-dp ovs-system', - require => Class['::midonet::agent'] -} diff --git a/deployment_scripts/puppet/manifests/midonet-install-analytics.pp b/deployment_scripts/puppet/manifests/midonet-install-analytics.pp deleted file mode 100644 index 197fa21..0000000 --- a/deployment_scripts/puppet/manifests/midonet-install-analytics.pp +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-install-analytics.pp') -include ::stdlib - -# Extract data from hiera -$ssl_hash = hiera_hash('use_ssl', {}) - -$midonet_settings = hiera('midonet') -$net_metadata = hiera_hash('network_metadata') -$controllers_map = get_nodes_hash_by_roles($net_metadata, ['controller', 'primary-controller']) -$controllers_mgmt_ips = get_node_to_ipaddr_map_by_network_role($controllers_map, 'management') -$nsdb_hash = get_nodes_hash_by_roles($net_metadata, ['nsdb']) -$nsdb_mgmt_ips = get_node_to_ipaddr_map_by_network_role($nsdb_hash, 'management') -$zoo_ips_hash = generate_api_zookeeper_ips(values($nsdb_mgmt_ips)) -$management_vip = hiera('management_vip') -$public_vip = hiera('public_vip') -$keystone_data = hiera_hash('keystone') -$access_data = hiera_hash('access') -$public_ssl_hash = hiera('public_ssl') -$cass_ips = values($nsdb_mgmt_ips) -$mem = $midonet_settings['mem'] -$admin_identity_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'protocol', 'http') -$metadata_hash = hiera_hash('quantum_settings', {}) -$metadata_secret = pick($metadata_hash['metadata']['metadata_proxy_shared_secret'], 'root') - -$ana_hash = get_nodes_hash_by_roles($net_metadata, ['midonet-analytics']) -$ana_mgmt_ip_hash = get_node_to_ipaddr_map_by_network_role($ana_hash, 'management') -$ana_mgmt_ip_list = values($ana_mgmt_ip_hash) -$ana_keys = keys($ana_hash) - -$ana_mgmt_ip = empty($ana_keys)? {true => $public_vip , default => $ana_mgmt_ip_list[0] } - -$midonet_version = $midonet_settings['midonet_version'] - -$nodes_hash = hiera('nodes') -$node = filter_nodes($nodes_hash, 'fqdn', $::fqdn) -$priv_ip = $node[0]['internal_address'] -$priv_netmask = $node[0]['internal_netmask'] -$pub_ip = $node[0]['public_address'] -#Add MEM analytics class -class {'midonet::analytics': - zookeeper_hosts => $zoo_ips_hash, - is_mem => true, - manage_repo => false, - heap_size_gb => '3', - midonet_version => $midonet_version, - elk_bind_ip => $priv_ip, - elk_hosts => $ana_mgmt_ip_list -} - -class { 'firewall': } - -firewall {'507 Midonet elk 1': - port => '9200', - proto => 'tcp', - action => 'accept', -} - -firewall {'508 Midonet clio': - port => '5000', - proto => 'tcp', - action => 'accept', -} - -firewall {'509 Midonet flow history': - port => '5001', - proto => 'tcp', - action => 'accept', -} - -firewall {'520 Midonet elk 2': - port => '9300', - proto => 'tcp', - action => 'accept', -} - -firewall {'520 Midonet elk 3': - port => '5005', - proto => 'tcp', - action => 'accept', -} diff --git a/deployment_scripts/puppet/manifests/midonet-install-cluster.pp b/deployment_scripts/puppet/manifests/midonet-install-cluster.pp deleted file mode 100644 index 41b1f1b..0000000 --- a/deployment_scripts/puppet/manifests/midonet-install-cluster.pp +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-install-cluster.pp') -# Extract data from hiera -$ssl_hash = hiera_hash('use_ssl', {}) -$midonet_settings = hiera('midonet') -$net_metadata = hiera_hash('network_metadata') -$controllers_map = get_nodes_hash_by_roles($net_metadata, ['controller', 'primary-controller']) -$controllers_mgmt_ips = get_node_to_ipaddr_map_by_network_role($controllers_map, 'management') -$nsdb_hash = get_nodes_hash_by_roles($net_metadata, ['nsdb']) -$nsdb_mgmt_ips = get_node_to_ipaddr_map_by_network_role($nsdb_hash, 'management') -$zoo_ips_hash = generate_api_zookeeper_ips(values($nsdb_mgmt_ips)) -$management_vip = hiera('management_vip') -$public_vip = hiera('public_vip') -$keystone_data = hiera_hash('keystone') -$access_data = hiera_hash('access') -$public_ssl_hash = hiera('public_ssl') -$cass_ips = values($nsdb_mgmt_ips) -$mem = $midonet_settings['mem'] -$admin_identity_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'protocol', 'http') -$metadata_hash = hiera_hash('quantum_settings', {}) -$metadata_secret = pick($metadata_hash['metadata']['metadata_proxy_shared_secret'], 'root') -$ana_hash = get_nodes_hash_by_roles($net_metadata, ['midonet-analytics']) -$ana_mgmt_ip_hash = get_node_to_ipaddr_map_by_network_role($ana_hash, 'management') -$ana_mgmt_ip_list = values($ana_mgmt_ip_hash) -$ana_keys = keys($ana_hash) -$ana_mgmt_ip = empty($ana_keys)? {true => $public_vip , default => $ana_mgmt_ip_list[0] } -$insights = $midonet_settings['mem_insights'] - -$midonet_version = $midonet_settings['midonet_version'] - -$nodes_hash = hiera('nodes') -$node = filter_nodes($nodes_hash, 'fqdn', $::fqdn) -$priv_ip = $node[0]['internal_address'] -$priv_netmask = $node[0]['internal_netmask'] -$pub_ip = $node[0]['public_address'] - - -include ::stdlib -class {'::midonet::cluster': - is_mem => $mem, - zookeeper_hosts => $zoo_ips_hash, - cassandra_servers => $cass_ips, - cassandra_rep_factor => size($nsdb_hash), - keystone_host => $management_vip, - keystone_admin_token => $keystone_data['admin_token'], - keystone_tenant_name => $access_data['tenant'], - keystone_protocol => $admin_identity_protocol, - cluster_port => '8181', - is_insights => $insights, - analytics_ip => $ana_mgmt_ip, - max_heap_size => '2048M', - heap_newsize => '1024M', - midonet_version => $midonet_version, - endpoint_host => $priv_ip, - endpoint_port => '8999', - elk_seeds => join($ana_mgmt_ip_list,','), - elk_target_endpoint => generate_cidr_from_ip_netlength("${priv_ip} ${priv_netmask}"), - jarvis_enabled => false, - state_proxy_address => $priv_ip -} -# HA proxy configuration -Haproxy::Service { use_include => true } -Haproxy::Balancermember { use_include => true } -Openstack::Ha::Haproxy_service { - server_names => keys($controllers_mgmt_ips), - ipaddresses => values($controllers_mgmt_ips), - public_virtual_ip => $public_vip, - internal_virtual_ip => $management_vip, -} -openstack::ha::haproxy_service { 'midonetcluster': - order => 199, - listen_port => 8181, - balancermember_port => 8181, - define_backups => true, - before_start => true, - public => true, - haproxy_config_options => { - 'balance' => 'roundrobin', - 'option' => ['httplog'], - }, - balancermember_options => 'check', -} -exec { 'haproxy reload': - command => 'export OCF_ROOT="/usr/lib/ocf"; (ip netns list | grep haproxy) && ip netns exec haproxy /usr/lib/ocf/resource.d/fuel/ns_haproxy reload', - path => '/usr/bin:/usr/sbin:/bin:/sbin', - logoutput => true, - provider => 'shell', - tries => 10, - try_sleep => 10, - returns => [0, ''], -} -Haproxy::Listen <||> -> Exec['haproxy reload'] -Haproxy::Balancermember <||> -> Exec['haproxy reload'] -class { 'firewall': } -firewall {'502 Midonet cluster': - port => '8181', - proto => 'tcp', - action => 'accept', -} - -firewall {'503 Midonet cluster state proxy': - port => '2346', - proto => 'tcp', - action => 'accept', -} - -firewall {'511 Midonet cluster unified endpoint': - port => '8999', - proto => 'tcp', - action => 'accept', -} - -firewall {'521 Midonet flow history': - port => '5001', - proto => 'tcp', - action => 'accept', -} diff --git a/deployment_scripts/puppet/manifests/midonet-install-haveged.pp b/deployment_scripts/puppet/manifests/midonet-install-haveged.pp deleted file mode 100644 index ab3c206..0000000 --- a/deployment_scripts/puppet/manifests/midonet-install-haveged.pp +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-install-haveged.pp') - -package { 'haveged': - ensure => present, -} diff --git a/deployment_scripts/puppet/manifests/midonet-install-java8.pp b/deployment_scripts/puppet/manifests/midonet-install-java8.pp deleted file mode 100644 index 2d9674c..0000000 --- a/deployment_scripts/puppet/manifests/midonet-install-java8.pp +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-install-java8.pp') - -class { '::midonet_openstack::profile::midojava::midojava': -} diff --git a/deployment_scripts/puppet/manifests/midonet-install-mem.pp b/deployment_scripts/puppet/manifests/midonet-install-mem.pp deleted file mode 100644 index 4870ce2..0000000 --- a/deployment_scripts/puppet/manifests/midonet-install-mem.pp +++ /dev/null @@ -1,273 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-install-mem.pp') -include ::stdlib -# Extract data from hiera -$ssl_hash = hiera_hash('use_ssl', {}) -$midonet_settings = hiera('midonet') -$net_metadata = hiera_hash('network_metadata') -$controllers_map = get_nodes_hash_by_roles($net_metadata, ['controller', 'primary-controller']) -$controllers_mgmt_ips = get_node_to_ipaddr_map_by_network_role($controllers_map, 'management') -$nsdb_hash = get_nodes_hash_by_roles($net_metadata, ['nsdb']) -$nsdb_mgmt_ips = get_node_to_ipaddr_map_by_network_role($nsdb_hash, 'management') -$zoo_ips_hash = generate_api_zookeeper_ips(values($nsdb_mgmt_ips)) -$management_vip = hiera('management_vip') -$public_vip = hiera('public_vip') -$keystone_data = hiera_hash('keystone') -$access_data = hiera_hash('access') -$public_ssl_hash = hiera('public_ssl') -$cass_ips = values($nsdb_mgmt_ips) -$mem = $midonet_settings['mem'] -$admin_identity_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'protocol', 'http') -$metadata_hash = hiera_hash('quantum_settings', {}) -$metadata_secret = pick($metadata_hash['metadata']['metadata_proxy_shared_secret'], 'root') -$ana_hash = get_nodes_hash_by_roles($net_metadata, ['midonet-analytics']) -$ana_mgmt_ip_hash = get_node_to_ipaddr_map_by_network_role($ana_hash, 'management') -$ana_mgmt_ip_list = values($ana_mgmt_ip_hash) -$ana_keys = keys($ana_hash) -$ana_mgmt_ip = empty($ana_keys)? {true => $public_vip , default => $ana_mgmt_ip_list[0] } -$ssl_horizon = $public_ssl_hash['horizon'] -$is_insights = $midonet_settings['mem_insights'] - -$midonet_version = $midonet_settings['midonet_version'] -$new_api = versioncmp($midonet_version,'5.2') ? {'1' => true, default => false} - -service { 'apache2': - ensure => running, - enable => true, - hasrestart => true, - hasstatus => true, -} -#Add MEM manager class -class {'midonet::mem': - cluster_ip => $public_vip, - analytics_ip => $public_vip, - is_insights => $is_insights, - mem_api_port => '', - mem_trace_port => '', - mem_analytics_port => '', - mem_subscription_port => '', - mem_fabric_port => '', -} - - - -if ($public_ssl_hash['horizon']) -{ - exec { 'https override': - command => "sed -i 's/http:/https:/g' /var/www/html/midonet-manager/config/client.js", - path => '/usr/bin:/usr/sbin:/bin:/sbin', - logoutput => true, - provider => 'shell', - tries => 10, - try_sleep => 10, - returns => [0, ''], - require => File['midonet-manager-config'] - } - exec { 'wss override': - command => "sed -i 's/ws:/wss:/g' /var/www/html/midonet-manager/config/client.js", - path => '/usr/bin:/usr/sbin:/bin:/sbin', - logoutput => true, - provider => 'shell', - tries => 10, - try_sleep => 10, - returns => [0, ''], - require => File['midonet-manager-config'] - } -} -else { - exec { 'wss override': - command => "sed -i 's/wss:/ws:/g' /var/www/html/midonet-manager/config/client.js", - path => '/usr/bin:/usr/sbin:/bin:/sbin', - logoutput => true, - provider => 'shell', - tries => 10, - try_sleep => 10, - returns => [0, ''], - require => File['midonet-manager-config'] - } -} - exec { 'a2enmod headers': - path => '/usr/bin:/usr/sbin:/bin', - alias => 'enable-mod-headers', - creates => '/etc/apache2/mods-enabled/headers.load', - notify => Service['apache2'], - tag => 'a2enmod-mem' - } - exec { 'a2enmod proxy': - path => '/usr/bin:/usr/sbin:/bin', - alias => 'enable-mod-proxy', - creates => '/etc/apache2/mods-enabled/proxy.load', - notify => Service['apache2'], - tag => 'a2enmod-mem' - } - exec { 'a2enmod proxy_http': - path => '/usr/bin:/usr/sbin:/bin', - alias => 'enable-mod-proxy-http', - creates => '/etc/apache2/mods-enabled/proxy_http.load', - notify => Service['apache2'], - tag => 'a2enmod-mem' - } - exec { 'a2enmod proxy_wstunnel': - path => '/usr/bin:/usr/sbin:/bin', - alias => 'enable-mod-proxy-wstunnel', - creates => '/etc/apache2/mods-enabled/proxy_wstunnel.load', - notify => Service['apache2'], - tag => 'a2enmod-mem' - } - exec { 'a2enmod ssl': - path => '/usr/bin:/usr/sbin:/bin', - alias => 'enable-mod-ssl', - creates => '/etc/apache2/mods-enabled/ssl.load', - notify => Service['apache2'], - tag => 'a2enmod-mem' - } -file { 'mem-vhost': - ensure => present, - path => '/etc/apache2/sites-available/30-midonet-mem.conf', - content => template('/etc/fuel/plugins/midonet-9.2/puppet/templates/vhost_mem_manager.erb'), -} -exec { 'a2ensite 30-midonet-mem': - path => '/usr/bin:/usr/sbin:/bin', - alias => 'enable-mem-vhost', - creates => '/etc/apache2/sites-enabled/30-midonet-mem.conf', - notify => Service['apache2'], -} -Exec<| tag == 'a2enmod-mem' |> --> File['mem-vhost'] --> Exec['a2ensite 30-midonet-mem'] -if ($is_insights) -{ - if($new_api) - { - Haproxy::Service { use_include => true } - Haproxy::Balancermember { use_include => true } - Openstack::Ha::Haproxy_service { - server_names => keys($controllers_mgmt_ips), - ipaddresses => values($controllers_mgmt_ips), - public_virtual_ip => $public_vip, - internal_virtual_ip => $management_vip, - } - openstack::ha::haproxy_service { 'midonetunified': - order => 200, - listen_port => 8999, - balancermember_port => 8999, - define_backups => true, - before_start => true, - public => true, - haproxy_config_options => { - 'balance' => 'roundrobin', - 'option' => ['httplog'], - }, - balancermember_options => 'check', - } - class { 'firewall': } - firewall {'504 Midonet Unified Endpoint': - port => '8999', - proto => 'tcp', - action => 'accept', - } - } - else - { - Haproxy::Service { use_include => true } - Haproxy::Balancermember { use_include => true } - Openstack::Ha::Haproxy_service { - server_names => keys($controllers_mgmt_ips), - ipaddresses => values($controllers_mgmt_ips), - public_virtual_ip => $public_vip, - internal_virtual_ip => $management_vip, - } - openstack::ha::haproxy_service { 'midonetsubscriptions': - order => 200, - listen_port => 8007, - balancermember_port => 8007, - define_backups => true, - before_start => true, - public => true, - haproxy_config_options => { - 'balance' => 'roundrobin', - 'option' => ['httplog'], - }, - balancermember_options => 'check', - } - openstack::ha::haproxy_service { 'midonettrace': - order => 201, - listen_port => 8460, - balancermember_port => 8460, - define_backups => true, - before_start => true, - public => true, - haproxy_config_options => { - 'balance' => 'roundrobin', - 'option' => ['httplog'], - }, - balancermember_options => 'check', - } - openstack::ha::haproxy_service { 'midonetfabric': - order => 202, - listen_port => 8009, - balancermember_port => 8009, - define_backups => true, - before_start => true, - public => true, - haproxy_config_options => { - 'balance' => 'roundrobin', - 'option' => ['httplog'], - }, - balancermember_options => 'check', - } - class { 'firewall': } - firewall {'504 Midonet subscription': - port => '8007', - proto => 'tcp', - action => 'accept', - } - firewall {'505 Midonet trace': - port => '8460', - proto => 'tcp', - action => 'accept', - } - firewall {'506 Midonet fabric': - port => '8009', - proto => 'tcp', - action => 'accept', - } - } - # HA proxy configuration - - file_line { 'Update tunnel timeout on haproxy': - path => '/etc/haproxy/haproxy.cfg', - line => ' timeout tunnel 3600s', - after => ' timeout check' - } - - exec { 'haproxy reload': - command => 'export OCF_ROOT="/usr/lib/ocf"; (ip netns list | grep haproxy) && ip netns exec haproxy /usr/lib/ocf/resource.d/fuel/ns_haproxy reload', - path => '/usr/bin:/usr/sbin:/bin:/sbin', - logoutput => true, - provider => 'shell', - tries => 10, - try_sleep => 10, - returns => [0, ''], - } - Haproxy::Listen <||> -> - File_line['Update tunnel timeout on haproxy'] -> - Exec['haproxy reload'] - - Haproxy::Balancermember <||> -> - File_line['Update tunnel timeout on haproxy'] -> - Exec['haproxy reload'] - -} diff --git a/deployment_scripts/puppet/manifests/midonet-mem-horizon-override.pp b/deployment_scripts/puppet/manifests/midonet-mem-horizon-override.pp deleted file mode 100644 index 5b49b35..0000000 --- a/deployment_scripts/puppet/manifests/midonet-mem-horizon-override.pp +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-mem-horizon-override.pp') -include ::stdlib - -service { 'apache2': - ensure => running, - enable => true, - hasrestart => true, - hasstatus => true, -} - -file_line { 'vhost horizon start': - ensure => absent, - path => '/etc/apache2/sites-enabled/horizon_vhost.conf', - line => '# disabled by puppet', - match => '^\ true, - replace => false -} -> - -file_line { 'dont aggresively redirect horizon': - ensure => absent, - path => '/etc/apache2/sites-enabled/horizon_vhost.conf', - line => '# disabled by puppet', - match => '^\ \ RedirectMatch.*', - match_for_absence => true, - replace => false -} -> - -file_line { 'dont set servername again for horizon': - ensure => absent, - path => '/etc/apache2/sites-enabled/horizon_vhost.conf', - line => '# disabled by puppet', - match => '^\ \ ServerName.*', - match_for_absence => true, - replace => false -} -> - -file_line { 'dont set serveralias again for horizon': - ensure => absent, - path => '/etc/apache2/sites-enabled/horizon_vhost.conf', - line => '# disabled by puppet', - match => '^\ \ ServerAlias.*', - match_for_absence => true, - replace => false -} -> - -file_line { 'remove closing horizon vhost': - ensure => absent, - path => '/etc/apache2/sites-enabled/horizon_vhost.conf', - line => '# disabled by puppet', - match => '^\<\/VirtualHost.*', - match_for_absence => true, - replace => false, - notify => Service['apache2'] -} -> - -file { '/var/www/html/index.html': - ensure => absent - } diff --git a/deployment_scripts/puppet/manifests/midonet-neutron-configure.pp b/deployment_scripts/puppet/manifests/midonet-neutron-configure.pp deleted file mode 100644 index 7433ee2..0000000 --- a/deployment_scripts/puppet/manifests/midonet-neutron-configure.pp +++ /dev/null @@ -1,161 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-neutron-configure.pp') - -# Neutron data -$amqp_port = '5673' -$rabbit_hash = hiera('rabbit', {}) -$management_vip = hiera('management_vip') -$service_endpoint = hiera('service_endpoint', $management_vip) -$neutron_config = hiera('quantum_settings') -$neutron_db_password = $neutron_config['database']['passwd'] -$neutron_user_password = $neutron_config['keystone']['admin_password'] - -$neutron_username = pick($neutron_config['keystone']['admin_user'], 'neutron') -$neutron_project_name = pick($neutron_config['keystone']['admin_tenant'], 'services') -$region_name = hiera('region', 'RegionOne') -$auth_endpoint_type = 'internalURL' - -$ssl_hash = hiera_hash('use_ssl', {}) - -$internal_auth_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'protocol', 'http') -$internal_auth_endpoint = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'hostname', [$service_endpoint, $management_vip]) - -# Neutron plugin data -$access_data = hiera_hash('access') -$username = $access_data['user'] -$password = $access_data['password'] -$tenant_name = $access_data['tenant'] - -$openstack_network_hash = hiera_hash('openstack_network', { }) -$use_syslog = hiera('use_syslog', true) -$use_stderr = hiera('use_stderr', false) -$verbose = pick($openstack_network_hash['verbose'], hiera('verbose', true)) - -$primary_ctrl = hiera('primary_controller') - - -# Unfortunately, core_plugin in the 'openstack-network-common-config' -# task is hardcoded. The core_plugin value for midonet is overrided -# in hiera file, so running again class{'::neutron'} should modify -# the core_plugin value in /etc/neutron/neutron.conf. -# Same goes for service_plugins -# -# Hoping that Fuel will make the core plugin configurable and we -# can remove this step -class {'::neutron': - verbose => $verbose, - debug => false, - use_syslog => $use_syslog, - use_stderr => $use_stderr, - log_facility => 'LOG_USER', - base_mac => 'fa:16:3e:00:00:00', - allow_overlapping_ips => true, - mac_generation_retries => '32', - dhcp_agent_notification => false, - report_interval => '10', - rabbit_user => $rabbit_hash['user'], - rabbit_host => ['localhost'], - rabbit_hosts => split(hiera('amqp_hosts', ''), ','), - rabbit_port => '5672', - rabbit_password => $rabbit_hash['password'], - kombu_reconnect_delay => '5.0', - network_device_mtu => undef, - advertise_mtu => true -} -> - -# NOTE: Don't comment these lines. Since we have changed the name -# of the package, we are trying to get rid of this restriction: -# https://github.com/openstack/puppet-neutron/blob/7.0.0/manifests/plugins/midonet.pp#L108 -package {'python-neutron-plugin-midonet': - ensure => absent -} - -file {'/etc/default/neutron-server': - ensure => present, - owner => 'root', - group => 'root', - mode => '0644' -} -> -class { '::midonet::neutron_plugin': - midonet_api_ip => $service_endpoint, - midonet_api_port => '8181', - keystone_username => $username, - keystone_password => $password, - keystone_tenant => $tenant_name, - sync_db => $primary_ctrl ? {true => true,default => false}, - } - - -class { '::neutron::server': - sync_db => $primary_ctrl ? {true => 'primary',default => 'slave'}, - - username => $neutron_username, - password => $neutron_user_password, - - auth_uri => "${internal_auth_protocol}://${internal_auth_endpoint}:5000/", - auth_url => "${internal_auth_protocol}://${internal_auth_endpoint}:35357/", - - region_name => $region_name, - project_name => $neutron_project_name, - - database_retry_interval => 2, - database_connection => "mysql://${neutron_username}:${neutron_db_password}@${service_endpoint}/neutron?&read_timeout=60", - database_max_retries => -1, - - agent_down_time => 15, - - api_workers => min($::processorcount + 0, 50 + 0), - rpc_workers => 0, -} - -if !defined(Neutron_config['service_providers/service_provider']) -{ -# The version of puppet-neutron included in Fuel 9 doesnt allow passing in service_providers option -# so let's override it directly - neutron_config { - 'service_providers/service_provider': value => ['LOADBALANCER:Midonet:midonet.neutron.services.loadbalancer.driver.MidonetLoadbalancerDriver:default'] - } - Class['::midonet::neutron_plugin'] -> Neutron_config['service_providers/service_providers'] -> Service['neutron-server'] -} - -Neutron_config<| title == 'service_providers/service_provider' |> { - value => ['LOADBALANCER:Midonet:midonet.neutron.services.loadbalancer.driver.MidonetLoadbalancerDriver:default'] -} - - -# Nova notifications needed data -$nova_endpoint = hiera('nova_endpoint', $management_vip) -$nova_hash = hiera_hash('nova', {}) -$nova_internal_protocol = get_ssl_property($ssl_hash, {}, 'nova', 'internal', 'protocol', 'http') -$nova_internal_endpoint = get_ssl_property($ssl_hash, {}, 'nova', 'internal', 'hostname', [$nova_endpoint]) -$admin_auth_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'protocol', 'http') -$admin_auth_endpoint = get_ssl_property($ssl_hash, {}, 'keystone', 'admin', 'hostname', [$service_endpoint, $management_vip]) - -# Actual attributes -$nova_url = "${nova_internal_protocol}://${nova_internal_endpoint}:8774/v2" -$nova_admin_auth_url = "${admin_auth_protocol}://${admin_auth_endpoint}:35357/" -$nova_auth_user = pick($nova_hash['user'], 'nova') -$nova_auth_tenant = pick($nova_hash['tenant'], 'services') -$nova_auth_password = $nova_hash['user_password'] -$auth_region = hiera('region', 'RegionOne') - -class { 'neutron::server::notifications': - nova_url => $nova_url, - auth_url => $nova_admin_auth_url, - username => $nova_auth_user, - tenant_name => $nova_auth_tenant, - password => $nova_auth_password, - region_name => $auth_region, -} diff --git a/deployment_scripts/puppet/manifests/midonet-neutron-networks.pp b/deployment_scripts/puppet/manifests/midonet-neutron-networks.pp deleted file mode 100644 index 9448ba6..0000000 --- a/deployment_scripts/puppet/manifests/midonet-neutron-networks.pp +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-neutron-networks.pp') - -# Extract data from hiera -$access_data = hiera_hash('access') -$keystone_admin_tenant = $access_data['tenant'] -$net_metadata = hiera_hash('network_metadata') -$neutron_settings = hiera('neutron_config') -$external_net_name = $neutron_settings['default_floating_net'] -$tenant_net_name = $neutron_settings['default_private_net'] -$predefined_nets = $neutron_settings['predefined_networks'] -$tenant_net = $predefined_nets[$tenant_net_name] -$external_net = $predefined_nets[$external_net_name] - -# Plugin settings data (overrides $external_net l3 values) -$midonet_settings = hiera_hash('midonet') -$tz_type = $midonet_settings['tunnel_type'] -$floating_range_start = $midonet_settings['floating_ip_range_start'] -$floating_range_end = $midonet_settings['floating_ip_range_end'] -$floating_cidr = $midonet_settings['floating_cidr'] -$floating_gateway_ip = $midonet_settings['gateway'] - -$allocation_pools = "start=${floating_range_start},end=${floating_range_end}" - -service { 'neutron-server': - ensure => running, -} - -neutron_network { $tenant_net_name: - ensure => present, - router_external => $tenant_net['L2']['router_ext'], - tenant_name => $tenant_net['tenant'], - shared => $tenant_net['shared'] -} -> - -neutron_subnet { "${tenant_net_name}__subnet": - ensure => present, - cidr => $tenant_net['L3']['subnet'], - network_name => $tenant_net_name, - tenant_name => $tenant_net['tenant'], - gateway_ip => $tenant_net['L3']['gateway'], - enable_dhcp => $tenant_net['L3']['enable_dhcp'], - dns_nameservers => $tenant_net['L3']['nameservers'] -} -> - -neutron_network { $external_net_name: - ensure => present, - router_external => $external_net['L2']['router_ext'], - tenant_name => $external_net['tenant'], - shared => $external_net['shared'] -} -> - -neutron_subnet { "${external_net_name}__subnet": - ensure => present, - cidr => $floating_cidr, - network_name => $external_net_name, - tenant_name => $external_net['tenant'], - gateway_ip => $floating_gateway_ip, - enable_dhcp => $external_net['L3']['enable_dhcp'], - dns_nameservers => $external_net['L3']['nameservers'], - allocation_pools => $allocation_pools -} -> - -neutron_router { 'mido_router': - ensure => present, - tenant_name => $external_net['tenant'], - gateway_network_name => $external_net_name, -} -> - -neutron_router_interface { "mido_router:${tenant_net_name}__subnet": - ensure => present, -} diff --git a/deployment_scripts/puppet/manifests/midonet-nsdb.pp b/deployment_scripts/puppet/manifests/midonet-nsdb.pp deleted file mode 100644 index 55464b8..0000000 --- a/deployment_scripts/puppet/manifests/midonet-nsdb.pp +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright 2015 Midokura SARL. -# -# 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. -notice('MODULAR: midonet-nsdb.pp') - -# Extract data from hiera -$fuel_settings = parseyaml($astute_settings_yaml) -$net_metadata = hiera_hash('network_metadata') -$nsdb_map = get_nodes_hash_by_roles($net_metadata, ['nsdb']) -$zoo_hash = generate_zookeeper_hash($nsdb_map) -$nsdb_mgmt_map = get_node_to_ipaddr_map_by_network_role($nsdb_map, 'management') - -class { '::midonet_openstack::profile::midojava::midojava':} -contain '::midonet_openstack::profile::midojava::midojava' - -class { '::midonet_openstack::profile::zookeeper::midozookeeper': - zk_servers => $zoo_hash['servers'], - id => $zoo_hash["${::fqdn}"]['id'], - client_ip => $zoo_hash["${::fqdn}"]['host'], - require => File['/usr/java/default'] -} - -class {'::midonet_openstack::profile::cassandra::midocassandra': - seeds => join(values($nsdb_mgmt_map),','), - seed_address => $zoo_hash["${::fqdn}"]['host'], - require => File['/usr/java/default'] -} - -class { 'firewall': } - -firewall {'500 zookeeper ports': - port => '2888-3888', - proto => 'tcp', - action => 'accept', - require => Class['::zookeeper'] -} - -firewall {'501 zookeeper ports': - port => '2181', - proto => 'tcp', - action => 'accept', - require => Class['::zookeeper'] -} - -firewall {'550 cassandra ports': - port => '9042', - proto => 'tcp', - action => 'accept', - require => Class['::cassandra'] -} - -firewall {'551 cassandra ports': - port => '7000', - proto => 'tcp', - action => 'accept', - require => Class['::cassandra'] -} - -firewall {'552 cassandra ports': - port => '7199', - proto => 'tcp', - action => 'accept', - require => Class['::cassandra'] -} - -firewall {'553 cassandra ports': - port => '9160', - proto => 'tcp', - action => 'accept', - require => Class['::cassandra'] -} - -firewall {'554 cassandra ports': - port => '59471', - proto => 'tcp', - action => 'accept', - require => Class['::cassandra'] -} diff --git a/deployment_scripts/puppet/manifests/midonet-override-hiera.pp b/deployment_scripts/puppet/manifests/midonet-override-hiera.pp deleted file mode 100644 index dae38b3..0000000 --- a/deployment_scripts/puppet/manifests/midonet-override-hiera.pp +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-override-hiera.pp') - -$midonet_settings = hiera('midonet') -$mem = $midonet_settings['mem'] - -file {'/etc/hiera/plugins/midonet.yaml': - ensure => file, - source => '/etc/fuel/plugins/midonet-9.2/puppet/files/midonet.yaml' -} diff --git a/deployment_scripts/puppet/manifests/midonet-replace-guess-func.pp b/deployment_scripts/puppet/manifests/midonet-replace-guess-func.pp deleted file mode 100644 index 63e3572..0000000 --- a/deployment_scripts/puppet/manifests/midonet-replace-guess-func.pp +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2015 Midokura SARL. -# -# 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. -notice('MODULAR: midonet-replace-guess-func.pp') - -# NOTE: This replacement may be only needed on Ubuntu hosts -file_line { 'replace_guess': - path => '/usr/share/neutron-common/plugin_guess_func', - match => '"neutron.plugins.midonet.plugin.MidonetPluginV2"', - line => "\t\"midonet.neutron.plugin_v2.MidonetPluginV2\")", - multiple => true -} diff --git a/deployment_scripts/puppet/manifests/midonet-restart-agent.pp b/deployment_scripts/puppet/manifests/midonet-restart-agent.pp deleted file mode 100644 index 7133a14..0000000 --- a/deployment_scripts/puppet/manifests/midonet-restart-agent.pp +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-restart-agent.pp') - -exec { 'service midolman restart': - path => '/usr/bin:/usr/sbin:/sbin:/bin' - } -> - -exec { 'sleep 4': - path => '/usr/bin:/usr/sbin:/sbin:/bin' - } -> - -exec { 'service midonet-jmxscraper restart': - path => '/usr/bin:/usr/sbin:/sbin:/bin' - } diff --git a/deployment_scripts/puppet/manifests/midonet-restart-cluster.pp b/deployment_scripts/puppet/manifests/midonet-restart-cluster.pp deleted file mode 100644 index e97ca9b..0000000 --- a/deployment_scripts/puppet/manifests/midonet-restart-cluster.pp +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2016 Midokura, SARL. -# -# 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. -notice('MODULAR: midonet-restart-cluster.pp') - -exec { 'service midonet-cluster restart': - path => '/usr/bin:/usr/sbin:/sbin:/bin' - } -> - -exec { 'sleep 4': - path => '/usr/bin:/usr/sbin:/sbin:/bin' - } diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/filter_nodes.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/filter_nodes.rb deleted file mode 100644 index 8a0f945..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/filter_nodes.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:filter_nodes, :type => :rvalue) do |args| - name = args[1] - value = args[2] - args[0].select do |it| - it[name] == value - end - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_api_zookeeper_ips.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_api_zookeeper_ips.rb deleted file mode 100644 index 31e3906..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_api_zookeeper_ips.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. - -module Puppet::Parser::Functions - newfunction(:generate_api_zookeeper_ips, :type => :rvalue, :doc => <<-EOS - This function returns Zookeper configuration hash - EOS - ) do |argv| - result = [] - nodes_hash = argv[0] - nodes_hash.each do |zk_ip| - result.push({'ip' => zk_ip}) - end - return result - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_edge_port_hash.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_edge_port_hash.rb deleted file mode 100644 index fe1c165..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_edge_port_hash.rb +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. - -require 'csv' -require 'netaddr' - -module Puppet::Parser::Functions - newfunction(:generate_bgp_edge_port_hash, :type => :rvalue, :doc => <<-EOS - This function generates a Hash to create the neutron subnet resources for BGP - on the edge router - EOS - ) do |argv| - result = {} - list_of_neighbors = argv[0].split(',') - list_of_local_ips = list_of_neighbors.collect { |x| x.split('-')[0].split('/')[0] }.uniq - list_of_local_ips.each do |localip| - port_name = 'edge-port-' + localip.gsub('.','') - result[port_name] = { - 'ip_address' => [[localip],['0.0.0.0']] - } - end - - return result - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_edge_subnet_hash.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_edge_subnet_hash.rb deleted file mode 100644 index b19a2de..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_edge_subnet_hash.rb +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. - -require 'csv' -require 'netaddr' - -module Puppet::Parser::Functions - newfunction(:generate_bgp_edge_subnet_hash, :type => :rvalue, :doc => <<-EOS - This function generates a Hash to create the neutron subnet resources for BGP - on the edge router - EOS - ) do |argv| - result = {} - list_of_neighbors = argv[0].split(',') - list_of_neighbors.each do |neighbor| - ip_netnl = neighbor.split('-')[0] - cidr = NetAddr::CIDR.create(ip_netnl).to_s - subnet_name = 'edge-subnet-' + cidr.gsub('.','').gsub("/","") - result[subnet_name] = { - 'cidr' => NetAddr::CIDR.create(ip_netnl).to_s - } - end - - return result - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_neighbors_for_gateway_bgp.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_neighbors_for_gateway_bgp.rb deleted file mode 100644 index 2024294..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_bgp_neighbors_for_gateway_bgp.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. - -require 'csv' -require 'netaddr' - -module Puppet::Parser::Functions - newfunction(:generate_bgp_neighbors_for_gateway_bgp, :type => :rvalue, :doc => <<-EOS - This function generates a Hash to create the neutron subnet resources for BGP - on the edge router - EOS - ) do |argv| - result = [] - split_list_of_neighbors = argv[0].split(',') - split_list_of_neighbors.each do |neighbor| - split_neighbor = neighbor.split('-') - remote_net = NetAddr::CIDR.create(split_neighbor[0]).to_s - ip_address = split_neighbor[1] - remote_asn = split_neighbor[2] - result.push ( - { - 'ip_address' => ip_address, - 'remote_asn' => remote_asn, - 'remote_net' => remote_net - } - ) - end - - return result - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_cidr_from_ip_netlength.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_cidr_from_ip_netlength.rb deleted file mode 100644 index 76d1e90..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_cidr_from_ip_netlength.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. - -require 'netaddr' - -module Puppet::Parser::Functions - newfunction(:generate_cidr_from_ip_netlength, :type => :rvalue, :doc => <<-EOS - This function returns BGP cidr CSV as an array - EOS - ) do |argv| - result = NetAddr::CIDR.create(argv[0]).to_s - return result - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_fqdn_list.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_fqdn_list.rb deleted file mode 100644 index d12d85d..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_fqdn_list.rb +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. - -require 'csv' - -module Puppet::Parser::Functions - newfunction(:generate_fqdn_list, :type => :rvalue, :doc => <<-EOS - This function returns a list of fqdns! - EOS - ) do |argv| - controllers_map = argv[0] - result = '' - controllers_map.each do |key,value| - result << value['fqdn'] + ',' - end - - return result.chop - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_port_bindings_to_delete.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_port_bindings_to_delete.rb deleted file mode 100644 index f70afe6..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_port_bindings_to_delete.rb +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. - -require 'csv' - -module Puppet::Parser::Functions - newfunction(:generate_port_bindings_to_delete, :type => :rvalue, :doc => <<-EOS - This function returns the port bindings to delete for create_resources - EOS - ) do |argv| - controllers_map = argv[0] - result = {} - controllers_map.each do |key,value| - port_name = 'port-static-' + argv[1] - result[port_name] = { - 'binding_host_id' => argv[1] - } - end - - return result - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_router_interfaces_list.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_router_interfaces_list.rb deleted file mode 100644 index 9f29f7e..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_router_interfaces_list.rb +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. - -require 'csv' - -module Puppet::Parser::Functions - newfunction(:generate_router_interfaces_list, :type => :rvalue, :doc => <<-EOS - This function returns the port bindings to create to pass to the shell script - Since you can't send an array to a bash script, let's send a CSV instead. - EOS - ) do |argv| - result = '' - list_of_neighbors = argv[0].split(',') - list_of_ports = list_of_neighbors.collect { |x| 'edge-port-' + x.split('-')[0].split('/')[0].gsub('.','') }.uniq - list_of_ports.each do |port| - result << port + ',' - end - - return result.chop - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_router_interfaces_to_delete.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_router_interfaces_to_delete.rb deleted file mode 100644 index 20cfd47..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_router_interfaces_to_delete.rb +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. - -require 'csv' - -module Puppet::Parser::Functions - newfunction(:generate_router_interfaces_to_delete, :type => :rvalue, :doc => <<-EOS - This function returns the port bindings to delete to pass to the shell script - Since you can't send an array to a bash script, let's send a CSV instead. - EOS - ) do |argv| - controllers_map = argv[0] - result = '' - controllers_map.each do |key,value| - port_name = 'port-static-' + argv[1] - result << port_name + ',' - end - - return result.chop - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_zookeeper_hash.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_zookeeper_hash.rb deleted file mode 100644 index 1bdc191..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/generate_zookeeper_hash.rb +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. -# -module Puppet::Parser::Functions - newfunction(:generate_zookeeper_hash, :type => :rvalue, :doc => <<-EOS - This function returns Zookeper configuration hash - EOS - ) do |argv| - nodes_hash = argv[0] - result = {} - nodes_hash.each_with_index do |ctrl, index| - result[ctrl[1]['fqdn']] = { - 'host' => ctrl[1]['network_roles']['management'], - 'id' => (index + 1).to_s, - } - end - - result['servers'] = [] - nodes_hash.each do |ctrl| - result['servers'] << ctrl[1]['network_roles']['management'] - end - - return result - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/get_node_by_fqdn.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/get_node_by_fqdn.rb deleted file mode 100644 index 628fdbc..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/get_node_by_fqdn.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:get_node_by_fqdn, :type => :rvalue, :doc => <<-EOS -Return a node (node names are keys) that match the fqdn. -example: - get_node_by_fqdn($network_metadata_hash, 'test.function.com') -EOS - ) do |args| - errmsg = "get_node_by_fqdn($network_metadata_hash, $fqdn)" - n_metadata, fqdn = args - raise(Puppet::ParseError, "#{errmsg}: 1st argument should be a hash") if !n_metadata.is_a?(Hash) - raise(Puppet::ParseError, "#{errmsg}: 1st argument should be a valid network_metadata hash") if !n_metadata.has_key?('nodes') - raise(Puppet::ParseError, "#{errmsg}: 2nd argument should be an string") if !fqdn.is_a?(String) - nodes = n_metadata['nodes'] - # Using unrequired node_property bellow -- is a workaround for ruby 1.8 - mynode = nodes.reject {|node_name, node_property| fqdn != node_property['fqdn']} - raise(Puppet::ArgumentError, "#{errmsg}: No matching node found") if mynode.empty? - return mynode.values[0] - end -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/loadyamlv2.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/loadyamlv2.rb deleted file mode 100644 index 1fd85ab..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/loadyamlv2.rb +++ /dev/null @@ -1,34 +0,0 @@ -module Puppet::Parser::Functions - newfunction(:loadyamlv2, :type => :rvalue, :arity => -2, :doc => <<-'ENDHEREDOC') do |args| -Load a YAML file containing an array, string, or hash, and return the data -in the corresponding native data type. -The second parameter is the default value. It will be returned if the file -was not found or could not be parsed. - -For example: - - $myhash = loadyaml('/etc/puppet/data/myhash.yaml') - $myhash = loadyaml('no-file.yaml', {'default' => 'value'}) - ENDHEREDOC - - raise ArgumentError, 'Wrong number of arguments. 1 or 2 arguments should be provided.' unless args.length >= 1 - require 'yaml' - - if File.exists?(args[0]) - begin - YAML::load_file(args[0]) || args[1] - rescue Exception => e - if args[1] - args[1] - else - raise e - end - end - else - warning("Can't load '#{args[0]}' File does not exist!") - args[1] - end - - end - -end diff --git a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/public_network_hash.rb b/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/public_network_hash.rb deleted file mode 100644 index 47ac96e..0000000 --- a/deployment_scripts/puppet/modules/plugin_midonet/lib/puppet/parser/functions/public_network_hash.rb +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2015 Midokura SARL, Inc. -# -# 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. -require 'ipaddr' - -module Puppet::Parser::Functions - newfunction(:public_network_hash, :type => :rvalue, :doc => <<-EOS - This function returns a network address and an integer mask based - on and IP address of the network and its IP mask - EOS - ) do |argv| - ip = argv[0] - netmask = argv[1] - result = {} - result['network_address'] = IPAddr.new(ip).mask(netmask).to_s - result['mask'] = IPAddr.new(netmask).to_i.to_s(2).count("1").to_s - return result - end -end diff --git a/deployment_scripts/puppet/templates/cleanup_masquerade.erb b/deployment_scripts/puppet/templates/cleanup_masquerade.erb deleted file mode 100644 index 7d67bdc..0000000 --- a/deployment_scripts/puppet/templates/cleanup_masquerade.erb +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -# Copyright 2016 Midokura SARL -# -# 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. - -set -e -set -x - -FIP=<%= @fip %> -NIC=<%= @nic %> - - -# Delete masquerading to enable NATing -if [ -n "$(iptables -v -n -L -t nat | grep "MASQUERADE" | grep "${FIP}" | grep "${NIC}")" ]; then - iptables -t nat -D POSTROUTING -o ${NIC} -s ${FIP} -j MASQUERADE - iptables -D FORWARD -s ${FIP} -j ACCEPT - echo "Succesfully deleted masquerading" -fi diff --git a/deployment_scripts/puppet/templates/cleanup_static_gateway.sh.erb b/deployment_scripts/puppet/templates/cleanup_static_gateway.sh.erb deleted file mode 100644 index e107474..0000000 --- a/deployment_scripts/puppet/templates/cleanup_static_gateway.sh.erb +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -# Copyright 2016 Midokura SARL -# -# 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. - -set -e -set -x - -FIP=<%= @fip %> -NIC=<%= @nic %> -EDGE_ROUTER=<%= @edge_router %> -VETH0_IP=<%= @veth0_ip %> -VETH1_IP=<%= @veth1_ip %> -VETH_NETWORK=<%= @veth_network %> -HOSTNAME=<%= @myhostname %> - - -# Delete Route packets towards floating IP network through the bridge -if [ -n "$(ip route | /bin/grep "${FIP} via ${VETH_1}")" ]; then - ip route delete ${FIP} via ${VETH1_IP} - echo "Succesfully deleted route to send packets on the bridge" -fi - -for host in ${HOSTNAME//,/ } -do - HOST_ID=$(midonet-cli -A -e host list | grep ${host} | awk '{ print $2 }') - - ROUTER_ID=$(midonet-cli -A -e router list | grep ${EDGE_ROUTER} | awk '{ print $2 }') - PORT_ID=$(midonet-cli -A -e host ${HOST_ID} binding list | grep veth1 | awk '{ print $6}') - ROUTE_ID=$(midonet-cli -A -e router ${ROUTER_ID} route list | grep "src 0.0.0.0/0 dst 0.0.0.0/0 gw ${VETH0_IP} port ${PORT_ID}" | awk '{ print $2 }') - - if [ -n ${ROUTE_ID} ]; then - midonet-cli -e router ${ROUTER_ID} delete route ${ROUTE_ID} - echo "Successfully deleted default route on edge router" - fi -done diff --git a/deployment_scripts/puppet/templates/create_router_interfaces.sh.erb b/deployment_scripts/puppet/templates/create_router_interfaces.sh.erb deleted file mode 100644 index fc94b78..0000000 --- a/deployment_scripts/puppet/templates/create_router_interfaces.sh.erb +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Copyright 2016 Midokura SARL -# -# 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. - -set -e -set -x - - -EDGE_ROUTER=<%= @edge_router %> -PORTS=<%= @ports_to_bind %> -HOSTNAME=<%= @myhostname %> - -HOST_ID=$(midonet-cli -A -e host list | grep ${HOSTNAME} | awk '{ print $2 }') - -ROUTER_ID=$(midonet-cli -A -e router list | grep ${EDGE_ROUTER} | awk '{ print $2 }') - -PORT_BINDING_LIST=$(midonet-cli -A -e host ${HOST_ID} binding list) - -if [ -z "${PORT_BINDING_LIST}" ]; then - PORT_ID= -else - PORT_ID=$(midonet-cli -A -e host ${HOST_ID} binding list | grep gw-veth-mn) -fi - - -if [ -z "${PORT_ID}" ]; then - for port in ${PORTS//,/ } - do - source /root/openrc && neutron router-interface-add ${EDGE_ROUTER} port=${port} - done -fi diff --git a/deployment_scripts/puppet/templates/create_router_interfaces_static.sh.erb b/deployment_scripts/puppet/templates/create_router_interfaces_static.sh.erb deleted file mode 100644 index ce20e4d..0000000 --- a/deployment_scripts/puppet/templates/create_router_interfaces_static.sh.erb +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Copyright 2016 Midokura SARL -# -# 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. - -set -e -set -x - - -EDGE_ROUTER=<%= @edge_router %> -PORTS=<%= @ports_to_bind %> -HOSTNAME=<%= @myhostname %> - -HOST_ID=$(midonet-cli -A -e host list | grep ${HOSTNAME} | awk '{ print $2 }') - -ROUTER_ID=$(midonet-cli -A -e router list | grep ${EDGE_ROUTER} | awk '{ print $2 }') - -PORT_BINDING_LIST=$(midonet-cli -A -e host ${HOST_ID} binding list) - -if [ -z ${PORT_BINDING_LIST} ]; then - PORT_ID= -else - PORT_ID=$(midonet-cli -A -e host ${HOST_ID} binding list | grep veth1) -fi - - -if [ -z ${PORT_ID} ]; then - for port in ${PORTS//,/ } - do - source /root/openrc && neutron router-interface-add ${EDGE_ROUTER} port=${port} - done -fi diff --git a/deployment_scripts/puppet/templates/delete_router_interfaces_bgp.sh.erb b/deployment_scripts/puppet/templates/delete_router_interfaces_bgp.sh.erb deleted file mode 100644 index 47e9116..0000000 --- a/deployment_scripts/puppet/templates/delete_router_interfaces_bgp.sh.erb +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# Copyright 2016 Midokura SARL -# -# 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. - -set -x - - -EDGE_ROUTER=<%= @edge_router %> -PORTS=<%= @ports_to_unbind %> -HOSTNAME=<%= @myhostname %> - -ROUTER_ID=$(midonet-cli -A -e router list | grep ${EDGE_ROUTER} | awk '{ print $2 }') - -for port in ${PORTS//,/ } - do - source /root/openrc && neutron router-interface-delete ${EDGE_ROUTER} port=${port} - done - -exit 0 diff --git a/deployment_scripts/puppet/templates/remove_router_interfaces.sh.erb b/deployment_scripts/puppet/templates/remove_router_interfaces.sh.erb deleted file mode 100644 index 711d9c7..0000000 --- a/deployment_scripts/puppet/templates/remove_router_interfaces.sh.erb +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -# Copyright 2016 Midokura SARL -# -# 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. - -set -x - - -EDGE_ROUTER=<%= @edge_router %> -PORTS=<%= @ports_to_unbind %> - -for port in ${PORTS//,/ } -do - source /root/openrc && neutron router-interface-delete ${EDGE_ROUTER} port=${port} -done - -exit 0 diff --git a/deployment_scripts/puppet/templates/vhost_mem_manager.erb b/deployment_scripts/puppet/templates/vhost_mem_manager.erb deleted file mode 100644 index 7174cf0..0000000 --- a/deployment_scripts/puppet/templates/vhost_mem_manager.erb +++ /dev/null @@ -1,46 +0,0 @@ -<% if !@new_api %> - -ProxyPreserveHost On -Alias /midonet-manager "/var/www/html/midonet-manager" - -ProxyPass /midonet-api http://<%= @public_vip %>:8181/midonet-api -ProxyPassReverse /midonet-api http://<%= @public_vip %>:8181/midonet-api - -ProxyPass /subscription ws://<%= @public_vip %>:8007/subscription -ProxyPassReverse /subscription ws://<%= @public_vip %>:8007/subscription - -ProxyPass /trace ws://<%= @public_vip %>:8460/trace -ProxyPassReverse /trace ws://<%= @public_vip %>:8460/trace - -ProxyPass /fabric ws://<%= @public_vip %>:8009/fabric -ProxyPassReverse /fabric ws://<%= @public_vip %>:8009/fabric - -ProxyPass /analytics ws://<%= @ana_mgmt_ip %>:8080/analytics -ProxyPassReverse /analytics ws://<%= @ana_mgmt_ip %>:8080/analytics - -Header set Access-Control-Allow-Origin * -Header append Access-Control-Allow-Headers Content-Type -Header append Access-Control-Allow-Headers X-Auth-Token -<% else %> -ProxyPreserveHost On -Alias /midonet-manager "/var/www/html/midonet-manager" - -ProxyPass /midonet-api http://<%= @public_vip %>:8181/midonet-api -ProxyPassReverse /midonet-api http://<%= @public_vip %>:8181/midonet-api - -ProxyPass /subscription ws://<%= @public_vip %>:8999/subscription -ProxyPassReverse /subscription ws://<%= @public_vip %>:8999/subscription - -ProxyPass /trace ws://<%= @public_vip %>:8999/trace -ProxyPassReverse /trace ws://<%= @public_vip %>:8999/trace - -ProxyPass /fabric ws://<%= @public_vip %>:8999/fabric -ProxyPassReverse /fabric ws://<%= @public_vip %>:8999/fabric - -ProxyPass /analytics ws://<%= @public_vip %>:8999/analytics -ProxyPassReverse /analytics ws://<%= @public_vip %>:8999/analytics - -Header set Access-Control-Allow-Origin * -Header append Access-Control-Allow-Headers Content-Type -Header append Access-Control-Allow-Headers X-Auth-Token -<% end %> diff --git a/deployment_tasks.yaml b/deployment_tasks.yaml deleted file mode 100644 index 3adc6b8..0000000 --- a/deployment_tasks.yaml +++ /dev/null @@ -1,977 +0,0 @@ -# -# GROUPS -# -- id: nsdb - parameters: - strategy: - type: parallel - requires: - - deploy_start - required_for: - - controller - - primary-controller - - deploy_end - role: - - nsdb - type: group - tasks: - - logging - - hiera - - globals - - netconfig - -- id: midonet-gw - parameters: - strategy: - type: parallel - requires: - - deploy_start - - nsdb - required_for: - - deploy_end - role: - - midonet-gw - type: group - tasks: - - logging - - hiera - - globals - - netconfig - -- id: midonet-analytics - parameters: - strategy: - type: parallel - requires: - - deploy_start - - nsdb - required_for: - - deploy_end - role: - - midonet-analytics - type: group - tasks: - - logging - - hiera - - globals - - netconfig - -# Override neutron params -- id: install_common_deps - role: - - primary-controller - - controller - - compute - - nsdb - - midonet-gw - - midonet-analytics - type: shell - requires: [pre_deployment_start] - required_for: [pre_deployment_end] - version: 2.1.0 - parameters: - cmd: bash install_midonet_common_modules_and_gems.sh - timeout: 1440 - condition: - yaql_exp: "$.midonet.midonet_version = '5.2'" - -- id: install_common_deps_54 - role: - - primary-controller - - controller - - compute - - nsdb - - midonet-gw - - midonet-analytics - type: shell - requires: [pre_deployment_start] - required_for: [pre_deployment_end] - version: 2.1.0 - parameters: - cmd: bash install_midonet_common_modules_and_gems_54.sh - timeout: 1440 - condition: - yaql_exp: "$.midonet.midonet_version = '5.4'" - - -- id: override_neutron_module - role: - - primary-controller - - controller - - compute - - nsdb - - midonet-gw - - midonet-analytics - type: shell - requires: [pre_deployment_start] - required_for: [pre_deployment_end] - version: 2.1.0 - parameters: - cmd: bash override_neutron_module.sh - timeout: 1440 - -# Override neutron params -- id: neutron-override - role: - - primary-controller - - controller - - compute - - nsdb - - midonet-gw - - midonet-analytics - type: puppet - requires: [pre_deployment_start] - required_for: [pre_deployment_end] - version: 2.1.0 - parameters: - puppet_manifest: puppet/manifests/midonet-override-hiera.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - -# Install the MidoNet Package. Everywhere -- id: install_midonet_package - role: - - primary-controller - - controller - - compute - - nsdb - - midonet-gw - - midonet-analytics - type: shell - requires: [deploy_start,setup_repositories] - required_for: [fuel_pkgs] - version: 2.1.0 - parameters: - cmd: bash install_midonet_package_from_source.sh - timeout: 1440 - - -# Install the MidoNet_Openstack Package where needed. For Java, Zookeeper and Cassandra -- id: install_midonet_openstack_package - role: - - primary-controller - - controller - - compute - - nsdb - - midonet-gw - - midonet-analytics - type: shell - requires: [deploy_start,setup_repositories] - required_for: [fuel_pkgs] - version: 2.1.0 - parameters: - cmd: bash install_midonet_openstack_package.sh - timeout: 1440 - - -# First independent tasks -- id: setup_repositories_midonet - groups: - - primary-controller - - controller - - compute - - nsdb - - midonet-gw - - midonet-analytics - required_for: - - deploy_end - requires: - - netconfig - - install_common_deps - - install_common_deps_54 - - install_midonet_package - - install_midonet_openstack_package - - override_neutron_module - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-define-repositories.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - -- id: enable_ip_forward_midonet - groups: - - compute - - controller - - primary-controller - - midonet-gw - - midonet-analytics - required_for: - - deploy_end - requires: - - deploy_start - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-enable-ip-forward.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - - -# PRE-NEUTRON CONFIGURATION -- id: deploy_cluster_midonet - groups: - - primary-controller - - controller - required_for: - - deploy_end - - openstack-network-start - requires: - - setup_repositories_midonet - - enable_ip_forward_midonet - - firewall - - primary-cluster-haproxy - - cluster-haproxy - cross-depends: - - name: zookeeper_and_cassandra_midonet - version: 2.1.0 - type: puppet - reexecute_on: - - deploy_changes - parameters: - puppet_manifest: puppet/manifests/midonet-install-cluster.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 3600 - -# In controllers, we have to install midolman 'before' the neutron -# configuration, because subnet creates a the DHCP port in neutron -# and we need to do the binding. -- id: agent-midonet-controller - groups: - - primary-controller - - controller - required_for: - - deploy_end - - openstack-network-start - requires: - - deploy_cluster_midonet - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-install-agent.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 4500 - - -# NEUTRON CONFIGURATION -- id: openstack-network-midonet-replace-service-name - groups: - - primary-controller - - controller - requires: - - openstack-network-common-config - required_for: - - openstack-network-end - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-replace-guess-func.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - -- id: openstack-network-midonet-config - groups: - - primary-controller - - controller - requires: - - openstack-network-midonet-replace-service-name - - setup_repositories_midonet - required_for: - - openstack-network-server-config - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-neutron-configure.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - -- id: openstack-network-midonet-networks - groups: - - primary-controller - requires: - - openstack-network-server-config - - openstack-network-midonet-config - - setup_repositories_midonet - required_for: - - openstack-network-end - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-neutron-networks.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - -- id: openstack-network-midonet-cleanup-static - groups: - - primary-controller - requires: - - openstack-network-server-config - - openstack-network-midonet-config - - setup_repositories_midonet - - openstack-network-midonet-networks - reexecute_on: - - deploy_changes - required_for: - - openstack-network-end - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-cleanup-static.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - condition: - yaql_exp: > - changedAny($.midonet.gateway_type,$.midonet.static_linux_bridge_address, - $.midonet.static_fake_edge_router_address, - $.midonet.static_use_masquerade) and $.cluster.status != 'new' - -- id: openstack-network-midonet-cleanup-bgp - groups: - - primary-controller - requires: - - openstack-network-server-config - - openstack-network-midonet-config - - setup_repositories_midonet - - openstack-network-midonet-networks - reexecute_on: - - deploy_changes - required_for: - - openstack-network-end - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-edge-router-cleanup-bgp.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - condition: - yaql_exp: > - (changedAny($.midonet.gateway_type,$.midonet.bgp_local_as, - $.midonet.bgp_neighbors) and $.cluster.status != 'new') - -- id: openstack-network-midonet-edge - groups: - - primary-controller - requires: - - openstack-network-server-config - - openstack-network-midonet-config - - setup_repositories_midonet - - openstack-network-midonet-networks - - openstack-network-midonet-cleanup-static - - openstack-network-midonet-cleanup-bgp - reexecute_on: - - deploy_changes - required_for: - - openstack-network-end - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-edge-router-setup.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - -- id: openstack-network-midonet-edge-bgp - groups: - - primary-controller - requires: - - openstack-network-server-config - - openstack-network-midonet-config - - setup_repositories_midonet - - openstack-network-midonet-networks - - openstack-network-midonet-edge - - openstack-network-midonet-cleanup-static - - openstack-network-midonet-cleanup-bgp - reexecute_on: - - deploy_changes - required_for: - - openstack-network-end - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-edge-router-setup-bgp.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - condition: - yaql_exp: > - (changedAny($.midonet.gateway_type,$.midonet.bgp_local_as, - $.midonet.bgp_neighbors) and $.midonet.gateway_type = 'bgp') - -- id: openstack-network-midonet-edge-static - groups: - - primary-controller - requires: - - openstack-network-server-config - - openstack-network-midonet-config - - setup_repositories_midonet - - openstack-network-midonet-networks - - openstack-network-midonet-edge - - openstack-network-midonet-cleanup-bgp - - openstack-network-midonet-cleanup-static - reexecute_on: - - deploy_changes - required_for: - - openstack-network-end - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-edge-router-setup-static.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - condition: - yaql_exp: > - (changedAny($.midonet.gateway_type,$.midonet.static_linux_bridge_address, - $.midonet.static_fake_edge_router_address, - $.midonet.static_use_masquerade) and $.midonet.gateway_type = 'static') - -- id: openstack-network-midonet-edge-static-per-host - groups: - - primary-controller - requires: - - openstack-network-server-config - - openstack-network-midonet-config - - setup_repositories_midonet - - openstack-network-midonet-networks - - openstack-network-midonet-edge - - openstack-network-midonet-cleanup-static - - openstack-network-midonet-cleanup-bgp - - openstack-network-midonet-edge-static - reexecute_on: - - deploy_changes - required_for: - - openstack-network-end - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-edge-router-setup-static-per-host.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - condition: - yaql_exp: > - (changedAny($.midonet.gateway_type,$.midonet.static_linux_bridge_address, - $.midonet.static_fake_edge_router_address, - $.midonet.static_use_masquerade) and $.midonet.gateway_type = 'static') - -- id: openstack-network-midonet-compute-nova - parameters: - puppet_manifest: puppet/manifests/midonet-compute-nova.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - required_for: - - openstack-network-end - requires: - - setup_repositories_midonet - - openstack-network-common-config - - openstack-network-agents-l3 - - openstack-network-agents-metadata - version: 2.1.0 - type: puppet - groups: - - compute - -# NSDB-only tasks -- id: zookeeper_and_cassandra_midonet - groups: - - nsdb - required_for: - - deploy_end - requires: - - deploy_start - - install_midonet_openstack_package - - install_midonet_package - - netconfig - version: 2.1.0 - type: puppet - reexecute_on: - - deploy_changes - parameters: - puppet_manifest: puppet/manifests/midonet-nsdb.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 3600 - -# Analytics Only tasks - -- id: mem-analytics-java8 - role: - - midonet-analytics - required_for: - - deploy_end - requires: - - deploy_start - - install_midonet_openstack_package - - install_midonet_package - - netconfig - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-install-java8.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - condition: - yaql_exp: "$.midonet.mem = true and $.midonet.mem_insights = true" - -- id: mem-analytics-haveged - role: - - midonet-analytics - required_for: - - deploy_end - requires: - - deploy_start - - install_midonet_openstack_package - - install_midonet_package - - netconfig - - mem-analytics-java8 - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-install-haveged.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - condition: - yaql_exp: "$.midonet.mem = true and $.midonet.mem_insights = true and $.midonet.vm_install = true" - -- id: mem-analytics-install - role: - - midonet-analytics - required_for: - - deploy_end - requires: - - deploy_start - - install_midonet_openstack_package - - install_midonet_package - - netconfig - - mem-analytics-java8 - - setup_repositories_midonet - - mem-analytics-haveged - cross-depends: - - name: zookeeper_and_cassandra_midonet - - name: deploy_cluster_midonet - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-install-analytics.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 4500 - condition: - yaql_exp: "$.midonet.mem = true and $.midonet.mem_insights = true" - - -# Skipped tasks -- id: openstack-network-server-config - type: skipped -- id: openstack-network-networks - type: skipped -- id: openstack-network-routers - type: skipped -- id: openstack-network-plugins-l2 - type: skipped -- id: primary-openstack-network-plugins-l2 - type: skipped -- id: openstack-network-agents-l3 - type: skipped -- id: primary-openstack-network-agents-l3 - type: skipped -- id: openstack-network-compute-nova - type: skipped - # This task tries to enable the service nova_compute but we already to that - # inside our custom midonet-compute-nova task. -- id: enable_nova_compute_service - type: skipped - -# POST-DEPLOYMENT TASKS - -# The task configure_default_route reinstalls openvswitch-switch -# and removes midolman. This task only runs on compute hosts, so -# we have to make sure that midolman is installed 'after' the -# 'configure_default_route' task has run -- id: agent-midonet-compute - role: - - compute - - midonet-gw - required_for: - - post_deployment_end - requires: - - configure_default_route - - post_deployment_start - version: 2.1.0 - type: puppet - reexecute_on: - - deploy_changes - parameters: - puppet_manifest: puppet/manifests/midonet-install-agent.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 4500 - -- id: tunnel-zones-midonet - role: - - compute - - controller - - primary-controller - - midonet-gw - reexecute_on: - - deploy_changes - required_for: - - post_deployment_end - requires: - - post_deployment_start - - agent-midonet-compute - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-host-registry.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - -- id: generate-openrc-gw - role: - - midonet-gw - required_for: - - post_deployment_end - requires: - - post_deployment_start - - tunnel-zones-midonet - version: 2.1.0 - reexecute_on: - - deploy_changes - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-generate-openrc-for-gw.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - -- id: midonet-edge-router-cleanup-bgp-gw - role: - - midonet-gw - required_for: - - post_deployment_end - requires: - - generate-openrc-gw - - post_deployment_start - - tunnel-zones-midonet - type: puppet - reexecute_on: - - deploy_changes - parameters: - puppet_manifest: puppet/manifests/midonet-edge-router-cleanup-bgp-gw.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - version: 2.1.0 - condition: - yaql_exp: > - (changedAny($.midonet.gateway_type,$.midonet.bgp_local_as, - $.midonet.bgp_neighbors) and $.cluster.status != 'new' ) - -- id: openstack-network-midonet-cleanup-static-per-host - role: - - midonet-gw - required_for: - - post_deployment_end - requires: - - generate-openrc-gw - - post_deployment_start - - tunnel-zones-midonet - reexecute_on: - - deploy_changes - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-cleanup-static-per-host.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - condition: - yaql_exp: > - changedAny($.midonet.gateway_type,$.midonet.static_linux_bridge_address, - $.midonet.static_fake_edge_router_address, - $.midonet.static_use_masquerade) and $.cluster.status != 'new' - -- id: openstack-network-midonet-cleanup-masq - role: - - midonet-gw - required_for: - - post_deployment_end - requires: - - generate-openrc-gw - - post_deployment_start - - tunnel-zones-midonet - reexecute_on: - - deploy_changes - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-cleanup-masquerade.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - condition: - yaql_exp: > - changedAny($.midonet.gateway_type,$.midonet.static_linux_bridge_address, - $.midonet.static_fake_edge_router_address, - $.midonet.static_use_masquerade) and $.cluster.status != 'new' - -- id: midonet-bgp-interfaces - role: - - midonet-gw - required_for: - - post_deployment_end - requires: - - generate-openrc-gw - - midonet-edge-router-cleanup-bgp-gw - - openstack-network-midonet-cleanup-static-per-host - - openstack-network-midonet-cleanup-masq - - post_deployment_start - - tunnel-zones-midonet - type: puppet - reexecute_on: - - deploy_changes - version: 2.1.0 - parameters: - puppet_manifest: puppet/manifests/midonet-bgp-interfaces.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - condition: - yaql_exp: "$.midonet.gateway_type = 'bgp'" - - -- id: midonet-edge-router-setup-bgp-gw - role: - - midonet-gw - required_for: - - post_deployment_end - requires: - - generate-openrc-gw - - post_deployment_start - - midonet-bgp-interfaces - - tunnel-zones-midonet - - midonet-edge-router-cleanup-bgp-gw - - openstack-network-midonet-cleanup-masq - - openstack-network-midonet-cleanup-static-per-host - version: 2.1.0 - type: puppet - reexecute_on: - - deploy_changes - parameters: - puppet_manifest: puppet/manifests/midonet-edge-router-setup-bgp-gw.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - condition: - yaql_exp: > - (changedAny($.midonet.gateway_type,$.midonet.bgp_local_as, - $.midonet.bgp_neighbors) and $.midonet.gateway_type = 'bgp') - -- id: openstack-network-midonet-gateway-static-router-ifaces - role: - - midonet-gw - required_for: - - post_deployment_end - requires: - - generate-openrc-gw - - post_deployment_start - - midonet-bgp-interfaces - - tunnel-zones-midonet - - midonet-edge-router-cleanup-bgp-gw - - openstack-network-midonet-cleanup-masq - - openstack-network-midonet-cleanup-static-per-host - reexecute_on: - - deploy_changes - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-gateway-static-router-ifaces.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - condition: - yaql_exp: "$.midonet.gateway_type = 'static'" - -- id: openstack-network-midonet-gateway-static - role: - - midonet-gw - required_for: - - post_deployment_end - requires: - - generate-openrc-gw - - post_deployment_start - - midonet-bgp-interfaces - - tunnel-zones-midonet - - midonet-edge-router-cleanup-bgp-gw - - openstack-network-midonet-cleanup-masq - - openstack-network-midonet-cleanup-static-per-host - - openstack-network-midonet-gateway-static-router-ifaces - reexecute_on: - - deploy_changes - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-gateway-static.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - condition: - yaql_exp: "$.midonet.gateway_type = 'static'" - - -- id: rootwrap-midonet - role: - - compute - - controller - - primary-controller - - midonet-gw - required_for: - - post_deployment_end - requires: - - post_deployment_start - - agent-midonet-compute - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-ensure-rootwrap.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - -# Midonet Enterprise Post-Deployment Tasks - -- id: mem-install - role: - - controller - - primary-controller - required_for: - - post_deployment_end - requires: - - post_deployment_start - type: puppet - reexecute_on: - - deploy_changes - version: 2.1.0 - parameters: - puppet_manifest: puppet/manifests/midonet-install-mem.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 3600 - condition: - yaql_exp: "$.midonet.mem = true" - -- id: mem-horizon-override - role: - - controller - - primary-controller - required_for: - - post_deployment_end - requires: - - post_deployment_start - - mem-install - version: 2.1.0 - reexecute_on: - - deploy_changes - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-mem-horizon-override.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - condition: - yaql_exp: "$.midonet.mem = true" - -- id: mem-horizon-enable-lb - role: - - controller - - primary-controller - required_for: - - post_deployment_end - requires: - - post_deployment_start - - mem-install - version: 2.1.0 - reexecute_on: - - deploy_changes - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-horizon-lb-firewall.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - -- id: mem-restart-cluster - role: - - controller - - primary-controller - required_for: - - post_deployment_end - requires: - - post_deployment_start - - mem-install - - mem-horizon-override - - agent-midonet-compute - - tunnel-zones-midonet - - openstack-network-midonet-cleanup-static-per-host - cross-depends: - - name: midonet-edge-router-setup-bgp-gw - - reexecute_on: - - deploy_changes - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-restart-cluster.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - condition: - yaql_exp: "$.midonet.mem = true" - -- id: mem-restart-agent - role: - - midonet-gw - - controller - - primary-controller - - compute - required_for: - - post_deployment_end - requires: - - post_deployment_start - - mem-install - - mem-horizon-override - - agent-midonet-compute - - tunnel-zones-midonet - - openstack-network-midonet-cleanup-static-per-host - cross-depends: - - name: midonet-edge-router-setup-bgp-gw - version: 2.1.0 - reexecute_on: - - deploy_changes - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-restart-agent.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 720 - condition: - yaql_exp: "$.midonet.mem = true" - -# Kill the unneccessary agents the hard way -- id: openstack-network-disable-services - role: - - primary-controller - - controller - requires: - - post_deployment_start - reexecute_on: - - deploy_changes - required_for: - - post_deployment_end - version: 2.1.0 - type: puppet - parameters: - puppet_manifest: puppet/manifests/midonet-disable-services.pp - puppet_modules: "puppet/modules/:/etc/puppet/modules/" - timeout: 1440 - -# In the end.. - -# Grab the Old Astute.yaml and save it somewhere so we can parse it -# later and do cleanup - -- id: save_old_astute - type: shell - version: 2.1.0 - role: - - controller - - primary-controller - required_for: - - post_deployment_end - requires: - - post_deployment_start - reexecute_on: - - deploy_changes - parameters: - cmd: cp /etc/fuel/cluster/{CLUSTER_ID}/astute.yaml /etc/fuel/cluster/astute.yaml.old - timeout: 180 diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 72e79d9..0000000 --- a/doc/Makefile +++ /dev/null @@ -1,184 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " pdf to make a PDF file" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Together-Message.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Together-Message.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/Together-Message" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Together-Message" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." - -pdf: - $(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) $(BUILDDIR)/pdf - @echo - @echo "Build finished. The PDF file is in $(BUILDDIR)/pdf." - diff --git a/doc/TestPlanforMidoNetFuelPlugin9.2.0.pdf b/doc/TestPlanforMidoNetFuelPlugin9.2.0.pdf deleted file mode 100644 index 46924e24cacf24e490326e90d11f6f5c8cde3853..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 127706 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 KfT+9}%>M!$Ke4(1 diff --git a/doc/TestReportforMidoNetFuelPlugin9.2.0.pdf b/doc/TestReportforMidoNetFuelPlugin9.2.0.pdf deleted file mode 100644 index 068e3451f514ece96a81f826008644d146fc3e9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143924 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