Class: Puppet::Provider::Netscaler

Inherits:
Puppet::Provider
  • Object
show all
Defined in:
lib/puppet/provider/netscaler.rb

Direct Known Subclasses

NetscalerBinding

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value = {}) ⇒ Netscaler

Returns a new instance of Netscaler.



6
7
8
9
10
11
12
13
14
# File 'lib/puppet/provider/netscaler.rb', line 6

def initialize(value={})
  super(value)
  if value.is_a? Hash
    @original_values = value.clone
  else
    @original_values = Hash.new
  end
  @create_elements = false
end

Class Method Details

.call(url, args = nil) ⇒ Object



77
78
79
# File 'lib/puppet/provider/netscaler.rb', line 77

def self.call(url, args=nil)
  transport.call(url, args)
end

.connectionObject



73
74
75
# File 'lib/puppet/provider/netscaler.rb', line 73

def self.connection
  transport.connection
end

.delete(url, args = nil) ⇒ Object



89
90
91
# File 'lib/puppet/provider/netscaler.rb', line 89

def self.delete(url,args=nil)
  transport.delete(url,args)
end

.device(url) ⇒ Object



59
60
61
# File 'lib/puppet/provider/netscaler.rb', line 59

def self.device(url)
  Puppet::Util::NetworkDevice::Netscaler::Device.new(url)
end

.is_ip_address(value) ⇒ Object



307
308
309
# File 'lib/puppet/provider/netscaler.rb', line 307

def self.is_ip_address(value)
  !! (value and (value.match(Resolv::IPv6::Regex) or value.match(Resolv::IPv4::Regex)))
end

.post(url, message, args = nil) ⇒ Object



81
82
83
# File 'lib/puppet/provider/netscaler.rb', line 81

def self.post(url, message, args=nil)
  transport.post(url, message, args)
end

.prefetch(resources) ⇒ Object



16
17
18
19
20
21
22
23
# File 'lib/puppet/provider/netscaler.rb', line 16

def self.prefetch(resources)
  nodes = instances
  resources.keys.each do |name|
    if provider = nodes.find { |node| node.name == name }
      resources[name].provider = provider
    end
  end
end

.put(url, message) ⇒ Object



85
86
87
# File 'lib/puppet/provider/netscaler.rb', line 85

def self.put(url, message)
  transport.put(url, message)
end

.transportObject



63
64
65
66
67
68
69
70
71
# File 'lib/puppet/provider/netscaler.rb', line 63

def self.transport
  if Puppet::Util::NetworkDevice.current
    #we are in `puppet device`
    Puppet::Util::NetworkDevice.current.transport
  else
    #we are in `puppet resource`
    Puppet::Util::NetworkDevice::Transport::Netscaler.new(Facter.value(:url))
  end
end

Instance Method Details

#basenameObject



93
94
95
# File 'lib/puppet/provider/netscaler.rb', line 93

def basename
  File.basename(resource[:name])
end

#createObject



29
30
31
32
33
34
35
# File 'lib/puppet/provider/netscaler.rb', line 29

def create
  @create_elements = true
  result = Puppet::Provider::Netscaler.post("/config/#{netscaler_api_type}", message(resource))
  @property_hash.clear

  return result
end

#create_message(hash) ⇒ Object



222
223
224
225
226
227
# File 'lib/puppet/provider/netscaler.rb', line 222

def create_message(hash)
  # Create the message by stripping :present.
  new_hash            = hash.reject { |k, _| [:ensure, :provider, Puppet::Type.metaparams].flatten.include?(k) }

  return new_hash
end

#destroyObject



37
38
39
40
# File 'lib/puppet/provider/netscaler.rb', line 37

def destroy
  Puppet::Provider::Netscaler.delete("/config/#{netscaler_api_type}/#{resource[:name]}")
  @property_hash.clear
end

#exists?Boolean

Returns:

  • (Boolean)


25
26
27
# File 'lib/puppet/provider/netscaler.rb', line 25

def exists?
  @property_hash[:ensure] == :present
end

#flushObject



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/puppet/provider/netscaler.rb', line 42

def flush
  if @property_hash and ! @property_hash.empty?
    #handle_unbinds('service', @original_values['binds'] - message['binds']) if ! @create_elements

    # We need to remove values from property hash that aren't specified in the Puppet resource
    @property_hash = @property_hash.reject { |k, v| !(resource[k]) }

    result = Puppet::Provider::Netscaler.put("/config/#{netscaler_api_type}/#{resource[:name]}", message(@property_hash))
    #handle_binds('service', message['binds'] - @original_values['binds']) if ! @create_elements
    # We have to update the state in a separate call.
    if @property_hash[:state] and ((@property_hash[:state] != @original_values[:state]) and (result.status == 200 or result.status == 201))
      set_state(@property_hash[:state], flush_state_args[:name_key], flush_state_args[:name_val])
    end
  end
  return result
end

#flush_state_argsObject



149
150
151
152
153
154
# File 'lib/puppet/provider/netscaler.rb', line 149

def flush_state_args
  {
    :name_key => 'name',
    :name_val => resource[:name],
  }
end

#global_provider_munge(message) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/puppet/provider/netscaler.rb', line 161

def global_provider_munge(message)
  if ! @create_elements
    immutable_properties.each do |property|
      if message[property] and message[property] != @original_values[property]
        err "Cannot update #{property} after creation"
      end
    end
    # Delete some properties if the resource already exists, since we can only
    # pass them on create. Otherwise we have to call #<property>=
    message = message.reject do |key, value|
      immutable_properties.include? key and ! required_properties.include? key
    end
    # And also...
    message.delete(:state)
  end

  message = strip_nil_values(message)
  message = rename_keys(property_to_rest_mapping, message)
  message = remove_underscores(message)
  message = create_message(message)
  message = { netscaler_api_type => message }

  message
end

#immutable_propertiesObject

Raises:

  • (RuntimeError)


137
138
139
140
# File 'lib/puppet/provider/netscaler.rb', line 137

def immutable_properties
  # Each provider must implement this
  raise RuntimeError, "Unimplemented method #immutable_properties"
end

#message(object) ⇒ Object



186
187
188
189
190
191
192
193
194
# File 'lib/puppet/provider/netscaler.rb', line 186

def message(object)
  message = object.clone.to_hash

  message = per_provider_munge(message)
  message = global_provider_munge(message)

  message = message.to_json
  message
end

#netscaler_api_typeObject

A helper to get the kind of netscaler thing we’re managing; ie service, lbvserver, lbmonitor, etc.

Raises:

  • (RuntimeError)


99
100
101
102
# File 'lib/puppet/provider/netscaler.rb', line 99

def netscaler_api_type
  # Each provider must implement this
  raise RuntimeError, "Unimplemented method #netscaler_api_type"
end

#per_provider_munge(message) ⇒ Object

Raises:

  • (RuntimeError)


156
157
158
159
# File 'lib/puppet/provider/netscaler.rb', line 156

def per_provider_munge(message)
  # Each provider must implement this
  raise RuntimeError, "Unimplemented method #per_provider_munge"
end

#property_to_rest_mappingObject

Raises:

  • (RuntimeError)


132
133
134
135
# File 'lib/puppet/provider/netscaler.rb', line 132

def property_to_rest_mapping
  # Each provider must implement this
  raise RuntimeError, "Unimplemented method #property_to_rest_mapping"
end

#remove_underscores(hash) ⇒ Object

return message end



285
286
287
288
289
290
291
292
293
# File 'lib/puppet/provider/netscaler.rb', line 285

def remove_underscores(hash)
  # We want to remove all _'s in the key names of the hash we create
  # from the object we've passed into message.
  hash.inject({}) do |memo, (k,v)|
    key = k.to_s.gsub(/_/, '').to_sym
    memo[key] = v
    memo
  end
end

#rename_keys(keys_to_rename, rename_hash) ⇒ Object

This allows us to simply rename keys from the puppet representation to the Netscaler representation.



212
213
214
215
216
217
218
219
220
# File 'lib/puppet/provider/netscaler.rb', line 212

def rename_keys(keys_to_rename, rename_hash)
  keys_to_rename.each do |k, v|
    next unless rename_hash[k]
    value = rename_hash[k]
    rename_hash.delete(k)
    rename_hash[v] = value
  end
  return rename_hash
end

#required_propertiesObject



142
143
144
145
146
147
# File 'lib/puppet/provider/netscaler.rb', line 142

def required_properties
  # Each provider must implement this
  #raise RuntimeError, "Unimplemented method #requried_properties"
  # Actually, I'm just going to assume there are none
  []
end

#set_state(value, name_key = nil, name_val = nil) ⇒ Object

I don’t want to use ‘def state=` because that will be called before flush



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/puppet/provider/netscaler.rb', line 105

def set_state(value, name_key=nil, name_val=nil)
  if name_key
    message_hash = { name_key => name_val }
  else
    message_hash = {}
  end
  message_hash = { netscaler_api_type => message_hash }
  message_hash = message_hash.to_json

  action = nil
  value = value.upcase
  case value
    when 'ENABLED'
      action = "enable"
    when 'DISABLED'
      action = "disable"
    when nil
      # Do nothing
    else
      err "Incorrect state: #{value}"
  end

  if action
    Puppet::Provider::Netscaler.post("/config/#{netscaler_api_type}", message_hash, {"action" => action})
  end
end

#string_to_integer(hash) ⇒ Object



229
230
231
232
233
234
# File 'lib/puppet/provider/netscaler.rb', line 229

def string_to_integer(hash)
  # Apply transformations
  hash.each do |k, v|
    hash[k] = Integer(v) if self.class.integer?(v)
  end
end

#strip_nil_values(hash) ⇒ Object

For some reason the object we pass in has undefined parameters in the object with nil values. Not at all helpful for us.



303
304
305
# File 'lib/puppet/provider/netscaler.rb', line 303

def strip_nil_values(hash)
  hash.reject { |k, v| v.nil? }
end