Import code from personal repo

Current status:
  * OpenDaylight controller is installed on primary controller
  * OpenDaylight is set as OVS manager
  * VLAN, GRE, VXLAN segmentation supported
  * Neutron agent is responsible for L3 traffic

Change-Id: Ibd804940e2c8acc81a1d507b1de964ee97250107
This commit is contained in:
Michal Skalski 2015-06-25 09:31:50 +02:00
parent bc793bf660
commit 2ce0d0b829
32 changed files with 1492 additions and 0 deletions

202
LICENSE Normal file
View File

@ -0,0 +1,202 @@
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.

36
README.md Normal file
View File

@ -0,0 +1,36 @@
OpenDaylight plugin
===================
This plugin will install OpenDaylight controller and set it as manager for ovs.
Building the plugin
-------------
1. Clone the fuel-plugin repo from:
``git clone https://github.com/stackforge/fuel-plugin-opendaylight``
2. Install the Fuel Plugin Builder:
``pip install fuel-plugin-builder``
3. Install the [fpm gem](https://github.com/jordansissel/fpm):
``gem install fpm``
4. Build OpenDaylight Fuel plugin:
``fpb --build fuel-plugin-opendaylight/``
5. The *opendaylight-[x.x.x].rpm* plugin package will be created in the plugin folder.
6. Move this file to the Fuel Master node with secure copy (scp):
``scp opendaylight-[x.x.x].rpm root@<the_Fuel_Master_node_IP address>:/tmp``
7. While logged in Fuel Master install the OpenDaylight plugin:
``fuel plugins --install opendaylight-[x.x.x].rpm``
8. Plugin is ready to use and can be enabled on the Settings tab of the Fuel web UI.

View File

@ -0,0 +1,11 @@
#!/bin/bash
source /root/openrc
router_id=`neutron router-list | grep "network_id" | awk '{print $2}'`
neutron router-gateway-clear $router_id
subnet_id=`neutron router-port-list $router_id | grep "subnet_id" | awk '{print $8}' | awk -F '\"' '{print $2}'`
neutron router-interface-delete $router_id $subnet_id
neutron router-delete $router_id
neutron subnet-delete $subnet_id
neutron net-delete net04
neutron net-delete net04_ext

View File

@ -0,0 +1,14 @@
$java_package = $operatingsystem ? {
'CentOS' => 'java-1.7.0-openjdk',
'Ubuntu' => 'openjdk-7-jre-headless',
}
package { 'java-jre':
ensure => installed,
name => $java_package,
}
package { 'opendaylight':
ensure => installed,
require => Package['java-jre'],
}

View File

@ -0,0 +1,17 @@
$role = hiera('role')
$ovs_agent_name = $operatingsystem ? {
'CentOS' => 'neutron-openvswitch-agent',
'Ubuntu' => 'neutron-plugin-openvswitch-agent',
}
if $role == 'primary-controller' {
cs_resource { "p_${ovs_agent_name}":
ensure => absent,
}
} else {
service {$ovs_agent_name:
ensure => stopped,
enable => false,
}
}

View File

@ -0,0 +1,20 @@
include opendaylight
$address = $opendaylight::rest_api_address
$port = $opendaylight::rest_api_port
$vni_start = $opendaylight::odl_settings['vni_range_start']
$vni_end = $opendaylight::odl_settings['vni_range_end']
neutron_plugin_ml2 {
'ml2/mechanism_drivers': value => 'opendaylight';
'ml2_odl/password': value => 'admin';
'ml2_odl/username': value => 'admin';
'ml2_odl/url': value => "http://${address}:${port}/controller/nb/v2/neutron";
}
if $opendaylight::odl_settings['use_vxlan'] {
neutron_plugin_ml2 {
'ml2/tenant_network_types': value => 'vxlan';
'ml2_type_vxlan/vni_ranges': value => "${vni_start}:${vni_end}";
}
}

View File

@ -0,0 +1,6 @@
include opendaylight
include firewall
class { 'opendaylight::service':
port => $opendaylight::rest_api_port,
}

View File

@ -0,0 +1,21 @@
exec { 'drop_neutron_db':
command => "mysql -e 'drop database if exists neutron;'",
path => '/usr/bin',
}
exec { 'create_neutron_db':
command => "mysql -e 'create database neutron character set utf8;'",
path => '/usr/bin',
}
exec { 'grant_neutron_db':
command => "mysql -e \"grant all on neutron.* to 'neutron'@'%';\"",
path => '/usr/bin',
}
exec { 'neutron_db_sync':
command => 'neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini upgrade head',
path => '/usr/bin',
}
Exec['drop_neutron_db'] -> Exec['create_neutron_db'] -> Exec['grant_neutron_db'] -> Exec['neutron_db_sync']

View File

@ -0,0 +1,56 @@
include opendaylight
$ovs_service_name = $operatingsystem ? {
'CentOS' => 'openvswitch',
'Ubuntu' => 'openvswitch-switch',
}
exec { 'stop-ovs-service':
command => "service ${ovs_service_name} stop",
path => '/bin:/usr/sbin:/usr/bin:/sbin',
logoutput => true,
}
exec { 'remove-ovs-logs':
command => 'rm -f /var/log/openvswitch/*',
path => '/bin:/usr/sbin:/usr/bin',
}
exec { 'remove-ovs-db':
command => 'rm -f /etc/openvswitch/*',
path => '/bin:/usr/sbin:/usr/bin',
}
exec { 'ovs-set-manager':
command => "ovs-vsctl set-manager tcp:${opendaylight::rest_api_address}:6640",
path => '/usr/bin'
}
if $opendaylight::node_private_address != undef {
exec { 'ovs-set-tunnel-endpoint':
command => "ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) other_config={'local_ip'='${opendaylight::node_private_address}'}",
path => '/usr/bin',
require => Exec['ovs-set-manager']
}
} else {
exec { 'ovs-br-int-to-phy':
command => 'ovs-vsctl --may-exist add-port br-int p_br-prv-0 -- set Interface p_br-prv-0 type=internal',
path => '/usr/bin',
tries => 30,
try_sleep => 5,
require => Exec['ovs-set-manager']
}
exec { 'ovs-set-provider-mapping':
command => "ovs-vsctl set Open_vSwitch $(ovs-vsctl show | head -n 1) other_config:provider_mappings=physnet2:p_br-prv-0",
path => '/usr/bin',
require => Exec['ovs-br-int-to-phy']
}
}
service { $ovs_service_name:
ensure => running,
}
Exec['stop-ovs-service'] ->
Exec['remove-ovs-logs'] ->
Exec['remove-ovs-db'] ->
Service[$ovs_service_name] ->
Exec['ovs-set-manager']

View File

@ -0,0 +1,13 @@
exec { 'add-br-floating':
command => 'ovs-vsctl add-br br-floating',
unless => 'ovs-vsctl br-exists br-floating',
path => '/usr/bin',
} ->
exec { 'set-br-floating-id':
command => 'ovs-vsctl br-set-external-id br-floating bridge-id br-floating',
path => '/usr/bin',
} ->
exec { 'add-floating-patch':
command => 'ovs-vsctl --may-exist add-port br-floating p_br-floating-0 -- set Interface p_br-floating-0 type=internal',
path => '/usr/bin',
}

View File

@ -0,0 +1,58 @@
include opendaylight
$access_hash = hiera('access', {})
$keystone_admin_tenant = $access_hash[tenant]
$neutron_settings = hiera('quantum_settings')
$nets = $neutron_settings['predefined_networks']
$primary_controller = hiera('primary_controller')
$physnet = $nets['net04']['L2']['physnet']
$segment_id = $nets['net04']['L2']['segment_id']
$vm_net_l3 = $nets['net04']['L3']
if $opendaylight::odl_settings['use_vxlan'] {
$segmentation_type = 'vxlan'
} else {
$segmentation_type = $neutron_settings['L2']['segmentation_type']
}
$vm_net = { shared => false,
"L2" => { network_type => $segmentation_type,
router_ext => false,
physnet => $physnet,
segment_id => $segment_id,
},
"L3" => $vm_net_l3,
tenant => 'admin'
}
service { 'neutron-server':
ensure => running,
}
if $primary_controller {
exec {'refresh-dhcp-agent':
command => 'crm resource restart p_neutron-dhcp-agent',
path => '/usr/bin:/usr/sbin',
} ->
exec {'refresh-metadata-agent':
command => 'crm resource restart p_neutron-metadata-agent',
path => '/usr/bin:/usr/sbin',
} ->
exec {'refresh-l3-agent':
command => 'crm resource restart p_neutron-l3-agent',
path => '/usr/bin:/usr/sbin',
} ->
openstack::network::create_network{'net04':
netdata => $vm_net,
require => Service['neutron-server']
} ->
openstack::network::create_network{'net04_ext':
netdata => $nets['net04_ext']
} ->
openstack::network::create_router{'router04':
internal_network => 'net04',
external_network => 'net04_ext',
tenant_name => $keystone_admin_tenant
}
}

View File

@ -0,0 +1,3 @@
service { 'neutron-server':
ensure => stopped,
}

View File

@ -0,0 +1,213 @@
require 'csv'
require 'puppet/util/inifile'
class Puppet::Provider::Neutron < Puppet::Provider
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'],
:OS_ENDPOINT_TYPE => 'internalURL'
}
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 = 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.get_tenant_id(catalog, name)
instance_type = 'keystone_tenant'
instance = catalog.resource("#{instance_type.capitalize!}[#{name}]")
if ! instance
instance = Puppet::Type.type(instance_type).instances.find do |i|
i.provider.name == name
end
end
if instance
return instance.provider.id
else
fail("Unable to find #{instance_type} for name #{name}")
end
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

@ -0,0 +1,140 @@
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

@ -0,0 +1,90 @@
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, :l3_ext, :vxlan)
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

@ -0,0 +1,11 @@
class opendaylight {
$odl_settings = hiera('opendaylight')
$nodes_hash = hiera('nodes')
$primary_controller_hash = filter_nodes($nodes_hash,'role','primary-controller')
$node = filter_nodes($nodes_hash,'name',$::hostname)
$rest_api_port = $odl_settings['rest_api_port']
$segmentation_type = $odl_settings['segmentation_type']
$rest_api_address = $primary_controller_hash[0]['internal_address']
$node_private_address = $node[0]['private_address']
}

View File

@ -0,0 +1,45 @@
class opendaylight::service (
$port = 8282,
) {
$role = hiera('role')
if $role == 'primary-controller' {
firewall {'215 odl':
port => [ $opendaylight::rest_api_port, 6633, 6640, 6653, 8181, 8101],
proto => 'tcp',
action => 'accept',
before => Service['opendaylight'],
}
service { 'opendaylight' :
ensure => running,
enable => true,
require => File['/opt/opendaylight/configuration/tomcat-server.xml'],
}
debug("Set odl rest api port to ${port}")
file { '/opt/opendaylight/configuration/tomcat-server.xml':
ensure => file,
owner => 'odl',
content => template('opendaylight/tomcat-server.erb')
}
exec { 'wait-until-odl-ready':
command => 'netstat -lpen --tcp | grep java | grep 6633',
path => '/bin:/usr/bin',
tries => 60,
try_sleep => 10,
require => Service['opendaylight'],
}
}
if $opendaylight::odl_settings['use_vxlan'] {
firewall {'216 vxlan':
port => [4789],
proto => 'udp',
action => 'accept',
}
}
}

View File

@ -0,0 +1,84 @@
<?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<Server>
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
<Listener className="org.apache.catalina.core.JasperListener" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="configuration/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="<%= @port %>" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!--
Please remove the comments around the following Connector tag to enable HTTPS Authentication support.
Remember to add a valid keystore in the configuration folder.
More info : http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
-->
<!--
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="configuration/keystore"
keystorePass="changeit"/>
-->
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase=""
unpackWARs="false" autoDeploy="false"
deployOnStartup="false" createDirs="false">
<!-- WIP custom realm, use the UserDatabaseRealm for now
<Realm className="org.opendaylight.controller.karafsecurity.ControllerCustomRealm" />
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="web_access_log_" suffix=".txt" resolveHosts="false"
rotatable="true" fileDateFormat="yyyy-MM"
pattern="%{yyyy-MM-dd HH:mm:ss.SSS z}t - [%a] - %r"/>
</Host>
</Engine>
</Service>
</Server>

47
environment_config.yaml Normal file
View File

@ -0,0 +1,47 @@
attributes:
metadata:
restrictions:
- "cluster:net_provider != 'neutron'": "Only neutron is supported by OpenDaylight"
use_vxlan:
type: "checkbox"
weight: 20
value: false
label: "Use vxlan"
description: "Configure neutron to use VXLAN tunneling"
restrictions:
- condition: "networking_parameters:segmentation_type == 'vlan'"
message: "Neutron with GRE segmentation required"
action: "disable"
vni_range_start:
value: '10'
label: 'VNI range start'
description: 'VXLAN VNI IDs range start'
type: 'text'
weight: 30
restrictions:
- condition: "networking_parameters:segmentation_type == 'vlan'"
action: "hide"
regex:
source: '^\d+$'
error: 'Invalid ID number'
vni_range_end:
value: '10000'
label: 'VNI range end'
description: 'VXLAN VNI IDs range end'
type: 'text'
weight: 31
restrictions:
- condition: "networking_parameters:segmentation_type == 'vlan'"
action: "hide"
regex:
source: '^\d+$'
error: 'Invalid ID number'
rest_api_port:
value: '8282'
label: 'Port number'
description: 'Port on which ODL REST API will be available.'
weight: 40
type: "text"
regex:
source: ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$
error: 'Invalid port number'

35
metadata.yaml Normal file
View File

@ -0,0 +1,35 @@
# Plugin name
name: opendaylight
# Human-readable name for your plugin
title: OpenDaylight Helium plugin
# Plugin version
version: '1.0.0'
# Description
description: This plugin provides OpenDaylight as a backend 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: ['Michal Skalski, Mirantis']
# A link to the plugin's page
homepage: 'https://github.com/stackforge/fuel-plugins'
# 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: ubuntu
version: 2014.2-6.1
mode: ['ha', 'multinode']
deployment_scripts_path: deployment_scripts/
repository_path: repositories/ubuntu
- os: centos
version: 2014.2-6.1
mode: ['ha', 'multinode']
deployment_scripts_path: deployment_scripts/
repository_path: repositories/centos
# Version of plugin package
package_version: '2.0.0'

View File

@ -0,0 +1,31 @@
#!/bin/bash
# chkconfig: 345 98 2
# description: ODL controller
# OpenDaylight service controller script
export JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64
USER=odl
cd /opt/opendaylight
case "$1" in
start)
/bin/su -m $USER -s /bin/bash -c ./bin/start
;;
stop)
/bin/su -m $USER -s /bin/bash -c ./bin/stop
;;
status)
PID=`ps aux | grep java | grep karaf | awk '{print $2}'`
if test -z $PID
then
echo "ODL is down..."
exit 1
else
echo "ODL is running... PID $PID"
exit 0
fi
;;
*)
echo "Usage: $0 {start|stop|status}"
exit 1
;;
esac

View File

@ -0,0 +1,6 @@
#!/bin/sh
set -e
adduser --system --home /opt/opendaylight --shell /sbin/nologin odl
/sbin/chkconfig --add opendaylight
chown -R odl:odl /opt/opendaylight

View File

@ -0,0 +1,70 @@
Eclipse Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
"Program" means the Contributions distributed in accordance with this Agreement.
"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained within the Program.
Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED 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. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.

View File

@ -0,0 +1,5 @@
This directory contains compiled code which is a part of
ovsdb opendaylight project which source code can be found
here https://github.com/opendaylight/ovsdb/tree/release/helium-sr3
Changes against orginal code are described inside fuel.patch file.

View File

@ -0,0 +1,43 @@
From ab131a2ebcd1e198269df8f8c4f8984b9a275131 Mon Sep 17 00:00:00 2001
From: Michal Skalski <mskalski@mirantis.com>
Date: Wed, 24 Jun 2015 13:43:01 +0200
Subject: [PATCH] Change names of external bridge and external patch port names
to support fuel network
---
.../java/org/opendaylight/ovsdb/openstack/netvirt/api/Constants.java | 3 ++-
.../ovsdb/openstack/netvirt/impl/ConfigurationServiceImpl.java | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/Constants.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/Constants.java
index acf7a9b..cd39527 100644
--- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/Constants.java
+++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/Constants.java
@@ -29,9 +29,10 @@ public final class Constants {
public static final String TUNNEL_ENDPOINT_KEY = "local_ip";
public static final String INTEGRATION_BRIDGE = "br-int";
public static final String NETWORK_BRIDGE = "br-net";
- public static final String EXTERNAL_BRIDGE = "br-ex";
+ public static final String EXTERNAL_BRIDGE = "br-floating";
public static final String PATCH_PORT_TO_INTEGRATION_BRIDGE_NAME = "patch-int";
public static final String PATCH_PORT_TO_NETWORK_BRIDGE_NAME = "patch-net";
+ public static final String PATCH_PORT_TO_EXTERNAL_BRIDGE_NAME = "p_br-floating-0";
public static final String PROVIDER_MAPPINGS_KEY = "provider_mappings";
public static final String PROVIDER_MAPPING = "physnet1:eth1";
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/ConfigurationServiceImpl.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/ConfigurationServiceImpl.java
index 3550292..9eb9448 100644
--- a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/ConfigurationServiceImpl.java
+++ b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/ConfigurationServiceImpl.java
@@ -51,6 +51,8 @@ public class ConfigurationServiceImpl implements org.opendaylight.ovsdb.openstac
Constants.PATCH_PORT_TO_NETWORK_BRIDGE_NAME);
patchPortNames.put(new ImmutablePair<>(networkBridgeName, integrationBridgeName),
Constants.PATCH_PORT_TO_INTEGRATION_BRIDGE_NAME);
+ patchPortNames.put(new ImmutablePair<>(externalBridgeName, integrationBridgeName),
+ Constants.PATCH_PORT_TO_EXTERNAL_BRIDGE_NAME);
providerMappingsKey = Constants.PROVIDER_MAPPINGS_KEY;
providerMapping = Constants.PROVIDER_MAPPING;
}
--
2.1.4

View File

@ -0,0 +1,39 @@
# vim:set ft=upstart ts=2 et:
description "OpenDaylight controller"
author "mskalski@miranits.com"
start on runlevel [2345]
stop on runlevel [!2345]
setgid odl
setuid odl
env KARAF_HOME="/opt/opendaylight"
env JAVA_HOME="/usr/lib/jvm/java-7-openjdk-amd64"
env JAVA_OPTS="-server -Xms128M -Xmx2048M -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass -XX:MaxPermSize=512M -Dcom.sun.management.jmxremote"
env OPTS="-Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=true"
env MAIN="org.apache.karaf.main.Main"
chdir /opt/opendaylight
script
export KARAF_BASE="$KARAF_HOME"
export KARAF_DATA="$KARAF_BASE/data"
export KARAF_ETC="$KARAF_BASE/etc"
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:$KARAF_BASE/lib"
export JAVA_ENDORSED_DIRS="${JAVA_HOME}/jre/lib/endorsed:${JAVA_HOME}/lib/endorsed:${KARAF_HOME}/lib/endorsed"
export JAVA_EXT_DIRS="${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext:${KARAF_HOME}/lib/ext"
for file in "$KARAF_HOME"/lib/karaf*.jar
do
if [ -z "$CLASSPATH" ]; then
CLASSPATH="$file"
else
CLASSPATH="$CLASSPATH:$file"
fi
done
exec /usr/bin/java $JAVA_OPTS -Djava.endorsed.dirs="${JAVA_ENDORSED_DIRS}" -Djava.ext.dirs="${JAVA_EXT_DIRS}" -Dkaraf.instances="${KARAF_HOME}/instances" -Dkaraf.home="$KARAF_HOME" -Dkaraf.base="$KARAF_BASE" -Dkaraf.data="$KARAF_DATA" -Dkaraf.etc="$KARAF_ETC" -Djava.io.tmpdir="$KARAF_DATA/tmp" -Djava.util.logging.config.file="$KARAF_BASE/etc/java.util.logging.properties" $KARAF_OPTS $OPTS -classpath "$CLASSPATH" $MAIN
end script

View File

@ -0,0 +1,6 @@
#!/bin/sh
set -e
adduser --quiet --system --group --no-create-home --home /opt/opendaylight odl
chown -R odl:odl /opt/opendaylight
chown odl:odl /etc/init/opendaylight.conf

83
pre_build_hook Executable file
View File

@ -0,0 +1,83 @@
#!/bin/bash
# Add here any the actions which are required before plugin build
# like packages building, packages downloading from mirrors and so on.
# The script should return 0 if there were no errors.
set -eux
# Where we can find odl karaf distribution tarball
# can be http(s) url or absolute path
ODL_TARBALL_LOCATION="https://nexus.opendaylight.org/content/groups/public/org/opendaylight/integration/distribution-karaf/0.2.3-Helium-SR3/distribution-karaf-0.2.3-Helium-SR3.tar.gz"
TMP_NAME="karaf-odl.tar.gz"
# URL of fuel library
FUEL_LIBRARY_COMMIT="c9a86ac0e6da95d36e328ce5130715792a2eb177"
FUEL_LIBRARY_TARBALL_URL="https://github.com/stackforge/fuel-library/archive/${FUEL_LIBRARY_COMMIT}.tar.gz"
# For which systems odl package should be build
BUILD_FOR="centos ubuntu"
DIR="$(dirname `readlink -f $0`)"
MODULES="${DIR}/deployment_scripts/puppet/modules"
function cleanup {
rm -f "${DIR}/${TMP_NAME}"
rm -rf "${DIR}/package"
}
function download {
wget "$1" -qO $2
}
function unpack {
tar xzf $1 --strip-components=1 -C "${DIR}/package"
}
function patch_odl {
sed -i 's/#\ ovsdb.of.version=1.3/ovsdb.of.version=1.3/' "${DIR}/package/etc/custom.properties"
sed -i 's/featuresBoot=.*/featuresBoot=config,standard,region,package,kar,ssh,management,odl-base-all,odl-aaa-authn,odl-restconf,odl-nsf-all,odl-adsal-northbound,odl-mdsal-apidocs,odl-ovsdb-openstack,odl-ovsdb-northbound,odl-dlux-core/' "${DIR}/package/etc/org.apache.karaf.features.cfg"
cp "${DIR}/odl_package/odl_helium_patch/openstack.net-virt-1.0.3-Helium-SR3.jar" "${DIR}/package/system/org/opendaylight/ovsdb/openstack.net-virt/1.0.3-Helium-SR3/openstack.net-virt-1.0.3-Helium-SR3.jar"
}
function build_pkg {
case $1 in
centos)
pushd "${DIR}/repositories/${1}/"
fpm --force -s dir -t rpm --prefix /opt/opendaylight --rpm-init "${DIR}/odl_package/${1}/opendaylight" --after-install "${DIR}/odl_package/${1}/opendaylight-post" --name opendaylight -d "java-1.7.0-openjdk" -C "${DIR}/package"
popd
;;
ubuntu)
pushd "${DIR}/repositories/${1}/"
fpm --force -s dir -t deb --prefix /opt/opendaylight --deb-upstart "${DIR}/odl_package/${1}/opendaylight" --after-install "${DIR}/odl_package/${1}/opendaylight-post" --name opendaylight -d "openjdk-7-jre-headless" -C "${DIR}/package"
popd
;;
*) echo "Not supported system"; exit 1;;
esac
}
command -v fpm >/dev/null 2>&1 || { echo >&2 "fpm ruby gem required but it's not installed. Aborting."; exit 1; }
cleanup
mkdir -p "${DIR}/package"
if [[ "$ODL_TARBALL_LOCATION" =~ ^http.* ]]
then
download $ODL_TARBALL_LOCATION ${DIR}/${TMP_NAME}
unpack ${DIR}/${TMP_NAME}
else
unpack $ODL_TARBALL_LOCATION
fi
patch_odl
for system in $BUILD_FOR
do
build_pkg $system
done
wget -qO- "${FUEL_LIBRARY_TARBALL_URL}" | \
tar -C "${MODULES}" --strip-components=3 -zxvf - \
fuel-library-${FUEL_LIBRARY_COMMIT}/deployment/puppet/{inifile,firewall,corosync,pacemaker}
cleanup

View File

View File

87
tasks.yaml Normal file
View File

@ -0,0 +1,87 @@
- id: odl_install
role: ['primary-controller']
stage: pre_deployment
type: puppet
parameters:
puppet_manifest: puppet/manifests/controller-pre.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 720
- id: odl_conifgure
role: ['primary-controller', 'controller', 'compute']
stage: post_deployment
type: puppet
parameters:
puppet_manifest: puppet/manifests/odl-service.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 720
- id: odl_delete_predefined_net
role: ['primary-controller']
stage: post_deployment
type: shell
requires: [odl_configure]
parameters:
cmd: ./clean-neutron.sh
timeout: 120
- id: odl_disable_ovs_agent
role: ['primary-controller', 'compute']
stage: post_deployment
type: puppet
requires: [odl_delete_predefined_net]
parameters:
puppet_manifest: puppet/manifests/disable-ovs-agent.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 60
- id: odl_stop_neutron
role: ['primary-controller', 'controller']
stage: post_deployment
type: puppet
requires: [odl_delete_predefined_net]
parameters:
puppet_manifest: puppet/manifests/stop-neutron.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 60
- id: odl_recreate_ovs
role: ['primary-controller', 'controller', 'compute']
stage: post_deployment
type: puppet
requires: [odl_stop_neutron]
parameters:
puppet_manifest: puppet/manifests/recreate-ovs.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 60
- id: odl_ml2_configuration
role: ['primary-controller', 'controller', 'compute']
stage: post_deployment
type: puppet
requires: [odl_recreate_ovs]
parameters:
puppet_manifest: puppet/manifests/ml2-configuration.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 60
- id: odl_recreate_neutron_db
role: ['primary-controller']
stage: post_deployment
type: puppet
requires: [odl_ml2_configuration]
parameters:
puppet_manifest: puppet/manifests/recreate-neutron-db.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 60
- id: odl_setup_floating
role: ['primary-controller', 'controller']
stage: post_deployment
type: puppet
requires: [odl_recreate_neutron_db]
parameters:
puppet_manifest: puppet/manifests/setup-floating.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 60
- id: odl_start_neutron
role: ['primary-controller', 'controller']
stage: post_deployment
type: puppet
requires: [odl_setup_floating]
parameters:
puppet_manifest: puppet/manifests/start-neutron.pp
puppet_modules: puppet/modules:/etc/puppet/modules
timeout: 180