Improve core network testing and validation

This commit is contained in:
Zach Leslie 2016-09-02 22:44:33 -07:00
parent 8eb4620ed4
commit d10ee590ce
15 changed files with 225 additions and 151 deletions

View File

@ -17,4 +17,5 @@ fixtures:
augeasproviders_core: 'herculesteam/augeasproviders_core'
augeasproviders_shellvar: 'herculesteam/augeasproviders_shellvar'
augeasproviders_sysctl: 'herculesteam/augeasproviders_sysctl'
ip: 'thrnio/ip'

View File

@ -10,7 +10,6 @@ rvm:
- 2.2
script: bundle exec rake test
env:
- PUPPET_VERSION="~> 4.3.0" STRICT_VARIABLES=yes
- PUPPET_VERSION="~> 4.4.0" STRICT_VARIABLES=yes
- PUPPET_VERSION="~> 4.5.0" STRICT_VARIABLES=yes
- PUPPET_VERSION="~> 4.6.0" STRICT_VARIABLES=yes

View File

@ -154,8 +154,6 @@ bsd::network::interface::carp { "carp0":
}
```
#### pfsync(4)
Closely related to carp(4) interfaces are the pfsync(4) interfaces.
They are supported by `bsd::network::interface::pfsync` defined type.

View File

@ -31,19 +31,12 @@ Puppet::Type.newtype(:bsd_interface) do
newparam :parents do
desc "a String or Array of parent interfaces"
validate do |value|
if value.is_a? Array
value.each { |v|
if ! v.match(/[[:alpha:]]+[[:digit:]]+/)
raise ArgumentError, "got illegal parent interface: '#{v}' for '#{resource[:name]}'"
end
}
elsif value.is_a? String
if ! value.match(/[[:alpha:]]+[[:digit:]]+/)
raise ArgumentError, "got illegal parent interface: '#{value}' for '#{resource[:name]}'"
raise ArgumentError, "param parents must be an Array, is: #{value.class}" unless value.is_a? Array
value.each { |v|
if ! v.match(/[[:alpha:]]+[[:digit:]]+/)
raise ArgumentError, "got illegal parent interface name: '#{v}' for '#{resource[:name]}'"
end
else
raise ArgumentError, "parents can only be a String or an Array, is: #{value.class}"
end
}
end
end

View File

@ -1,5 +1,3 @@
require_relative '../puppet_x/bsd/puppet_interface'
module PuppetX
module BSD
# a module for interfacing with parts of BSD from Ruby

View File

@ -12,23 +12,9 @@ class Hostname_if < PuppetX::BSD::PuppetInterface
attr_reader :content
def initialize(config)
options :desc,
:type,
:options,
:addresses,
:raw_values,
:mtu
multiopts :addresses,
:options,
:raw_values
oneof :addresses,
:raw_values,
:options,
:desc
#exclusive :addresses, :raw_values
options :desc, :type, :options, :addresses, :raw_values, :mtu
multiopts :addresses, :options, :raw_values
oneof :addresses, :raw_values, :options, :desc
configure(config)

View File

@ -40,6 +40,10 @@ class PuppetX::BSD::PuppetInterface
@config_booleans = []
end
unless @config_integers
@config_integers = []
end
@config = validate(reject_undef(config))
end
@ -68,7 +72,7 @@ class PuppetX::BSD::PuppetInterface
end
def validation(*required_array)
# an array of requirements to validate
# an array of required items to validate
unless required_array.is_a? Array
raise ArgumentError, "Array of names to validate required"
end
@ -108,8 +112,18 @@ class PuppetX::BSD::PuppetInterface
@config_booleans = boolean_options
end
def integers(*integer_options)
unless integer_options.is_a? Array
raise ArgumentError, "Array required for integer options"
end
@config_integers = integer_options
end
def validate(config)
# Check for required configurations
# Check requirements for all options
if @config_validation
@config_validation.each do |k,v|
unless config.keys.include? k
@ -158,12 +172,22 @@ class PuppetX::BSD::PuppetInterface
end
}
@config_integers.each {|i|
if config.keys.include? i
unless config[i].is_a? Fixnum
raise ArgumentError, "Integer-option #{i} must be an Integer, is: #{i.class}"
end
end
}
# Config values not in multopts should be a string
config.each {|k,v|
if not @config_multiopts.include? k and not @config_booleans.include? k
if not v.is_a? String
raise ArgumentError, "Config option #{k} must be a String"
end
next if @config_multiopts.include? k
next if @config_booleans.include? k
next if @config_integers.include? k
if not v.is_a? String
raise ArgumentError, "Config option #{k} must be a String"
end
}

View File

@ -11,13 +11,9 @@ require_relative '../../puppet_x/bsd/puppet_interface'
class Rc_conf < PuppetX::BSD::PuppetInterface
def initialize(config)
options :desc,
:addresses,
:options,
:raw_values,
:mtu
validation :name
options :desc, :addresses, :options, :raw_values, :mtu
integers :mtu
multiopts :addresses, :options, :raw_values
oneof :name, :desc
@ -36,7 +32,13 @@ class Rc_conf < PuppetX::BSD::PuppetInterface
end
def options_string
@options.join(' ')
result = ''
if @options and @options.size > 0
result = @options.join(' ')
end
result = result.to_s + "mtu #{@config[:mtu]}" if @config.keys.include? :mtu
result
end
def get_hash
@ -63,6 +65,8 @@ class Rc_conf < PuppetX::BSD::PuppetInterface
else
key = "ifconfig_#{ifname}"
end
# Set the value property on the resource
resources[key] = {
"value" => i,
}
@ -127,14 +131,16 @@ class Rc_conf < PuppetX::BSD::PuppetInterface
}
# append the options to the first address
opts = options_string()
if addrs.size > 0
ifconfig[:addrs] = addrs
if @options.size > 0
ifconfig[:addrs][0] = [ifconfig[:addrs][0],options_string()].join(' ')
if opts and opts.size > 0
ifconfig[:addrs][0] = [ifconfig[:addrs][0],opts].join(' ')
end
else
if @options.size > 0
if opts and opts.size > 0
ifconfig[:addrs] = options_string()
end
end

View File

@ -16,10 +16,10 @@
# Copyright 2013 Puppet Labs
#
class bsd::network (
$v4gateway = '',
$v6gateway = '',
$v4forwarding = false,
$v6forwarding = false,
Optional[IP::Address::V4] $v4gateway = undef,
Optional[IP::Address::V6] $v6gateway = undef,
Boolean $v4forwarding = false,
Boolean $v6forwarding = false,
) {
# Options common to both FreeBSD and OpenBSD
@ -53,21 +53,21 @@ class bsd::network (
# Manage the /etc/mygate file
# TODO Sanitize input here
if $v4gateway != '' and $v6gateway != '' {
if $v4gateway and $v6gateway {
$mygate = [$v4gateway,$v6gateway]
} elsif $v4gateway != '' {
} elsif $v4gateway {
$mygate = [$v4gateway]
} elsif $v6gateway != '' {
} elsif $v6gateway {
$mygate = [$v6gateway]
} else {
$mygate = []
}
if $v4gateway != '' or $v6gateway != '' {
file { '/etc/mygate':
owner => 'root',
group => '0',
mode => '0644',
content => inline_template("<%= @mygate.join(\"\n\") + \"\n\" %>"),
}
file { '/etc/mygate':
owner => 'root',
group => '0',
mode => '0644',
content => inline_template("<%= @mygate.join(\"\n\") + \"\n\" %>"),
}
}
'FreeBSD': {
@ -98,7 +98,7 @@ class bsd::network (
}
# What is our IPv4 default router?
if $v4gateway != '' {
if $v4gateway {
shellvar { 'defaultrouter':
value => $v4gateway,
}
@ -110,7 +110,7 @@ class bsd::network (
}
# What is our IPv6 default router?
if $v6gateway != '' {
if $v6gateway {
shellvar { 'ipv6_defaultrouter':
value => $v6gateway,
}

View File

@ -11,14 +11,22 @@
# carp, trunk, and it is recommended to use the more specific classes when
# available.
#
# @param state One of up, down, present or absent
# @param description A short description of the interface
# @param addresses An array of IPv4 or IPv6, or the keywords
# @param raw_values An array values to pass directly to the interface configuration
# @param options An array of option values to set
# @param parents An array of interface names to which this interface belongs
# @param mtu An integer representing the Maxium Transmition unit
#
define bsd::network::interface (
Pattern[/^(up|down|present|absent)$/] $ensure = 'present',
Optional[String] $description = undef,
Optional[Array] $addresses = undef,
Optional[Array] $raw_values = undef,
Optional[Array] $options = undef,
$parents = undef,
$mtu = undef,
Optional[Array] $parents = undef,
Optional[Integer] $mtu = undef,
) {
$if_name = $name
@ -91,13 +99,14 @@ define bsd::network::interface (
'FreeBSD': {
$rec_hash = get_freebsd_rc_conf_shellvar($config)
Shellvar {
$shellvar_defaults = {
ensure => $file_ensure,
target => '/etc/rc.conf',
before => Bsd_interface[$if_name],
notify => Bsd_interface[$if_name],
}
create_resources('shellvar', $rec_hash)
create_resources('shellvar', $rec_hash, $shellvar_defaults)
if $state == 'up' {
$action = 'start'
@ -109,7 +118,6 @@ define bsd::network::interface (
ensure => $state,
parents => $parents,
mtu => $mtu,
require => Shellvar["ifconfig_${if_name}"],
}
}
default: {

View File

@ -11,8 +11,7 @@
{
"operatingsystem": "FreeBSD",
"operatingsystemrelease": [
"10.3",
"9.3"
"10"
]
},
{
@ -24,10 +23,7 @@
}
],
"requirements": [
{
"name": "puppet",
"version_requirement": ">= 3.2.0 < 5.0.0"
}
{ "name": "puppet", "version_requirement": ">= 4.5.1 < 5.0.0" }
],
"description": "A module to manage parts of BSD",
"dependencies": [
@ -36,6 +32,7 @@
{ "name": "herculesteam-augeasproviders_core", "version_requirement": ">= 2.1.0" },
{ "name": "herculesteam-augeasproviders_shellvar", "version_requirement": ">= 2.2.0" },
{ "name": "herculesteam-augeasproviders_sysctl", "version_requirement": ">= 2.0.2" },
{ "name": "puppetlabs/stdlib","version_requirement":">=4.4.0"}
{ "name": "puppetlabs/stdlib","version_requirement":">=4.4.0"},
{ "name": "thrnio/ip","version_requirement":">=1.0.0"}
]
}

View File

@ -2,8 +2,8 @@ require 'spec_helper'
describe 'bsd::network' do
on_supported_os.each do |os, facts|
let(:facts) { facts }
context "on #{os}" do
let(:facts) { facts }
context 'with default params' do
it {
should contain_class('bsd::network')
@ -35,6 +35,7 @@ describe 'bsd::network' do
it {
should contain_class('bsd::network')
}
case facts[:osfamily]
when 'FreeBSD'
it {

View File

@ -1,6 +1,82 @@
require 'spec_helper'
describe "bsd::network::interface" do
on_supported_os.each do |os, facts|
context "on #{os}" do
let(:facts) { facts }
context "a basic configuration" do
let(:title) { 'igb0' }
let(:params) { {:ensure => 'up'} }
case facts[:osfamily]
when 'FreeBSD'
it {
should contain_bsd__network__interface('igb0').with_ensure('up')
should contain_bsd__network__interface('igb0').with_mtu(nil)
should contain_bsd__network__interface('igb0').with_parents(nil)
should contain_bsd_interface('igb0').with_ensure('up')
should contain_bsd_interface('igb0').with_mtu(nil)
should contain_bsd_interface('igb0').with_parents(nil)
}
end
end
context "a basic configuration with an address" do
let(:title) { 'igb0' }
let(:params) { {:addresses => ['10.0.0.1/24'], :description => 'simple' } }
case facts[:osfamily]
when 'FreeBSD'
it {
should contain_shellvar('ifconfig_igb0').with_value(/inet 10.0.0.1\/24/)
should contain_shellvar('ifconfig_igb0').with_target('/etc/rc.conf')
should contain_shellvar('ifconfig_igb0').that_notifies('Bsd_interface[igb0]')
should contain_bsd_interface('igb0').with_ensure('up')
should contain_bsd_interface('igb0').with_mtu(nil)
should contain_bsd_interface('igb0').with_parents(nil)
}
end
end
context "a basic configuration with mtu" do
let(:title) { 'igb0' }
let(:params) { {:mtu => 9000, :description => 'simple mtu' } }
case facts[:osfamily]
when 'FreeBSD'
it {
should contain_shellvar('ifconfig_igb0').with_value(/mtu 9000/)
should contain_shellvar('ifconfig_igb0').with_target('/etc/rc.conf')
should contain_bsd_interface('igb0').with_ensure('up')
should contain_bsd_interface('igb0').with_mtu(9000)
should contain_bsd_interface('igb0').with_parents(nil)
}
end
end
context "a basic vlan interface with an address" do
let(:title) { 'vlan1' }
let(:params) { {:addresses => ['10.0.0.1/24'], :options => ['vlan 1', 'vlandev em0'] } }
case facts[:osfamily]
when 'FreeBSD'
it do
should contain_shellvar('ifconfig_vlan1').with_value(/inet 10.0.0.1\/24 vlan 1 vlandev em0/)
should contain_shellvar('ifconfig_vlan1').with_ensure('present')
should contain_shellvar('ifconfig_vlan1').that_notifies('Bsd_interface[vlan1]')
should contain_bsd_interface('vlan1').that_requires('Shellvar[ifconfig_vlan1]')
should contain_bsd__network__interface('vlan1')
should contain_bsd_interface('vlan1').with_ensure('up')
should contain_bsd_interface('vlan1').with_mtu(nil)
should contain_bsd_interface('vlan1').with_parents(nil)
end
end
end
end
end
context "on OpenBSD" do
let(:facts) { {:kernel => 'OpenBSD'} }
context "a basic configuration" do
@ -73,31 +149,4 @@ describe "bsd::network::interface" do
end
end
context "on FreeBSD" do
let(:facts) { {:kernel => 'FreeBSD'} }
context "a basic configuration" do
let(:title) { 'igb0' }
let(:params) { {:addresses => ['10.0.0.1/24'], :description => 'simple' } }
it do
should contain_shellvar('ifconfig_igb0').with_value(/inet 10.0.0.1\/24/)
should contain_shellvar('ifconfig_igb0').that_notifies('Bsd_interface[igb0]')
should contain_bsd_interface('igb0').that_requires('Shellvar[ifconfig_igb0]')
should contain_bsd__network__interface('igb0')
end
end
context "when processing a vlan interface with one address" do
let(:title) { 'vlan1' }
let(:params) { {:addresses => ['10.0.0.1/24'], :options => ['vlan 1', 'vlandev em0'] } }
it do
should contain_shellvar('ifconfig_vlan1').with_value(/inet 10.0.0.1\/24 vlan 1 vlandev em0/)
should contain_shellvar('ifconfig_vlan1').with_ensure('present')
should contain_shellvar('ifconfig_vlan1').that_notifies('Bsd_interface[vlan1]')
should contain_bsd_interface('vlan1').that_requires('Shellvar[ifconfig_vlan1]')
should contain_bsd__network__interface('vlan1')
end
end
end
end

View File

@ -1,28 +1,45 @@
describe 'get_freebsd_rc_conf_shellvar' do
hash = {
'ifconfig_re0' => {
'value' => 'inet 10.0.1.12/24 mtu 9000',
},
'ifconfig_re0_alias0' => {
'value' => 'inet 10.0.1.13/24',
},
'ifconfig_re0_alias1' => {
'value' => 'inet 10.0.1.14/24',
},
}
full = {
"name" => 're0',
"description" => "Uplink",
"addresses" => [
'10.0.1.12/24',
'10.0.1.13/24',
'10.0.1.14/24',
],
"options" => [
'mtu 9000',
]
}
context 'setting only the mtu' do
hash = {
'ifconfig_re0' => {
'value' => 'mtu 9000',
},
}
it { should run.with_params(full).and_return(hash) }
c = {
"name" => 're0',
"mtu" => 9000,
}
it { should run.with_params(c).and_return(hash) }
end
context 'a full example' do
hash = {
'ifconfig_re0' => {
'value' => 'inet 10.0.1.12/24 mtu 9000',
},
'ifconfig_re0_alias0' => {
'value' => 'inet 10.0.1.13/24',
},
'ifconfig_re0_alias1' => {
'value' => 'inet 10.0.1.14/24',
},
}
full = {
"name" => 're0',
"description" => "Uplink",
"addresses" => [
'10.0.1.12/24',
'10.0.1.13/24',
'10.0.1.14/24',
],
"options" => [
'mtu 9000',
]
}
it { should run.with_params(full).and_return(hash) }
end
end

View File

@ -12,24 +12,6 @@ describe 'Rc_conf' do
end
describe '#validate_config' do
context "when config is not present" do
it "should raise an error" do
expect { rc.new() }.to raise_error(ArgumentError)
end
end
context "when minimal config is supplied" do
it "should not raise an error" do
c = {
:name => 're0',
:desc => "Uplink",
}
expect { rc.new(c) }.to_not raise_error(ArgumentError)
end
end
end
describe '#get_hash' do
context 'with a dynamic v4-only config' do
it "should return a valid config" do
@ -131,9 +113,7 @@ describe 'Rc_conf' do
'fc00::124/64',
'fc00::125/64',
],
:options => [
'mtu 9000',
]
:mtu => 9000,
}
expect(rc.new(c).get_hash).to eq(hash)
end
@ -141,6 +121,23 @@ describe 'Rc_conf' do
end
describe '#to_create_resources' do
context 'when only mtu is spplied' do
it {
hash = {
'ifconfig_re0' => {
'value' => 'mtu 9000',
},
}
c = {
:name => 're0',
:mtu => 9000,
}
expect(rc.new(c).to_create_resources).to eq(hash)
}
end
context 'when a full interface config is supplied' do
it 'should convert the hash for create_resources()' do
hash = {