chef/cookbooks/neutron/recipes/post_install_conf.rb
# Copyright 2011 Dell, Inc.
# Copyright 2015 SUSE Linux GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require "ipaddr"
def mask_to_bits(mask)
IPAddr.new(mask).to_i.to_s(2).count("1")
end
# accessing the network definition directly, since the node is not using this
# network
fixed_net = Barclamp::Inventory.get_network_definition(node, "nova_fixed")
fixed_net_ranges = fixed_net["ranges"]
fixed_range = "#{fixed_net["subnet"]}/#{mask_to_bits(fixed_net["netmask"])}"
fixed_pool_start = fixed_net_ranges[:dhcp][:start]
fixed_pool_end = fixed_net_ranges[:dhcp][:end]
fixed_first_ip = IPAddr.new("#{fixed_range}").to_range().to_a[2]
fixed_last_ip = IPAddr.new("#{fixed_range}").to_range().to_a[-2]
fixed_pool_start = fixed_first_ip if fixed_first_ip > fixed_pool_start
fixed_pool_end = fixed_last_ip if fixed_last_ip < fixed_pool_end
public_net = Barclamp::Inventory.get_network_by_type(node, "public")
# accessing the network definition directly, since the node is not necessarily
# using this network
floating_net = Barclamp::Inventory.get_network_definition(node, "nova_floating")
floating_net_ranges = floating_net["ranges"]
public_net_addr = IPAddr.new("#{public_net.subnet}/#{public_net.netmask}")
floating_net_addr = IPAddr.new("#{floating_net["subnet"]}/#{floating_net["netmask"]}")
# For backwards compatibility, if floating is a subnet of public use the
# router and range/netmask from public (otherwise router creation will fail)
if public_net_addr.include?(floating_net_addr)
floating_router = public_net.router
floating_range = "#{public_net.subnet}/#{mask_to_bits(public_net.netmask)}"
else
floating_router = floating_net["router"]
floating_range = "#{floating_net["subnet"]}/#{mask_to_bits(floating_net["netmask"])}"
end
floating_pool_start = floating_net_ranges[:host][:start]
floating_pool_end = floating_net_ranges[:host][:end]
ironic_net = node[:network][:networks]["ironic"]
if ironic_net
ironic_range = "#{ironic_net["subnet"]}/#{mask_to_bits(ironic_net["netmask"])}"
ironic_pool_start = ironic_net[:ranges][:dhcp][:start]
ironic_pool_end = ironic_net[:ranges][:dhcp][:end]
ironic_router = ironic_net["router"]
end
vni_start = [node[:neutron][:vxlan][:vni_start], 0].max
keystone_settings = KeystoneHelper.keystone_settings(node, @cookbook_name)
ssl_insecure = CrowbarOpenStackHelper.insecure(node[:neutron]) || keystone_settings["insecure"]
env = "OS_USERNAME='#{keystone_settings["service_user"]}' "
env << "OS_PASSWORD='#{keystone_settings["service_password"]}' "
env << "OS_PROJECT_NAME='#{keystone_settings["service_tenant"]}' "
env << "OS_AUTH_URL='#{keystone_settings["internal_auth_url"]}' "
env << "OS_REGION_NAME='#{keystone_settings["endpoint_region"]}' "
env << "OS_INTERFACE=internal "
env << "OS_ENDPOINT_TYPE=internalURL "
env << "OS_USER_DOMAIN_NAME=Default "
env << "OS_PROJECT_DOMAIN_NAME=Default "
env << "OS_IDENTITY_API_VERSION=3"
openstack_cmd = "#{env} openstack #{ssl_insecure ? "--insecure" : ""}"
fixed_network_type = ""
floating_network_type = ""
networking_plugin = node[:neutron][:networking_plugin]
ml2_type_drivers_default_provider_network = node[:neutron][:ml2_type_drivers_default_provider_network]
case networking_plugin
when "ml2"
# For ml2 always create the floating network as a flat provider network
# find the network node, to figure out the right "physnet" parameter
network_node = NeutronHelper.get_network_node_from_neutron_attributes(node)
physnet_map = NeutronHelper.get_neutron_physnets(network_node, ["nova_floating", "ironic"])
floating_network_type = "--provider-network-type flat " \
"--provider-physical-network #{physnet_map["nova_floating"]}"
ironic_network_type = "--provider-network-type flat " \
"--provider-physical-network #{physnet_map["ironic"]}"
case ml2_type_drivers_default_provider_network
when "vlan"
fixed_network_type = "--provider-network-type vlan " \
"--provider-segment #{fixed_net["vlan"]} " \
"--provider-physical-network physnet1"
when "gre"
fixed_network_type = "--provider-network-type gre --provider-segment 1"
when "vxlan"
fixed_network_type = "--provider-network-type vxlan " \
"--provider-segment #{vni_start}"
else
Chef::Log.error("default provider network ml2 type driver " \
"'#{ml2_type_drivers_default_provider_network}' invalid for creating provider networks")
end
when "vmware"
fixed_network_type = ""
# We would like to be sure that floating network will be created
# without any additional options, NSX will take care about everything.
floating_network_type = ""
else
Chef::Log.error("networking plugin '#{networking_plugin}' invalid for creating provider networks")
end
package "python-openstackclient"
execute "create_fixed_network" do
command "#{openstack_cmd} network create --share #{fixed_network_type} fixed"
not_if "out=$(#{openstack_cmd} network list --name fixed); [ $? != 0 ] || echo ${out} | grep -q ' fixed '"
retries 5
retry_delay 10
action :nothing
end
execute "create_floating_network" do
command "#{openstack_cmd} network create --external #{floating_network_type} floating"
not_if "out=$(#{openstack_cmd} network list --name floating); [ $? != 0 ] || echo ${out} | grep -q ' floating '"
retries 5
retry_delay 10
action :nothing
end
execute "create_ironic_network" do
command "#{openstack_cmd} network create --share #{ironic_network_type} ironic"
only_if { ironic_net }
not_if "out=$(#{openstack_cmd} network list --name ironic); [ $? != 0 ] || echo ${out} | grep -q ' ironic '"
retries 5
retry_delay 10
action :nothing
end
execute "create_fixed_subnet" do
command "#{openstack_cmd} subnet create --network fixed " \
"--allocation-pool start=#{fixed_pool_start},end=#{fixed_pool_end} " \
"--subnet-range #{fixed_range} fixed"
not_if "out=$(#{openstack_cmd} subnet list); [ $? != 0 ] || echo ${out} | grep -q ' fixed '"
retries 5
retry_delay 10
action :nothing
end
execute "create_floating_subnet" do
command "#{openstack_cmd} subnet create --network floating " \
"--allocation-pool start=#{floating_pool_start},end=#{floating_pool_end} " \
"--gateway #{floating_router} --subnet-range #{floating_range} --no-dhcp floating"
not_if "out=$(#{openstack_cmd} subnet list); [ $? != 0 ] || echo ${out} | grep -q ' floating '"
retries 5
retry_delay 10
action :nothing
end
execute "create_ironic_subnet" do
command "#{openstack_cmd} subnet create --network ironic --ip-version=4 " \
"--allocation-pool start=#{ironic_pool_start},end=#{ironic_pool_end} " \
"--gateway #{ironic_router} --subnet-range #{ironic_range} --dhcp ironic"
only_if { ironic_net }
not_if "out=$(#{openstack_cmd} subnet list); [ $? != 0 ] || echo ${out} | grep -q ' ironic '"
retries 5
retry_delay 10
action :nothing
end
execute "create_router" do
command "#{openstack_cmd} router create router-floating"
not_if "out=$(#{openstack_cmd} router list); [ $? != 0 ] || echo ${out} | grep -q router-floating"
retries 5
retry_delay 10
action :nothing
end
execute "set_router_gateway" do
command "#{openstack_cmd} router set --external-gateway floating router-floating"
# on Newton, the output for external_gateway_info was an empty string, on Ocata, the output is None
not_if "out=$(#{openstack_cmd} router show router-floating -f shell) ; " \
"[ $? != 0 ] || eval $out && [ \"${external_gateway_info}\" != \"None\" ] && " \
"[ \"${external_gateway_info}\" != \"\" ]"
retries 5
retry_delay 10
action :nothing
end
execute "add_fixed_network_to_router" do
command "#{openstack_cmd} router add subnet router-floating fixed"
not_if "out=$(#{openstack_cmd} port list --router router-floating --network fixed | wc -l); " \
"[ $? != 0 ] || (( ${out} > 1 ))"
retries 5
retry_delay 10
action :nothing
end
execute "add_ironic_network_to_router" do
command "#{openstack_cmd} router add subnet router-floating ironic"
only_if { ironic_net }
not_if "out=$(#{openstack_cmd} port list --router router-floating --network ironic | wc -l); " \
"[ $? != 0 ] || (( ${out} > 1 ))"
retries 5
retry_delay 10
action :nothing
end
domain_float = node[:neutron][:floating_dns_domain]
domain_fixed = node[:neutron][:dns_domain]
neutron_insecure = ssl_insecure ? "--insecure" : ""
execute "update_dns_domain_for_fixed_network" do
command "#{env} neutron #{neutron_insecure} net-update fixed --dns-domain #{domain_fixed}"
not_if "#{openstack_cmd} network show fixed -f value -c dns_domain | grep -q #{domain_fixed}"
retries 5
retry_delay 10
action :nothing
end
execute "update_dns_domain_for_floating_network" do
command "#{env} neutron #{neutron_insecure} net-update floating --dns-domain #{domain_float}"
not_if "#{openstack_cmd} network show floating -f value -c dns_domain | grep -q #{domain_float}"
retries 5
retry_delay 10
action :nothing
end
execute "Neutron network configuration" do
command "#{openstack_cmd} network list -c ID &>/dev/null"
retries 5
retry_delay 10
action :nothing
notifies :run, "execute[create_fixed_network]", :delayed
notifies :run, "execute[create_floating_network]", :delayed
notifies :run, "execute[create_ironic_network]", :delayed
notifies :run, "execute[create_fixed_subnet]", :delayed
notifies :run, "execute[create_floating_subnet]", :delayed
notifies :run, "execute[create_ironic_subnet]", :delayed
notifies :run, "execute[create_router]", :delayed
notifies :run, "execute[set_router_gateway]", :delayed
notifies :run, "execute[add_fixed_network_to_router]", :delayed
notifies :run, "execute[add_ironic_network_to_router]", :delayed
notifies :run, "execute[update_dns_domain_for_fixed_network]", :delayed
notifies :run, "execute[update_dns_domain_for_floating_network]", :delayed
end
# This is to trigger all the above "execute" resources to run :delayed, so that
# they run at the end of the chef-client run, after the neutron service has been
# restarted (in case of a config change)
execute "Trigger Neutron network configuration" do
command "true"
notifies :run, "execute[Neutron network configuration]", :delayed
end