cisco_node_utils 1.8.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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