Class: PuppetX::Cisco::Utils

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet_x/cisco/cmnutils.rb

Overview

PuppetX::Cisco::Utils: - Common helper methods shared by any Type/Provider rubocop:disable Metrics/ClassLength

Constant Summary collapse

TACACS_SERVER_ENC_NONE =
0
TACACS_SERVER_ENC_CISCO_TYPE_7 =
7
TACACS_SERVER_ENC_UNKNOWN =
8

Class Method Summary collapse

Class Method Details

.bool_sym_to_s(val) ⇒ Object

Convert boolean symbols to strings



42
43
44
45
# File 'lib/puppet_x/cisco/cmnutils.rb', line 42

def self.bool_sym_to_s(val)
  return val unless val == :true || val == :false
  (val == :true)
end

.check_slot_pid(inv) ⇒ Object

fretta check



247
248
249
250
251
252
# File 'lib/puppet_x/cisco/cmnutils.rb', line 247

def self.check_slot_pid(inv)
  inv.each do |_x, slot|
    return true if slot['pid'][/-R/]
  end
  false
end

.dash_range_to_ruby_range(range) ⇒ Object

Convert a cli-dash-syntax range to ruby-range. This is useful for preparing inputs to merge_range().

Inputs an array or string of dash-syntax ranges -> returns an array of ruby ranges.

Accepts an array or string: [“2-5”, “9”, “4-6”] or ‘2-5, 9, 4-6’ Returns an array of ranges: [2..5, 9..9, 4..6]



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/puppet_x/cisco/cmnutils.rb', line 104

def self.dash_range_to_ruby_range(range)
  range = range.split(',') if range.is_a?(String)
  # [["45", "7-8"], ["46", "9,10"]]
  range.map! do |rng|
    if rng[/-/]
      # '2-5' -> 2..5
      rng.split('-').inject { |a, e| a.to_i..e.to_i }
    else
      # '9' -> 9..9
      rng.to_i..rng.to_i
    end
  end
  range
end

.enc_sym_to_type(sym) ⇒ Object

Convert encryption symbol to type



286
287
288
289
290
291
292
293
294
295
# File 'lib/puppet_x/cisco/cmnutils.rb', line 286

def self.enc_sym_to_type(sym)
  case sym
  when :none
    TACACS_SERVER_ENC_UNKNOWN
  when :clear, :default
    TACACS_SERVER_ENC_NONE
  when :encrypted
    TACACS_SERVER_ENC_CISCO_TYPE_7
  end
end

.enc_type_to_sym(type) ⇒ Object

Convert encryption type to symbol



274
275
276
277
278
279
280
281
282
283
# File 'lib/puppet_x/cisco/cmnutils.rb', line 274

def self.enc_type_to_sym(type)
  case type
  when TACACS_SERVER_ENC_UNKNOWN
    :none
  when TACACS_SERVER_ENC_NONE
    :clear
  when TACACS_SERVER_ENC_CISCO_TYPE_7
    :encrypted
  end
end

.enforce_simple_types(context, return_value) ⇒ Object

Convert return values to their specified ruby type

Accepts the Resource API context and array of return values

Returns the array of return values with individual values correctly converted to their ruby type eg. Integer



303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/puppet_x/cisco/cmnutils.rb', line 303

def self.enforce_simple_types(context, return_value)
  return_value.each do |individual_value_hash|
    individual_value_hash.each do |k, v|
      type_to_use = context.type.definition[:attributes][k][:type]
      if type_to_use.downcase =~ %r{^integer} || type_to_use.downcase =~ %r{^optional\[integer}
        individual_value_hash[k] = v.to_i
      end
      if type_to_use.downcase =~ %r{^string} || type_to_use.downcase =~ %r{^optional\[string}
        individual_value_hash[k] = v.to_s
      end
      next unless type_to_use.downcase =~ %r{^boolean} || type_to_use.downcase =~ %r{^optional\[boolean}
      individual_value_hash[k] = if v.to_s.casecmp('true').zero?
                                   true
                                 else
                                   false
                                 end
    end
  end
  return_value
end

.fail_array_overlap(list) ⇒ Object

Helper utility for checking if arrays are overlapping in a give list. For ex: if the list has ‘2-10,32,42,44-89’ and ‘11-33’ then this will fail as they overlap



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/puppet_x/cisco/cmnutils.rb', line 171

def self.fail_array_overlap(list)
  array = []
  list.each do |range, _val|
    larray = range.split(',')
    larray.each do |elem|
      if elem.include?('-')
        elema = elem.split('-').map { |d| Integer(d) }
        ele = elema[0]..elema[1]
        if (array & ele.to_a).empty?
          array << ele.to_a
          array = array.flatten
        else
          fail 'overlapping arrays not allowed'
        end
      else
        elema = []
        elema << elem.to_i
        if (array & elema).empty?
          array << elema
          array = array.flatten
        else
          fail 'overlapping arrays not allowed'
        end
      end
    end
  end
end

.flush_boolean?(prop) ⇒ Boolean

Special handling for boolean properties. This helper method returns true if the property flush contains a TrueClass or FalseClass value.

Returns:

  • (Boolean)


50
51
52
# File 'lib/puppet_x/cisco/cmnutils.rb', line 50

def self.flush_boolean?(prop)
  prop.is_a?(TrueClass) || prop.is_a?(FalseClass)
end

.merge_range(range) ⇒ Object

Merge overlapping ranges.

Inputs an array of ruby ranges: [2..5, 9..9, 4..6] Returns an array of merged ruby ranges: [2..6, 9..9]



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/puppet_x/cisco/cmnutils.rb', line 147

def self.merge_range(range)
  # sort to lowest range 'first' values:
  #    [2..5, 9..9, 4..6]  ->  [2..5, 4..6, 9..9]
  range = range.sort_by(&:first)

  *merged = range.shift
  range.each do |r|
    lastr = merged[-1]
    if lastr.last >= r.first - 1
      merged[-1] = lastr.first..[r.last, lastr.last].max
    else
      merged.push(r)
    end
  end
  merged
end

.normalize_range_array(range, type = :array) ⇒ Object

normalize_range_array

Given a list of ranges, merge any overlapping ranges and normalize the them as a string that can be used directly on the switch.

Note: The ranges are converted to ruby ranges for easy merging, then converted back to a cli-syntax ranges.

Accepts an array or string:

["2-5", "9", "4-6"]  -or-  '2-5, 9, 4-6'  -or-  ["2-5, 9, 4-6"]

Returns a merged and ordered range:

["2-6", "9"]


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/puppet_x/cisco/cmnutils.rb', line 67

def self.normalize_range_array(range, type=:array)
  return range if range.nil? || range.empty?

  # This step is puppet only
  return range if range[0] == :default

  # Handle string within an array: ["2-5, 9, 4-6"] to '2-5, 9, 4-6'
  range = range.shift if range.is_a?(Array) && range.length == 1

  # Handle string only: '2-5, 9, 4-6' to ["2-5", "9", "4-6"]
  range = range.split(',') if range.is_a?(String)

  # Convert to ruby-syntax ranges
  range = dash_range_to_ruby_range(range)

  # Sort & Merge
  merged = merge_range(range)

  # Convert back to cli dash-syntax
  ruby_range_to_dash_range(merged, type)
end

.normalize_range_string(range) ⇒ Object



89
90
91
92
93
# File 'lib/puppet_x/cisco/cmnutils.rb', line 89

def self.normalize_range_string(range)
  range = range.to_s
  return normalize_range_array(range, :string) if range[/[-,]/]
  range
end

.process_network_mask(network) ⇒ Object

Helper utility method for ip/prefix format networks. For ip/prefix format ‘1.1.1.1/24’ or ‘2000:123:38::34/64’, we need to mask the address using the prefix length so that they are converted to ‘1.1.1.0/24’ or ‘2000:123:38::/64’



34
35
36
37
38
39
# File 'lib/puppet_x/cisco/cmnutils.rb', line 34

def self.process_network_mask(network)
  mask = network.split('/')[1]
  address = IPAddr.new(network).to_s
  network = address + '/' + mask unless mask.nil?
  network
end

.product_tagObject



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/puppet_x/cisco/cmnutils.rb', line 254

def self.product_tag
  data = Facter.value('cisco')
  case data['inventory']['chassis']['pid']
  when /N3/
    tag = check_slot_pid(data['inventory']) ? 'n3k-f' : 'n3k'
  when /N5/
    tag = 'n5k'
  when /N6/
    tag = 'n6k'
  when /N7/
    tag = 'n7k'
  when /N9/
    tag = check_slot_pid(data['inventory']) ? 'n9k-f' : 'n9k'
  else
    fail "Unrecognized product_id: #{data['inventory']['chassis']['pid']}"
  end
  tag
end

.range_summarize(range_str, sort = true) ⇒ Object

Helper utility method for range summarization of VLAN and BD ranges Input is a range string. For example: ‘10-20, 30, 14, 100-105, 21’ Output should be: ‘10-21,30,100-105’



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/puppet_x/cisco/cmnutils.rb', line 202

def self.range_summarize(range_str, sort=true)
  ranges = []
  range_str.split(/,/).each do |elem|
    if elem =~ /\d+\s*\-\s*\d+/
      range_limits = elem.split(/\-/).map { |d| Integer(d) }
      ranges << (range_limits[0]..range_limits[1])
    else
      ranges << Integer(elem)
    end
  end
  # nrange array below will expand the ranges and get a single list
  nrange = []
  ranges.each do |item|
    # OR operations below will get rid of duplicates
    if item.class == Range
      nrange |= item.to_a
    else
      nrange |= [item]
    end
  end
  nrange.sort! if sort
  ranges = []
  left = nrange.first
  right = nil
  nrange.each do |obj|
    if right && obj != right.succ
      # obj cannot be included in the current range, end this range
      if left != right
        ranges << Range.new(left, right)
      else
        ranges << left
      end
      left = obj # start of new range
    end
    right = obj # move right to point to obj
  end
  if left != right
    ranges << Range.new(left, right)
  else
    ranges << left
  end
  ranges.join(',').gsub('..', '-')
end

.ruby_range_to_dash_range(range, type = :array) ⇒ Object

Convert a ruby-range to cli-dash-syntax.

Inputs an array of ruby ranges -> returns an array or string of dash-syntax ranges.

when (:array) [2..6, 9..9] -> [‘2-6’, ‘9’]

when (:string) [2..6, 9..9] -> ‘2-6, 9’



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/puppet_x/cisco/cmnutils.rb', line 128

def self.ruby_range_to_dash_range(range, type=:array)
  range.map! do |r|
    if r.first == r.last
      # 9..9 -> '9'
      r.first.to_s
    else
      # 2..6 -> '2-6'
      r.first.to_s + '-' + r.last.to_s
    end
  end
  return range.join(',') if type == :string
  range
end