diff --git a/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/configure_default_route.rb b/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/configure_default_route.rb new file mode 100644 index 0000000000..6d1f88870d --- /dev/null +++ b/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/configure_default_route.rb @@ -0,0 +1,121 @@ +require 'ipaddr' +require 'pp' +#require 'puppetx/l23_utils' +#require 'puppetx/l23_network_scheme' +#require 'puppetx/l23_hash_tools' + +Puppet::Parser::Functions::newfunction(:configure_default_route, :type => :rvalue, :doc => <<-EOS +This function gets hash of network endpoints configuration and compare whether master_ip is the gateway +for fw-admin network. If yes - it removes it and set default route for management network to ip of vrouter +, if no - it does nothing. +EOS +) do |argv| + raise Puppet::ParseError, 'configure_default_route(): Arguments: network_scheme, master_ip, management_vrouter_vip' if argv.size != 5 + + network_scheme = argv[0] + master_ip = argv[1] + management_vrouter_vip = argv[2] + fw_admin_int = argv[3].to_sym + management_int = argv[4].to_sym + + raise Puppet::ParseError, 'network_scheme is empty!' if network_scheme.nil? + raise Puppet::ParseError, 'master_ip is empty!' if master_ip.nil? + raise Puppet::ParseError, 'management_vrouter_vip is empty!' if management_vrouter_vip.nil? + raise Puppet::ParseError, 'fw_admin_int is empty!' if fw_admin_int.nil? + raise Puppet::ParseError, 'management_int is empty!' if management_int.nil? + + network_scheme = L23network.sanitize_keys_in_hash network_scheme + network_scheme = L23network.sanitize_bool_in_hash network_scheme + + # we can't imagine, that user can write in this field, but we try to convert to numeric and compare + if network_scheme[:version].to_s.to_f < 1.1 + raise Puppet::ParseError, 'configure_default_route(): You network_scheme hash has wrong format. This parser can work with v1.1 format, please convert you config.' + end + + # collect L3::ifconfig properties from 'endpoints' section + debug 'configure_default_route(): collect endpoints' + endpoints = {} + if network_scheme[:endpoints].is_a? Hash and network_scheme[:endpoints].any? + network_scheme[:endpoints].each do |endpoint_name, endpoint_properties| + endpoint_name = endpoint_name.to_sym + endpoints[endpoint_name] = { :ipaddr => [] } + if endpoint_properties and endpoint_properties.any? + endpoint_properties.each do |endpoint_property_name, endpoint_property_value| + endpoint_property_name = endpoint_property_name.to_s.tr('-', '_').to_sym + if endpoint_property_name == :IP + if ['none', 'dhcp', ''].include? endpoint_property_value.to_s + # 'none' and 'dhcp' should be passed to resource not as list + endpoints[endpoint_name][:ipaddr] = (endpoint_property_value.to_s == 'dhcp' ? 'dhcp' : 'none') + elsif endpoint_property_value.is_a? Array + # pass array of ip addresses validating every ip + endpoint_property_value.each do |ip| + begin + # validate ip address + IPAddr.new ip + endpoints[endpoint_name][:ipaddr] = [] unless endpoints[endpoint_name][:ipaddr] + endpoints[endpoint_name][:ipaddr] << ip + rescue + raise Puppet::ParseError, "configure_default_route(): IP address '#{ip}' for endpoint '#{endpoint_name}' is wrong!" + end + end + else + raise Puppet::ParseError, "configure_default_route(): IP field for endpoint '#{endpoint_name}' must be array of IP addresses, 'dhcp' or 'none'" + end + else + endpoints[endpoint_name][endpoint_property_name] = endpoint_property_value + end + end + else + endpoints[endpoint_name][:ipaddr] = 'none' + end + end + else + network_scheme[:endpoints] = {} + end + + + change_to_vrouter = false + network_scheme[:endpoints].each do |endpoint, body| + change_to_vrouter = true if body[:gateway] == master_ip and endpoint == fw_admin_int + end + + unless change_to_vrouter + debug 'configure_default_route(): Will not change the default route to the vrouter IP address' + return nil + end + + data = '' + debug 'configure_default_route(): Change default route to vrouter ip address' + interface_names = [ fw_admin_int, management_int ] + previous = nil + interface_names.each do |endpoint_name| + next unless endpoints[endpoint_name] + # collect properties for creating endpoint resource + resource_properties = {} + endpoints[endpoint_name][:gateway] = management_vrouter_vip if endpoint_name == management_int + endpoints[endpoint_name].each do |property, value| + value = :absent if property == :gateway and endpoint_name == fw_admin_int + next unless value + if property.to_s.downcase == 'routes' + # TODO: support setting of routes? + elsif %w(Hash Array).include? value.class.to_s + # sanitize hash or array + resource_properties[property.to_s] = L23network.reccursive_sanitize_hash(value) + else + # pass value as is + resource_properties[property.to_s] = value + end + end + resource_properties['require'] = previous if previous + # save resource parameters + debug "configure_default_route(): Endpoint '#{endpoint_name}' will be created with additional properties:\n#{resource_properties.pretty_inspect}" + function_create_resources(['l23network::l3::ifconfig', { + "#{endpoint_name}" => resource_properties + }]) + previous = "l23network::l3::ifconfig[#{endpoint_name}]" + data << "#{endpoint_name} " + end + data +end + +# vim: set ts=2 sw=2 et : diff --git a/deployment/puppet/osnailyfacter/modular/astute/tasks.yaml b/deployment/puppet/osnailyfacter/modular/astute/tasks.yaml index 9a405900bc..20025a8a4e 100644 --- a/deployment/puppet/osnailyfacter/modular/astute/tasks.yaml +++ b/deployment/puppet/osnailyfacter/modular/astute/tasks.yaml @@ -100,6 +100,17 @@ timeout: 3600 cwd: / +- id: configure_default_route + type: puppet + role: [primary-mongo, mongo, compute, ceph-osd, cinder, zabbix-server, base-os] + requires: [post_deployment_start] + required_for: [post_deployment_end] + parameters: + puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/netconfig/configure_default_route.pp + puppet_modules: /etc/puppet/modules + timeout: 3600 + cwd: / + #PRE DEPLOYMENT - id: upload_core_repos type: upload_file diff --git a/deployment/puppet/osnailyfacter/modular/netconfig/configure_default_route.pp b/deployment/puppet/osnailyfacter/modular/netconfig/configure_default_route.pp new file mode 100644 index 0000000000..6fff09406d --- /dev/null +++ b/deployment/puppet/osnailyfacter/modular/netconfig/configure_default_route.pp @@ -0,0 +1,12 @@ +notice('MODULAR: configure_default_route.pp') + +$network_scheme = hiera('network_scheme') +$master_ip = hiera('master_ip') +$management_vrouter_vip = hiera('management_vrouter_vip') + +prepare_network_config($network_scheme) +$management_int = get_network_role_property('management', 'interface') +$fw_admin_int = get_network_role_property('fw-admin', 'interface') +$ifconfig = configure_default_route($network_scheme, $master_ip, $management_vrouter_vip, $fw_admin_int, $management_int ) + +notice ($ifconfig) diff --git a/deployment/puppet/osnailyfacter/spec/functions/configure_default_route__spec.rb b/deployment/puppet/osnailyfacter/spec/functions/configure_default_route__spec.rb new file mode 100644 index 0000000000..13ef9a0151 --- /dev/null +++ b/deployment/puppet/osnailyfacter/spec/functions/configure_default_route__spec.rb @@ -0,0 +1,84 @@ +require 'spec_helper' + +describe 'configure_default_route' do + let(:scope) { PuppetlabsSpec::PuppetInternals.scope } + + let(:subject) do + Puppet::Parser::Functions.function(:configure_default_route) + end + + let(:network_scheme) do + {:provider => "lnx", + :transformations => + [{:action => "add-br", :name => "br-fw-admin"}, + {:action => "add-br", :name => "br-mgmt"}, + {:action => "add-br", :name => "br-storage"}, + {:action => "add-br", :provider => "ovs", :name => "br-prv"}, + {:action => "add-patch", + :provider => "ovs", + :bridges => ["br-prv", "br-fw-admin"]}, + {:action => "add-port", :bridge => "br-fw-admin", :name => "eth0"}, + {:action => "add-port", :bridge => "br-storage", :name => "eth0.102"}, + {:action => "add-port", :bridge => "br-mgmt", :name => "eth0.101"}], + :roles => + {:management => "br-mgmt", + :"fw-admin" => "br-fw-admin", + :storage => "br-storage", + :"neutron/private" => "br-prv"}, + :endpoints => + {:"br-mgmt" => + {:IP => ["192.168.0.5/24"], + :vendor_specific => {:vlans => 101, :phy_interfaces => ["eth0"]}}, + :"br-prv" => + {:IP => nil, + :vendor_specific => {:vlans => "1000:1030", :phy_interfaces => ["eth0"]}}, + :"br-fw-admin" => {:IP => ["10.20.0.6/24"], :gateway => "10.20.0.2",}, + :"br-storage" => + {:IP => ["192.168.1.3/24"], + :vendor_specific => {:vlans => 102, :phy_interfaces => ["eth0"]}}}, + :version => "1.1", + :interfaces => + {:eth1 => {:vendor_specific => {:driver => "e1000", :bus_info => "0000:00:07.0"}}, + :eth0 => {:vendor_specific => {:driver => "e1000", :bus_info => "0000:00:03.0"}}, + :eth2 => {:vendor_specific => {:driver => "e1000", :bus_info => "0000:00:08.0"}}}} + end + + let(:master_ip) { '10.20.0.2' } + + let(:management_vrouter_vip) { '192.168.0.2' } + + let(:management_int) { 'br-mgmt' } + let(:fw_admin_int) { 'br-fw-admin' } + + it 'should exist' do + expect(subject).to eq 'function_configure_default_route' + end + + it 'should expect 5 arguments' do + expect { scope.function_configure_default_route [] }.to raise_error + end + + it 'should configure default the default route if gateway ip is equal to master_ip' do + arguments = [network_scheme, master_ip, management_vrouter_vip, fw_admin_int, management_int] + ifconfig = scope.function_configure_default_route arguments + expect(ifconfig['br-mgmt']).to eq({ + "ipaddr"=>["192.168.0.5/24"], + "vendor_specific"=>{ + "vlans"=>"101", + "phy_interfaces"=>["eth0"] + }, + "gateway"=>"192.168.0.2" + }) + expect(ifconfig['br-fw-admin']).to eq({ + "ipaddr"=>["10.20.0.6/24"] + }) + + end + + it 'should not configure interfaces if master_ip is not equal to the gateway' do + arguments = [network_scheme, '10.20.0.3', management_vrouter_vip] + ifconfig = scope.function_configure_default_route arguments + expect(ifconfig).to eq({}) + end + +end diff --git a/tests/noop/spec/hosts/netconfig/configure_default_route_spec.rb b/tests/noop/spec/hosts/netconfig/configure_default_route_spec.rb new file mode 100644 index 0000000000..db191afc86 --- /dev/null +++ b/tests/noop/spec/hosts/netconfig/configure_default_route_spec.rb @@ -0,0 +1,8 @@ +require 'spec_helper' +require 'shared-examples' +manifest = 'netconfig/configure_default_route.pp' + +describe manifest do + test_ubuntu_and_centos manifest +end +