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: I0223569bb67af0f3e9e45c0ed59abbaf9b89cf05
This commit is contained in:
Andreas Jaeger 2019-12-18 19:33:17 +01:00
parent 6efb8886a2
commit a4671b7051
78 changed files with 10 additions and 4179 deletions

202
LICENSE
View File

@ -1,202 +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 {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,4 +0,0 @@
# fuel-plugin-cisco-aci
Fuel Plugin for Cisco ACI
Full specification can be found at https://github.com/stackforge/fuel-plugin-cisco-aci/blob/master/doc/fuel-plugin-cisco-aci.rst

10
README.rst Normal file
View File

@ -0,0 +1,10 @@
This project is no longer maintained.
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".
For any further questions, please email
openstack-discuss@lists.openstack.org or join #openstack-dev on
Freenode.

View File

@ -1,12 +0,0 @@
#Class apic::api
class apic::api (
$package_ensure = 'present',
) {
include apic::params
package { 'apic_api':
ensure => $package_ensure,
name => $::apic::params::package_apic_api,
}
}

View File

@ -1,39 +0,0 @@
#Class apic::host_agent
class apic::host_agent (
$package_ensure = 'present',
$enabled = true,
$manage_service = true,
){
include apic::params
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
package { 'apic_host_agent':
ensure => $package_ensure,
name => $::apic::params::package_apic_agent,
}
service { 'apic-host-agent':
ensure => $service_ensure,
name => $::apic::params::service_apic_host_agent,
enable => $enabled,
hasstatus => true,
hasrestart => true,
require => Package['apic_host_agent'],
}
Package['apic_host_agent'] -> Neutron_config<||>
Package['apic_host_agent'] -> Neutron_plugin_ml2<||>
Package['apic_host_agent'] -> Neutron_plugin_ml2_cisco<||>
Neutron_config<||> ~> Service['apic-host-agent']
Neutron_plugin_ml2<||> ~> Service['apic-host-agent']
Neutron_plugin_ml2_cisco<||> ~> Service['apic-host-agent']
File_line<||> ~> Service['apic-host-agent']
}

View File

@ -1,23 +0,0 @@
#Class apic::params
class apic::params {
$package_apic_api = 'apicapi'
$package_apic_svc = 'apicapi'
$package_apic_agent = 'apicapi'
case $::osfamily {
'RedHat': {
$service_apic_svc_agent = 'neutron-apic-service-agent'
$service_apic_host_agent = 'neutron-apic-host-agent'
}
'Debian': {
$service_apic_svc_agent = 'neutron-driver-apic-svc'
$service_apic_host_agent = 'neutron-driver-apic-agent'
}
default: {
fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, module ${module_name} only support osfamily RedHat and Debian")
}
}
}

View File

@ -1,39 +0,0 @@
#Class apic::svc_agent
class apic::svc_agent (
$package_ensure = 'present',
$enabled = true,
$manage_service = true,
){
include apic::params
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
Package['apic_svc_agent'] -> Neutron_config<||>
Package['apic_svc_agent'] -> Neutron_plugin_ml2<||>
Package['apic_svc_agent'] -> Neutron_plugin_ml2_cisco<||>
Neutron_config<||> ~> Service['apic-svc-agent']
Neutron_plugin_ml2<||> ~> Service['apic-svc-agent']
Neutron_plugin_ml2_cisco<||> ~> Service['apic-svc-agent']
File_line<||> ~> Service['apic-svc-agent']
package { 'apic_svc_agent':
ensure => $package_ensure,
name => $::apic::params::package_apic_svc,
}
service { 'apic-svc-agent':
ensure => $service_ensure,
name => $::apic::params::service_apic_svc_agent,
enable => $enabled,
hasstatus => true,
hasrestart => true,
require => Package['apic_svc_agent'],
}
}

View File

@ -1,89 +0,0 @@
#Class cisco_aci::gbp_and_apic_gbp
class cisco_aci::gbp_and_apic_gbp (
$ha_prefix = '',
$role = 'compute',
$use_lldp = true,
$apic_hosts = '10.0.0.1',
$apic_username = 'admin',
$apic_password = 'password',
$static_config = '',
$additional_config = '',
$service_plugins = 'neutron.services.l3_router.l3_router_plugin.L3RouterPlugin,gbpservice.neutron.services.grouppolicy.plugin.GroupPolicyPlugin,gbpservice.neutron.services.servicechain.servicechain_plugin.ServiceChainPlugin',
$mechanism_drivers = 'openvswitch,apic_gbp',
$policy_drivers = 'implicit_policy,apic',
$admin_username = 'admin',
$admin_password = 'admin',
$admin_tenant = 'admin',
$ext_net_enable = false,
$ext_net_name = 'ext',
$ext_net_switch = '101',
$ext_net_port = '1/1',
$ext_net_subnet = '10.0.0.0/24',
$ext_net_gateway = '10.0.0.1',
){
include 'apic::params'
include 'apic::api'
case $role {
/controller/: {
if $use_lldp {
include 'apic::svc_agent'
}
include 'neutron::services::apic_server'
include "neutron::services::${ha_prefix}agents"
include 'gbp::heat'
include "heat::${ha_prefix}services"
include 'gbp::horizon'
include 'gbp::client'
include 'gbp::manage'
class {'neutron::config_auth':
admin_username => $admin_username,
admin_password => $admin_password,
admin_tenant => $admin_tenant,
}
if ($role == 'primary-controller' and $ext_net_enable == true){
class {'neutron::network':
tenant_name => $admin_tenant,
ext_net_name => $ext_net_name,
ext_net_subnet => $ext_net_subnet,
ext_net_gateway => $ext_net_gateway,
}
}
}
'compute': {
include 'neutron::services::ovs_agent'
}
default: {
}
}
if $use_lldp {
include 'lldp'
include 'apic::host_agent'
}
class {'gbp::config':
policy_drivers => $policy_drivers,
}
class {'neutron::config':
service_plugins => $service_plugins,
mechanism_drivers => $mechanism_drivers,
}
class {'neutron::config_apic':
apic_hosts => $apic_hosts,
apic_username => $apic_username,
apic_password => $apic_password,
static_config => $static_config,
additional_config => $additional_config,
ext_net_enable => $ext_net_enable,
ext_net_name => $ext_net_name,
ext_net_switch => $ext_net_switch,
ext_net_port => $ext_net_port,
ext_net_subnet => $ext_net_subnet,
ext_net_gateway => $ext_net_gateway,
}
}

View File

@ -1,89 +0,0 @@
#Class cisco_aci::gbp_and_apic_ml2
class cisco_aci::gbp_and_apic_ml2 (
$ha_prefix = '',
$role = 'compute',
$use_lldp = true,
$apic_hosts = '10.0.0.1',
$apic_username = 'admin',
$apic_password = 'password',
$static_config = '',
$additional_config = '',
$service_plugins = 'neutron.services.l3_router.l3_apic.ApicL3ServicePlugin',
$mechanism_drivers = 'openvswitch,cisco_apic',
$policy_drivers = 'implicit_policy,apic',
$admin_username = 'admin',
$admin_password = 'admin',
$admin_tenant = 'admin',
$ext_net_enable = false,
$ext_net_name = 'ext',
$ext_net_switch = '101',
$ext_net_port = '1/1',
$ext_net_subnet = '10.0.0.0/24',
$ext_net_gateway = '10.0.0.1',
){
include 'apic::params'
include 'apic::api'
case $role {
/controller/: {
if $use_lldp {
include 'apic::svc_agent'
}
include 'neutron::services::apic_server'
include "neutron::services::${ha_prefix}agents"
include 'gbp::heat'
include "heat::${ha_prefix}services"
include 'gbp::horizon'
include 'gbp::client'
include 'gbp::manage'
class {'neutron::config_auth':
admin_username => $admin_username,
admin_password => $admin_password,
admin_tenant => $admin_tenant,
}
if ($role == 'primary-controller' and $ext_net_enable == true){
class {'neutron::network':
tenant_name => $admin_tenant,
ext_net_name => $ext_net_name,
ext_net_subnet => $ext_net_subnet,
ext_net_gateway => $ext_net_gateway,
}
}
}
'compute': {
include 'neutron::services::ovs_agent'
}
default: {
}
}
if $use_lldp {
include 'lldp'
include 'apic::host_agent'
}
class {'gbp::config':
policy_drivers => $policy_drivers,
}
class {'neutron::config':
service_plugins => $service_plugins,
mechanism_drivers => $mechanism_drivers,
}
class {'neutron::config_apic':
apic_hosts => $apic_hosts,
apic_username => $apic_username,
apic_password => $apic_password,
static_config => $static_config,
additional_config => $additional_config,
ext_net_enable => $ext_net_enable,
ext_net_name => $ext_net_name,
ext_net_switch => $ext_net_switch,
ext_net_port => $ext_net_port,
ext_net_subnet => $ext_net_subnet,
ext_net_gateway => $ext_net_gateway,
}
}

View File

@ -1,37 +0,0 @@
#Class cisco_aci::gbp_and_mapping
class cisco_aci::gbp_and_mapping (
$ha_prefix = '',
$role = 'compute',
$service_plugins = 'neutron.services.l3_router.l3_router_plugin.L3RouterPlugin,gbpservice.neutron.services.grouppolicy.plugin.GroupPolicyPlugin,gbpservice.neutron.services.servicechain.servicechain_plugin.ServiceChainPlugin',
$mechanism_drivers = 'openvswitch',
$policy_drivers = 'implicit_policy,resource_mapping',
){
include 'apic::api'
case $role {
/controller/: {
include 'neutron::services::server'
include "neutron::services::${ha_prefix}agents"
include 'gbp::heat'
include "heat::${ha_prefix}services"
include 'gbp::horizon'
include 'gbp::client'
include 'gbp::manage'
}
'compute': {
include 'neutron::services::ovs_agent'
}
default: {
}
}
class {'gbp::config':
policy_drivers => $policy_drivers,
}
class {'neutron::config':
service_plugins => $service_plugins,
mechanism_drivers => $mechanism_drivers,
}
}

View File

@ -1,79 +0,0 @@
#Class cisco_aci::generic_apic_ml2
class cisco_aci::generic_apic_ml2 (
$ha_prefix = '',
$role = 'compute',
$use_lldp = true,
$apic_hosts = '10.0.0.1',
$apic_username = 'admin',
$apic_password = 'password',
$static_config = '',
$additional_config = '',
$service_plugins = 'neutron.services.l3_router.l3_apic.ApicL3ServicePlugin',
$mechanism_drivers = 'openvswitch,cisco_apic',
$admin_username = 'admin',
$admin_password = 'admin',
$admin_tenant = 'admin',
$ext_net_enable = false,
$ext_net_name = 'ext',
$ext_net_switch = '101',
$ext_net_port = '1/1',
$ext_net_subnet = '10.0.0.0/24',
$ext_net_gateway = '10.0.0.1',
){
include 'apic::params'
include 'apic::api'
case $role {
/controller/: {
if $use_lldp {
include 'apic::svc_agent'
}
include 'neutron::services::apic_server'
include "neutron::services::${ha_prefix}agents"
class {'neutron::config_auth':
admin_username => $admin_username,
admin_password => $admin_password,
admin_tenant => $admin_tenant,
}
if ($role == 'primary-controller' and $ext_net_enable == true){
class {'neutron::network':
tenant_name => $admin_tenant,
ext_net_name => $ext_net_name,
ext_net_subnet => $ext_net_subnet,
ext_net_gateway => $ext_net_gateway,
}
}
}
'compute': {
include 'neutron::services::ovs_agent'
}
default: {
}
}
if $use_lldp {
include 'lldp'
include 'apic::host_agent'
}
class {'neutron::config':
service_plugins => $service_plugins,
mechanism_drivers => $mechanism_drivers,
}
class {'neutron::config_apic':
apic_hosts => $apic_hosts,
apic_username => $apic_username,
apic_password => $apic_password,
static_config => $static_config,
additional_config => $additional_config,
ext_net_enable => $ext_net_enable,
ext_net_name => $ext_net_name,
ext_net_switch => $ext_net_switch,
ext_net_port => $ext_net_port,
ext_net_subnet => $ext_net_subnet,
ext_net_gateway => $ext_net_gateway,
}
}

View File

@ -1,11 +0,0 @@
#Class gbp::client
class gbp::client (
$package_ensure = 'present',
){
include gbp::params
package { 'gbp_client':
ensure => $package_ensure,
name => $::gbp::params::package_gbp_client,
}
}

View File

@ -1,17 +0,0 @@
#Class gbp::config
class gbp::config (
$policy_drivers = '',
){
neutron_config {
'group_policy/policy_drivers': value => $policy_drivers;
'servicechain/servicechain_drivers': value => 'simplechain_driver';
'quotas/default_quota': value => '-1';
'quotas/quota_network': value => '-1';
'quotas/quota_subnet': value => '-1';
'quotas/quota_port': value => '-1';
'quotas/quota_security_group': value => '-1';
'quotas/quota_security_group_rule': value => '-1';
'quotas/quota_router': value => '-1';
'quotas/quota_floatingip': value => '-1';
}
}

View File

@ -1,18 +0,0 @@
#Class gbp::heat
class gbp::heat (
$package_ensure = 'present',
){
include gbp::params
Package['gbp_heat'] -> Heat_config<||>
package { 'gbp_heat':
ensure => $package_ensure,
name => $::gbp::params::package_gbp_heat,
}
heat_config{
'DEFAULT/plugin_dirs' : value => $::gbp::params::gbp_heat_plugin_path;
}
}

View File

@ -1,30 +0,0 @@
#Class gbp::horizon
class gbp::horizon (
$package_ensure = 'present',
){
include gbp::params
$enable_project = ['_50_gbp_project_add_panel_group.py','_60_gbp_project_add_panel.py','_61_gbp_project_add_panel.py','_62_gbp_project_add_panel.py','_63_gbp_project_add_panel.py']
package { 'gbp_horizon':
ensure => $package_ensure,
name => $::gbp::params::package_gbp_horizon,
}
case $::osfamily {
'RedHat': {
include horizon::service
Package['gbp_horizon'] ~> Service['httpd']
}
'Debian': {
horizon::project{$enable_project:
project_dir => $::gbp::params::gbp_horizon_project,
}
}
default: {
fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, module ${module_name} only support osfamily RedHat and Debian")
}
}
}

View File

@ -1,22 +0,0 @@
#Class gbp::manage
class gbp::manage (
$package_ensure = 'present',
){
include gbp::params
include neutron::services::server
Exec['gbp_dbsync'] ~> Service['neutron-server']
package { 'gbp_manage':
ensure => $package_ensure,
name => $::gbp::params::package_gbp_manage,
}
exec { 'gbp_dbsync':
command => $::gbp::params::dbsync_command,
path => '/usr/bin',
refreshonly => true,
logoutput => on_failure,
require => Package['gbp_manage'],
}
}

View File

@ -1,28 +0,0 @@
#Class gbp::params
class gbp::params {
$dbsync_command = 'gbp-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head'
case $::osfamily {
'RedHat': {
$package_gbp_client = 'python-gbpclient'
$package_gbp_manage = 'openstack-neutron-gbp'
$package_gbp_heat = 'openstack-heat-gbp'
$package_gbp_horizon = 'openstack-dashboard-gbp'
$gbp_heat_plugin_path = '/usr/lib/python2.6/site-packages/gbpautomation/heat'
}
'Debian': {
$package_gbp_client = 'python-group-based-policy-client'
$package_gbp_manage = 'group-based-policy'
$package_gbp_heat = 'group-based-policy-automation'
$package_gbp_horizon = 'group-based-policy-ui'
$gbp_horizon_project = '/usr/lib/python2.7/dist-packages/gbpui'
$gbp_heat_plugin_path = '/usr/lib/python2.7/site-packages/gbpautomation/heat'
}
default: {
fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, module ${module_name} only support osfamily RedHat and Debian")
}
}
}

View File

@ -1,22 +0,0 @@
Puppet::Type.type(:heat_api_cfn_config).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/heat/heat-api-cfn.conf'
end
end

View File

@ -1,23 +0,0 @@
Puppet::Type.type(:heat_api_cfn_paste_ini).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/heat/heat-api-cfn-paste.ini'
end
end

View File

@ -1,22 +0,0 @@
Puppet::Type.type(:heat_api_cloudwatch_config).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/heat/heat-api-cloudwatch.conf'
end
end

View File

@ -1,23 +0,0 @@
Puppet::Type.type(:heat_api_cloudwatch_paste_ini).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/heat/heat-api-cloudwatch-paste.ini'
end
end

View File

@ -1,23 +0,0 @@
Puppet::Type.type(:heat_api_config).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/heat/heat-api.conf'
end
end

View File

@ -1,23 +0,0 @@
Puppet::Type.type(:heat_api_paste_ini).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/heat/heat-api-paste.ini'
end
end

View File

@ -1,22 +0,0 @@
Puppet::Type.type(:heat_config).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/heat/heat.conf'
end
end

View File

@ -1,22 +0,0 @@
Puppet::Type.type(:heat_engine_config).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/heat/heat-engine.conf'
end
end

View File

@ -1,19 +0,0 @@
Puppet::Type.newtype(:heat_api_cfn_config) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from heat_api_cfn.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
end
end

View File

@ -1,19 +0,0 @@
Puppet::Type.newtype(:heat_api_cfn_paste_ini) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from heat-api.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
end
end

View File

@ -1,19 +0,0 @@
Puppet::Type.newtype(:heat_api_cloudwatch_config) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from heat-api-cloudwatch.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
end
end

View File

@ -1,19 +0,0 @@
Puppet::Type.newtype(:heat_api_cloudwatch_paste_ini) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from heat-api.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
end
end

View File

@ -1,19 +0,0 @@
Puppet::Type.newtype(:heat_api_config) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from heat-api.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
end
end

View File

@ -1,19 +0,0 @@
Puppet::Type.newtype(:heat_api_paste_ini) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from heat-api.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
end
end

View File

@ -1,19 +0,0 @@
Puppet::Type.newtype(:heat_config) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from heat.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
end
end

View File

@ -1,20 +0,0 @@
Puppet::Type.newtype(:heat_engine_config) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from heat-engine.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
puts value
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
end
end

View File

@ -1,49 +0,0 @@
#Class heat::ha_services
class heat::ha_services (
$enabled = true,
) {
include heat::params
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
service { 'heat-api':
ensure => $service_ensure,
name => $::heat::params::api_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'heat',
}
service { 'heat-api-cloudwatch':
ensure => $service_ensure,
name => $::heat::params::api_cloudwatch_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'heat',
}
service { 'heat-api-cfn':
ensure => $service_ensure,
name => $::heat::params::api_cfn_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'heat',
}
service { 'heat-engine':
ensure => $service_ensure,
name => $::heat::params::engine_ha_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
provider => 'pacemaker',
tag => 'heat',
}
Heat_config<||> ~> Service<| tag == 'heat' |>
}

View File

@ -1,31 +0,0 @@
# Parameters for puppet-heat
#
class heat::params {
$dbsync_command =
'heat-manage --config-file /etc/heat/heat.conf db_sync'
case $::osfamily {
'RedHat': {
# service names
$api_service_name = 'openstack-heat-api'
$api_cloudwatch_service_name = 'openstack-heat-api-cloudwatch'
$api_cfn_service_name = 'openstack-heat-api-cfn'
$engine_service_name = 'openstack-heat-engine'
$engine_ha_service_name = 'p_openstack-heat-engine'
}
'Debian': {
# service names
$api_service_name = 'heat-api'
$api_cloudwatch_service_name = 'heat-api-cloudwatch'
$api_cfn_service_name = 'heat-api-cfn'
$engine_service_name = 'heat-engine'
$engine_ha_service_name = 'p_heat-engine'
}
default: {
fail("Unsupported osfamily: ${::osfamily} operatingsystem: \
${::operatingsystem}, module ${module_name} only support osfamily \
RedHat and Debian")
}
}
}

View File

@ -1,48 +0,0 @@
#Class heat::services
class heat::services (
$enabled = true,
) {
include heat::params
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
service { 'heat-api':
ensure => $service_ensure,
name => $::heat::params::api_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'heat',
}
service { 'heat-api-cloudwatch':
ensure => $service_ensure,
name => $::heat::params::api_cloudwatch_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'heat',
}
service { 'heat-api-cfn':
ensure => $service_ensure,
name => $::heat::params::api_cfn_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'heat',
}
service { 'heat-engine_service':
ensure => $service_ensure,
name => $::heat::params::engine_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'heat',
}
Heat_config<||> ~> Service<| tag == 'heat' |>
}

View File

@ -1,19 +0,0 @@
# these parameters need to be accessed from several locations and
# should be considered to be constant
class horizon::params {
$dashboard_enabled = '/usr/share/openstack-dashboard/openstack_dashboard/enabled'
case $::osfamily {
'RedHat': {
$http_service = 'httpd'
}
'Debian': {
$http_service = 'apache2'
}
default: {
fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, module ${module_name} only support osfamily RedHat and Debian")
}
}
}

View File

@ -1,15 +0,0 @@
#
define horizon::project(
$project_dir = '/tmp',
){
include horizon::params
include horizon::service
File[$name] ~> Service['httpd']
file {$name:
ensure => link,
path => "${::horizon::params::dashboard_enabled}/${name}",
target => "${project_dir}/${name}",
}
}

View File

@ -1,13 +0,0 @@
#
class horizon::service(
$package_ensure = present,
) {
include horizon::params
service { 'httpd':
ensure => 'running',
name => $::horizon::params::http_service,
enable => true
}
}

View File

@ -1,58 +0,0 @@
#Class lldp
class lldp (
$ensure = 'present',
$autoupdate = true,
$package_name = 'lldpd',
$service_name = 'lldpd',
){
include lldp::params
case $ensure {
'present': {
if $autoupdate {
$pkg_ensure = 'latest'
} else {
$pkg_ensure = 'present'
}
$svc_ensure = 'running'
$svc_enable = true
$file_ensure = 'present'
}
'absent': {
$pkg_ensure = 'absent'
$svc_ensure = 'stopped'
$svc_enable = false
$file_ensure = 'absent'
}
'purged': {
$pkg_ensure = 'purged'
$svc_ensure = 'stopped'
$svc_enable = false
$file_ensure = 'absent'
}
default: {
}
}
package {$package_name:
ensure => $pkg_ensure,
}
file {$::lldp::params::config_file_path:
ensure => $file_ensure,
content => inline_template($::lldp::params::config_file_data),
require => Package[$package_name],
notify => Service[$service_name],
}
service {$service_name:
ensure => $svc_ensure,
enable => $svc_enable,
require => File[$::lldp::params::config_file_path],
hasstatus => false,
hasrestart => true,
}
}

View File

@ -1,20 +0,0 @@
#Class lldp::params
class lldp::params {
$autoupdate = false
$package_name = 'lldpd'
$service_name = 'lldpd'
case $::osfamily {
'Debian': {
$config_file_path = '/etc/default/lldpd'
$config_file_data = '#Generated by puppet <%= "\n" %>DAEMON_ARGS="-c -I eth*"<%= "\n" %>'
}
'RedHat': {
$config_file_path = '/etc/sysconfig/lldpd'
$config_file_data = '#Generated by puppet <%= "\n" %>LLDPD_OPTIONS="-c -I eth*"<%= "\n" %>'
}
default: { fail("lldp: unsuported OS family ${::osfamily}") }
}
}

View File

@ -1,3 +0,0 @@
configs+=(
"/etc/neutron/plugins/ml2/ml2_conf_cisco.ini" \
)

View File

@ -1,25 +0,0 @@
# vim:set ft=upstart ts=2 et:
description "Neutron API Server"
author "Chuck Short <zulcss@ubuntu.com>"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
chdir /var/run
pre-start script
mkdir -p /var/run/neutron
chown neutron:root /var/run/neutron
end script
script
[ -r /etc/default/neutron-server ] && . /etc/default/neutron-server
[ -r "$NEUTRON_PLUGIN_CONFIG" ] && CONF_ARG="--config-file $NEUTRON_PLUGIN_CONFIG"
exec start-stop-daemon --start --chuid neutron --exec /usr/bin/neutron-server -- \
--config-file /etc/neutron/neutron.conf \
--config-file /etc/neutron/plugins/ml2/ml2_conf.ini \
--config-file /etc/neutron/plugins/ml2/ml2_conf_cisco.ini \
--log-file /var/log/neutron/server.log $CONF_ARG
end script

View File

@ -1,272 +0,0 @@
require 'csv'
require 'puppet/util/inifile'
class Puppet::Provider::Neutron < Puppet::Provider
#NOTE(xenolog): self.prefetch was removed with comment:
# FIXME:(xarses) needs to be abstraced from subresources and re-written here
def self.conf_filename
'/etc/neutron/neutron.conf'
end
def self.withenv(hash, &block)
saved = ENV.to_hash
hash.each do |name, val|
ENV[name.to_s] = val
end
yield
ensure
ENV.clear
saved.each do |name, val|
ENV[name] = val
end
end
def self.neutron_credentials
@neutron_credentials ||= get_neutron_credentials
end
def self.get_neutron_credentials
auth_keys = ['auth_host', 'auth_port', 'auth_protocol',
'admin_tenant_name', 'admin_user', 'admin_password']
conf = neutron_conf
if conf and conf['keystone_authtoken'] and
auth_keys.all?{|k| !conf['keystone_authtoken'][k].nil?}
creds = Hash[ auth_keys.map \
{ |k| [k, conf['keystone_authtoken'][k].strip] } ]
if conf['DEFAULT'] and !conf['DEFAULT']['nova_region_name'].nil?
creds['nova_region_name'] = conf['DEFAULT']['nova_region_name']
end
return creds
else
raise(Puppet::Error, "File: #{conf_filename} does not contain all \
required sections. Neutron types will not work if neutron is not \
correctly configured.")
end
end
def neutron_credentials
self.class.neutron_credentials
end
def self.auth_endpoint
@auth_endpoint ||= get_auth_endpoint
end
def self.get_auth_endpoint
q = neutron_credentials
"#{q['auth_protocol']}://#{q['auth_host']}:#{q['auth_port']}/v2.0/"
end
def self.neutron_conf
return @neutron_conf if @neutron_conf
@neutron_conf = Puppet::Util::IniConfig::File.new
@neutron_conf.read(conf_filename)
@neutron_conf
end
def self.auth_neutron(*args)
q = neutron_credentials
authenv = {
:OS_AUTH_URL => self.auth_endpoint,
:OS_USERNAME => q['admin_user'],
:OS_TENANT_NAME => q['admin_tenant_name'],
:OS_PASSWORD => q['admin_password']
}
if q.key?('nova_region_name')
authenv[:OS_REGION_NAME] = q['nova_region_name']
end
# NOTE(bogdando) contribute change to upstream #1384097:
# enhanced message checks within a given time frame
rv = nil
timeout = 120
end_time = Time.now.to_i + timeout
loop do
begin
withenv authenv do
rv = neutron(args)
end
break
rescue Puppet::ExecutionFailure => e
if ! e.message =~ /(\(HTTP\s+400\))|
(400-\{\'message\'\:\s+\'\'\})|
(\[Errno 111\]\s+Connection\s+refused)|
(503\s+Service\s+Unavailable)|
(504\s+Gateway\s+Time-out)|
(\:\s+Maximum\s+attempts\s+reached)|
(Unauthorized\:\s+bad\s+credentials)|
(Max\s+retries\s+exceeded)/
raise(e)
end
current_time = Time.now.to_i
if current_time > end_time
break
else
wait = end_time - current_time
Puppet::debug("Non-fatal error: \"#{e.message}\"")
notice("Neutron API not avalaible. Wait up to #{wait} sec.")
end
sleep(2)
# Note(xarses): Don't remove, we know that there is one of the
# Recoverable erros above, So we will retry a few more times
end
end
return rv
end
def auth_neutron(*args)
self.class.auth_neutron(args)
end
def self.reset
@neutron_conf = nil
@neutron_credentials = nil
end
def self.list_neutron_resources(type)
ids = []
list = auth_neutron("#{type}-list", '--format=csv',
'--column=id', '--quote=none')
# NOTE(bogdando) contribute change to upstream #1384101:
# raise Puppet exception, if resources list is empty
if list.nil?
raise(Puppet::ExecutionFailure, "Can't prefetch #{type}-list Neutron or Keystone API is not avalaible.")
end
(list.split("\n")[1..-1] || []).compact.collect do |line|
ids << line.strip
end
return ids
end
def self.get_neutron_resource_attrs(type, id)
attrs = {}
net = auth_neutron("#{type}-show", '--format=shell', id)
# NOTE(bogdando) contribute change to upstream #1384101:
# raise Puppet exception, if list of resources' attributes is empty
if net.nil?
raise(Puppet::ExecutionFailure, "Can't prefetch #{type}-show Neutron or Keystone API is not avalaible.")
end
last_key = nil
(net.split("\n") || []).compact.collect do |line|
if line.include? '='
k, v = line.split('=', 2)
attrs[k] = v.gsub(/\A"|"\Z/, '')
last_key = k
else
# Handle the case of a list of values
v = line.gsub(/\A"|"\Z/, '')
attrs[last_key] = [attrs[last_key], v].flatten
end
end
return attrs
end
def self.list_router_ports(router_name_or_id)
results = []
cmd_output = auth_neutron("router-port-list",
'--format=csv',
router_name_or_id)
if ! cmd_output
return results
end
headers = nil
CSV.parse(cmd_output) do |row|
if headers == nil
headers = row
else
result = Hash[*headers.zip(row).flatten]
match_data = /.*"subnet_id": "(.*)", .*/.match(result['fixed_ips'])
if match_data
result['subnet_id'] = match_data[1]
end
results << result
end
end
return results
end
def self.auth_keystone(*args)
q = neutron_credentials
authenv = {
:OS_AUTH_URL => self.auth_endpoint,
:OS_USERNAME => q['admin_user'],
:OS_TENANT_NAME => q['admin_tenant_name'],
:OS_PASSWORD => q['admin_password']
}
if q.key?('nova_region_name')
authenv[:OS_REGION_NAME] = q['nova_region_name']
end
rv = nil
timeout = 120
end_time = Time.now.to_i + timeout
loop do
begin
withenv authenv do
rv = keystone(args)
end
break
rescue Puppet::ExecutionFailure => e
if ! e.message =~ /(\(HTTP\s+400\))|
(400-\{\'message\'\:\s+\'\'\})|
(\[Errno 111\]\s+Connection\s+refused)|
(503\s+Service\s+Unavailable)|
(504\s+Gateway\s+Time-out)|
(\:\s+Maximum\s+attempts\s+reached)|
(Unauthorized\:\s+bad\s+credentials)|
(Max\s+retries\s+exceeded)/
raise(e)
end
current_time = Time.now.to_i
if current_time > end_time
#raise(e)
break
else
wait = end_time - current_time
Puppet::debug("Non-fatal error: \"#{e.message}\"")
notice("Keystone API not avalaible. Wait up to #{wait} sec.")
end
sleep(2)
# Note(xarses): Don't remove, we know that there is one of the
# Recoverable erros above, So we will retry a few more times
end
end
return rv
end
def auth_keystone(*args)
self.class.auth_neutron(args)
end
def self.get_tenant_id(catalog, name)
rv = nil
auth_keystone('tenant-list').each do |line|
fields=line.split(/\s*\|\s*/)
if fields[1] and fields[1].size == 32
if fields[2] == name
rv = fields[1]
break
end
end
end
if rv.nil?
fail("Unable to get tenant-ID for tenant '#{name}'")
end
return rv
end
def self.parse_creation_output(data)
hash = {}
data.split("\n").compact.each do |line|
if line.include? '='
hash[line.split('=').first] = line.split('=', 2)[1].gsub(/\A"|"\Z/, '')
end
end
hash
end
end

View File

@ -1,22 +0,0 @@
Puppet::Type.type(:neutron_config).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/neutron/neutron.conf'
end
end

View File

@ -1,140 +0,0 @@
require File.join(File.dirname(__FILE__), '..','..','..',
'puppet/provider/neutron')
Puppet::Type.type(:neutron_network).provide(
:neutron,
:parent => Puppet::Provider::Neutron
) do
desc <<-EOT
Neutron provider to manage neutron_network type.
Assumes that the neutron service is configured on the same host.
EOT
commands :neutron => 'neutron'
commands :keystone => 'keystone'
mk_resource_methods
def self.neutron_type
'net'
end
def self.instances
list_neutron_resources(neutron_type).collect do |id|
attrs = get_neutron_resource_attrs(neutron_type, id)
new(
:ensure => :present,
:name => attrs['name'],
:id => attrs['id'],
:admin_state_up => attrs['admin_state_up'],
:provider_network_type => attrs['provider:network_type'],
:provider_physical_network => attrs['provider:physical_network'],
:provider_segmentation_id => attrs['provider:segmentation_id'],
:router_external => attrs['router:external'],
:shared => attrs['shared'],
:tenant_id => attrs['tenant_id']
)
end
end
def self.prefetch(resources)
networks = instances
resources.keys.each do |name|
if provider = networks.find{ |net| net.name == name }
resources[name].provider = provider
end
end
end
def exists?
@property_hash[:ensure] == :present
end
def create
network_opts = Array.new
if @resource[:shared] =~ /true/i
network_opts << '--shared'
end
if @resource[:tenant_name]
tenant_id = self.class.get_tenant_id(model.catalog,
@resource[:tenant_name])
notice("***N*** neutron_network::create *** tenant_id='#{tenant_id.inspect}'")
network_opts << "--tenant_id=#{tenant_id}"
elsif @resource[:tenant_id]
network_opts << "--tenant_id=#{@resource[:tenant_id]}"
end
if @resource[:provider_network_type]
network_opts << \
"--provider:network_type=#{@resource[:provider_network_type]}"
end
if @resource[:provider_physical_network]
network_opts << \
"--provider:physical_network=#{@resource[:provider_physical_network]}"
end
if @resource[:provider_segmentation_id]
network_opts << \
"--provider:segmentation_id=#{@resource[:provider_segmentation_id]}"
end
if @resource[:router_external]
network_opts << "--router:external=#{@resource[:router_external]}"
end
results = auth_neutron('net-create', '--format=shell',
network_opts, resource[:name])
if results =~ /Created a new network:/
attrs = self.class.parse_creation_output(results)
@property_hash = {
:ensure => :present,
:name => resource[:name],
:id => attrs['id'],
:admin_state_up => attrs['admin_state_up'],
:provider_network_type => attrs['provider:network_type'],
:provider_physical_network => attrs['provider:physical_network'],
:provider_segmentation_id => attrs['provider:segmentation_id'],
:router_external => attrs['router:external'],
:shared => attrs['shared'],
:tenant_id => attrs['tenant_id'],
}
else
fail("did not get expected message on network creation, got #{results}")
end
end
def destroy
auth_neutron('net-delete', name)
@property_hash[:ensure] = :absent
end
def admin_state_up=(value)
auth_neutron('net-update', "--admin_state_up=#{value}", name)
end
def shared=(value)
auth_neutron('net-update', "--shared=#{value}", name)
end
def router_external=(value)
auth_neutron('net-update', "--router:external=#{value}", name)
end
[
:provider_network_type,
:provider_physical_network,
:provider_segmentation_id,
:tenant_id,
].each do |attr|
define_method(attr.to_s + "=") do |value|
fail("Property #{attr.to_s} does not support being updated")
end
end
end

View File

@ -1,22 +0,0 @@
Puppet::Type.type(:neutron_plugin_ml2).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/neutron/plugins/ml2/ml2_conf.ini'
end
end

View File

@ -1,22 +0,0 @@
Puppet::Type.type(:neutron_plugin_ml2_cisco).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def file_path
'/etc/neutron/plugins/ml2/ml2_conf_cisco.ini'
end
end

View File

@ -1,192 +0,0 @@
require File.join(File.dirname(__FILE__), "..","..","..",
"puppet/provider/neutron")
Puppet::Type.type(:neutron_port).provide(
:neutron,
:parent => Puppet::Provider::Neutron
) do
desc <<-EOT
Neutron provider to manage neutron_port type.
Assumes that the neutron service is configured on the same host.
EOT
#TODO No security group support
commands :neutron => "neutron"
commands :keystone => 'keystone'
mk_resource_methods
def self.instances
list_neutron_resources("port").collect do |id|
attrs = get_neutron_resource_attrs("port", id)
attrs["name"] = attrs["id"] if attrs["name"].empty?
new(
:ensure => :present,
:name => attrs["name"],
:id => attrs["id"],
:status => attrs["status"],
:tenant_id => attrs["tenant_id"],
:network_id => attrs["network_id"],
:admin_state_up => attrs["admin_state_up"],
:network_name => get_network_name(attrs["network_id"]),
:subnet_name => get_subnet_name(parse_subnet_id(attrs["fixed_ips"])),
:subnet_id => parse_subnet_id(attrs["fixed_ips"]),
:ip_address => parse_ip_address(attrs["fixed_ips"])
)
end
end
def self.prefetch(resources)
instances_ = instances
resources.keys.each do |name|
if provider = instances_.find{ |instance| instance.name == name }
resources[name].provider = provider
end
end
end
def exists?
@property_hash[:ensure] == :present
end
def create
opts = Array.new
if @resource[:admin_state_up] == "False"
opts << "--admin-state-down"
end
if @resource[:ip_address]
# The spec says that multiple ip addresses may be specified, but this
# doesn't seem to work yet.
opts << "--fixed-ip"
opts << @resource[:ip_address].map{|ip|"ip_address=#{ip}"}.join(',')
end
if @resource[:subnet_name]
# The spec says that multiple subnets may be specified, but this doesn't
# seem to work yet.
opts << "--fixed-ip"
opts << @resource[:subnet_name].map{|s|"subnet_id=#{s}"}.join(',')
end
if @resource[:tenant_name]
tenant_id = self.class.get_tenant_id(
model.catalog,
@resource[:tenant_name]
)
opts << "--tenant_id=#{tenant_id}"
elsif @resource[:tenant_id]
opts << "--tenant_id=#{@resource[:tenant_id]}"
end
results = auth_neutron(
"port-create",
"--format=shell",
"--name=#{resource[:name]}",
opts,
resource[:network_name]
)
if results =~ /Created a new port:/
attrs = self.class.parse_creation_output(results)
@property_hash = {
:ensure => :present,
:name => resource[:name],
:id => attrs["id"],
:status => attrs["status"],
:tenant_id => attrs["tenant_id"],
:network_id => attrs["network_id"],
:admin_state_up => attrs["admin_state_up"],
:network_name => resource[:network_name],
:subnet_name => resource[:subnet_name],
:subnet_id => self.class.parse_subnet_id(attrs["fixed_ips"]),
:ip_address => self.class.parse_ip_address(attrs["fixed_ips"])
}
else
fail("did not get expected message on port creation, got #{results}")
end
end
def destroy
auth_neutron("port-delete", name)
@property_hash[:ensure] = :absent
end
def admin_state_up=(value)
auth_neutron("port-update", "--admin-state-up=#{value}", name)
end
private
def self.get_network_name(network_id_)
if network_id_
network_instances = Puppet::Type.type("neutron_network").instances
network_name = network_instances.find do |instance|
instance.provider.id == network_id_
end.provider.name
end
network_name
end
def get_network_name(network_id_)
@get_network_name ||= self.class.get_network_name(network_id_)
end
def self.get_subnet_name(subnet_id_)
if subnet_id_
subnet_ids = Array(subnet_id_)
subnet_instances = Puppet::Type.type("neutron_subnet").instances
subnet_names = subnet_instances.collect do |instance|
if subnet_ids.include?(instance.provider.id)
instance.provider.name
else
nil
end
end.compact
if subnet_names.length > 1
subnet_names
else
subnet_names.first
end
end
end
def get_subnet_name(subnet_id_)
@subnet_name ||= self.class.subnet_name(subnet_id_)
end
def self.parse_subnet_id(fixed_ips_)
subnet_ids = Array(fixed_ips_).collect do |json|
match_data = /\{"subnet_id": "(.*)", /.match(json)
if match_data
match_data[1]
else
nil
end
end.compact
if subnet_ids.length > 1
subnet_ids
else
subnet_ids.first
end
end
def self.parse_ip_address(fixed_ips_)
ip_addresses = Array(fixed_ips_).collect do |json|
match_data = /"ip_address": "(.*)"\}/.match(json)
if match_data
match_data[1]
else
nil
end
end.compact
if ip_addresses.length > 1
ip_addresses
else
ip_addresses.first
end
end
end

View File

@ -1,139 +0,0 @@
require File.join(File.dirname(__FILE__), '..','..','..',
'puppet/provider/neutron')
Puppet::Type.type(:neutron_router).provide(
:neutron,
:parent => Puppet::Provider::Neutron
) do
desc <<-EOT
Neutron provider to manage neutron_router type.
Assumes that the neutron service is configured on the same host.
EOT
commands :neutron => 'neutron'
commands :keystone => 'keystone'
mk_resource_methods
def self.instances
list_neutron_resources('router').collect do |id|
attrs = get_neutron_resource_attrs('router', id)
new(
:ensure => :present,
:name => attrs['name'],
:id => attrs['id'],
:admin_state_up => attrs['admin_state_up'],
:external_gateway_info => attrs['external_gateway_info'],
:status => attrs['status'],
:tenant_id => attrs['tenant_id']
)
end
end
def self.prefetch(resources)
instances_ = instances
resources.keys.each do |name|
if provider = instances_.find{ |instance| instance.name == name }
resources[name].provider = provider
end
end
end
def exists?
@property_hash[:ensure] == :present
end
def create
opts = Array.new
if @resource[:admin_state_up] == 'False'
opts << '--admin-state-down'
end
if @resource[:tenant_name]
tenant_id = self.class.get_tenant_id(model.catalog,
@resource[:tenant_name])
opts << "--tenant_id=#{tenant_id}"
elsif @resource[:tenant_id]
opts << "--tenant_id=#{@resource[:tenant_id]}"
end
results = auth_neutron("router-create", '--format=shell',
opts, resource[:name])
if results =~ /Created a new router:/
attrs = self.class.parse_creation_output(results)
@property_hash = {
:ensure => :present,
:name => resource[:name],
:id => attrs['id'],
:admin_state_up => attrs['admin_state_up'],
:external_gateway_info => attrs['external_gateway_info'],
:status => attrs['status'],
:tenant_id => attrs['tenant_id'],
}
if @resource[:gateway_network_name]
results = auth_neutron('router-gateway-set',
@resource[:name],
@resource[:gateway_network_name])
if results =~ /Set gateway for router/
attrs = self.class.get_neutron_resource_attrs('router',
@resource[:name])
@property_hash[:external_gateway_info] = \
attrs['external_gateway_info']
else
fail(<<-EOT
did not get expected message on setting router gateway, got #{results}
EOT
)
end
end
else
fail("did not get expected message on router creation, got #{results}")
end
end
def destroy
auth_neutron('router-delete', name)
@property_hash[:ensure] = :absent
end
def gateway_network_name
if @gateway_network_name == nil and gateway_network_id
Puppet::Type.type('neutron_network').instances.each do |instance|
if instance.provider.id == gateway_network_id
@gateway_network_name = instance.provider.name
end
end
end
@gateway_network_name
end
def gateway_network_name=(value)
if value == ''
auth_neutron('router-gateway-clear', name)
else
auth_neutron('router-gateway-set', name, value)
end
end
def parse_gateway_network_id(external_gateway_info_)
match_data = /\{"network_id": "(.*?)"/.match(external_gateway_info_)
if match_data
match_data[1]
else
''
end
end
def gateway_network_id
@gateway_network_id ||= parse_gateway_network_id(external_gateway_info)
end
def admin_state_up=(value)
auth_neutron('router-update', "--admin-state-up=#{value}", name)
end
end

View File

@ -1,93 +0,0 @@
require File.join(File.dirname(__FILE__), '..','..','..',
'puppet/provider/neutron')
Puppet::Type.type(:neutron_router_interface).provide(
:neutron,
:parent => Puppet::Provider::Neutron
) do
desc <<-EOT
Neutron provider to manage neutron_router_interface type.
Assumes that the neutron service is configured on the same host.
It is not possible to manage an interface for the subnet used by
the gateway network, and such an interface will appear in the list
of resources ('puppet resource [type]'). Attempting to manage the
gateway interfae will result in an error.
EOT
commands :neutron => 'neutron'
mk_resource_methods
def self.instances
subnet_name_hash = {}
Puppet::Type.type('neutron_subnet').instances.each do |instance|
subnet_name_hash[instance.provider.id] = instance.provider.name
end
instances_ = []
Puppet::Type.type('neutron_router').instances.each do |instance|
list_router_ports(instance.provider.id).each do |port_hash|
router_name = instance.provider.name
subnet_name = subnet_name_hash[port_hash['subnet_id']]
name = "#{router_name}:#{subnet_name}"
instances_ << new(
:ensure => :present,
:name => name,
:id => port_hash['id'],
:port => port_hash['name']
)
end
end
return instances_
end
def self.prefetch(resources)
instances_ = instances
resources.keys.each do |name|
if provider = instances_.find{ |instance| instance.name == name }
resources[name].provider = provider
end
end
end
def exists?
@property_hash[:ensure] == :present
end
def create
router,subnet = resource[:name].split(':', 2)
port = resource[:port]
args = ["router-interface-add", "--format=shell", router]
if port
args << "port=#{port}"
else
args << "subnet=#{subnet}"
end
results = auth_neutron(args)
if results =~ /Added interface.* to router/
@property_hash = {
:ensure => :present,
:name => resource[:name],
}
else
fail("did not get expected message on interface addition, got #{results}")
end
end
def router_name
name.split(':', 2).first
end
def subnet_name
name.split(':', 2).last
end
def destroy
auth_neutron('router-interface-delete', router_name, subnet_name)
@property_hash[:ensure] = :absent
end
end

View File

@ -1,220 +0,0 @@
require File.join(File.dirname(__FILE__), '..','..','..',
'puppet/provider/neutron')
Puppet::Type.type(:neutron_subnet).provide(
:neutron,
:parent => Puppet::Provider::Neutron
) do
desc <<-EOT
Neutron provider to manage neutron_subnet type.
Assumes that the neutron service is configured on the same host.
EOT
commands :neutron => 'neutron'
commands :keystone => 'keystone'
mk_resource_methods
def self.neutron_type
'subnet'
end
def self.instances
list_neutron_resources(neutron_type).collect do |id|
attrs = get_neutron_resource_attrs(neutron_type, id)
new(
:ensure => :present,
:name => attrs['name'],
:id => attrs['id'],
:cidr => attrs['cidr'],
:ip_version => attrs['ip_version'],
:gateway_ip => parse_gateway_ip(attrs['gateway_ip']),
:allocation_pools => parse_allocation_pool(attrs['allocation_pools']),
:host_routes => parse_host_routes(attrs['host_routes']),
:dns_nameservers => parse_dns_nameservers(attrs['dns_nameservers']),
:enable_dhcp => attrs['enable_dhcp'],
:network_id => attrs['network_id'],
:tenant_id => attrs['tenant_id']
)
end
end
def self.prefetch(resources)
subnets = instances
resources.keys.each do |name|
if provider = subnets.find{ |subnet| subnet.name == name }
resources[name].provider = provider
end
end
end
def self.parse_gateway_ip(value)
return '' if value.nil?
return value
end
def self.parse_allocation_pool(values)
allocation_pools = []
return [] if values.empty?
for value in Array(values)
matchdata = /\{\s*"start"\s*:\s*"(.*)"\s*,\s*"end"\s*:\s*"(.*)"\s*\}/.match(value.gsub(/\\"/,'"'))
start_ip = matchdata[1]
end_ip = matchdata[2]
allocation_pools << "start=#{start_ip},end=#{end_ip}"
end
return allocation_pools
end
def self.parse_host_routes(values)
host_routes = []
return [] if values.empty?
for value in Array(values)
matchdata = /\{\s*"destination"\s*:\s*"(.*)"\s*,\s*"nexthop"\s*:\s*"(.*)"\s*\}/.match(value)
destination = matchdata[1]
nexthop = matchdata[2]
host_routes << "destination=#{destination},nexthop=#{nexthop}"
end
return host_routes
end
def self.parse_dns_nameservers(values)
# just enforce that this is actually an array
return Array(values)
end
def exists?
@property_hash[:ensure] == :present
end
def create
opts = ["--name=#{@resource[:name]}"]
if @resource[:ip_version]
opts << "--ip-version=#{@resource[:ip_version]}"
end
if @resource[:gateway_ip]
if @resource[:gateway_ip] == ''
opts << '--no-gateway'
else
opts << "--gateway-ip=#{@resource[:gateway_ip]}"
end
end
if @resource[:enable_dhcp] == 'False'
opts << "--disable-dhcp"
else
opts << "--enable-dhcp"
end
if @resource[:allocation_pools]
Array(@resource[:allocation_pools]).each do |allocation_pool|
opts << "--allocation-pool=#{allocation_pool}"
end
end
if @resource[:dns_nameservers]
Array(@resource[:dns_nameservers]).each do |nameserver|
opts << "--dns-nameserver=#{nameserver}"
end
end
if @resource[:host_routes]
Array(@resource[:host_routes]).each do |host_route|
opts << "--host-route=#{host_route}"
end
end
if @resource[:tenant_name]
tenant_id = self.class.get_tenant_id(model.catalog,
@resource[:tenant_name])
opts << "--tenant_id=#{tenant_id}"
elsif @resource[:tenant_id]
opts << "--tenant_id=#{@resource[:tenant_id]}"
end
if @resource[:network_name]
opts << resource[:network_name]
elsif @resource[:network_id]
opts << resource[:network_id]
end
results = auth_neutron('subnet-create', '--format=shell',
opts, resource[:cidr])
if results =~ /Created a new subnet:/
attrs = self.class.parse_creation_output(results)
@property_hash = {
:ensure => :present,
:name => resource[:name],
:id => attrs['id'],
:cidr => attrs['cidr'],
:ip_version => attrs['ip_version'],
:gateway_ip => self.class.parse_gateway_ip(attrs['gateway_ip']),
:allocation_pools => self.class.parse_allocation_pool(attrs['allocation_pools']),
:host_routes => self.class.parse_host_routes(attrs['host_routes']),
:dns_nameservers => self.class.parse_dns_nameservers(attrs['dns_nameservers']),
:enable_dhcp => attrs['enable_dhcp'],
:network_id => attrs['network_id'],
:tenant_id => attrs['tenant_id'],
}
else
fail("did not get expected message on subnet creation, got #{results}")
end
end
def destroy
auth_neutron('subnet-delete', name)
@property_hash[:ensure] = :absent
end
def gateway_ip=(value)
if value == ''
auth_neutron('subnet-update', '--no-gateway', name)
else
auth_neutron('subnet-update', "--gateway-ip=#{value}", name)
end
end
def enable_dhcp=(value)
if value == 'False'
auth_neutron('subnet-update', "--disable-dhcp", name)
else
auth_neutron('subnet-update', "--enable-dhcp", name)
end
end
def dns_nameservers=(values)
unless values.empty?
opts = ["#{name}", "--dns-nameservers", "list=true"]
for value in values
opts << value
end
auth_neutron('subnet-update', opts)
end
end
def host_routes=(values)
unless values.empty?
opts = ["#{name}", "--host-routes", "type=dict", "list=true"]
for value in values
opts << value
end
auth_neutron('subnet-update', opts)
end
end
[
:cidr,
:ip_version,
:network_id,
:allocation_pools,
:tenant_id,
].each do |attr|
define_method(attr.to_s + "=") do |value|
fail("Property #{attr.to_s} does not support being updated")
end
end
end

View File

@ -1,47 +0,0 @@
Puppet::Type.newtype(:neutron_config) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from neutron.conf'
newvalues(/\S+\/\S+/)
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
def is_to_s( currentvalue )
if resource.secret?
return '[old secret redacted]'
else
return currentvalue
end
end
def should_to_s( newvalue )
if resource.secret?
return '[new secret redacted]'
else
return newvalue
end
end
end
newparam(:secret, :boolean => true) do
desc 'Whether to hide the value from Puppet logs. Defaults to `false`.'
newvalues(:true, :false)
defaultto false
end
def create
provider.create
end
end

View File

@ -1,90 +0,0 @@
Puppet::Type.newtype(:neutron_network) do
ensurable
newparam(:name, :namevar => true) do
desc 'Symbolic name for the network'
newvalues(/.*/)
end
newproperty(:id) do
desc 'The unique id of the network'
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:admin_state_up) do
desc 'The administrative status of the network'
newvalues(/(t|T)rue/, /(f|F)alse/)
munge do |v|
v.to_s.capitalize
end
end
newproperty(:shared) do
desc 'Whether this network should be shared across all tenants or not'
newvalues(/(t|T)rue/, /(f|F)alse/)
munge do |v|
v.to_s.capitalize
end
end
newparam(:tenant_name) do
desc 'The name of the tenant which will own the network.'
end
newproperty(:tenant_id) do
desc 'A uuid identifying the tenant which will own the network.'
end
newproperty(:provider_network_type) do
desc 'The physical mechanism by which the virtual network is realized.'
newvalues(:flat, :vlan, :local, :gre)
end
newproperty(:provider_physical_network) do
desc <<-EOT
The name of the physical network over which the virtual network
is realized for flat and VLAN networks.
EOT
newvalues(/\S+/)
end
newproperty(:provider_segmentation_id) do
desc 'Identifies an isolated segment on the physical network.'
munge do |v|
Integer(v)
end
end
newproperty(:router_external) do
desc 'Whether this router will route traffic to an external network'
newvalues(/(t|T)rue/, /(f|F)alse/)
munge do |v|
v.to_s.capitalize
end
end
# Require the neutron-server service to be running
autorequire(:service) do
['neutron-server']
end
autorequire(:keystone_tenant) do
[self[:tenant_name]] if self[:tenant_name]
end
validate do
if self[:ensure] != :present
return
end
if self[:tenant_id] && self[:tenant_name]
raise(Puppet::Error, <<-EOT
Please provide a value for only one of tenant_name and tenant_id.
EOT
)
end
end
end

View File

@ -1,20 +0,0 @@
Puppet::Type.newtype(:neutron_plugin_ml2) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from ml2_conf.ini'
newvalues(/\S+\/\S+/)
end
autorequire(:package) do ['neutron'] end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
end
end

View File

@ -1,47 +0,0 @@
Puppet::Type.newtype(:neutron_plugin_ml2_cisco) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from cisco_plugins.ini'
newvalues(/\S+\/\S+/)
end
autorequire(:file) do
['/etc/neutron/plugins/ml2/ml2_conf_cisco.ini']
end
newproperty(:value) do
desc 'The value of the setting to be defined.'
munge do |value|
value = value.to_s.strip
value.capitalize! if value =~ /^(true|false)$/i
value
end
def is_to_s( currentvalue )
if resource.secret?
return '[old secret redacted]'
else
return currentvalue
end
end
def should_to_s( newvalue )
if resource.secret?
return '[new secret redacted]'
else
return newvalue
end
end
end
newparam(:secret, :boolean => true) do
desc 'Whether to hide the value from Puppet logs. Defaults to `false`.'
newvalues(:true, :false)
defaultto false
end
end

View File

@ -1,98 +0,0 @@
Puppet::Type.newtype(:neutron_port) do
desc <<-EOT
This is currently used to model the creation of neutron ports.
Ports are used when associating a network and a router interface.
EOT
ensurable
newparam(:name, :namevar => true) do
desc 'Symbolic name for the port'
newvalues(/.*/)
end
newproperty(:id) do
desc 'The unique id of the port'
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:admin_state_up) do
desc 'The administrative status of the router'
newvalues(/(t|T)rue/, /(f|F)alse/)
munge do |v|
v.to_s.capitalize
end
end
newproperty(:network_name) do
desc <<-EOT
The name of the network that this port is assigned to on creation.
EOT
end
newproperty(:network_id) do
desc <<-EOT
The uuid of the network that this port is assigned to on creation.
EOT
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:subnet_name) do
desc 'A subnet to which the port is assigned on creation.'
end
newproperty(:subnet_id) do
desc <<-EOT
The uuid of the subnet on which this ports ip exists.
EOT
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:ip_address) do
desc 'A static ip address given to the port on creation.'
end
newproperty(:status) do
desc 'Whether the port is currently operational or not.'
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newparam(:tenant_name) do
desc 'The name of the tenant which will own the port.'
end
newproperty(:tenant_id) do
desc 'A uuid identifying the tenant which will own the port.'
end
autorequire(:service) do
['neutron-server']
end
autorequire(:keystone_tenant) do
[self[:tenant_name]] if self[:tenant_name]
end
autorequire(:neutron_network) do
[self[:name]]
end
validate do
if self[:tenant_id] && self[:tenant_name]
raise(Puppet::Error, 'Please provide a value for only one of tenant_name and tenant_id.')
end
if self[:ip_address] && self[:subnet_name]
raise(Puppet::Error, 'Please provide a value for only one of ip_address and subnet_name.')
end
end
end

View File

@ -1,91 +0,0 @@
Puppet::Type.newtype(:neutron_router) do
ensurable
newparam(:name, :namevar => true) do
desc 'Symbolic name for the router'
newvalues(/.*/)
end
newproperty(:id) do
desc 'The unique id of the router'
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:admin_state_up) do
desc 'The administrative status of the router'
newvalues(/(t|T)rue/, /(f|F)alse/)
munge do |v|
v.to_s.capitalize
end
end
newproperty(:external_gateway_info) do
desc <<-EOT
External network that this router connects to for gateway services
(e.g., NAT).
EOT
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:gateway_network_name) do
desc <<-EOT
The name of the external network that this router connects to
for gateway services (e.g. NAT).
EOT
end
newproperty(:gateway_network_id) do
desc <<-EOT
The uuid of the external network that this router connects to
for gateway services (e.g. NAT).
EOT
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:status) do
desc 'Whether the router is currently operational or not.'
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newparam(:tenant_name) do
desc 'The name of the tenant which will own the router.'
end
newproperty(:tenant_id) do
desc 'A uuid identifying the tenant which will own the router.'
end
autorequire(:service) do
['neutron-server']
end
autorequire(:keystone_tenant) do
[self[:tenant_name]] if self[:tenant_name]
end
autorequire(:neutron_network) do
[self[:gateway_network_name]] if self[:gateway_network_name]
end
validate do
if self[:ensure] != :present
return
end
if self[:tenant_id] && self[:tenant_name]
raise(Puppet::Error, <<-EOT
Please provide a value for only one of tenant_name and tenant_id.
EOT
)
end
end
end

View File

@ -1,51 +0,0 @@
Puppet::Type.newtype(:neutron_router_interface) do
desc <<-EOT
This is currently used to model the creation of
neutron router interfaces.
Router interfaces are an association between a router and a
subnet.
EOT
ensurable
newparam(:name, :namevar => true) do
newvalues(/^\S+:\S+$/)
end
newproperty(:id) do
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:router_name) do
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:subnet_name) do
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:port) do
desc 'An existing neutron port to which a rounter interface should be assigned'
end
autorequire(:service) do
['neutron-server']
end
autorequire(:neutron_router) do
self[:name].split(':', 2).first
end
autorequire(:neutron_subnet) do
self[:name].split(':', 2).last
end
end

View File

@ -1,114 +0,0 @@
Puppet::Type.newtype(:neutron_subnet) do
ensurable
newparam(:name, :namevar => true) do
desc 'Symbolic name for the subnet'
newvalues(/.*/)
end
newproperty(:id) do
desc 'The unique id of the subnet'
validate do |v|
raise(Puppet::Error, 'This is a read only property')
end
end
newproperty(:cidr) do
desc 'CIDR representing IP range for this subnet, based on IP version'
end
newproperty(:ip_version) do
desc 'The IP version of the CIDR'
newvalues('4', '6')
end
newproperty(:allocation_pools, :array_matching => :all) do
desc <<-EOT
Array of Sub-ranges of cidr available for dynamic allocation to ports.
Syntax:["start=IPADDR,end=IPADDR", ...]
EOT
end
newproperty(:gateway_ip) do
desc <<-EOT
The default gateway provided by DHCP to devices in this subnet. If set to
'' then no gateway IP address will be provided via DHCP.
EOT
end
newproperty(:enable_dhcp) do
desc 'Whether DHCP is enabled for this subnet or not.'
newvalues(/(t|T)rue/, /(f|F)alse/)
munge do |v|
v.to_s.capitalize
end
end
newproperty(:host_routes, :array_matching => :all) do
desc <<-EOT
Array of routes that should be used by devices with IPs from this subnet
(not including local subnet route).
Syntax:["destination=CIDR,nexhop=IP_ADDR", ...]
EOT
end
newproperty(:dns_nameservers, :array_matching => :all) do
desc <<-EOT
'Array of DNS name servers used by hosts in this subnet.'
EOT
end
newproperty(:network_id) do
desc 'A uuid identifying the network this subnet is associated with.'
end
newparam(:network_name) do
desc 'The name of the network this subnet is associated with.'
end
newparam(:tenant_name) do
desc 'The name of the tenant which will own the subnet.'
end
newproperty(:tenant_id) do
desc 'A uuid identifying the tenant which will own the subnet.'
end
autorequire(:service) do
['neutron-server']
end
autorequire(:keystone_tenant) do
[self[:tenant_name]] if self[:tenant_name]
end
autorequire(:neutron_network) do
[self[:network_name]] if self[:network_name]
end
validate do
if self[:ensure] != :present
return
end
if ! self[:cidr]
raise(Puppet::Error, 'Please provide a valid CIDR')
elsif ! (self[:network_id] || self[:network_name])
raise(Puppet::Error, <<-EOT
A value for one of network_name or network_id must be provided.
EOT
)
elsif self[:network_id] && self[:network_name]
raise(Puppet::Error, <<-EOT
Please provide a value for only one of network_name and network_id.
EOT
)
elsif self[:tenant_id] && self[:tenant_name]
raise(Puppet::Error, <<-EOT
Please provide a value for only one of tenant_name and tenant_id.
EOT
)
end
end
end

View File

@ -1,26 +0,0 @@
#Class neutron::config
class neutron::config (
$service_plugins = 'neutron.services.l3_router.l3_router_plugin.L3RouterPlugin',
$mechanism_drivers = 'openvswitch',
){
neutron_config {
'DEFAULT/service_plugins': value => $service_plugins;
'DEFAULT/core_plugin': value => 'neutron.plugins.ml2.plugin.Ml2Plugin';
}
neutron_plugin_ml2 {
'ml2/type_drivers': value => 'local,flat,vlan,gre,vxlan';
'ml2/tenant_network_types': value => 'vlan';
'ml2/mechanism_drivers': value => $mechanism_drivers;
#'ml2_type_vlan/network_vlan_ranges': value => "$physnets_dev:$vlan_range";
'securitygroup/enable_security_group': value => 'True';
'securitygroup/firewall_driver': value => 'neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver';
#'ovs/integration_bridge': value => "$int_bridge";
#'ovs/bridge_mappings': value => "$physnets_dev:$int_bridge";
#'ovs/enable_tunneling': value => 'False';
'agent/polling_interval': value => '2';
'agent/l2_population': value => 'False';
'agent/arp_responder': value => 'False';
}
}

View File

@ -1,49 +0,0 @@
#Class neutron::config_apic
class neutron::config_apic (
$apic_hosts = '10.0.0.1',
$apic_username = 'admin',
$apic_password = 'password',
$static_config = '',
$additional_config = '',
$ext_net_enable = false,
$ext_net_name = 'ext',
$ext_net_switch = '101',
$ext_net_port = '1/1',
$ext_net_subnet = '10.0.0.0/24',
$ext_net_gateway = '10.0.0.1',
){
neutron_plugin_ml2_cisco {
'DEFAULT/apic_system_id': value => 'openstack';
'ml2_cisco_apic/apic_hosts': value => $apic_hosts;
'ml2_cisco_apic/apic_username': value => $apic_username;
'ml2_cisco_apic/apic_password': value => $apic_password;
'ml2_cisco_apic/apic_name_mapping': value => 'use_name' ;
}
if $::osfamily == 'RedHat' {
neutron_plugin_ml2_cisco {
'ml2_cisco_apic/root_helper': value => 'sudo';
}
}
if !empty($additional_config) {
file_line{ 'additional_config':
path => '/etc/neutron/plugins/ml2/ml2_conf_cisco.ini',
line => $additional_config,
}
}
if !empty($static_config) {
file_line{ 'static_config':
path => '/etc/neutron/plugins/ml2/ml2_conf_cisco.ini',
line => $static_config,
}
}
if ($ext_net_enable == true){
neutron_plugin_ml2_cisco {
"apic_external_network:${ext_net_name}/switch": value => $ext_net_switch;
"apic_external_network:${ext_net_name}/port": value => $ext_net_port;
"apic_external_network:${ext_net_name}/cidr_exposed": value => $ext_net_subnet;
"apic_external_network:${ext_net_name}/gateway_ip": value => $ext_net_gateway;
}
}
}

View File

@ -1,13 +0,0 @@
#Class neutron::config_auth
class neutron::config_auth (
$admin_username = 'admin',
$admin_password = 'admin',
$admin_tenant = 'admin',
){
neutron_config {
'keystone_authtoken/admin_user': value => $admin_username;
'keystone_authtoken/admin_password': value => $admin_password;
'keystone_authtoken/admin_tenant_name': value => $admin_tenant;
}
}

View File

@ -1,39 +0,0 @@
#Class neutron::network
class neutron::network (
$ensure = 'present',
$ext_net_name = 'extnet',
$ext_net_subnet = '10.0.0.0/24',
$ext_net_gateway = '10.0.0.1',
$shared = true,
$tenant_name = 'admin',
) {
neutron_network { $ext_net_name:
ensure => $ensure,
router_external => true,
tenant_name => $tenant_name,
shared => $shared,
}
->
neutron_subnet { "${ext_net_name}__subnet":
ensure => $ensure,
cidr => $ext_net_subnet,
network_name => $ext_net_name,
tenant_name => $tenant_name,
gateway_ip => $ext_net_gateway,
}
->
neutron_router { "${ext_net_name}__router":
ensure => $ensure,
tenant_name => $tenant_name,
}
->
neutron_router_interface { "${ext_net_name}__router:${ext_net_name}__subnet":
ensure => present,
}
Service<| title == 'neutron-server'|> -> Neutron_network<||>
Service<| title == 'neutron-server'|> -> Neutron_subnet<||>
Service<| title == 'neutron-server'|> -> Neutron_router<||>
Service<| title == 'neutron-server'|> -> Neutron_router_interface<||>
}

View File

@ -1,31 +0,0 @@
#Class neutron::params
class neutron::params {
$ha_metadata_agent = 'p_neutron-metadata-agent'
$ha_dhcp_agent = 'p_neutron-dhcp-agent'
$ha_l3_agent = 'p_neutron-l3-agent'
$service_metadata_agent = 'neutron-metadata-agent'
$service_dhcp_agent = 'neutron-dhcp-agent'
$service_l3_agent = 'neutron-l3-agent'
$service_neutron_server = 'neutron-server'
case $::osfamily {
'RedHat': {
$service_ovs_agent = 'neutron-openvswitch-agent'
$ha_ovs_agent = 'p_neutron-openvswitch-agent'
$initd_file_path = '/etc/sysconfig/neutron'
$initd_file_template = 'puppet:///modules/neutron/neutron'
}
'Debian': {
$service_ovs_agent = 'neutron-plugin-openvswitch-agent'
$ha_ovs_agent = 'p_neutron-plugin-openvswitch-agent'
$initd_file_path = '/etc/init/neutron-server.conf'
$initd_file_template = 'puppet:///modules/neutron/neutron-server.conf'
}
default: {
fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, module ${module_name} only support osfamily RedHat and Debian")
}
}
}

View File

@ -1,57 +0,0 @@
#Class neutron::services::agents
class neutron::services::agents (
$enabled = true,
$manage_service = true,
){
include neutron::params
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
service { 'neutron-ovs-agent':
ensure => $service_ensure,
name => $::neutron::params::service_ovs_agent,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'neutron_agents'
}
service { 'neutron-metadata-agent':
ensure => $service_ensure,
name => $::neutron::params::service_metadata_agent,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'neutron_agents'
}
service { 'neutron-dhcp-agent':
ensure => $service_ensure,
name => $::neutron::params::service_dhcp_agent,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'neutron_agents'
}
service { 'neutron-l3-agent':
ensure => $service_ensure,
name => $::neutron::params::service_l3_agent,
enable => $enabled,
hasstatus => true,
hasrestart => true,
tag => 'neutron_agents'
}
Neutron_config<||> ~> Service<| tag == 'neutron_agents' |>
Neutron_plugin_ml2<||> ~> Service<| tag == 'neutron_agents' |>
Neutron_plugin_ml2_cisco<||> ~> Service<| tag == 'neutron_agents' |>
File_line<||> ~> Service<| tag == 'neutron_agents' |>
}

View File

@ -1,16 +0,0 @@
#Class neutron::services::apic_server
class neutron::services::apic_server (
$enabled = true,
$manage_service = true,
){
include neutron::params
include neutron::services::server
File['neutron_initd'] ~> Service['neutron-server']
file {'neutron_initd':
ensure => 'present',
path => $::neutron::params::initd_file_path,
source => $::neutron::params::initd_file_template,
}
}

View File

@ -1,62 +0,0 @@
#Class neutron::services::ha_agents
class neutron::services::ha_agents (
$enabled = true,
$manage_service = true,
){
include neutron::params
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
service {'neutron-dhcp-agent':
ensure => $service_ensure,
name => $::neutron::params::ha_dhcp_agent,
enable => $enabled,
hasstatus => true,
hasrestart => false,
provider => 'pacemaker',
tag => 'ha_agents',
}
service {'neutron-metadata-agent':
ensure => $service_ensure,
name => $::neutron::params::ha_metadata_agent,
enable => $enabled,
hasstatus => true,
hasrestart => false,
provider => 'pacemaker',
tag => 'ha_agents',
}
service {'neutron-plugin-openvswitch-agent':
ensure => $service_ensure,
name => $::neutron::params::ha_ovs_agent,
enable => $enabled,
hasstatus => true,
hasrestart => false,
provider => 'pacemaker',
tag => 'ha_agents',
}
service {'neutron-l3-agent':
ensure => $service_ensure,
name => $::neutron::params::ha_l3_agent,
enable => $enabled,
hasstatus => true,
hasrestart => false,
provider => 'pacemaker',
tag => 'ha_agents',
}
Neutron_config<||> ~> Service<| tag == 'ha_agents' |>
Neutron_plugin_ml2<||> ~> Service<| tag == 'ha_agents' |>
Neutron_plugin_ml2_cisco<||> ~> Service<| tag == 'ha_agents' |>
File_line<||> ~> Service<| tag == 'ha_agents' |>
}

View File

@ -1,29 +0,0 @@
#Class neutron::services::ovs_agent
class neutron::services::ovs_agent (
$enabled = true,
$manage_service = true,
){
include neutron::params
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
service { 'neutron-ovs-agent':
ensure => $service_ensure,
name => $::neutron::params::service_ovs_agent,
enable => $enabled,
hasstatus => true,
hasrestart => true,
}
Neutron_config<||> ~> Service['neutron-ovs-agent']
Neutron_plugin_ml2<||> ~> Service['neutron-ovs-agent']
Neutron_plugin_ml2_cisco<||> ~> Service['neutron-ovs-agent']
File_line<||> ~> Service['neutron-ovs-agent']
}

View File

@ -1,35 +0,0 @@
#Class neutron::services::server
class neutron::services::server (
$enabled = true,
$manage_service = true,
){
include neutron::params
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
File['rootwrap'] ~> Service['neutron-server']
Neutron_config<||> ~> Service['neutron-server']
Neutron_plugin_ml2<||> ~> Service['neutron-server']
Neutron_plugin_ml2_cisco<||> ~> Service['neutron-server']
File_line<||> ~> Service['neutron-server']
file {'rootwrap':
ensure => link,
path => '/usr/local/bin/neutron-rootwrap',
target => '/usr/bin/neutron-rootwrap',
}
service { 'neutron-server':
ensure => $service_ensure,
name => $::neutron::params::service_neutron_server,
enable => $enabled,
hasstatus => true,
hasrestart => true,
}
}

View File

@ -1,71 +0,0 @@
$role = hiera('role')
$deployment_mode = hiera('deployment_mode')
$cisco_aci_hash = hiera('cisco_aci',{})
$access_hash = hiera('access',{})
$ha_prefix = $deployment_mode ? {
'ha_compact' => 'ha_',
default => '',
}
if ($cisco_aci_hash['use_gbp'] == false and $cisco_aci_hash['use_apic'] == false){
fail('Wrong configuration')
}
if ($cisco_aci_hash['use_gbp'] == false and $cisco_aci_hash['use_apic'] == true){
if ($cisco_aci_hash['driver_type'] == 'ML2'){
$install_type = 'US1'
$class_name = 'generic_apic_ml2'
}else{
fail('Wrong configuration')
}
}
if ($cisco_aci_hash['use_gbp'] == true and $cisco_aci_hash['use_apic'] == false){
$install_type = 'US2a'
$class_name = 'gbp_and_mapping'
}
if ($cisco_aci_hash['use_gbp'] == true and $cisco_aci_hash['use_apic'] == true){
if ($cisco_aci_hash['driver_type'] == 'ML2'){
$install_type = 'US2b'
$class_name = 'gbp_and_apic_ml2'
}elsif ($cisco_aci_hash['driver_type'] == 'GBP'){
$install_type = 'US3'
$class_name = 'gbp_and_apic_gbp'
}
}
case $install_type {
'US1','US2b','US3': {
class {"cisco_aci::${class_name}":
ha_prefix => $ha_prefix,
role => $role,
admin_username => $access_hash['user'],
admin_password => $access_hash['password'],
admin_tenant => $access_hash['tenant'],
use_lldp => $cisco_aci_hash['use_lldp'],
apic_hosts => $cisco_aci_hash['apic_hosts'],
apic_username => $cisco_aci_hash['apic_username'],
apic_password => $cisco_aci_hash['apic_password'],
static_config => $cisco_aci_hash['static_config'],
additional_config => $cisco_aci_hash['additional_config'],
ext_net_enable => $cisco_aci_hash['ext_net_enable'],
ext_net_name => $cisco_aci_hash['ext_net_name'],
ext_net_switch => $cisco_aci_hash['ext_net_switch'],
ext_net_port => $cisco_aci_hash['ext_net_port'],
ext_net_subnet => $cisco_aci_hash['ext_net_subnet'],
ext_net_gateway => $cisco_aci_hash['ext_net_gateway'],
}
}
'US2a': {
class {"cisco_aci::${class_name}":
ha_prefix => $ha_prefix,
role => $role,
}
}
default: {
fail("Wrong module ${module_name}")
}
}

View File

@ -1,504 +0,0 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
===================================
Fuel Plugin Cisco ACI specification
===================================
The Cisco Application Policy Infrastructure Controller (Cisco APIC) is the unifying point of automation and management for the Application Centric Infrastructure (ACI) fabric. The Cisco APIC provides centralized access to all fabric information, optimizes the application lifecycle for scale and performance, and supports flexible application provisioning across physical and virtual resources.[1]
This specification describes automation of deployment Cisco ACI with OpenStack.
Problem description
===================
This integration should be supported with the upstream version of Fuel product.
Mirantis Openstack 6.0 release has Pluggable Architecture feature, that prevents developers from bringing any changes to the core product. Instead, the Cisco APIC functionality can be implemented as a plugin for Fuel.[2]
This plugin will let end user install the Mirantis OpenStack with Cisco SDN (software defined network) solution. This new feature supports 4 types of installation:
* Generic APIC ML2 driver
* GBP module and Mapping driver
* GBP module and APIC ML2 driver
* GBP module and APIC GBP driver
Each configuration will be described on its own section.
Proposed change
===============
Right now Fuel supports 4 types of network configurations:
* Neutron with VLAN segmentation (default)
* Neutron with GRE segmentation
* Neutron with VMware NSX
* Legacy Networking (nova-network)
When successfully copied to the Fuel Master node and installed, a new submenu will appear on the Settings tab of the Fuel web UI.
End user will have to select a checkbox/radiobutton with User Stories described below.
User Story 1: Generic APIC ML2 driver
---------------------------------------------------
This case will provide availability to configure Neutron for using Cisco SDN solution based on generic upstream ML2 neutron driver [3]. To enable this functionality, the plugin should support 2 types of configuration:
* with automatic hosts discovery (using lldp)
* static config.
This list describes what software and configuration should be added to corresponding hosts to support User Story 1 with autodiscovery feature enabled(checkbox called “Use lldp” set):
* All hosts will be installed with LLDP package
* All hosts will be installed with pip apicapi package
* All hosts will be installed with neutron-driver-apic-agent package
* All hosts will have these configurations in *<neutron.conf>*:
::
[DEFAULT]
service_plugins=neutron.services.l3_router.l3_apic.ApicL3ServicePlugin
core_plugin=neutron.plugins.ml2.plugin.Ml2Plugin
* All hosts will have these configurations in *ml2_conf.ini* file:
::
[ml2]
type_drivers=local,flat,vlan,gre,vxlan
tenant_network_types=vlan
mechanism_drivers=openvswitch,cisco_apic
[ml2_type_vlan]
network_vlan_ranges="$physnets_dev:$vlan_range"
[securitygroup]
enable_security_group=True
firewall_driver=neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
[ovs]
integration_bridge="$integration_bridge"
bridge_mappings="$physnets_dev:$integration_bridge"
enable_tunneling=False
[agent]
polling_interval=2
l2_population=False
arp_responder=False
Where **$integration_bridge** , **$physnets_dev**, **$vlan_range** should be configured through the Fuel web UI in Neutron L2 Configuration section of the Networks tab.
* All hosts will have these configurations in *ml2_conf_cisco.ini* file:
::
[DEFAULT]
apic_system_id=openstack
[ml2_cisco_apic]
apic_hosts=$apic_hosts
apic_username=$apic_username
apic_password=$apic_password
apic_name_mapping=use_name
Where **$apic_hosts**, **$apic_username**, **$apic_password** - should be configured through the Fuel web UI.
* All controllers will have neutron-driver-apic-svc-agent package installed
* All hosts *ml2_config_cisco.ini* will have [apic_external_network:ext] section, if configured through the Fuel web UI.
This list describes what software and configuration should be added to the corresponding hosts to support User Story 1 with static config chosen:
* All controllers have pip apicapi installed
* neutron-driver-apic-svc-agent neutron-driver-apic-agent and lldp is not installed
* All configurations are the same as "Auto discovery" way
* On all hosts in *ml2_config_cisco.ini* file, we will add an example (user-defined) section configured through the Fuel web UI.
::
[apic_switch:201]
compute11,compute21=1/10
compute12=1/11
* For both cases (autodiscovery and static), configuration files
on controller nodes (*neutron.conf*) should have admin credentials:
::
[keystone_authtoken]
admin_user="$admin_username"
admin_password="$admin_password"
admin_tenant_name="$admin_tenant"
Where **$admin_username**, **$admin_password** and **$admin_tenant** point to the cloud administrator credentials.
User Story 2a: GBP module and Mapping driver
-------------------------------------------------------------
This case will provide availability to configure Neutron for using Cisco SDN solution that is targeted at Cisco group-based policy packages.
This list describes what software and configuration should be added to the corresponding hosts to support User Story 2a.
* All controllers will have these configurations in *neutron.conf* file:
::
[DEFAULT]
service_plugins=neutron.services.
l3_router.l3_router_plugin.L3RouterPlugin,
gbpservice.neutron.services.grouppolicy.plugin.GroupPolicyPlugin,
gbpservice.neutron.services.servicechain.servicechain_plugin.ServiceChainPlugin
core_plugin=neutron.plugins.ml2.plugin.Ml2Plugin
[group_policy]
policy_drivers=implicit_policy,resource_mapping
[servicechain]
servicechain_drivers = simplechain_driver
[quotas]
default_quota = -1
quota_network = -1
quota_subnet = -1
quota_port = -1
quota_security_group = -1
quota_security_group_rule = -1
quota_router = -1
quota_floatingip = -1
* All controllers will have these configurations in *ml2_conf.ini* file:
::
[ml2]
type_drivers=local,flat,vlan,gre,vxlan
tenant_network_types=vlan
mechanism_drivers=openvswitch
[ml2_type_vlan]
network_vlan_ranges="$physnets_dev:$vlan_range"
[securitygroup]
enable_security_group=True
firewall_driver=neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
[ovs]
integration_bridge="$integration_bridge"
bridge_mappings="$physnets_dev:$integration_bridge"
enable_tunneling=False
[agent]
polling_interval=2
l2_population=False
arp_responder=False
Where **$integration_bridge**, **$physnets_dev**, **$vlan_range** - should be configured through the
Fuel web UI in the Neutron L2 Configuration section of the Networks tab.
* All controllers will have 4 additional package installed:
* group-based-policy
* python-group-based-policy-client
* group-based-policy-ui
* group-based-policy-automation
* All controllers will enable heat plugin in *heat.conf* file:
::
[DEFAULT]
plugin_dirs=/path/to/code/gbpautomation/heat
* All controllers will enable Horizon projects by linking *project.py* file to enabled_dashboards directory.
User Story 2b: GBP module and APIC ML2 driver
---------------------------------------------------------
This case will provide availability to configure Neutron for using Cisco SDN solution that is targeted at Cisco group-based policy packages
and APIC Controller with ML2 driver.
This list describes what software and configuration should be added to the corresponding hosts to support User Story 2b.
* All controllers will have these configurations in *neutron.conf* file:
::
[DEFAULT]
service_plugins=neutron.services.l3_router.l3_apic.ApicL3ServicePlugin
core_plugin=neutron.plugins.ml2.plugin.Ml2Plugin
[group_policy]
policy_drivers=implicit_policy,apic
[servicechain]
servicechain_drivers = simplechain_driver
[quotas]
default_quota = -1
quota_network = -1
quota_subnet = -1
quota_port = -1
quota_security_group = -1
quota_security_group_rule = -1
quota_router = -1
quota_floatingip = -1
* All controllers will have these configurations in *ml2_conf.ini* file:
::
[ml2]
type_drivers=local,flat,vlan,gre,vxlan
tenant_network_types=vlan
mechanism_drivers=openvswitch,cisco_aci
[ml2_type_vlan]
network_vlan_ranges="$physnets_dev:$vlan_range"
[securitygroup]
enable_security_group=True
firewall_driver=neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
[ovs]
integration_bridge="$integration_bridge"
bridge_mappings="$physnets_dev:$integration_bridge"
enable_tunneling=False
[agent]
polling_interval=2
l2_population=False
arp_responder=False
Where **$integration_bridge**, **$physnets_dev**, **$vlan_range** - should be configured through the
Fuel web UI in the Neutron L2 Configuration section of the Networks tab.
* All controllers will have these configurations in *ml2_conf_cisco.ini* file:
::
[DEFAULT]
apic_system_id=openstack
[ml2_cisco_apic]
apic_hosts=$apic_hosts
apic_username=$apic_username
apic_password=$apic_password
apic_name_mapping=use_name
Where **$apic_hosts**, **$apic_username**, **$apic_password** - should be configured through the Fuel web UI.
* All controllers will have these configurations in *neutron.conf* file:
::
[keystone_authtoken]
admin_user="$admin_username"
admin_password="$admin_password"
admin_tenant_name="$admin_tenant"
Where **$admin_username**, **$admin_password** and **$admin_tenant** point to the cloud administrator credentials.
* All controllers will have 4 additional package installed:
* group-based-policy
* python-group-based-policy-client
* group-based-policy-ui
* group-based-policy-automation
* All controllers will enable heat plugin in *heat.conf* file:
::
[DEFAULT]
plugin_dirs=/path/to/code/gbpautomation/heat
* All controllers will enable Horizon projects by linking *project.py* file to enabled_dashboards directory.
* All hosts will have [apic_external_network:ext] section in the *ml2_config_cisco.ini* file, if configured though Fuel web UI.
* All controllers have pip apicapi installed
* If LLDP is using - see US1 for configuration options that should be added.
User Story 3: GBP module and APIC GBP driver
---------------------------------------------------------
This case will provide availability to configure Neutron for using Cisco SDN solution that is targeted at Cisco group-based policy packages
and APIC Controller with GBP driver.
This list describes what software and configuration should be added to the corresponding hosts to support User Story 3.
* All controllers will have these configurations in *neutron.conf* file:
::
[DEFAULT]
service_plugins=neutron.services.
l3_router.l3_router_plugin.L3RouterPlugin,
gbpservice.neutron.services.grouppolicy.plugin.GroupPolicyPlugin,
gbpservice.neutron.services.servicechain.servicechain_plugin.ServiceChainPlugin
core_plugin=neutron.plugins.ml2.plugin.Ml2Plugin
[group_policy]
policy_drivers=implicit_policy,apic
[servicechain]
servicechain_drivers = simplechain_driver
[quotas]
default_quota = -1
quota_network = -1
quota_subnet = -1
quota_port = -1
quota_security_group = -1
quota_security_group_rule = -1
quota_router = -1
quota_floatingip = -1
* All controllers will have these configurations in *ml2_conf.ini* file:
::
[ml2]
type_drivers=local,flat,vlan,gre,vxlan
tenant_network_types=vlan
mechanism_drivers=openvswitch,apic_gbp
[ml2_type_vlan]
network_vlan_ranges="$physnets_dev:$vlan_range"
[securitygroup]
enable_security_group=True
firewall_driver=neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
[ovs]
integration_bridge="$integration_bridge"
bridge_mappings="$physnets_dev:$integration_bridge"
enable_tunneling=False
[agent]
polling_interval=2
l2_population=False
arp_responder=False
Where **$integration_bridge**, **$physnets_dev**, **$vlan_range** - should be configured through the
Fuel web UI in the Neutron L2 Configuration section of the Networks tab.
* All controllers will have these configurations in *ml2_conf_cisco.ini* file:
::
[DEFAULT]
apic_system_id=openstack
[ml2_cisco_apic]
apic_hosts=$apic_hosts
apic_username=$apic_username
apic_password=$apic_password
apic_name_mapping=use_name
Where **$apic_hosts**, **$apic_username**, **$apic_password** - should be configured through the Fuel web UI.
* All controllers will have these configurations in *neutron.conf* file:
::
[keystone_authtoken]
admin_user="$admin_username"
admin_password="$admin_password"
admin_tenant_name="$admin_tenant"
Where **$admin_username**, **$admin_password** and **$admin_tenant** point to the cloud administrator credentials.
* All controllers will have 4 additional package installed:
* group-based-policy
* python-group-based-policy-client
* group-based-policy-ui
* group-based-policy-automation
* All controllers will enable heat plugin in *heat.conf* file:
::
[DEFAULT]
plugin_dirs=/path/to/code/gbpautomation/heat
* All controllers will enable Horizon projects by linking *project.py* file to enabled_dashboards directory.
* All hosts will have [apic_external_network:ext] section in the *ml2_config_cisco.ini* file, if configured though Fuel web UI.
* All controllers have pip apicapi installed
* If LLDP is using - see US1 for configuration options that should be added.
Alternatives
---------------
There are no known alternatives for this plugin, although all steps can be performed manually.
Data model impact
-------------------------
GBP installation type requires additional tables in Neutron database.
New scheme will be managed by `gbp-db-manage` command that comes from group-based-policy package.
REST API impact
---------------
None.
Upgrade impact
--------------
Upgrading should be tested explicitly with this plugin installed and APIC controller enabled.
Security impact
---------------
This plugin changes Neutron keystone_authtoken credentials from `neutron` user and `services`
tenant to `admin` user and `admin` tenant on controller nodes. This may change in future, but
for Juno release this must be set to admin values.
Notifications impact
--------------------
None.
Other end user impact
---------------------
None.
Plugin impact
-------------
This plugin should not impact other plugins until they do not modify the same settings for Neutron configuration.
Other deployer impact
---------------------
Developer impact
----------------
Implementation
==============
Assignee(s)
-----------
Primary assignee:
Nikita Koshikov - nkoshikov@mirantis.com
Work Items
----------
* Create fuel-plugin-cisco-aci plugin
* Develop the Fuel web UI part of the plugin
* Add puppet support for all configuration cases
* Write documentation (User Guide)
Dependencies
============
* Ubuntu 14.04 support in MOS [4]
* This bug should also be fixed [5]
Testing
========
Plugin should pass tempest framework tests.
Documentation Impact
====================
Reference to this plugin should be added to main Fuel documentation.
References
==========
[1] http://cisco.com/go/apic
[2] http://docs.mirantis.com/openstack/fuel/fuel-6.0/plugin-dev.html
[3] https://blueprints.launchpad.net/neutron/+spec/ml2-cisco-apic-mechanism-driver
[4] https://blueprints.launchpad.net/fuel/+spec/support-ubuntu-trusty
[5] https://bugs.launchpad.net/fuel/+bug/1417994

View File

@ -1,155 +0,0 @@
attributes:
metadata:
restrictions:
- condition: "not (cluster:net_provider == 'neutron' and networking_parameters:segmentation_type == 'vlan')"
action: hide
use_gbp:
type: "checkbox"
weight: 30
value: false
label: "Group-Based Policy"
description: "Enable/Disable Group-Based Policy installation"
restrictions:
- condition: "not (cluster:net_provider == 'neutron' and (networking_parameters:segmentation_type == 'vlan' or networking_parameters:segmentation_type == 'gre'))"
action: disable
use_apic:
type: "checkbox"
weight: 31
value: false
label: "APIC Driver"
description: "Enable/Disable APIC API Controller"
restrictions:
- condition: "not (cluster:net_provider == 'neutron' and networking_parameters:segmentation_type == 'vlan')"
action: disable
driver_type:
type: "radio"
weight: 33
value: "ML2"
label: "APIC Driver mode"
restrictions:
- condition: "settings:cisco_aci.use_apic.value != true"
action: disable
values:
- data: "ML2"
label: "ML2"
description: "ML2 Driver"
- data: "GBP"
label: "GBP"
description: "Group-Based Policy Driver"
restrictions:
- condition: "settings:cisco_aci.use_gbp.value != true"
action: disable
apic_hosts:
value: '10.0.0.100'
label: 'APIC Host'
description: 'Comma­separated list of Cisco APIC IP addresses'
weight: 41
type: "text"
restrictions:
- condition: "settings:cisco_aci.use_apic.value != true"
action: disable
apic_username:
value: 'admin'
label: 'APIC Username'
description: 'Username for Cisco APIC; usually admin is used to allow configuration for multiple tenants'
weight: 42
type: "text"
regex:
source: '\S'
error: "Error field cannot be empty"
restrictions:
- condition: "settings:cisco_aci.use_apic.value != true"
action: disable
apic_password:
value: 'password'
label: 'APIC Password'
description: 'Password for the Cisco APIC user identified by the username'
weight: 43
type: "password"
regex:
source: '\S'
error: "Error field cannot be empty"
restrictions:
- condition: "settings:cisco_aci.use_apic.value != true"
action: disable
use_lldp:
type: "checkbox"
weight: 50
value: false
label: "Use lldp"
description: "Try to automatically discover hosts"
restrictions:
- condition: "settings:cisco_aci.use_apic.value != true"
action: disable
static_config:
type: "textarea"
weight: 51
value: ""
label: "Static config"
description: "Example:\n[apic_switch:201]\ncompute11,compute21=1/10\ncompute12=1/11\n"
restrictions:
- condition: "settings:cisco_aci.use_lldp.value != false or settings:cisco_aci.use_apic.value != true"
action: disable
additional_config:
type: "textarea"
weight: 52
value: ""
label: "Additional config"
description: "Example:\n[DEFAULT]\napic_vpc_pairs=201:202,203:204"
restrictions:
- condition: "settings:cisco_aci.use_apic.value != true"
action: disable
ext_net_enable:
type: "checkbox"
weight: 70
value: false
label: "Configure external network"
description: "Create external neutron network"
restrictions:
- condition: "settings:cisco_aci.use_apic.value != true"
action: disable
ext_net_name:
type: "text"
weight: 71
value: "myextnet"
label: "Network name:"
description: "External network name"
restrictions:
- condition: "settings:cisco_aci.ext_net_enable.value == false"
action: hide
ext_net_subnet:
type: "text"
weight: 72
value: "10.0.0.0/24"
label: "Subnet range:"
description: "CIDR for external network"
restrictions:
- condition: "settings:cisco_aci.ext_net_enable.value == false"
action: hide
ext_net_gateway:
type: "text"
weight: 73
value: "10.0.0.1"
label: "Gateway IP:"
description: "IP address of the external gateway"
restrictions:
- condition: "settings:cisco_aci.ext_net_enable.value == false"
action: hide
ext_net_switch:
type: "text"
weight: 74
value: "203"
label: "Switch ID:"
description: "Switch ID from Cisco APIC"
restrictions:
- condition: "settings:cisco_aci.ext_net_enable.value == false"
action: hide
ext_net_port:
type: "text"
weight: 75
value: "1/34"
label: "Port ID:"
description: "Switch port to which the external router is connected"
restrictions:
- condition: "settings:cisco_aci.ext_net_enable.value == false"
action: hide

View File

@ -1,35 +0,0 @@
# Plugin name
name: cisco_aci
# Human-readable name for your plugin
title: Cisco APIC Plugin
# Plugin version
version: 1.0.1
# Description
description: Enable to use Cisco SDN solutions for Neutron
# Required fuel version
fuel_version: ['6.1']
# Specify license of your plugin
licenses: ['Apache License Version 2.0']
# Specify author or company name
authors: ['Mirantis']
# A link to the plugin's page
homepage: 'https://github.com/stackforge/fuel-plugin-cisco-aci'
# Specify a group which your plugin implements, possible options:
# # network, storage, storage::cinder, storage::glance, hypervisor
groups: ['network']
# The plugin is compatible with releases in the list
releases:
- os: centos
version: 2014.2-6.1
mode: ['ha', 'multinode']
deployment_scripts_path: deployment_scripts/
repository_path: repositories/centos
- os: ubuntu
version: 2014.2-6.1
mode: ['ha', 'multinode']
deployment_scripts_path: deployment_scripts/
repository_path: repositories/ubuntu
# Version of plugin package
package_version: '2.0.0'

View File

@ -1,13 +0,0 @@
#!/bin/bash
set -eux
ROOT="$(dirname `readlink -f $0`)"
MODULES="${ROOT}"/deployment_scripts/puppet/modules
mkdir -p "${MODULES}"
#REPO_PATH='https://github.com/stackforge/fuel-library/tarball/aded04f6b5d4dbc4b4e4cf904fc882879184d097'
REPO_PATH='https://api.github.com/repos/stackforge/fuel-library/tarball/a478b8c6180af33612b19d09785bd63f2b6673c6'
RPM_REPO="${ROOT}"/repositories/centos/
DEB_REPO="${ROOT}"/repositories/ubuntu/
wget -qO- "${REPO_PATH}" | \
tar -C "${MODULES}" --strip-components=3 -zxvf - \
stackforge-fuel-library-a478b8c/deployment/puppet/{inifile,stdlib,pacemaker}

View File

@ -1,11 +0,0 @@
# This tasks will be applied on controller nodes,
# here you can also specify several roles, for example
# ['cinder', 'compute'] will be applied only on
# cinder and compute nodes
- role: ['primary-controller','controller','compute']
stage: post_deployment
type: puppet
parameters:
puppet_manifest: puppet/site.pp
puppet_modules: puppet/modules/
timeout: 3600