cisco_node_utils 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +3 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +5 -0
  6. data/CONTRIBUTING.md +31 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +201 -0
  9. data/README.md +113 -0
  10. data/Rakefile +4 -0
  11. data/cisco_node_utils.gemspec +30 -0
  12. data/lib/cisco_node_utils.rb +33 -0
  13. data/lib/cisco_node_utils/README_YAML.md +333 -0
  14. data/lib/cisco_node_utils/cisco_cmn_utils.rb +92 -0
  15. data/lib/cisco_node_utils/command_reference.rb +415 -0
  16. data/lib/cisco_node_utils/command_reference_common.yaml +845 -0
  17. data/lib/cisco_node_utils/command_reference_n3064.yaml +13 -0
  18. data/lib/cisco_node_utils/command_reference_n7k.yaml +48 -0
  19. data/lib/cisco_node_utils/command_reference_n9k.yaml +35 -0
  20. data/lib/cisco_node_utils/configparser_lib.rb +196 -0
  21. data/lib/cisco_node_utils/interface.rb +501 -0
  22. data/lib/cisco_node_utils/interface_ospf.rb +241 -0
  23. data/lib/cisco_node_utils/node.rb +673 -0
  24. data/lib/cisco_node_utils/platform.rb +184 -0
  25. data/lib/cisco_node_utils/platform_info.rb +58 -0
  26. data/lib/cisco_node_utils/platform_info.yaml +10 -0
  27. data/lib/cisco_node_utils/router_ospf.rb +96 -0
  28. data/lib/cisco_node_utils/router_ospf_vrf.rb +258 -0
  29. data/lib/cisco_node_utils/snmpcommunity.rb +91 -0
  30. data/lib/cisco_node_utils/snmpgroup.rb +55 -0
  31. data/lib/cisco_node_utils/snmpserver.rb +150 -0
  32. data/lib/cisco_node_utils/snmpuser.rb +342 -0
  33. data/lib/cisco_node_utils/tacacs_server.rb +175 -0
  34. data/lib/cisco_node_utils/tacacs_server_host.rb +128 -0
  35. data/lib/cisco_node_utils/version.rb +17 -0
  36. data/lib/cisco_node_utils/vlan.rb +153 -0
  37. data/lib/cisco_node_utils/vtp.rb +127 -0
  38. data/lib/cisco_node_utils/yum.rb +84 -0
  39. data/tests/basetest.rb +93 -0
  40. data/tests/ciscotest.rb +136 -0
  41. data/tests/cmd_config.yaml +51 -0
  42. data/tests/cmd_config_invalid.yaml +16 -0
  43. data/tests/test_all_cisco.rb +46 -0
  44. data/tests/test_command_config.rb +192 -0
  45. data/tests/test_command_reference.rb +222 -0
  46. data/tests/test_interface.rb +1017 -0
  47. data/tests/test_interface_ospf.rb +763 -0
  48. data/tests/test_interface_svi.rb +267 -0
  49. data/tests/test_interface_switchport.rb +722 -0
  50. data/tests/test_node.rb +108 -0
  51. data/tests/test_node_ext.rb +450 -0
  52. data/tests/test_platform.rb +188 -0
  53. data/tests/test_router_ospf.rb +164 -0
  54. data/tests/test_router_ospf_vrf.rb +753 -0
  55. data/tests/test_snmpcommunity.rb +344 -0
  56. data/tests/test_snmpgroup.rb +71 -0
  57. data/tests/test_snmpserver.rb +443 -0
  58. data/tests/test_snmpuser.rb +803 -0
  59. data/tests/test_tacacs_server.rb +388 -0
  60. data/tests/test_tacacs_server_host.rb +391 -0
  61. data/tests/test_vlan.rb +264 -0
  62. data/tests/test_vtp.rb +319 -0
  63. data/tests/test_yum.rb +106 -0
  64. metadata +188 -0
@@ -0,0 +1,127 @@
1
+ # VTP provider class
2
+ #
3
+ # Mike Wiebe, November 2014
4
+ #
5
+ # Copyright (c) 2014-2015 Cisco and/or its affiliates.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require File.join(File.dirname(__FILE__), 'node')
20
+
21
+ module Cisco
22
+ class Vtp
23
+ attr_reader :name
24
+
25
+ MAX_VTP_DOMAIN_NAME_SIZE = 32
26
+ MAX_VTP_PASSWORD_SIZE = 64
27
+
28
+ @@node = Node.instance
29
+
30
+ # Constructor for Vtp
31
+ def initialize(instantiate=true)
32
+ enable if instantiate and not Vtp.enabled
33
+ end
34
+
35
+ def Vtp.enabled
36
+ not @@node.config_get("vtp", "feature").nil?
37
+ end
38
+
39
+ def enable
40
+ @@node.config_set("vtp", "feature", "")
41
+ end
42
+
43
+ # Disable vtp feature
44
+ def destroy
45
+ @@node.config_set("vtp", "feature", "no")
46
+ end
47
+
48
+ # Get vtp domain name
49
+ def Vtp.domain
50
+ @@node.config_get("vtp", "domain")
51
+ end
52
+
53
+ def domain
54
+ Vtp.domain
55
+ end
56
+
57
+ # Set vtp domain name
58
+ def domain=(domain)
59
+ raise ArgumentError unless domain and domain.is_a? String and
60
+ domain.length.between?(1, MAX_VTP_DOMAIN_NAME_SIZE)
61
+ begin
62
+ @@node.config_set("vtp", "domain", domain)
63
+ rescue Cisco::CliError => e
64
+ # cmd will syntax reject when setting name to same name
65
+ raise unless e.clierror =~ /ERROR: Domain name already set to /
66
+ end
67
+ end
68
+
69
+ # Get vtp password
70
+ def password
71
+ # Unfortunately nxapi returns "\\" when the password is not set
72
+ password = @@node.config_get("vtp", "password")
73
+ return '' if password.nil?
74
+ password.gsub(/\\/, '')
75
+ end
76
+
77
+ # Set vtp password
78
+ def password=(password)
79
+ raise TypeError if password.nil?
80
+ raise TypeError unless password.is_a? String
81
+ raise ArgumentError if password.length > MAX_VTP_PASSWORD_SIZE
82
+ password == default_password ?
83
+ @@node.config_set("vtp", "password", "no", "") :
84
+ @@node.config_set("vtp", "password", "", password)
85
+ end
86
+
87
+ # Get default vtp password
88
+ def default_password
89
+ @@node.config_get_default("vtp", "password")
90
+ end
91
+
92
+ # Get vtp filename
93
+ def filename
94
+ match = @@node.config_get("vtp", "filename")
95
+ match.nil? ? default_filename : match.first
96
+ end
97
+
98
+ # Set vtp filename
99
+ def filename=(uri)
100
+ raise TypeError if uri.nil?
101
+ uri.empty? ?
102
+ @@node.config_set("vtp", "filename", "no", "") :
103
+ @@node.config_set("vtp", "filename", "", uri)
104
+ end
105
+
106
+ # Get default vtp filename
107
+ def default_filename
108
+ @@node.config_get_default("vtp", "filename")
109
+ end
110
+
111
+ # Get vtp version
112
+ def version
113
+ match = @@node.config_get("vtp", "version")
114
+ match.nil? ? default_version : match.first.to_i
115
+ end
116
+
117
+ # Set vtp version
118
+ def version=(version)
119
+ @@node.config_set("vtp", "version", "#{version}")
120
+ end
121
+
122
+ # Get default vtp version
123
+ def default_version
124
+ @@node.config_get_default("vtp", "version")
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,84 @@
1
+ #
2
+ # NXAPI implementation of Yum class
3
+ #
4
+ # April 2015, Alex Hunsberger
5
+ #
6
+ # Copyright (c) 2015 Cisco and/or its affiliates.
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+
20
+ require File.join(File.dirname(__FILE__), 'node')
21
+
22
+ module Cisco
23
+ # This Yum class provides cisco package management functions through nxapi.
24
+ class Yum
25
+ @@node = Cisco::Node.instance
26
+
27
+ def self.decompose_name(file_name)
28
+ # ex: chef-12.0.0alpha.2+20150319.git.1.b6f-1.el5.x86_64.rpm
29
+ name_ver_arch_regex = /^([\w\-\+]+)-(\d+\..*)\.(\w{4,})(?:\.rpm)?$/
30
+
31
+ # ex n9000_sample-1.0.0-7.0.3.x86_64.rpm
32
+ name_ver_arch_regex_nx = /^(.*)-([\d\.]+-[\d\.]+)\.(\w{4,})\.rpm$/
33
+
34
+ # ex: b+z-ip2.x64_64
35
+ name_arch_regex = /^([\w\-\+]+)\.(\w+)$/
36
+
37
+ file_name.match(name_ver_arch_regex) ||
38
+ file_name.match(name_ver_arch_regex_nx) ||
39
+ file_name.match(name_arch_regex)
40
+ end
41
+
42
+ def self.validate(pkg)
43
+ file_name = pkg.strip.gsub(':', '/').split('/').last
44
+ pkg_info = Yum.decompose_name(file_name)
45
+ if pkg_info.nil?
46
+ query_name = file_name
47
+ else
48
+ if pkg_info[3].nil?
49
+ query_name = pkg_info[1]
50
+ else
51
+ query_name = "#{pkg_info[1]}.#{pkg_info[3]}"
52
+ end
53
+ end
54
+ should_ver = pkg_info[2] if pkg_info && pkg_info[3]
55
+ ver = self.query(query_name)
56
+ if ver.nil? || (!should_ver.nil? && should_ver != ver)
57
+ raise RuntimeError, "Failed to install the requested rpm"
58
+ end
59
+ end
60
+
61
+ def self.install(pkg)
62
+ @@node.config_set("yum", "install", pkg)
63
+
64
+ # HACK: The current nxos host installer is a multi-part command
65
+ # which may fail at a later stage yet return a false positive;
66
+ # therefore a post-validation check is needed here to verify the
67
+ # actual outcome.
68
+ self.validate(pkg)
69
+ end
70
+
71
+ # returns version of package, or false if package doesn't exist
72
+ def self.query(pkg)
73
+ raise TypeError unless pkg.is_a? String
74
+ raise ArgumentError if pkg.empty?
75
+ b = @@node.config_get("yum", "query", pkg)
76
+ raise "Multiple matching packages found for #{pkg}" if b and b.size > 1
77
+ b.nil? ? nil : b.first
78
+ end
79
+
80
+ def self.remove(pkg)
81
+ @@node.config_set("yum", "remove", pkg)
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Basic unit test case class.
4
+ # December 2014, Glenn F. Matthews
5
+ #
6
+ # Copyright (c) 2014-2015 Cisco and/or its affiliates.
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+
20
+ require 'rubygems'
21
+ gem 'minitest', '>= 2.5.1', '< 5.0.0'
22
+ require 'minitest/autorun'
23
+ require 'net/telnet'
24
+ require 'test/unit'
25
+ begin
26
+ require 'cisco_nxapi'
27
+ rescue LoadError
28
+ require File.expand_path("../../../cisco_nxapi/lib/cisco_nxapi")
29
+ end
30
+
31
+ class TestCase < Test::Unit::TestCase
32
+ @@address = nil
33
+ @@username = nil
34
+ @@password = nil
35
+
36
+ def process_arguments
37
+ if ARGV.length != 3 and ARGV.length != 4
38
+ puts "Usage:"
39
+ puts " ruby test_nxapi.rb [options] -- <address> <username> <password> [debug]"
40
+ exit
41
+ end
42
+
43
+ # Record the version of Ruby we got invoked with.
44
+ puts "\nRuby Version - #{RUBY_VERSION}"
45
+
46
+ @@address = ARGV[0]
47
+ @@username = ARGV[1]
48
+ @@password = ARGV[2]
49
+
50
+ if ARGV.length == 4
51
+ if ARGV[3] == "debug"
52
+ CiscoLogger.debug_enable
53
+ else
54
+ puts "Only 'debug' is allowed"
55
+ exit
56
+ end
57
+ end
58
+ end
59
+
60
+ # setup-once params
61
+ def address
62
+ process_arguments unless @@address
63
+ @@address
64
+ end
65
+
66
+ def username
67
+ process_arguments unless @@username
68
+ @@username
69
+ end
70
+
71
+ def password
72
+ process_arguments unless @@password
73
+ @@password
74
+ end
75
+
76
+ def setup
77
+ @device = Net::Telnet.new("Host" => address, "Timeout" => 240)
78
+ @device.login(username, password)
79
+ rescue Errno::ECONNREFUSED
80
+ puts "Connection refused - please check that the IP address is correct"
81
+ puts " and that you have enabled 'feature telnet' on the UUT"
82
+ exit
83
+ end
84
+
85
+ def teardown
86
+ @device.close unless @device.nil?
87
+ GC.start
88
+ end
89
+
90
+ def test_placeholder
91
+ # needed so that we don't get a "no tests were specified" error
92
+ end
93
+ end
@@ -0,0 +1,136 @@
1
+ # Copyright (c) 2013-2015 Cisco and/or its affiliates.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require File.join(File.dirname(__FILE__), 'basetest')
16
+ require File.expand_path("../../lib/cisco_node_utils/platform_info", __FILE__)
17
+ require File.expand_path("../../lib/cisco_node_utils/node", __FILE__)
18
+
19
+ include Cisco
20
+
21
+ Node.lazy_connect = true # we'll specify the connection info later
22
+
23
+ class CiscoTestCase < TestCase
24
+ @@node = nil
25
+ @@interfaces = nil
26
+ @@interfaces_id = nil
27
+
28
+ def node
29
+ unless @@node
30
+ @@node = Node.instance
31
+ @@node.connect(@@address, @@username, @@password)
32
+ @@node.cache_enable = true
33
+ @@node.cache_auto = true
34
+ puts "Node in CiscoTestCase Class: #{@@node}"
35
+ end
36
+ @@node
37
+ end
38
+
39
+ def process_arguments
40
+ super
41
+ node # Connect to device
42
+ # Record the platform we're running on
43
+ puts "Platform:"
44
+ puts " - name - #{@@node.host_name}"
45
+ puts " - type - #{@@node.product_id}"
46
+ puts " - image - #{@@node.system}\n\n"
47
+ end
48
+
49
+ def cmd_ref
50
+ node.cmd_ref
51
+ end
52
+
53
+ def interfaces
54
+ unless @@interfaces
55
+ # Build the platform_info, used for interface lookup
56
+ begin
57
+ platform_info = PlatformInfo.new(node.host_name)
58
+ @@interfaces = platform_info.get_value_from_key("interfaces")
59
+ rescue Exception => e
60
+ # If there is a problem reading platform_info.yaml, assign default values
61
+ default_interfaces = ["Ethernet1/1", "Ethernet1/2", "Ethernet1/10"]
62
+ puts "Caught exception: #{e}, assigning interfaces to default - #{default_interfaces}"
63
+ @@interfaces = default_interfaces
64
+ end
65
+ end
66
+ @@interfaces
67
+ end
68
+
69
+ def interfaces_id
70
+ unless @@interfaces_id
71
+ @@interfaces_id = []
72
+ interfaces.each { |interface|
73
+ id = interface.split("Ethernet")[1]
74
+ @@interfaces_id << id
75
+ }
76
+ end
77
+ @@interfaces_id
78
+ end
79
+
80
+ # Class method method to set the class variable 'debug_flag'
81
+ # Can be true or false.
82
+ def self.debug_flag=(flag)
83
+ @@debug_flag = flag
84
+ end
85
+
86
+ # Class method to set the class variable 'debug_method'
87
+ # Can be name of the method or "all"
88
+ def self.debug_method=(name)
89
+ @@debug_method = name
90
+ end
91
+
92
+ # Class method to set the class variable 'debug_group'
93
+ # Can be the name of the method or "all"
94
+ def self.debug_group=(group)
95
+ @@debug_group = group
96
+ end
97
+
98
+ # Class method to set the class variable 'debug_detail'
99
+ # Can be true or false
100
+ def self.debug_detail=(detail)
101
+ @@debug_detail = detail
102
+ end
103
+
104
+ # Class method to dump debug data.
105
+ # The passed in parameters will control what is printed and how.
106
+ # Parameters:
107
+ # method - Name of the method the debug belongs to.
108
+ # group - Name of the group the debug belongs to.
109
+ # indent - Indent controls the display of the data.
110
+ # detail - Detail controls if detail debugs should be displayed.
111
+ # data - Data to be displayed. Must be a fully formatted string.
112
+ def self.debug(method, group, indent, data)
113
+ if (@@debug_flag) &&
114
+ (((@@debug_method == method) || (@@debug_method == "all")) ||
115
+ ((@@debug_group == group) || (@@debug_group == "all")))
116
+ indent_spaces = " " * indent
117
+ puts "#{indent_spaces}#{method} - #{data}"
118
+ end
119
+ end
120
+
121
+ # Class method to dump detailed debug data.
122
+ # The passed in parameters will control what is printed and how.
123
+ # Parameters:
124
+ # method - Name of the method the debug belongs to.
125
+ # group - Name of the group the debug belongs to.
126
+ # indent - Indent controls the display of the data.
127
+ # data - Data to be displayed. Must be a fully formatted string.
128
+ def self.debug_detail(method, group, indent, data)
129
+ if (@@debug_detail) &&
130
+ (((@@debug_method == method) || (@@debug_method == "all")) ||
131
+ ((@@debug_group == group) || (@@debug_group == "all")))
132
+ indent_spaces = " " * indent
133
+ puts "#{indent_spaces}#{method} - #{data}"
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,51 @@
1
+ # test command config yaml file
2
+ ---
3
+ feature-enable:
4
+ command: |
5
+ feature tacacs+
6
+ feature ospf
7
+ feature bgp
8
+ feature pim
9
+ feature msdp
10
+ feature private-vlan
11
+ feature udld
12
+ feature interface-vlan
13
+ feature hsrp
14
+ feature lacp
15
+ feature dhcp
16
+ feature vtp
17
+
18
+ feature-disable:
19
+ command: |
20
+ no feature tacacs+
21
+ no feature ospf
22
+ no feature bgp
23
+ no feature pim
24
+ no feature msdp
25
+ no feature private-vlan
26
+ no feature udld
27
+ no feature interface-vlan
28
+ no feature hsrp
29
+ no feature lacp
30
+ no feature dhcp
31
+ no feature vtp
32
+
33
+ feature-snmp-comm-acl-ro:
34
+ command: |
35
+ snmp-server community networkopercom group network-operator
36
+ snmp-server community networkopercom use-acl SNMP_RO
37
+
38
+ feature-snmp-comm-acl-rw:
39
+ command: |
40
+ snmp-server community admincom group network-admin
41
+ snmp-server community admincom use-acl SNMP_RW
42
+
43
+ feature-int-loopback:
44
+ command: >
45
+ interface loopback0
46
+ description testloopback
47
+
48
+ feature-int-portchannel:
49
+ command: >
50
+ interface port-channel100
51
+ description test-portchannel