cisco_node_utils 0.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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +293 -0
- data/CHANGELOG.md +5 -0
- data/CONTRIBUTING.md +31 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/README.md +113 -0
- data/Rakefile +4 -0
- data/cisco_node_utils.gemspec +30 -0
- data/lib/cisco_node_utils.rb +33 -0
- data/lib/cisco_node_utils/README_YAML.md +333 -0
- data/lib/cisco_node_utils/cisco_cmn_utils.rb +92 -0
- data/lib/cisco_node_utils/command_reference.rb +415 -0
- data/lib/cisco_node_utils/command_reference_common.yaml +845 -0
- data/lib/cisco_node_utils/command_reference_n3064.yaml +13 -0
- data/lib/cisco_node_utils/command_reference_n7k.yaml +48 -0
- data/lib/cisco_node_utils/command_reference_n9k.yaml +35 -0
- data/lib/cisco_node_utils/configparser_lib.rb +196 -0
- data/lib/cisco_node_utils/interface.rb +501 -0
- data/lib/cisco_node_utils/interface_ospf.rb +241 -0
- data/lib/cisco_node_utils/node.rb +673 -0
- data/lib/cisco_node_utils/platform.rb +184 -0
- data/lib/cisco_node_utils/platform_info.rb +58 -0
- data/lib/cisco_node_utils/platform_info.yaml +10 -0
- data/lib/cisco_node_utils/router_ospf.rb +96 -0
- data/lib/cisco_node_utils/router_ospf_vrf.rb +258 -0
- data/lib/cisco_node_utils/snmpcommunity.rb +91 -0
- data/lib/cisco_node_utils/snmpgroup.rb +55 -0
- data/lib/cisco_node_utils/snmpserver.rb +150 -0
- data/lib/cisco_node_utils/snmpuser.rb +342 -0
- data/lib/cisco_node_utils/tacacs_server.rb +175 -0
- data/lib/cisco_node_utils/tacacs_server_host.rb +128 -0
- data/lib/cisco_node_utils/version.rb +17 -0
- data/lib/cisco_node_utils/vlan.rb +153 -0
- data/lib/cisco_node_utils/vtp.rb +127 -0
- data/lib/cisco_node_utils/yum.rb +84 -0
- data/tests/basetest.rb +93 -0
- data/tests/ciscotest.rb +136 -0
- data/tests/cmd_config.yaml +51 -0
- data/tests/cmd_config_invalid.yaml +16 -0
- data/tests/test_all_cisco.rb +46 -0
- data/tests/test_command_config.rb +192 -0
- data/tests/test_command_reference.rb +222 -0
- data/tests/test_interface.rb +1017 -0
- data/tests/test_interface_ospf.rb +763 -0
- data/tests/test_interface_svi.rb +267 -0
- data/tests/test_interface_switchport.rb +722 -0
- data/tests/test_node.rb +108 -0
- data/tests/test_node_ext.rb +450 -0
- data/tests/test_platform.rb +188 -0
- data/tests/test_router_ospf.rb +164 -0
- data/tests/test_router_ospf_vrf.rb +753 -0
- data/tests/test_snmpcommunity.rb +344 -0
- data/tests/test_snmpgroup.rb +71 -0
- data/tests/test_snmpserver.rb +443 -0
- data/tests/test_snmpuser.rb +803 -0
- data/tests/test_tacacs_server.rb +388 -0
- data/tests/test_tacacs_server_host.rb +391 -0
- data/tests/test_vlan.rb +264 -0
- data/tests/test_vtp.rb +319 -0
- data/tests/test_yum.rb +106 -0
- metadata +188 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
# Command Reference N3K, 3064 specific model
|
2
|
+
#
|
3
|
+
# For documentation please see these files for fields and defaults:
|
4
|
+
# - README_YAML.md
|
5
|
+
# - command_reference_common.yaml
|
6
|
+
#
|
7
|
+
---
|
8
|
+
interface:
|
9
|
+
negotiate_auto_ethernet:
|
10
|
+
config_set: ~
|
11
|
+
config_get: ~
|
12
|
+
config_get_token: ~
|
13
|
+
default_value: false
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Command Reference N7K
|
2
|
+
#
|
3
|
+
# For documentation please see these files for fields and defaults:
|
4
|
+
# - README_YAML.md
|
5
|
+
# - command_reference_common.yaml
|
6
|
+
#
|
7
|
+
---
|
8
|
+
interface:
|
9
|
+
admin_state_ethernet_noswitchport_shutdown:
|
10
|
+
default_value: "shutdown"
|
11
|
+
|
12
|
+
ipv4_redirects_loopback:
|
13
|
+
default_value: false
|
14
|
+
config_set: ~
|
15
|
+
config_get: ~
|
16
|
+
config_get_token: ~
|
17
|
+
test_config_result:
|
18
|
+
false: RuntimeError
|
19
|
+
true: RuntimeError
|
20
|
+
|
21
|
+
negotiate_auto_ethernet:
|
22
|
+
config_set: ~
|
23
|
+
config_get: ~
|
24
|
+
config_get_token: ~
|
25
|
+
default_value: false
|
26
|
+
|
27
|
+
negotiate_auto_portchannel:
|
28
|
+
config_set: ~
|
29
|
+
config_get: ~
|
30
|
+
config_get_token:
|
31
|
+
default_value: false
|
32
|
+
|
33
|
+
|
34
|
+
inventory:
|
35
|
+
inventory:
|
36
|
+
test_config_get_regex: [!ruby/regexp '/.*\nNAME: "(.+)",\s+DESCR: "(.+)"\s+\nPID: (\S+)\s+,\s+VID: (.+) ,\s+SN: (.+)\s+\n/', !ruby/regexp '/.*NAME: "(.+)",\s+DESCR: "(.+)"\s+PID: (\S+)\s+,\s+VID: (.+) ,\s+SN: (.+)\s+\n/']
|
37
|
+
|
38
|
+
|
39
|
+
show_version:
|
40
|
+
description:
|
41
|
+
test_config_get_regex: !ruby/regexp '/.*Hardware\n cisco (\w+ \w+ \(\w+ \w+\) \w+).*/'
|
42
|
+
|
43
|
+
|
44
|
+
vtp:
|
45
|
+
version:
|
46
|
+
test_config_result:
|
47
|
+
3: 3
|
48
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Command Reference N9K
|
2
|
+
#
|
3
|
+
# For documentation please see these files for fields and defaults:
|
4
|
+
# - README_YAML.md
|
5
|
+
# - command_reference_common.yaml
|
6
|
+
#
|
7
|
+
---
|
8
|
+
|
9
|
+
inventory:
|
10
|
+
inventory:
|
11
|
+
test_config_get_regex: [!ruby/regexp '/.*\nNAME: "(.+)",\s+DESCR: "(.+)"\s+\nPID: (\S+)\s+,\s+VID: (.+) ,\s+SN: (.+)\s+\n/', !ruby/regexp '/.*NAME: "(.+)",\s+DESCR: "(.+)"\s+PID: (\S+)\s+,\s+VID: (.+) ,\s+SN: (.+)\s+\n/']
|
12
|
+
|
13
|
+
|
14
|
+
show_version:
|
15
|
+
boot_image:
|
16
|
+
test_config_get_regex: !ruby/regexp '/.*NXOS image file is: (.*)$.*/'
|
17
|
+
|
18
|
+
system_image:
|
19
|
+
config_get_token: "kick_file_name"
|
20
|
+
test_config_get_regex: !ruby/regexp '/.*NXOS image file is: (.*)$.*/'
|
21
|
+
|
22
|
+
snmp_user:
|
23
|
+
auth_protocol:
|
24
|
+
config_get_token: "auth"
|
25
|
+
|
26
|
+
groups:
|
27
|
+
config_get_token: "group"
|
28
|
+
|
29
|
+
priv_protocol:
|
30
|
+
config_get_token: "priv"
|
31
|
+
|
32
|
+
vlan:
|
33
|
+
name:
|
34
|
+
test_config_result:
|
35
|
+
32: "Long VLAN name knob is not enabled"
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# Shared Library to compare configurations.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2013-2015 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
|
+
# Current | Target | Configuration Case
|
18
|
+
# no command | no command | to Match Existing
|
19
|
+
# ------------------------------------------
|
20
|
+
# - - | - a | (no match or trans match)
|
21
|
+
# - - | y a | no match nor base match
|
22
|
+
# - a | - a | match
|
23
|
+
# - a | y a | (base match)
|
24
|
+
# y a | - a | (base match)
|
25
|
+
# y a | y a | match
|
26
|
+
# - b | - a | trans match
|
27
|
+
# - b | y a | (base match)
|
28
|
+
# y b | - a | (base match)
|
29
|
+
# y b | y a | trans match)
|
30
|
+
|
31
|
+
module Cisco
|
32
|
+
module ConfigParser
|
33
|
+
class Configuration
|
34
|
+
attr_accessor :configuration
|
35
|
+
|
36
|
+
# Constructor for Configuration
|
37
|
+
#
|
38
|
+
# @raise [ArgumentError] if config_str is not a String
|
39
|
+
# @param config_str [String] to parse
|
40
|
+
def initialize(config_str)
|
41
|
+
raise ArgumentError, "Argument is not a String." unless config_str.kind_of? String
|
42
|
+
|
43
|
+
@configuration = {}
|
44
|
+
@ordered_keys = []
|
45
|
+
@indent = ""
|
46
|
+
parse(config_str)
|
47
|
+
end # initialize
|
48
|
+
|
49
|
+
# build_min_config_hash
|
50
|
+
#
|
51
|
+
# Build a config hash of the minimum keys that would be needed to update
|
52
|
+
# current config to all of the changes in the "must" config. Each hash key
|
53
|
+
# is a configuration command; some keys have subconfigs which must be
|
54
|
+
# checked before dismissing top-level keys as present. This method is
|
55
|
+
# used primarily by the free-form command_config providers.
|
56
|
+
#
|
57
|
+
# @param current [Hash] superset of running-config & must config
|
58
|
+
# @param must [Hash] pending config from recipe, manifest, etc
|
59
|
+
# @param min_config [Hash] in-progress recursion-built minimum config
|
60
|
+
# @return min_config [Hash] in-progress recursion-built minimum config
|
61
|
+
#
|
62
|
+
def Configuration.build_min_config_hash(current, must, min_config={})
|
63
|
+
return {} if must.empty? # base case
|
64
|
+
must.each { |k, v| # check each must{k} is present in current{}
|
65
|
+
if current.key?(k) # if cmd is in current then compare subconfig
|
66
|
+
min_config[k] = Configuration.new("")
|
67
|
+
min_config[k].configuration =
|
68
|
+
build_min_config_hash(current[k].configuration,
|
69
|
+
v.configuration, {})
|
70
|
+
if min_config[k].configuration.empty?
|
71
|
+
# no differing subconfigs, so empty hash is returned
|
72
|
+
min_config.delete(k)
|
73
|
+
end
|
74
|
+
else # command NOT in current, apply it + all subcommands
|
75
|
+
min_config[k] = v
|
76
|
+
end
|
77
|
+
}
|
78
|
+
min_config
|
79
|
+
end # build_min_config_hash
|
80
|
+
|
81
|
+
def Configuration.config_hash_to_str(cmd_hash, str="")
|
82
|
+
return "" if cmd_hash.empty?
|
83
|
+
cmd_hash.each { |k, v|
|
84
|
+
str += k + "\n"
|
85
|
+
str += config_hash_to_str(v.configuration, "")
|
86
|
+
}
|
87
|
+
str
|
88
|
+
end # config_hash_to_str
|
89
|
+
|
90
|
+
# Get base command and prefix
|
91
|
+
#
|
92
|
+
# @param command [String]
|
93
|
+
# @return [String, String] containing prefix (if any) and
|
94
|
+
# base command.
|
95
|
+
def base_commands(command)
|
96
|
+
prefix, base = command.match(/^(no )?(.*)$/).captures
|
97
|
+
prefix = "" if prefix.nil?
|
98
|
+
[prefix, base]
|
99
|
+
end # base_commands
|
100
|
+
|
101
|
+
# Compare ConfigParser::Configuration objects
|
102
|
+
#
|
103
|
+
# @param config [ConfigParser::Configuration] obj to search
|
104
|
+
# for match.
|
105
|
+
# @return [String] containing match, empty if no match found.
|
106
|
+
def compare_with(config)
|
107
|
+
return nil if config.nil?
|
108
|
+
existing = ""
|
109
|
+
@ordered_keys.each { |config_line|
|
110
|
+
command = config_line.strip
|
111
|
+
submode = @configuration[command]
|
112
|
+
raise StopIteration, "Could not find submode." if submode.nil?
|
113
|
+
|
114
|
+
if special_command?(command)
|
115
|
+
# match special exit/end command
|
116
|
+
existing << config_line
|
117
|
+
break
|
118
|
+
elsif config.include_command?(command)
|
119
|
+
# match whole command
|
120
|
+
existing << config_line
|
121
|
+
config_submode = config.submode_config(command)
|
122
|
+
existing << submode.compare_with(config_submode)
|
123
|
+
next
|
124
|
+
end # if
|
125
|
+
|
126
|
+
prefix, base = base_commands(command)
|
127
|
+
if prefix != "" and !config.include_command?(base)
|
128
|
+
existing << config_line
|
129
|
+
next
|
130
|
+
end
|
131
|
+
}
|
132
|
+
existing
|
133
|
+
end # compare_with
|
134
|
+
|
135
|
+
# @return [Array] containing command with leading/trailing
|
136
|
+
# whitespace removed.
|
137
|
+
def mode_configuration
|
138
|
+
@ordered_keys.collect(&:strip)
|
139
|
+
end # mode_configuration
|
140
|
+
|
141
|
+
# Check command [Array] for test command
|
142
|
+
#
|
143
|
+
# @param command [String] test command
|
144
|
+
# @return [Boolean] true if command found, else false
|
145
|
+
def include_command?(command)
|
146
|
+
commands = mode_configuration()
|
147
|
+
commands.include?(command)
|
148
|
+
end # include_command?
|
149
|
+
|
150
|
+
# Parse each config command line and create a
|
151
|
+
# hash of ConfigParser::Configuration objects
|
152
|
+
#
|
153
|
+
# @param config_str [String] Config command
|
154
|
+
def parse(config_str)
|
155
|
+
config_str += "\n"
|
156
|
+
config_str.gsub!(/^\s*$\n/, '')
|
157
|
+
# ignore leading ! or # (comments)
|
158
|
+
config_str.gsub!(/^\s*[!#].*$\n/, '')
|
159
|
+
if config_str.match(/^ *\t/)
|
160
|
+
highlight_str = config_str.gsub(/\t/, '[TAB]')
|
161
|
+
raise "Tab character detected in indentation area:\n" + highlight_str
|
162
|
+
end
|
163
|
+
indent_level = config_str.match(/^\s*/)
|
164
|
+
@indent = indent_level.to_s # capture indentation of level
|
165
|
+
escaped_indent = Regexp.escape(@indent)
|
166
|
+
@ordered_keys = config_str.scan(/^#{escaped_indent}\S.*\n/) # find current configuration mode lines
|
167
|
+
@ordered_keys.each { |config_line|
|
168
|
+
command = config_line.strip
|
169
|
+
escaped_cmd = Regexp.escape(config_line)
|
170
|
+
submode_string = config_str.match(/^(?:#{escaped_cmd})((?:#{escaped_indent}\s.+\n)*)/).captures.join
|
171
|
+
@configuration[command] = Configuration.new(submode_string)
|
172
|
+
}
|
173
|
+
end # parse
|
174
|
+
|
175
|
+
# Process 'exit' and 'end' commands
|
176
|
+
#
|
177
|
+
# @param command [String] Configuration command.
|
178
|
+
# @return [Boolean] true when command is
|
179
|
+
# 'exit' or 'end', else false
|
180
|
+
def special_command?(command)
|
181
|
+
(/^(?:exit|end)/ === command)
|
182
|
+
end # special_command?
|
183
|
+
|
184
|
+
# Fetch ConfigParser::Configuration object containing config_line
|
185
|
+
#
|
186
|
+
# @param config_line [String]
|
187
|
+
# @return [ConfigParser::Configuration] containing config_line
|
188
|
+
def submode_config(config_line)
|
189
|
+
command = config_line.strip
|
190
|
+
@configuration[command]
|
191
|
+
end # submode_config
|
192
|
+
|
193
|
+
private :base_commands, :parse, :special_command?
|
194
|
+
end # Configuration
|
195
|
+
end # ConfigParser
|
196
|
+
end # Cisco
|
@@ -0,0 +1,501 @@
|
|
1
|
+
#
|
2
|
+
# NXAPI implementation of Interface class
|
3
|
+
#
|
4
|
+
# November 2015, Chris Van Heuveln
|
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
|
+
IF_SWITCHPORT_MODE = {
|
24
|
+
:disabled => "",
|
25
|
+
:access => "access",
|
26
|
+
:trunk => "trunk",
|
27
|
+
:fex_fabric => "fex-fabric",
|
28
|
+
:tunnel => "dot1q-tunnel",
|
29
|
+
}
|
30
|
+
|
31
|
+
class Interface
|
32
|
+
attr_reader :name
|
33
|
+
|
34
|
+
@@node = Cisco::Node.instance
|
35
|
+
|
36
|
+
def initialize(name, instantiate=true)
|
37
|
+
raise TypeError unless name.is_a?(String)
|
38
|
+
raise ArgumentError unless name.length > 0
|
39
|
+
@name = name.downcase
|
40
|
+
|
41
|
+
create if instantiate
|
42
|
+
end
|
43
|
+
|
44
|
+
def Interface.interfaces
|
45
|
+
hash = {}
|
46
|
+
intf_list = @@node.config_get("interface", "all_interfaces")
|
47
|
+
return hash if intf_list.nil?
|
48
|
+
|
49
|
+
intf_list.each do |id|
|
50
|
+
id = id.downcase
|
51
|
+
hash[id] = Interface.new(id, false)
|
52
|
+
end
|
53
|
+
hash
|
54
|
+
end
|
55
|
+
|
56
|
+
def create
|
57
|
+
feature_vlan_set(true) if @name[/vlan/i]
|
58
|
+
@@node.config_set("interface", "create", @name)
|
59
|
+
end
|
60
|
+
|
61
|
+
def destroy
|
62
|
+
@@node.config_set("interface", "destroy", @name)
|
63
|
+
end
|
64
|
+
|
65
|
+
########################################################
|
66
|
+
# PROPERTIES #
|
67
|
+
########################################################
|
68
|
+
|
69
|
+
def access_vlan
|
70
|
+
vlan = @@node.config_get("interface", "access_vlan", @name)
|
71
|
+
return default_access_vlan if vlan.nil?
|
72
|
+
vlan.shift.to_i
|
73
|
+
end
|
74
|
+
|
75
|
+
def access_vlan=(vlan)
|
76
|
+
@@node.config_set("interface", "access_vlan", @name, vlan)
|
77
|
+
rescue Cisco::CliError => e
|
78
|
+
raise "[#{@name}] '#{e.command}' : #{e.clierror}"
|
79
|
+
end
|
80
|
+
|
81
|
+
def default_access_vlan
|
82
|
+
@@node.config_get_default("interface", "access_vlan")
|
83
|
+
end
|
84
|
+
|
85
|
+
def description
|
86
|
+
desc = @@node.config_get("interface", "description", @name)
|
87
|
+
return "" if desc.nil?
|
88
|
+
desc.shift.strip
|
89
|
+
end
|
90
|
+
|
91
|
+
def description=(desc)
|
92
|
+
raise TypeError unless desc.is_a?(String)
|
93
|
+
desc.empty? ?
|
94
|
+
@@node.config_set("interface", "description", @name, "no", "") :
|
95
|
+
@@node.config_set("interface", "description", @name, "", desc)
|
96
|
+
rescue Cisco::CliError => e
|
97
|
+
raise "[#{@name}] '#{e.command}' : #{e.clierror}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def default_description
|
101
|
+
@@node.config_get_default("interface", "description")
|
102
|
+
end
|
103
|
+
|
104
|
+
def fex_feature
|
105
|
+
fex = @@node.config_get("fex", "feature")
|
106
|
+
raise "fex_feature not found" if fex.nil?
|
107
|
+
fex.shift.to_sym
|
108
|
+
end
|
109
|
+
|
110
|
+
def fex_feature_set(fex_set)
|
111
|
+
curr = fex_feature
|
112
|
+
return if curr == fex_set
|
113
|
+
|
114
|
+
case fex_set
|
115
|
+
when :enabled
|
116
|
+
@@node.config_set("fex", "feature_install", "") if curr == :uninstalled
|
117
|
+
@@node.config_set("fex", "feature", "")
|
118
|
+
when :disabled
|
119
|
+
@@node.config_set("fex", "feature", "no") if curr == :enabled
|
120
|
+
return
|
121
|
+
when :installed
|
122
|
+
@@node.config_set("fex", "feature_install", "") if curr == :uninstalled
|
123
|
+
when :uninstalled
|
124
|
+
@@node.config_set("fex", "feature", "no") if curr == :enabled
|
125
|
+
@@node.config_set("fex", "feature_install", "no")
|
126
|
+
end
|
127
|
+
rescue Cisco::CliError => e
|
128
|
+
raise "[#{@name}] '#{e.command}' : #{e.clierror}"
|
129
|
+
end
|
130
|
+
|
131
|
+
def ipv4_addr_mask
|
132
|
+
@@node.config_get("interface", "ipv4_addr_mask", @name)
|
133
|
+
end
|
134
|
+
|
135
|
+
def ipv4_addr_mask_set(addr, mask)
|
136
|
+
check_switchport_disabled
|
137
|
+
if addr.nil? or addr == default_ipv4_address
|
138
|
+
@@node.config_set("interface", "ipv4_addr_mask", @name, "no", "")
|
139
|
+
else
|
140
|
+
@@node.config_set("interface", "ipv4_addr_mask", @name, "",
|
141
|
+
"#{addr}/#{mask}")
|
142
|
+
end
|
143
|
+
rescue Cisco::CliError => e
|
144
|
+
raise "[#{@name}] '#{e.command}' : #{e.clierror}"
|
145
|
+
end
|
146
|
+
|
147
|
+
def ipv4_address
|
148
|
+
val = ipv4_addr_mask
|
149
|
+
return default_ipv4_address if val.nil?
|
150
|
+
addr, mask = val.shift
|
151
|
+
addr
|
152
|
+
end
|
153
|
+
|
154
|
+
def default_ipv4_address
|
155
|
+
@@node.config_get_default("interface", "ipv4_address")
|
156
|
+
end
|
157
|
+
|
158
|
+
def ipv4_netmask_length
|
159
|
+
val = ipv4_addr_mask
|
160
|
+
return default_ipv4_netmask_length if val.nil?
|
161
|
+
addr, mask = val.shift
|
162
|
+
mask.to_i
|
163
|
+
end
|
164
|
+
|
165
|
+
def default_ipv4_netmask_length
|
166
|
+
@@node.config_get_default("interface", "ipv4_netmask_length")
|
167
|
+
end
|
168
|
+
|
169
|
+
def ipv4_proxy_arp
|
170
|
+
state = @@node.config_get("interface", "ipv4_proxy_arp", @name)
|
171
|
+
state.nil? ? false : true
|
172
|
+
end
|
173
|
+
|
174
|
+
def ipv4_proxy_arp=(proxy_arp)
|
175
|
+
check_switchport_disabled
|
176
|
+
no_cmd = (proxy_arp ? "" : "no")
|
177
|
+
@@node.config_set("interface", "ipv4_proxy_arp", @name, no_cmd)
|
178
|
+
end
|
179
|
+
|
180
|
+
def default_ipv4_proxy_arp
|
181
|
+
@@node.config_get_default("interface", "ipv4_proxy_arp")
|
182
|
+
end
|
183
|
+
|
184
|
+
def ipv4_redirects_lookup_string
|
185
|
+
case @name
|
186
|
+
when /loopback/i
|
187
|
+
return "ipv4_redirects_loopback"
|
188
|
+
else
|
189
|
+
return "ipv4_redirects_other_interfaces"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def ipv4_redirects
|
194
|
+
begin
|
195
|
+
state = @@node.config_get("interface",
|
196
|
+
ipv4_redirects_lookup_string, @name)
|
197
|
+
rescue IndexError
|
198
|
+
state = nil
|
199
|
+
end
|
200
|
+
# We return default state for the platform if the platform doesn't support
|
201
|
+
# the command
|
202
|
+
return default_ipv4_redirects if state.nil? or state.empty?
|
203
|
+
state.shift[/^ip redirects$/] ? true : false
|
204
|
+
end
|
205
|
+
|
206
|
+
def ipv4_redirects=(redirects)
|
207
|
+
check_switchport_disabled
|
208
|
+
no_cmd = (redirects ? "" : "no")
|
209
|
+
@@node.config_set("interface", ipv4_redirects_lookup_string, @name, no_cmd)
|
210
|
+
rescue IndexError
|
211
|
+
raise "ipv4 redirects not supported on #{@name}"
|
212
|
+
end
|
213
|
+
|
214
|
+
def default_ipv4_redirects
|
215
|
+
@@node.config_get_default("interface", ipv4_redirects_lookup_string)
|
216
|
+
end
|
217
|
+
|
218
|
+
def negotiate_auto_lookup_string
|
219
|
+
case @name
|
220
|
+
when /Ethernet/i
|
221
|
+
return "negotiate_auto_ethernet"
|
222
|
+
when /port-channel/i # Ether-channel
|
223
|
+
return "negotiate_auto_portchannel"
|
224
|
+
else
|
225
|
+
return "negotiate_auto_other_interfaces"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def negotiate_auto
|
230
|
+
lookup = negotiate_auto_lookup_string
|
231
|
+
begin
|
232
|
+
state = @@node.config_get("interface", lookup, @name)
|
233
|
+
rescue IndexError
|
234
|
+
# We return default state even if the config_get is not supported
|
235
|
+
# for this platform / interface type. This is done so that we can set
|
236
|
+
# the manifest to 'default' so there is a 'workaround' for the
|
237
|
+
# unsupported attribute
|
238
|
+
return default_negotiate_auto
|
239
|
+
end
|
240
|
+
state.nil? ? false : true
|
241
|
+
end
|
242
|
+
|
243
|
+
def negotiate_auto=(negotiate_auto)
|
244
|
+
lookup = negotiate_auto_lookup_string
|
245
|
+
no_cmd = (negotiate_auto ? "" : "no")
|
246
|
+
begin
|
247
|
+
@@node.config_set("interface", lookup, @name, no_cmd)
|
248
|
+
rescue Cisco::CliError => e
|
249
|
+
raise "[#{@name}] '#{e.command}' : #{e.clierror}"
|
250
|
+
rescue IndexError
|
251
|
+
raise "[#{@name}] negotiate_auto is not supported on this interface"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def default_negotiate_auto
|
256
|
+
@@node.config_get_default("interface", negotiate_auto_lookup_string)
|
257
|
+
end
|
258
|
+
|
259
|
+
def shutdown
|
260
|
+
state = @@node.config_get("interface", "shutdown", @name)
|
261
|
+
state ? true : false
|
262
|
+
end
|
263
|
+
|
264
|
+
def shutdown=(state)
|
265
|
+
no_cmd = (state ? "" : "no")
|
266
|
+
@@node.config_set("interface", "shutdown", @name, no_cmd)
|
267
|
+
rescue Cisco::CliError => e
|
268
|
+
raise "[#{@name}] '#{e.command}' : #{e.clierror}"
|
269
|
+
end
|
270
|
+
|
271
|
+
def default_shutdown
|
272
|
+
case @name
|
273
|
+
when /Ethernet/i
|
274
|
+
def_sw = system_default_switchport
|
275
|
+
def_shut = system_default_switchport_shutdown
|
276
|
+
|
277
|
+
if def_sw and def_shut
|
278
|
+
lookup = "shutdown_ethernet_switchport_shutdown"
|
279
|
+
elsif def_sw and not def_shut
|
280
|
+
lookup = "shutdown_ethernet_switchport_noshutdown"
|
281
|
+
elsif not def_sw and def_shut
|
282
|
+
lookup = "shutdown_ethernet_noswitchport_shutdown"
|
283
|
+
elsif not def_sw and not def_shut
|
284
|
+
lookup = "shutdown_ethernet_noswitchport_noshutdown"
|
285
|
+
else
|
286
|
+
raise "Error: def_sw #{def_sw}, def_shut #{def_shut}"
|
287
|
+
end
|
288
|
+
|
289
|
+
when /loopback/i
|
290
|
+
lookup = "shutdown_loopback"
|
291
|
+
|
292
|
+
when /port-channel/i # EtherChannel
|
293
|
+
lookup = "shutdown_ether_channel"
|
294
|
+
|
295
|
+
when /Vlan/i
|
296
|
+
lookup = "shutdown_vlan"
|
297
|
+
|
298
|
+
else
|
299
|
+
lookup = "shutdown_unknown"
|
300
|
+
end
|
301
|
+
@@node.config_get_default("interface", lookup)
|
302
|
+
end
|
303
|
+
|
304
|
+
def switchport
|
305
|
+
# This is "switchport", not "switchport mode"
|
306
|
+
sw = @@node.config_get("interface", "switchport", @name)
|
307
|
+
sw.nil? ? false : true
|
308
|
+
end
|
309
|
+
|
310
|
+
def switchport_enable(val=true)
|
311
|
+
@@node.config_set("interface", "switchport", @name, val ? "" : "no")
|
312
|
+
end
|
313
|
+
|
314
|
+
# switchport_autostate_exclude is exclusive to switchport interfaces
|
315
|
+
def switchport_autostate_exclude
|
316
|
+
not @@node.config_get("interface",
|
317
|
+
"switchport_autostate_exclude", @name).nil?
|
318
|
+
end
|
319
|
+
|
320
|
+
def switchport_autostate_exclude=(val)
|
321
|
+
# cannot configure autostate unless feature vlan is enabled
|
322
|
+
raise "switchport mode must be configured before switchport autostate" unless
|
323
|
+
switchport
|
324
|
+
feature_vlan_set(true)
|
325
|
+
@@node.config_set("interface", "switchport_autostate_exclude",
|
326
|
+
@name, val ? "" : "no")
|
327
|
+
end
|
328
|
+
|
329
|
+
def default_switchport_autostate_exclude
|
330
|
+
@@node.config_get_default("interface", "switchport_autostate_exclude")
|
331
|
+
end
|
332
|
+
|
333
|
+
def switchport_mode_lookup_string
|
334
|
+
case @name
|
335
|
+
when /Ethernet/i
|
336
|
+
return "switchport_mode_ethernet"
|
337
|
+
when /port-channel/i
|
338
|
+
return "switchport_mode_port_channel"
|
339
|
+
else
|
340
|
+
return "switchport_mode_other_interfaces"
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
def switchport_mode
|
345
|
+
mode = @@node.config_get("interface", switchport_mode_lookup_string, @name)
|
346
|
+
|
347
|
+
return mode.nil? ? :disabled : IF_SWITCHPORT_MODE.key(mode.shift)
|
348
|
+
|
349
|
+
rescue IndexError
|
350
|
+
# Assume this is an interface that doesn't support switchport.
|
351
|
+
# Do not raise exception since the providers will prefetch this property
|
352
|
+
# regardless of interface type.
|
353
|
+
return :disabled
|
354
|
+
end
|
355
|
+
|
356
|
+
def switchport_enable_and_mode(mode_set)
|
357
|
+
switchport_enable unless switchport
|
358
|
+
|
359
|
+
if (:fex_fabric == mode_set)
|
360
|
+
fex_feature_set(:enabled) unless (:enabled == fex_feature)
|
361
|
+
end
|
362
|
+
@@node.config_set("interface", switchport_mode_lookup_string, @name, "",
|
363
|
+
IF_SWITCHPORT_MODE[mode_set])
|
364
|
+
|
365
|
+
rescue RuntimeError
|
366
|
+
raise "[#{@name}] switchport_mode is not supported on this interface"
|
367
|
+
end
|
368
|
+
|
369
|
+
def switchport_mode=(mode_set)
|
370
|
+
# no system default switchport
|
371
|
+
# int e1/1
|
372
|
+
# switchport
|
373
|
+
# switchport mode [access|trunk|fex|...]
|
374
|
+
raise ArgumentError unless IF_SWITCHPORT_MODE.keys.include? mode_set
|
375
|
+
case mode_set
|
376
|
+
when :disabled
|
377
|
+
if switchport
|
378
|
+
# Note: turn off switchport command, not switchport mode
|
379
|
+
@@node.config_set("interface", "switchport", @name, "no")
|
380
|
+
end
|
381
|
+
|
382
|
+
when :default
|
383
|
+
if :disabled == default_switchport_mode
|
384
|
+
@@node.config_set("interface", switchport_mode_lookup_string,
|
385
|
+
@name, "no", "")
|
386
|
+
else
|
387
|
+
switchport_enable_and_mode(mode_set)
|
388
|
+
end
|
389
|
+
|
390
|
+
else
|
391
|
+
switchport_enable_and_mode(mode_set)
|
392
|
+
end # case
|
393
|
+
|
394
|
+
rescue Cisco::CliError => e
|
395
|
+
raise "[#{@name}] '#{e.command}' : #{e.clierror}"
|
396
|
+
end
|
397
|
+
|
398
|
+
def default_switchport_mode
|
399
|
+
return :disabled unless system_default_switchport
|
400
|
+
IF_SWITCHPORT_MODE.key(
|
401
|
+
@@node.config_get_default("interface", switchport_mode_lookup_string))
|
402
|
+
end
|
403
|
+
|
404
|
+
def system_default_switchport
|
405
|
+
# This command is a user-configurable system default.
|
406
|
+
sys_def = @@node.config_get("interface", "system_default_switchport")
|
407
|
+
sys_def.nil? ? false : true
|
408
|
+
end
|
409
|
+
|
410
|
+
def system_default_switchport_shutdown
|
411
|
+
# This command is a user-configurable system default.
|
412
|
+
sys_def = @@node.config_get("interface",
|
413
|
+
"system_default_switchport_shutdown")
|
414
|
+
sys_def.nil? ? false : true
|
415
|
+
end
|
416
|
+
|
417
|
+
def system_default_svi_autostate
|
418
|
+
# This command is a user-configurable system default.
|
419
|
+
sys_def = @@node.config_get("interface",
|
420
|
+
"system_default_svi_autostate")
|
421
|
+
sys_def.nil? ? false : true
|
422
|
+
end
|
423
|
+
|
424
|
+
def switchport_vtp_mode_capable?
|
425
|
+
not switchport_mode.to_s.match(/(access|trunk)/).nil?
|
426
|
+
end
|
427
|
+
|
428
|
+
def switchport_vtp
|
429
|
+
return false unless switchport_vtp_mode_capable?
|
430
|
+
vtp = @@node.config_get("interface", "vtp", @name)
|
431
|
+
vtp.nil? ? false : true
|
432
|
+
end
|
433
|
+
|
434
|
+
def switchport_vtp=(vtp_set)
|
435
|
+
return false unless switchport_vtp_mode_capable?
|
436
|
+
no_cmd = (vtp_set) ? "" : "no"
|
437
|
+
@@node.config_set("interface", "vtp", @name, no_cmd)
|
438
|
+
rescue Cisco::CliError => e
|
439
|
+
raise "[#{@name}] '#{e.command}' : #{e.clierror}"
|
440
|
+
end
|
441
|
+
|
442
|
+
def svi_cmd_allowed?(cmd)
|
443
|
+
raise "[#{@name}] Invalid interface type for command [#{cmd}]" unless
|
444
|
+
@name[/vlan/i]
|
445
|
+
end
|
446
|
+
|
447
|
+
# svi_autostate is exclusive to svi interfaces
|
448
|
+
def svi_autostate
|
449
|
+
return nil unless @name[/^vlan/i]
|
450
|
+
not @@node.config_get("interface", "svi_autostate", @name).nil?
|
451
|
+
end
|
452
|
+
|
453
|
+
def svi_autostate=(val)
|
454
|
+
check_switchport_disabled
|
455
|
+
svi_cmd_allowed?('autostate')
|
456
|
+
@@node.config_set("interface", "svi_autostate", @name, val ? "" : "no")
|
457
|
+
end
|
458
|
+
|
459
|
+
def default_svi_autostate
|
460
|
+
system_default_svi_autostate
|
461
|
+
end
|
462
|
+
|
463
|
+
def feature_vlan?
|
464
|
+
not @@node.config_get("interface", "feature_vlan").nil?
|
465
|
+
end
|
466
|
+
|
467
|
+
def feature_vlan_set(val)
|
468
|
+
return if feature_vlan? == val
|
469
|
+
@@node.config_set("interface", "feature_vlan", val ? "" : "no")
|
470
|
+
end
|
471
|
+
|
472
|
+
# svi_management is exclusive to svi interfaces
|
473
|
+
def svi_management
|
474
|
+
return nil unless @name[/^vlan/i]
|
475
|
+
not @@node.config_get("interface", "svi_management", @name).nil?
|
476
|
+
end
|
477
|
+
|
478
|
+
def svi_management=(val)
|
479
|
+
check_switchport_disabled
|
480
|
+
svi_cmd_allowed?('management')
|
481
|
+
@@node.config_set("interface", "svi_management", @name, val ? "" : "no")
|
482
|
+
end
|
483
|
+
|
484
|
+
def default_svi_management
|
485
|
+
@@node.config_get_default("interface", "svi_management")
|
486
|
+
end
|
487
|
+
|
488
|
+
def default_switchport_vtp
|
489
|
+
@@node.config_get_default("interface", "vtp")
|
490
|
+
end
|
491
|
+
|
492
|
+
def switchport_vtp_feature?
|
493
|
+
@@node.config_get("vtp", "feature")
|
494
|
+
end
|
495
|
+
|
496
|
+
def check_switchport_disabled
|
497
|
+
raise "#{caller[0][/`.*'/][1..-2]} cannot be set unless switchport mode" +
|
498
|
+
" is disabled" unless switchport_mode == :disabled
|
499
|
+
end
|
500
|
+
end # Class
|
501
|
+
end # Module
|