This repository has been archived by the owner on Jun 5, 2020. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #120 from dblessing/selfip
Support Self IP and VLAN
- Loading branch information
Showing
5 changed files
with
386 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
require 'puppet/provider/f5' | ||
|
||
Puppet::Type.type(:f5_selfip).provide(:f5_selfip, :parent => Puppet::Provider::F5) do | ||
@doc = 'Manage F5 self IPs.' | ||
|
||
confine :feature => :posix | ||
defaultfor :feature => :posix | ||
|
||
def self.wsdl | ||
'Networking.SelfIPV2' | ||
end | ||
|
||
def wsdl | ||
self.class.wsdl | ||
end | ||
|
||
def self.instances | ||
instances = [] | ||
get_list.each do |selfip| | ||
instances << new(name: selfip, ensure: :present) | ||
end | ||
instances | ||
end | ||
|
||
def self.prefetch(resources) | ||
selfips = instances | ||
resources.keys.each do |name| | ||
if provider = selfips.find { |selfip| selfip.name == name } | ||
resources[name].provider = provider | ||
|
||
end | ||
end | ||
end | ||
|
||
def destroy | ||
message = { routes: { item: resource[:name] }} | ||
transport[wsdl].call(:delete_self_ip, message: message) | ||
|
||
@property_hash[:ensure] = :absent | ||
end | ||
|
||
def create | ||
message = { | ||
self_ips: { item: resource[:name] }, | ||
vlan_names: { item: resource[:vlan] }, | ||
addresses: { item: resource[:address] }, | ||
netmasks: { item: resource[:netmask] }, | ||
traffic_groups: { item: resource[:traffic_group] }, | ||
floating_states: { item: resource[:floating_state] } | ||
} | ||
transport[wsdl].call(:create, message: message) | ||
end | ||
|
||
def exists? | ||
@property_hash[:ensure] == :present | ||
end | ||
|
||
def address | ||
message = { self_ips: { item: self.name } } | ||
transport[wsdl].get(:get_address, message) | ||
end | ||
|
||
# Unfortunately you can't change the address. | ||
def address=(value) | ||
Puppet.debug('Cannot change this value, destroying and recreating.') | ||
destroy | ||
create | ||
end | ||
|
||
def floating_state | ||
message = { self_ips: { item: self.name } } | ||
transport[wsdl].get(:get_floating_state, message) | ||
end | ||
|
||
def floating_state=(value) | ||
message = { | ||
self_ips: { item: self.name }, | ||
states: { item: resource[:floating_state] }, | ||
} | ||
transport[wsdl].call(:set_floating_states, message: message) | ||
end | ||
|
||
def netmask | ||
message = { self_ips: { item: self.name }} | ||
transport[wsdl].get(:get_netmask, message) | ||
end | ||
|
||
# Unfortunately you can't change the netmask either. | ||
def netmask=(value) | ||
Puppet.debug('Cannot change this value, destroying and recreating.') | ||
destroy | ||
create | ||
end | ||
|
||
def traffic_group | ||
message = { self_ips: { item: self.name }} | ||
transport[wsdl].get(:get_traffic_group, message) | ||
end | ||
|
||
def traffic_group=(value) | ||
message = { | ||
self_ips: { item: self.name }, | ||
traffic_groups: { item: resource[:traffic_group] }, | ||
} | ||
transport[wsdl].call(:set_traffic_group, message: message) | ||
end | ||
|
||
def vlan | ||
message = { self_ips: { item: self.name }} | ||
transport[wsdl].get(:get_vlan, message) | ||
end | ||
|
||
def vlan=(value) | ||
message = { | ||
self_ips: { item: self.name }, | ||
vlan_names: { item: resource[:vlan] }, | ||
} | ||
transport[wsdl].call(:set_vlan, message: message) | ||
end | ||
|
||
# Obtain a list of static routes. | ||
def self.get_list | ||
response = transport[wsdl].get(:get_list) | ||
return Array(response) | ||
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,116 @@ | ||
require 'puppet/provider/f5' | ||
|
||
Puppet::Type.type(:f5_vlan).provide(:f5_vlan, :parent => Puppet::Provider::F5) do | ||
@doc = 'Manage F5 VLANs.' | ||
|
||
confine :feature => :posix | ||
defaultfor :feature => :posix | ||
|
||
def self.wsdl | ||
'Networking.VLAN' | ||
end | ||
|
||
def wsdl | ||
self.class.wsdl | ||
end | ||
|
||
def self.instances | ||
instances = [] | ||
get_list.each do |vlan| | ||
instances << new(name: vlan, ensure: :present) | ||
end | ||
instances | ||
end | ||
|
||
def self.prefetch(resources) | ||
vlans = instances | ||
resources.keys.each do |name| | ||
if provider = vlans.find { |vlan| vlan.name == name } | ||
resources[name].provider = provider | ||
|
||
end | ||
end | ||
end | ||
|
||
def destroy | ||
message = { vlans: { item: resource[:name] }} | ||
transport[wsdl].call(:delete_vlan, message: message) | ||
|
||
@property_hash[:ensure] = :absent | ||
end | ||
|
||
def create | ||
members = Array.new(1) { Array.new(resource[:members].length) } | ||
members[0] = resource[:members] | ||
message = { | ||
vlans: { item: resource[:name] }, | ||
vlan_ids: { item: resource[:vlan_id] }, | ||
members: { item: members }, | ||
failsafe_states: { item: resource[:failsafe_state] }, | ||
timeouts: { item: resource[:timeout] }, | ||
} | ||
transport[wsdl].call(:create_v2, message: message) | ||
end | ||
|
||
def exists? | ||
@property_hash[:ensure] == :present | ||
end | ||
|
||
def failsafe_state | ||
message = { vlans: { item: self.name } } | ||
transport[wsdl].get(:get_failsafe_state, message) | ||
end | ||
|
||
def failsafe_state=(value) | ||
message = { | ||
vlans: { item: self.name }, | ||
states: { item: resource[:failsafe_state] }, | ||
} | ||
transport[wsdl].call(:set_failsafe_state, message: message) | ||
end | ||
|
||
def members | ||
message = { vlans: { item: self.name }} | ||
response = transport[wsdl].get(:get_member, message) | ||
return response.is_a?(Array) ? response : Array.new(1) { response } | ||
end | ||
|
||
# Unfortunately you can't change the members. | ||
def members=(value) | ||
Puppet.debug('Cannot change this value, destroying and recreating.') | ||
destroy | ||
create | ||
end | ||
|
||
def timeout | ||
message = { vlans: { item: self.name } } | ||
transport[wsdl].get(:get_failsafe_timeout, message) | ||
end | ||
|
||
def timeout=(value) | ||
message = { | ||
vlans: { item: self.name }, | ||
timeouts: { item: resource[:timeouts] }, | ||
} | ||
transport[wsdl].call(:set_failsafe_timeout, message: message) | ||
end | ||
|
||
def vlan_id | ||
message = { vlans: { item: self.name }} | ||
transport[wsdl].get(:get_vlan_id, message) | ||
end | ||
|
||
def vlan_id=(value) | ||
message = { | ||
vlans: { item: self.name }, | ||
vlan_ids: { item: resource[:vlan_id] }, | ||
} | ||
transport[wsdl].call(:set_vlan_id, message: message) | ||
end | ||
|
||
# Obtain a list of static routes. | ||
def self.get_list | ||
response = transport[wsdl].get(:get_list) | ||
return Array(response) | ||
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,57 @@ | ||
require 'ipaddr' # For validation. | ||
|
||
Puppet::Type.newtype(:f5_selfip) do | ||
@doc = 'Manage self IPs within the F5.' | ||
|
||
apply_to_device | ||
ensurable | ||
|
||
VALID_PARTITION = /^\/.*\// | ||
|
||
newparam(:name, :namevar => true) do | ||
desc 'The name of the self IP object' | ||
|
||
validate do |value| | ||
raise(ArgumentError, "Must match pattern of /Partition/ObjectName") unless value =~ VALID_PARTITION | ||
end | ||
end | ||
|
||
newproperty(:address) do | ||
desc 'The IP address of the self IP object' | ||
|
||
validate do |value| | ||
raise(ArgumentError, 'Address must be a valid IP address.') unless IPAddr.new(value) | ||
end | ||
end | ||
|
||
newproperty(:netmask) do | ||
desc 'Netmask of the self IP object' | ||
|
||
validate do |value| | ||
raise(ArgumentError, 'Destination must be a valid IP address.') unless IPAddr.new(value) | ||
end | ||
end | ||
|
||
newproperty(:vlan) do | ||
desc 'VLAN or Tunnel name for the self IP object' | ||
|
||
validate do |value| | ||
raise(ArgumentError, "Must match pattern of /Partition/ObjectName") unless value =~ VALID_PARTITION | ||
end | ||
end | ||
|
||
newproperty(:traffic_group) do | ||
desc 'Traffic group for the self IP object' | ||
|
||
validate do |value| | ||
raise(ArgumentError, "Must match pattern of /Partition/ObjectName") unless value =~ VALID_PARTITION | ||
end | ||
end | ||
|
||
newproperty(:floating_state) do | ||
desc 'The floating state of the self IP object' | ||
|
||
newvalue('STATE_ENABLED') | ||
newvalue('STATE_DISABLED') | ||
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,85 @@ | ||
require 'ipaddr' # For validation. | ||
|
||
Puppet::Type.newtype(:f5_vlan) do | ||
@doc = 'Manage self IPs within the F5.' | ||
|
||
apply_to_device | ||
ensurable | ||
|
||
VALID_PARTITION = /^\/.*\// | ||
|
||
newparam(:name, :namevar => true) do | ||
desc 'The name of the VLAN object' | ||
|
||
validate do |value| | ||
raise(ArgumentError, "Must match pattern of /Partition/ObjectName") unless value =~ VALID_PARTITION | ||
end | ||
end | ||
|
||
newproperty(:vlan_id) do | ||
desc 'The ID of the VLAN object' | ||
|
||
newvalues(/^\d+$/) | ||
end | ||
|
||
newproperty(:members, :array_matching => :all) do | ||
desc 'The list of interfaces/trunks that will be members of the VLAN.' | ||
required_keys = ['member_name','member_type','tag_state'] | ||
|
||
validate do |value| | ||
value = [ value ] unless value.is_a?(Array) | ||
|
||
value.each do |hash| | ||
unless required_keys.any? { |k| hash.key?(k) } | ||
raise Puppet::Error, "Puppet::Type::F5_Vlan_Class: members property hash must include keys ${required_keys.join(', ')}." | ||
end | ||
unless hash['member_type'] =~ /^MEMBER_(INTERFACE|TRUNK)$/ | ||
raise Puppet::Error, "Puppet::Type::F5_Vlan_Class: members property hash key 'member_type' must have value 'MEMBER_INTERFACE' or 'MEMBER_TRUNK'." | ||
end | ||
unless hash['tag_state'] =~ /^MEMBER_(TAGGED|UNTAGGED)$/ | ||
raise Puppet::Error, "Puppet::Type::F5_Vlan_Class: members property hash key 'tag_state' must have value 'MEMBER_TAGGED' or 'MEMBER_UNTAGGED'." | ||
end | ||
end | ||
end | ||
|
||
def insync?(is) | ||
is = [ is ] unless is.is_a?(Array) | ||
|
||
is.sort! | ||
should = @should.sort | ||
|
||
# For some reason `is` hash keys are symbols and `@should` hash keys | ||
# are strings. We want strings, so transform them. | ||
is.each do |element| | ||
element.keys.each do |key| | ||
element[key.to_s] = element.delete(key) | ||
end | ||
end | ||
|
||
return true if is == should | ||
false | ||
end | ||
|
||
def should_to_s(newvalue) | ||
newvalue | ||
end | ||
|
||
def is_to_s(currentvalue) | ||
currentvalue | ||
end | ||
end | ||
|
||
newproperty(:failsafe_state) do | ||
desc 'Failsafe state value for the VLAN.' | ||
defaultto 'STATE_DISABLED' | ||
|
||
newvalues(/^STATE_(DISABLED|ENABLED)$/) | ||
end | ||
|
||
newproperty(:timeout) do | ||
desc 'Failsafe timeout' | ||
defaultto '90' | ||
|
||
newvalues(/^\d+$/) | ||
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