-
-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: David Hollinger <[email protected]>
- Loading branch information
David Hollinger
committed
May 29, 2018
1 parent
797f1bd
commit ec9599f
Showing
9 changed files
with
262 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
require 'net/ip' | ||
# require_relative '../../../puppet_x/voxpupuli/utils' | ||
require 'puppet/resource_api/simple_provider' | ||
|
||
# Implementation for the network_route type using the Resource API. | ||
class Puppet::Provider::NetworkRoute::NetworkRoute < Puppet::ResourceApi::SimpleProvider | ||
# include PuppetX::FileMapper | ||
|
||
def routes_list | ||
routes = [] | ||
Net::IP.routes.each do |route| | ||
routes.push(route.instance_variables.each_with_object({}) { |var, hash| hash[var.to_s.delete("@")] = route.instance_variable_get(var) }) | ||
end | ||
routes | ||
end | ||
|
||
def get(_context) | ||
routes_list.map do |route| | ||
default = if route['prefix'] == 'default' | ||
true | ||
else | ||
false | ||
end | ||
|
||
{ | ||
ensure: 'present', | ||
prefix: route['prefix'], | ||
default_route: default, | ||
gateway: route['via'], | ||
interface: route['dev'], | ||
metric: route['metric'], | ||
table: route['table'], | ||
source: route['src'], | ||
scope: route['scope'], | ||
protocol: route['proto'], | ||
mtu: route['mtu'] | ||
}.compact! | ||
end | ||
end | ||
|
||
def puppet_munge(should) | ||
should.delete(:ensure) | ||
if should[:default_route] | ||
should[:prefix] = 'default' | ||
should.delete(:default_route) | ||
should.delete(:prefix) | ||
else | ||
should[:prefix] = should.delete(:prefix) | ||
end | ||
should[:via] = should.delete(:gateway) if should[:gateway] | ||
should[:dev] = should.delete(:interface) if should[:interface] | ||
should[:metric] = should.delete(:metric) | ||
should[:table] = should.delete(:table) | ||
should[:src] = should.delete(:source) if should[:source] | ||
should[:scope] = should.delete(:scope) | ||
should[:proto] = should.delete(:protocol) | ||
should[:mtu] = should.delete(:mtu) if should[:mtu] | ||
should | ||
end | ||
end |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,60 @@ | ||
require 'ipaddr' | ||
require_relative '../../puppet_x/voxpupuli/utils.rb' | ||
|
||
Puppet::Type.newtype(:network_route) do | ||
@doc = 'Manage non-volatile route configuration information' | ||
|
||
include PuppetX::Voxpupuli::Utils | ||
|
||
ensurable | ||
|
||
newparam(:name) do | ||
isnamevar | ||
desc 'The name of the network route' | ||
end | ||
|
||
newproperty(:network) do | ||
isrequired | ||
desc 'The target network address' | ||
validate do |value| | ||
unless value == 'default' | ||
a = PuppetX::Voxpupuli::Utils.try { IPAddr.new(value) } | ||
raise("Invalid value for network: #{value}") unless a | ||
end | ||
end | ||
end | ||
|
||
newproperty(:netmask) do | ||
isrequired | ||
desc 'The subnet mask to apply to the route' | ||
|
||
validate do |value| | ||
unless value.length <= 3 || PuppetX::Voxpupuli::Utils.try { IPAddr.new(value) } | ||
raise("Invalid value for argument netmask: #{value}") | ||
end | ||
end | ||
|
||
munge do |value| | ||
# '255.255.255.255'.to_i will return 255, so we try to convert it back: | ||
if value.to_i.to_s == value | ||
# what are the chances someone is using /16 for their IPv6 network? | ||
addr = value.to_i <= 32 ? '255.255.255.255' : 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' | ||
IPAddr.new(addr).mask(value.strip.to_i).to_s | ||
elsif PuppetX::Voxpupuli::Utils.try { IPAddr.new(value).ipv6? } | ||
IPAddr.new('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff').mask(value).to_s | ||
elsif PuppetX::Voxpupuli::Utils.try { IPAddr.new(value).ipv4? } | ||
IPAddr.new('255.255.255.255').mask(value).to_s | ||
else | ||
raise("Invalid value for argument netmask: #{value}") | ||
end | ||
end | ||
end | ||
|
||
newproperty(:gateway) do | ||
isrequired | ||
desc 'The gateway to use for the route' | ||
|
||
validate do |value| | ||
begin | ||
IPAddr.new(value) | ||
rescue ArgumentError | ||
raise("Invalid value for gateway: #{value}") | ||
end | ||
end | ||
end | ||
|
||
newproperty(:interface) do | ||
isrequired | ||
desc 'The interface to use for the route' | ||
end | ||
|
||
# `:options` provides an arbitrary passthrough for provider properties, so | ||
# that provider specific behavior doesn't clutter up the main type but still | ||
# allows for more powerful actions to be taken. | ||
newproperty(:options, required_features: :provider_options) do | ||
desc 'Provider specific options to be passed to the provider' | ||
|
||
validate do |value| | ||
raise ArgumentError, "#{self.class} requires a string for the options property" unless value.is_a?(String) | ||
end | ||
end | ||
end | ||
require 'puppet/resource_api' | ||
|
||
Puppet::ResourceApi.register_type( | ||
name: 'network_route', | ||
docs: <<-EOS, | ||
Manage non-volatile route configuration information. | ||
EOS | ||
attributes: { | ||
ensure: { | ||
type: 'Enum[present, absent]', | ||
desc: 'Whether the network route should be present or absent on the target system.', | ||
default: 'present', | ||
}, | ||
prefix: { | ||
type: 'String', | ||
desc: 'The destination prefix/network of the route.', | ||
behaviour: :namevar, | ||
}, | ||
default_route: { | ||
type: 'Optional[Boolean]', | ||
desc: 'Whether the route is default or not.', | ||
}, | ||
gateway: { | ||
type: 'Optional[String]', | ||
desc: 'The gateway to use for the route.', | ||
}, | ||
interface: { | ||
type: 'Optional[String]', | ||
desc: 'The interface to use for the route.', | ||
}, | ||
metric: { | ||
type: 'String', | ||
desc: 'preference value of the route. NUMBER is an arbitrary 32bit number.', | ||
default: '100', | ||
}, | ||
table: { | ||
type: 'String', | ||
desc: 'table to add this route.', | ||
default: 'local', | ||
}, | ||
source: { | ||
type: 'Optional[String]', | ||
desc: 'the source address to prefer using when sending to the destinations covered by route prefix.', | ||
}, | ||
scope: { | ||
type: 'Enum["global", "nowhere", "host", "link", "site"]', | ||
desc: 'scope of the destinations covered by the route prefix.', | ||
default: 'global', | ||
}, | ||
protocol: { | ||
type: 'String', | ||
desc: 'routing protocol identifier of this route.', | ||
default: 'boot', | ||
}, | ||
mtu: { | ||
type: 'Optional[String]', | ||
desc: 'the MTU along the path to destination.', | ||
}, | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
require 'ipaddr' | ||
require_relative '../../puppet_x/voxpupuli/utils.rb' | ||
|
||
Puppet::Type.newtype(:network_route) do | ||
@doc = 'Manage non-volatile route configuration information' | ||
|
||
include PuppetX::Voxpupuli::Utils | ||
|
||
ensurable | ||
|
||
newparam(:name) do | ||
isnamevar | ||
desc 'The name of the network route' | ||
end | ||
|
||
newproperty(:network) do | ||
isrequired | ||
desc 'The target network address' | ||
validate do |value| | ||
unless value == 'default' | ||
a = PuppetX::Voxpupuli::Utils.try { IPAddr.new(value) } | ||
raise("Invalid value for network: #{value}") unless a | ||
end | ||
end | ||
end | ||
|
||
newproperty(:netmask) do | ||
isrequired | ||
desc 'The subnet mask to apply to the route' | ||
|
||
validate do |value| | ||
unless value.length <= 3 || PuppetX::Voxpupuli::Utils.try { IPAddr.new(value) } | ||
raise("Invalid value for argument netmask: #{value}") | ||
end | ||
end | ||
|
||
munge do |value| | ||
# '255.255.255.255'.to_i will return 255, so we try to convert it back: | ||
if value.to_i.to_s == value | ||
# what are the chances someone is using /16 for their IPv6 network? | ||
addr = value.to_i <= 32 ? '255.255.255.255' : 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' | ||
IPAddr.new(addr).mask(value.strip.to_i).to_s | ||
elsif PuppetX::Voxpupuli::Utils.try { IPAddr.new(value).ipv6? } | ||
IPAddr.new('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff').mask(value).to_s | ||
elsif PuppetX::Voxpupuli::Utils.try { IPAddr.new(value).ipv4? } | ||
IPAddr.new('255.255.255.255').mask(value).to_s | ||
else | ||
raise("Invalid value for argument netmask: #{value}") | ||
end | ||
end | ||
end | ||
|
||
newproperty(:gateway) do | ||
isrequired | ||
desc 'The gateway to use for the route' | ||
|
||
validate do |value| | ||
begin | ||
IPAddr.new(value) | ||
rescue ArgumentError | ||
raise("Invalid value for gateway: #{value}") | ||
end | ||
end | ||
end | ||
|
||
newproperty(:interface) do | ||
isrequired | ||
desc 'The interface to use for the route' | ||
end | ||
|
||
# `:options` provides an arbitrary passthrough for provider properties, so | ||
# that provider specific behavior doesn't clutter up the main type but still | ||
# allows for more powerful actions to be taken. | ||
newproperty(:options, required_features: :provider_options) do | ||
desc 'Provider specific options to be passed to the provider' | ||
|
||
validate do |value| | ||
raise ArgumentError, "#{self.class} requires a string for the options property" unless value.is_a?(String) | ||
end | ||
end | ||
end |
49 changes: 49 additions & 0 deletions
49
spec/unit/puppet/provider/network_route/network_route_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
require 'spec_helper' | ||
|
||
ensure_module_defined('Puppet::Provider::NetworkRoute') | ||
require 'puppet/provider/network_route/network_route' | ||
|
||
RSpec.describe Puppet::Provider::NetworkRoute::NetworkRoute do | ||
subject(:provider) { described_class.new } | ||
|
||
let(:context) { instance_double('Puppet::ResourceApi::BaseContext', 'context') } | ||
|
||
describe '#get' do | ||
it 'processes resources' do | ||
expect(provider.get(context)).to eq [ | ||
{ | ||
name: 'foo', | ||
ensure: 'present', | ||
}, | ||
{ | ||
name: 'bar', | ||
ensure: 'present', | ||
}, | ||
] | ||
end | ||
end | ||
|
||
describe 'create(context, name, should)' do | ||
it 'creates the resource' do | ||
expect(context).to receive(:notice).with(%r{\ACreating 'a'}) | ||
|
||
provider.create(context, 'a', name: 'a', ensure: 'present') | ||
end | ||
end | ||
|
||
describe 'update(context, name, should)' do | ||
it 'updates the resource' do | ||
expect(context).to receive(:notice).with(%r{\AUpdating 'foo'}) | ||
|
||
provider.update(context, 'foo', name: 'foo', ensure: 'present') | ||
end | ||
end | ||
|
||
describe 'delete(context, name, should)' do | ||
it 'deletes the resource' do | ||
expect(context).to receive(:notice).with(%r{\ADeleting 'foo'}) | ||
|
||
provider.delete(context, 'foo') | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
require 'spec_helper' | ||
require 'puppet/type/network_route' | ||
|
||
RSpec.describe 'the network_route type' do | ||
it 'loads' do | ||
expect(Puppet::Type.type(:network_route)).not_to be_nil | ||
end | ||
end |