cisco_node_utils 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -1
  3. data/README.md +4 -4
  4. data/docs/README-maintainers.md +1 -0
  5. data/lib/cisco_node_utils/bgp_neighbor.rb +20 -0
  6. data/lib/cisco_node_utils/bgp_neighbor_af.rb +20 -0
  7. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor.yaml +7 -0
  8. data/lib/cisco_node_utils/cmd_ref/bgp_neighbor_af.yaml +7 -0
  9. data/lib/cisco_node_utils/cmd_ref/evpn_multicast.yaml +12 -0
  10. data/lib/cisco_node_utils/cmd_ref/evpn_multisite.yaml +18 -0
  11. data/lib/cisco_node_utils/cmd_ref/evpn_stormcontrol.yaml +18 -0
  12. data/lib/cisco_node_utils/cmd_ref/feature.yaml +7 -0
  13. data/lib/cisco_node_utils/cmd_ref/interface_evpn_multisite.yaml +17 -0
  14. data/lib/cisco_node_utils/cmd_ref/ip_multicast.yaml +18 -0
  15. data/lib/cisco_node_utils/cmd_ref/vrf_af.yaml +21 -0
  16. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep.yaml +6 -0
  17. data/lib/cisco_node_utils/cmd_ref/vxlan_vtep_vni.yaml +7 -0
  18. data/lib/cisco_node_utils/evpn_multicast.rb +66 -0
  19. data/lib/cisco_node_utils/evpn_multisite.rb +96 -0
  20. data/lib/cisco_node_utils/evpn_stormcontrol.rb +84 -0
  21. data/lib/cisco_node_utils/feature.rb +19 -0
  22. data/lib/cisco_node_utils/interface.rb +2 -1
  23. data/lib/cisco_node_utils/interface_evpn_multisite.rb +63 -0
  24. data/lib/cisco_node_utils/ip_multicast.rb +86 -0
  25. data/lib/cisco_node_utils/version.rb +2 -2
  26. data/lib/cisco_node_utils/vrf_af.rb +56 -5
  27. data/lib/cisco_node_utils/vxlan_vtep.rb +24 -0
  28. data/lib/cisco_node_utils/vxlan_vtep_vni.rb +21 -0
  29. data/tests/ciscotest.rb +36 -3
  30. data/tests/tacacs_server.yaml.example +1 -1
  31. data/tests/test_bgp_af.rb +1 -1
  32. data/tests/test_bgp_neighbor.rb +15 -0
  33. data/tests/test_bgp_neighbor_af.rb +27 -0
  34. data/tests/test_evpn_multicast.rb +65 -0
  35. data/tests/test_evpn_multisite.rb +70 -0
  36. data/tests/test_evpn_stormcontrol.rb +56 -0
  37. data/tests/test_feature.rb +6 -1
  38. data/tests/test_interface_evpn_multisite.rb +59 -0
  39. data/tests/test_ip_multicast.rb +69 -0
  40. data/tests/test_node_ext.rb +3 -2
  41. data/tests/test_radius_global.rb +7 -5
  42. data/tests/test_router_ospf_vrf.rb +2 -0
  43. data/tests/test_stp_global.rb +7 -0
  44. data/tests/test_tacacs_global.rb +10 -7
  45. data/tests/test_vrf_af.rb +52 -1
  46. data/tests/test_vxlan_vtep.rb +23 -0
  47. data/tests/test_vxlan_vtep_vni.rb +31 -0
  48. data/tests/yum_package.yaml +10 -0
  49. metadata +18 -3
@@ -0,0 +1,84 @@
1
+ # October 2017, Rahul Shenoy
2
+ #
3
+ # Copyright (c) 2017 Cisco and/or its affiliates.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative 'cisco_cmn_utils'
18
+ require_relative 'node_util'
19
+ require_relative 'feature'
20
+
21
+ module Cisco
22
+ # node_utils class for evpn_stormcontrol
23
+ class EvpnStormcontrol < NodeUtil
24
+ attr_reader :stormcontrol_type, :level
25
+
26
+ def initialize(stormcontrol_type, level, instantiate=true)
27
+ err_msg = 'storm control type must be one of the following:' \
28
+ ' broadcast, multicast or unicast'
29
+ type_list = %w(broadcast multicast unicast)
30
+ fail ArgumentError, err_msg unless type_list.include?(stormcontrol_type)
31
+ @stormcontrol_type = stormcontrol_type
32
+
33
+ err_msg = "level must be either a 'String' or an" \
34
+ " 'Integer' object"
35
+ fail ArgumentError, err_msg unless level.is_a?(Integer) ||
36
+ level.is_a?(String)
37
+ @level = level.to_i
38
+ @get_args = @set_args = { stormcontrol_type: @stormcontrol_type,
39
+ level: @level }
40
+ create if instantiate
41
+ end
42
+
43
+ def config_stormcontrol
44
+ stormcontrol_type = @set_args[:stormcontrol_type]
45
+ config_set('evpn_stormcontrol', stormcontrol_type, @set_args)
46
+ end
47
+
48
+ def create
49
+ @set_args[:state] = ''
50
+ config_stormcontrol
51
+ end
52
+
53
+ def destroy
54
+ @set_args[:state] = 'no'
55
+ config_stormcontrol
56
+ end
57
+
58
+ # Create a hash of all stormcontrol instances
59
+ def self.stormcontrol
60
+ hash = {}
61
+ type_list = %w(broadcast multicast unicast)
62
+ type_list.each do |type|
63
+ level = config_get('evpn_stormcontrol', type)
64
+ hash[type] = EvpnStormcontrol.new(type, level, false) if level
65
+ end
66
+ hash
67
+ end
68
+
69
+ def level
70
+ config_get('evpn_stormcontrol', @get_args[:stormcontrol_type])
71
+ end
72
+
73
+ def level=(level)
74
+ err_msg = "level must be either a 'String' or an" \
75
+ " 'Integer' object"
76
+ fail ArgumentError, err_msg unless level.is_a?(Integer) ||
77
+ level.is_a?(String)
78
+ @level = level.to_i
79
+ @set_args[:level] = @level
80
+ @set_args[:state] = ''
81
+ config_stormcontrol
82
+ end
83
+ end
84
+ end
@@ -160,6 +160,25 @@ module Cisco
160
160
  return false
161
161
  end
162
162
 
163
+ # ---------------------------
164
+ def self.ngmvpn_enable
165
+ return if ngmvpn_enabled?
166
+ config_set('feature', 'ngmvpn', state: '')
167
+ end
168
+
169
+ def self.ngmvpn_enabled?
170
+ config_get('feature', 'ngmvpn')
171
+ rescue Cisco::CliError => e
172
+ # cmd will syntax reject when feature is not enabled.
173
+ raise unless e.clierror =~ /Syntax error/
174
+ return false
175
+ end
176
+
177
+ def self.ngmvpn_disable
178
+ return unless ngmvpn_enabled?
179
+ config_set('feature', 'ngmvpn', state: 'no')
180
+ end
181
+
163
182
  # ---------------------------
164
183
  def self.nv_overlay_enable
165
184
  # Note: vdc platforms restrict this feature to F3 or newer linecards
@@ -1227,8 +1227,9 @@ module Cisco
1227
1227
  if val
1228
1228
  state = ''
1229
1229
  else
1230
+ return unless stp_port_type
1230
1231
  state = 'no'
1231
- val = ''
1232
+ val = stp_port_type
1232
1233
  end
1233
1234
  config_set('interface', 'stp_port_type', name: @name,
1234
1235
  state: state, type: val)
@@ -0,0 +1,63 @@
1
+ # October 2017, Rahul Shenoy
2
+ #
3
+ # Copyright (c) 2017 Cisco and/or its affiliates.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative 'node_util'
18
+
19
+ module Cisco
20
+ # node_utils class for interface_evpn_multisite
21
+ class InterfaceEvpnMultisite < NodeUtil
22
+ attr_reader :interface, :tracking
23
+
24
+ def initialize(interface)
25
+ fail TypeError unless interface.is_a?(String)
26
+ @interface = interface.downcase
27
+ @get_args = @set_args = { interface: @interface }
28
+ end
29
+
30
+ def self.interfaces
31
+ hash = {}
32
+ intf_list = config_get('interface_evpn_multisite', 'all_interfaces')
33
+ return hash if intf_list.nil?
34
+
35
+ intf_list.each do |id|
36
+ id = id.downcase
37
+ intf = InterfaceEvpnMultisite.new(id)
38
+ hash[id] = intf if intf.tracking
39
+ end
40
+ hash
41
+ end
42
+
43
+ def enable(tracking)
44
+ @set_args[:tracking] = tracking
45
+ @set_args[:state] = ''
46
+ config_set('interface_evpn_multisite', 'evpn_multisite', @set_args)
47
+ end
48
+
49
+ def disable(tracking='dci-tracking')
50
+ @set_args[:tracking] = tracking
51
+ @set_args[:state] = 'no'
52
+ config_set('interface_evpn_multisite', 'evpn_multisite', @set_args)
53
+ end
54
+
55
+ def tracking
56
+ config_get('interface_evpn_multisite', 'evpn_multisite', @get_args)
57
+ end
58
+
59
+ def tracking=(tracking)
60
+ enable(tracking)
61
+ end
62
+ end # class
63
+ end # module
@@ -0,0 +1,86 @@
1
+ # January 2018, Rahul Shenoy
2
+ #
3
+ # Copyright (c) 2018 Cisco and/or its affiliates.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require_relative 'cisco_cmn_utils'
18
+ require_relative 'node_util'
19
+ require_relative 'feature'
20
+
21
+ module Cisco
22
+ # node_utils class for evpn_multisite
23
+ class IpMulticast < NodeUtil
24
+ def initialize(instantiate=true)
25
+ @get_args = @set_args = {}
26
+ enable_features if instantiate
27
+ end
28
+
29
+ def destroy
30
+ @set_args[:state] = 'no'
31
+ config_set('ip_multicast', 'overlay_distributed_dr', @set_args)
32
+ config_set('ip_multicast', 'overlay_spt_only', @set_args)
33
+ Feature.ngmvpn_disable
34
+ end
35
+
36
+ def enable_features
37
+ Feature.nv_overlay_enable
38
+ Feature.nv_overlay_evpn_enable
39
+ Feature.ngmvpn_enable
40
+ end
41
+
42
+ def ip_multicast
43
+ Feature.ngmvpn_enabled?
44
+ end
45
+
46
+ def overlay_distributed_dr
47
+ config_get('ip_multicast', 'overlay_distributed_dr')
48
+ end
49
+
50
+ def overlay_distributed_dr=(bool)
51
+ fail TypeError unless [true, false].include?(bool)
52
+ @set_args[:state] = bool ? '' : 'no'
53
+ if @set_args[:state] == 'no'
54
+ unless overlay_distributed_dr == default_overlay_distributed_dr
55
+ config_set('ip_multicast', 'overlay_distributed_dr', @set_args)
56
+ end
57
+ else
58
+ config_set('ip_multicast', 'overlay_distributed_dr', @set_args)
59
+ end
60
+ end
61
+
62
+ def default_overlay_distributed_dr
63
+ config_get_default('ip_multicast', 'overlay_distributed_dr')
64
+ end
65
+
66
+ def overlay_spt_only
67
+ config_get('ip_multicast', 'overlay_spt_only')
68
+ end
69
+
70
+ def overlay_spt_only=(bool)
71
+ fail TypeError unless [true, false].include?(bool)
72
+ @set_args[:state] = bool ? '' : 'no'
73
+ if @set_args[:state] == 'no'
74
+ unless overlay_spt_only == default_overlay_spt_only
75
+ config_set('ip_multicast', 'overlay_spt_only', @set_args)
76
+ end
77
+ else
78
+ config_set('ip_multicast', 'overlay_spt_only', @set_args)
79
+ end
80
+ end
81
+
82
+ def default_overlay_spt_only
83
+ config_get_default('ip_multicast', 'overlay_spt_only')
84
+ end
85
+ end
86
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2015-2017 Cisco and/or its affiliates.
1
+ # Copyright (c) 2015-2018 Cisco and/or its affiliates.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
14
14
 
15
15
  # Container module for version number only.
16
16
  module CiscoNodeUtils
17
- VERSION = '1.8.0'
17
+ VERSION = '1.9.0'
18
18
  gem_version = Gem::Version.new(Gem::VERSION)
19
19
  min_gem_version = Gem::Version.new('2.1.0')
20
20
  fail 'Required rubygems version >= 2.1.0' if gem_version < min_gem_version
@@ -75,16 +75,20 @@ module Cisco
75
75
  @set_args = @get_args.merge!(hash) unless hash.empty?
76
76
  end
77
77
 
78
- def route_target_feature_enable(require_nv_overlay=nil)
78
+ def route_target_feature_enable(require_nv_overlay=nil, require_ngmvpn=nil)
79
79
  return unless platform == :nexus
80
80
 
81
81
  # All NX route-target properties require feature bgp
82
82
  Feature.bgp_enable
83
83
 
84
84
  # Some platforms/versions also require nv overlay for some properties
85
- return unless require_nv_overlay
86
- Feature.nv_overlay_enable if Feature.nv_overlay_supported?
87
- Feature.nv_overlay_evpn_enable if Feature.nv_overlay_evpn_supported?
85
+ if require_nv_overlay
86
+ Feature.nv_overlay_enable if Feature.nv_overlay_supported?
87
+ Feature.nv_overlay_evpn_enable if Feature.nv_overlay_evpn_supported?
88
+ end
89
+
90
+ # ngmvpn feature is required for 'mvpn' enablement
91
+ Feature.ngmvpn_enable if require_ngmvpn
88
92
  end
89
93
 
90
94
  ########################################################
@@ -163,6 +167,21 @@ module Cisco
163
167
  config_get_default('vrf_af', 'route_target_both_auto_evpn')
164
168
  end
165
169
 
170
+ # --------------------------
171
+ def route_target_both_auto_mvpn
172
+ config_get('vrf_af', 'route_target_both_auto_mvpn', @get_args)
173
+ end
174
+
175
+ def route_target_both_auto_mvpn=(state)
176
+ route_target_feature_enable(nil, :require_ngmvpn)
177
+ set_args_keys(state: (state ? '' : 'no'))
178
+ config_set('vrf_af', 'route_target_both_auto_mvpn', @set_args)
179
+ end
180
+
181
+ def default_route_target_both_auto_mvpn
182
+ config_get_default('vrf_af', 'route_target_both_auto_mvpn')
183
+ end
184
+
166
185
  # --------------------------
167
186
  def route_target_export
168
187
  cmds = config_get('vrf_af', 'route_target_export', @get_args)
@@ -194,6 +213,22 @@ module Cisco
194
213
  config_get_default('vrf_af', 'route_target_export_evpn')
195
214
  end
196
215
 
216
+ # --------------------------
217
+ def route_target_export_mvpn
218
+ cmds = config_get('vrf_af', 'route_target_export_mvpn', @get_args)
219
+ cmds.nil? ? nil : cmds.sort
220
+ end
221
+
222
+ def route_target_export_mvpn=(should)
223
+ route_target_feature_enable(nil, :require_ngmvpn)
224
+ route_target_delta(should, route_target_export_mvpn,
225
+ 'route_target_export_mvpn')
226
+ end
227
+
228
+ def default_route_target_export_mvpn
229
+ config_get_default('vrf_af', 'route_target_export_mvpn')
230
+ end
231
+
197
232
  # --------------------------
198
233
  def route_target_export_stitching
199
234
  cmds = config_get('vrf_af', 'route_target_export_stitching', @get_args)
@@ -226,12 +261,12 @@ module Cisco
226
261
 
227
262
  # --------------------------
228
263
  def route_target_import_evpn
229
- route_target_feature_enable(:require_nv_overlay)
230
264
  cmds = config_get('vrf_af', 'route_target_import_evpn', @get_args)
231
265
  cmds.nil? ? nil : cmds.sort
232
266
  end
233
267
 
234
268
  def route_target_import_evpn=(should)
269
+ route_target_feature_enable(:require_nv_overlay)
235
270
  route_target_delta(should, route_target_import_evpn,
236
271
  'route_target_import_evpn')
237
272
  end
@@ -240,6 +275,22 @@ module Cisco
240
275
  config_get_default('vrf_af', 'route_target_import_evpn')
241
276
  end
242
277
 
278
+ # --------------------------
279
+ def route_target_import_mvpn
280
+ cmds = config_get('vrf_af', 'route_target_import_mvpn', @get_args)
281
+ cmds.nil? ? nil : cmds.sort
282
+ end
283
+
284
+ def route_target_import_mvpn=(should)
285
+ route_target_feature_enable(nil, :require_ngmvpn)
286
+ route_target_delta(should, route_target_import_mvpn,
287
+ 'route_target_import_mvpn')
288
+ end
289
+
290
+ def default_route_target_import_mvpn
291
+ config_get_default('vrf_af', 'route_target_import_mvpn')
292
+ end
293
+
243
294
  # --------------------------
244
295
  def route_target_import_stitching
245
296
  cmds = config_get('vrf_af', 'route_target_import_stitching', @get_args)
@@ -173,5 +173,29 @@ module Cisco
173
173
  def default_shutdown
174
174
  config_get_default('vxlan_vtep', 'shutdown')
175
175
  end
176
+
177
+ def multisite_border_gateway_interface
178
+ config_get('vxlan_vtep', 'multisite_bg_intf', name: @name)
179
+ end
180
+
181
+ def multisite_border_gateway_interface=(val)
182
+ set_args = { name: @name }
183
+ set_args[:state] = val.empty? ? 'no' : ''
184
+ set_args[:lpbk_intf] = val.empty? ? 'loopback0' : val
185
+ if set_args[:state] == 'no'
186
+ # 'no multisite border-gateway' doesn't work without interface
187
+ # defaulting to 'loopback0' still clears any configuration
188
+ intf = multisite_border_gateway_interface
189
+ unless intf == default_multisite_border_gateway_interface
190
+ config_set('vxlan_vtep', 'multisite_bg_intf', set_args)
191
+ end
192
+ else
193
+ config_set('vxlan_vtep', 'multisite_bg_intf', set_args)
194
+ end
195
+ end
196
+
197
+ def default_multisite_border_gateway_interface
198
+ config_get_default('vxlan_vtep', 'multisite_bg_intf')
199
+ end
176
200
  end # Class
177
201
  end # Module
@@ -262,5 +262,26 @@ module Cisco
262
262
  def default_suppress_uuc
263
263
  config_get_default('vxlan_vtep_vni', 'suppress_uuc')
264
264
  end
265
+
266
+ def multisite_ingress_replication
267
+ config_get('vxlan_vtep_vni', 'multisite_ingress_replication', @get_args)
268
+ end
269
+
270
+ def multisite_ingress_replication=(state)
271
+ @set_args[:state] = state ? '' : 'no'
272
+ if @set_args[:state] == 'no'
273
+ unless multisite_ingress_replication ==
274
+ default_multisite_ingress_replication
275
+ config_set('vxlan_vtep_vni', 'multisite_ingress_replication',
276
+ @set_args)
277
+ end
278
+ else
279
+ config_set('vxlan_vtep_vni', 'multisite_ingress_replication', @set_args)
280
+ end
281
+ end
282
+
283
+ def default_multisite_ingress_replication
284
+ config_get_default('vxlan_vtep_vni', 'multisite_ingress_replication')
285
+ end
265
286
  end
266
287
  end