puppet_x_eos_eapi 0.2.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 +17 -0
- data/Gemfile +24 -0
- data/LICENSE.txt +202 -0
- data/README.md +87 -0
- data/Rakefile +1 -0
- data/lib/puppet_x/eos/autoload.rb +57 -0
- data/lib/puppet_x/eos/eapi.rb +259 -0
- data/lib/puppet_x/eos/module_base.rb +37 -0
- data/lib/puppet_x/eos/modules/daemon.rb +109 -0
- data/lib/puppet_x/eos/modules/extension.rb +167 -0
- data/lib/puppet_x/eos/modules/interface.rb +180 -0
- data/lib/puppet_x/eos/modules/ipinterface.rb +133 -0
- data/lib/puppet_x/eos/modules/mlag.rb +268 -0
- data/lib/puppet_x/eos/modules/ntp.rb +129 -0
- data/lib/puppet_x/eos/modules/ospf.rb +129 -0
- data/lib/puppet_x/eos/modules/portchannel.rb +277 -0
- data/lib/puppet_x/eos/modules/radius.rb +367 -0
- data/lib/puppet_x/eos/modules/snmp.rb +177 -0
- data/lib/puppet_x/eos/modules/switchport.rb +255 -0
- data/lib/puppet_x/eos/modules/system.rb +138 -0
- data/lib/puppet_x/eos/modules/tacacs.rb +302 -0
- data/lib/puppet_x/eos/modules/vlan.rb +179 -0
- data/lib/puppet_x/eos/modules/vxlan.rb +132 -0
- data/lib/puppet_x/eos/provider.rb +71 -0
- data/lib/puppet_x/eos/version.rb +41 -0
- data/lib/puppet_x/net_dev/eos_api.rb +1011 -0
- data/lib/puppet_x/net_dev/eos_api/common_methods.rb +27 -0
- data/lib/puppet_x/net_dev/eos_api/snmp_methods.rb +647 -0
- data/lib/puppet_x/net_dev/eos_api/version.rb +8 -0
- data/lib/puppet_x_eos_eapi.rb +4 -0
- data/puppet_x_eos_eapi.gemspec +31 -0
- data/spec/fixtures/fixture_all_portchannel_modes.json +8 -0
- data/spec/fixtures/fixture_all_portchannels_detailed.json +15 -0
- data/spec/fixtures/fixture_create_vlan_error.json +17 -0
- data/spec/fixtures/fixture_create_vlan_success.json +12 -0
- data/spec/fixtures/fixture_eapi_conf.yaml +4 -0
- data/spec/fixtures/fixture_enable_configure_vlan_3111_name_foo.json +14 -0
- data/spec/fixtures/fixture_enable_configure_vlan_foo_name_bar.json +19 -0
- data/spec/fixtures/fixture_get_snmp_communities_non_existent_acl.yaml +2 -0
- data/spec/fixtures/fixture_get_snmp_location_westeros.json +5 -0
- data/spec/fixtures/fixture_portchannel_min_links_1.json +8 -0
- data/spec/fixtures/fixture_portchannel_min_links_2.json +8 -0
- data/spec/fixtures/fixture_running_config.yaml +1 -0
- data/spec/fixtures/fixture_running_configuration_radius_configured.yaml +30 -0
- data/spec/fixtures/fixture_running_configuration_radius_default.yaml +29 -0
- data/spec/fixtures/fixture_running_configuration_radius_server_groups.yaml +38 -0
- data/spec/fixtures/fixture_running_configuration_radius_servers.yaml +34 -0
- data/spec/fixtures/fixture_running_configuration_tacacs_configured.yaml +38 -0
- data/spec/fixtures/fixture_running_configuration_tacacs_default.yaml +38 -0
- data/spec/fixtures/fixture_running_configuration_tacacs_groups.yaml +1 -0
- data/spec/fixtures/fixture_running_configuration_tacacs_groups_3.yaml +43 -0
- data/spec/fixtures/fixture_running_configuration_tacacs_servers.yaml +41 -0
- data/spec/fixtures/fixture_s4_show_etherchannel_detailed.json +9 -0
- data/spec/fixtures/fixture_show_flowcontrol_et1.json +5 -0
- data/spec/fixtures/fixture_show_interfaces.json +297 -0
- data/spec/fixtures/fixture_show_interfaces_switchport_format_text.json +9 -0
- data/spec/fixtures/fixture_show_port_channel_summary_2_lags.json +9 -0
- data/spec/fixtures/fixture_show_port_channel_summary_static.json +9 -0
- data/spec/fixtures/fixture_show_snmp_community.yaml +2 -0
- data/spec/fixtures/fixture_show_snmp_contact_empty.json +5 -0
- data/spec/fixtures/fixture_show_snmp_contact_name.json +5 -0
- data/spec/fixtures/fixture_show_snmp_disabled.json +5 -0
- data/spec/fixtures/fixture_show_snmp_enabled.json +5 -0
- data/spec/fixtures/fixture_show_snmp_host.yaml +2 -0
- data/spec/fixtures/fixture_show_snmp_host_duplicates.yaml +2 -0
- data/spec/fixtures/fixture_show_snmp_host_more_duplicates.yaml +2 -0
- data/spec/fixtures/fixture_show_snmp_location_empty.json +5 -0
- data/spec/fixtures/fixture_show_snmp_trap.yaml +2 -0
- data/spec/fixtures/fixture_show_snmp_user.yaml +2 -0
- data/spec/fixtures/fixture_show_snmp_user_raw_text.yaml +1 -0
- data/spec/fixtures/fixture_show_vlan.json +37 -0
- data/spec/fixtures/fixture_show_vlan_3110.json +18 -0
- data/spec/fixtures/fixture_show_vlan_4000.json +18 -0
- data/spec/fixtures/fixture_snmp_host_opts.yaml +11 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/fixtures.rb +104 -0
- data/spec/unit/puppet_x/eos/eapi_spec.rb +182 -0
- data/spec/unit/puppet_x/eos/module_base_spec.rb +26 -0
- data/spec/unit/puppet_x/eos/modules/daemon_spec.rb +110 -0
- data/spec/unit/puppet_x/eos/modules/extension_spec.rb +197 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/daemon_getall.json +3 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/extension_getall.json +28 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/hostname.json +6 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/interface_getall.json +509 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/ipinterface_getall.json +56 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/mlag_get.json +21 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/mlag_get_interfaces.json +18 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/ntp_get.json +5 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/ospf_instance_getall.json +58 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/portchannel_get.json +54 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/portchannel_getlacpmode.json +5 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/portchannel_getmembers.json +5 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/portchannel_po1.json +7 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/snmp_get.json +14 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/switchport_get.json +5 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/switchport_get_et1.json +7 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/switchport_getall_interfaces.json +230 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/system_domain_list.json +5 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/system_domain_name.json +5 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/system_hostname.json +6 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/system_name_servers.json +5 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/vlan_getall.json +123 -0
- data/spec/unit/puppet_x/eos/modules/fixtures/vxlan_get.json +24 -0
- data/spec/unit/puppet_x/eos/modules/interface_spec.rb +281 -0
- data/spec/unit/puppet_x/eos/modules/ipinterface_spec.rb +143 -0
- data/spec/unit/puppet_x/eos/modules/mlag_spec.rb +349 -0
- data/spec/unit/puppet_x/eos/modules/ntp_spec.rb +136 -0
- data/spec/unit/puppet_x/eos/modules/ospf_spec.rb +143 -0
- data/spec/unit/puppet_x/eos/modules/portchannel_spec.rb +357 -0
- data/spec/unit/puppet_x/eos/modules/radius_spec.rb +509 -0
- data/spec/unit/puppet_x/eos/modules/snmp_spec.rb +202 -0
- data/spec/unit/puppet_x/eos/modules/switchport_get_et1.json +7 -0
- data/spec/unit/puppet_x/eos/modules/switchport_spec.rb +307 -0
- data/spec/unit/puppet_x/eos/modules/system_spec.rb +170 -0
- data/spec/unit/puppet_x/eos/modules/tacacs_spec.rb +448 -0
- data/spec/unit/puppet_x/eos/modules/vlan_spec.rb +244 -0
- data/spec/unit/puppet_x/eos/modules/vxlan_spec.rb +189 -0
- data/spec/unit/puppet_x/eos/provider_spec.rb +35 -0
- data/spec/unit/puppet_x/net_dev/eos_api/common_methods_spec.rb +34 -0
- data/spec/unit/puppet_x/net_dev/eos_api/snmp_methods_spec.rb +842 -0
- data/spec/unit/puppet_x/net_dev/eos_api_spec.rb +1000 -0
- metadata +369 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module PuppetX
|
|
4
|
+
module Eos
|
|
5
|
+
##
|
|
6
|
+
# ModuleBase provides a base class for other modules to inherit from.
|
|
7
|
+
# Methods common to all modules should be placed here.
|
|
8
|
+
class ModuleBase
|
|
9
|
+
attr_reader :api
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# Initialize instance of Module. The Module class provides instance
|
|
13
|
+
# methods to configure module related resources on the target device.
|
|
14
|
+
#
|
|
15
|
+
# @param [PuppetX::Eos::Eapi] api An instance of Eapi
|
|
16
|
+
#
|
|
17
|
+
# @return [PuppetX::Eos::ModuleBase]
|
|
18
|
+
def initialize(api)
|
|
19
|
+
@api = api
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# running_configuration returns the current running configuration as a
|
|
24
|
+
# string. This method is intended to be used by subclasses. The running
|
|
25
|
+
# configuration is returned as a single string object to faciliate the
|
|
26
|
+
# use of String#scan
|
|
27
|
+
#
|
|
28
|
+
# @api private
|
|
29
|
+
#
|
|
30
|
+
# @return [String]
|
|
31
|
+
def running_configuration
|
|
32
|
+
result = api.enable('show running-config', format: 'text')
|
|
33
|
+
result.last['output']
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2014, Arista Networks, Inc.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
|
6
|
+
# modification, are permitted provided that the following conditions are
|
|
7
|
+
# met:
|
|
8
|
+
#
|
|
9
|
+
# Redistributions of source code must retain the above copyright notice,
|
|
10
|
+
# this list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# Redistributions in binary form must reproduce the above copyright
|
|
13
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
14
|
+
# documentation and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# Neither the name of Arista Networks nor the names of its
|
|
17
|
+
# contributors may be used to endorse or promote products derived from
|
|
18
|
+
# this software without specific prior written permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
21
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
22
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
23
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARISTA NETWORKS
|
|
24
|
+
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
27
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
28
|
+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
29
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
30
|
+
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
#
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# PuppetX is the toplevel namespace for working with Arista EOS nodes
|
|
35
|
+
module PuppetX
|
|
36
|
+
##
|
|
37
|
+
# Eos is module namesapce for working with the EOS command API
|
|
38
|
+
module Eos
|
|
39
|
+
##
|
|
40
|
+
# The Daemon class provides management of daemons using EOS CLI
|
|
41
|
+
# commands over eAPI. This class provides method for creating and
|
|
42
|
+
# deleting daemons
|
|
43
|
+
#
|
|
44
|
+
class Daemon
|
|
45
|
+
##
|
|
46
|
+
# Initializes a new instance of Daemon.
|
|
47
|
+
#
|
|
48
|
+
# @param [PuppetX::Eos::Eapi] api An instance of Eapi
|
|
49
|
+
#
|
|
50
|
+
# @return [PuppetX::Eos::Daemon] instance
|
|
51
|
+
def initialize(api)
|
|
52
|
+
@api = api
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Returns a hash of configured daemons from the running config
|
|
57
|
+
#
|
|
58
|
+
# Example
|
|
59
|
+
# {
|
|
60
|
+
# "agent": "command"
|
|
61
|
+
# }
|
|
62
|
+
#
|
|
63
|
+
# @return [Hash<String, String>] Hash of configured agents
|
|
64
|
+
def getall
|
|
65
|
+
result = @api.enable('show running-config section daemon',
|
|
66
|
+
format: 'text')
|
|
67
|
+
response = {}
|
|
68
|
+
key = nil
|
|
69
|
+
result.first['output'].split("\n").each do |entry|
|
|
70
|
+
token = entry.strip.match(/^daemon\s(?<name>.*)$/)
|
|
71
|
+
unless token.nil?
|
|
72
|
+
key = token['name']
|
|
73
|
+
response[key] = nil
|
|
74
|
+
end
|
|
75
|
+
token = entry.strip.match(/^command\s(?<command>.*)$/)
|
|
76
|
+
unless token.nil?
|
|
77
|
+
value = token['command']
|
|
78
|
+
response[key] = value
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
response
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
##
|
|
85
|
+
# Configures a new daemon agent in EOS using eAPI
|
|
86
|
+
#
|
|
87
|
+
# @param [String] name The name of the daemon agent
|
|
88
|
+
# @param [String] command The path to the daemon executable
|
|
89
|
+
#
|
|
90
|
+
# @return [Boolean] True if the commands succeed otherwise False
|
|
91
|
+
def create(name, command)
|
|
92
|
+
return false unless File.executable?(command)
|
|
93
|
+
@api.config(["daemon #{name}", "command #{command}"]) == [{}, {}]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
##
|
|
97
|
+
# Deletes a previously configured daemon from the running-configuration
|
|
98
|
+
# in EOS using eAPI
|
|
99
|
+
#
|
|
100
|
+
# @param [String] name The name of the agent to delete
|
|
101
|
+
#
|
|
102
|
+
# @return [Boolean] True if the operation was successful otherwise
|
|
103
|
+
# False
|
|
104
|
+
def delete(name)
|
|
105
|
+
@api.config("no daemon #{name}") == [{}]
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2014, Arista Networks, Inc.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
|
6
|
+
# modification, are permitted provided that the following conditions are
|
|
7
|
+
# met:
|
|
8
|
+
#
|
|
9
|
+
# Redistributions of source code must retain the above copyright notice,
|
|
10
|
+
# this list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# Redistributions in binary form must reproduce the above copyright
|
|
13
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
14
|
+
# documentation and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# Neither the name of Arista Networks nor the names of its
|
|
17
|
+
# contributors may be used to endorse or promote products derived from
|
|
18
|
+
# this software without specific prior written permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
21
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
22
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
23
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARISTA NETWORKS
|
|
24
|
+
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
27
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
28
|
+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
29
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
30
|
+
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
#
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# Eos is the toplevel namespace for working with Arista EOS nodes
|
|
35
|
+
module PuppetX
|
|
36
|
+
##
|
|
37
|
+
# Eapi is module namesapce for working with the EOS command API
|
|
38
|
+
module Eos
|
|
39
|
+
##
|
|
40
|
+
# The Extensio class provides management of extensions in EOS. Extensions
|
|
41
|
+
# are simply RPM packages that can loaded onto the switch. This class
|
|
42
|
+
# allows installing, deleting and configuring extensions
|
|
43
|
+
#
|
|
44
|
+
class Extension
|
|
45
|
+
BOOTEXT = '/mnt/flash/boot-extensions'
|
|
46
|
+
|
|
47
|
+
def initialize(api)
|
|
48
|
+
@api = api
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# Retrieves all of the extenions loaded in EOS and returns an array
|
|
53
|
+
# of hashes using the 'show extensions' command over eAPI.
|
|
54
|
+
#
|
|
55
|
+
# Example:
|
|
56
|
+
# [{
|
|
57
|
+
# "ruby-1.9.3-1.swix": {
|
|
58
|
+
# "status": "installed", # installed, forceInstalled
|
|
59
|
+
# "version": "1.9.3.484",
|
|
60
|
+
# "presence": "present",
|
|
61
|
+
# "release": "32.eos4",
|
|
62
|
+
# "numRpms": 10,
|
|
63
|
+
# "error": false
|
|
64
|
+
# }
|
|
65
|
+
# }]
|
|
66
|
+
#
|
|
67
|
+
# @return [Hash<Hash<String, String>>] Nested hash describing
|
|
68
|
+
# the extension details. If there are no extensions then an
|
|
69
|
+
# empty Hash is returned
|
|
70
|
+
def get
|
|
71
|
+
@api.enable('show extensions')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
##
|
|
75
|
+
# Returns if file is loaded on boot or not
|
|
76
|
+
#
|
|
77
|
+
# @param [String] name The name of the file
|
|
78
|
+
#
|
|
79
|
+
# @return [Boolean] True if it loades on boot otherwise False
|
|
80
|
+
def autoload?(name)
|
|
81
|
+
name = URI(name).to_s.split('/')[-1]
|
|
82
|
+
File.open(BOOTEXT).read.scan(/#{name}[\sforce\n|\n]/).size > 0
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
##
|
|
86
|
+
# Copies and installs the extension from a remote server to the
|
|
87
|
+
# node running EOS using the eAPI coopy command.
|
|
88
|
+
#
|
|
89
|
+
# @param [String] url The full url to the RPM
|
|
90
|
+
# @param [String] force Specifies the use of the force keyword
|
|
91
|
+
#
|
|
92
|
+
# @return [Boolean] True if the installation succeeds and False if it
|
|
93
|
+
# does not succeed
|
|
94
|
+
def install(url, force)
|
|
95
|
+
force = false if force.nil?
|
|
96
|
+
@api.enable("copy #{url} extension:")
|
|
97
|
+
load(url, force)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
##
|
|
101
|
+
# Loads an existing extension into EOS. The extension must already
|
|
102
|
+
# be copied over to the node using #create
|
|
103
|
+
#
|
|
104
|
+
# @params [String] name The name of the extension to load
|
|
105
|
+
# @param [Hash] opt Options for loading the extions
|
|
106
|
+
# @option opts [Boolean] :force Appends force to the command
|
|
107
|
+
#
|
|
108
|
+
# @return [Boolean] True if the command succeeds or False if it does
|
|
109
|
+
# not succeed
|
|
110
|
+
def load(name, force)
|
|
111
|
+
name = URI(name).to_s.split('/')[-1]
|
|
112
|
+
command = "extension #{name}"
|
|
113
|
+
command << ' force' if force
|
|
114
|
+
@api.enable(command) == [{}]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
##
|
|
118
|
+
# Uninstalls and removes and extension from an EOS node. The extension
|
|
119
|
+
# will be unloaded and deleted from /mnt/flash
|
|
120
|
+
#
|
|
121
|
+
# @params [String] name The name of the extension to remove
|
|
122
|
+
#
|
|
123
|
+
# @return [Boolean] True if the command succeeds or False if it does
|
|
124
|
+
# not succeed
|
|
125
|
+
def delete(name)
|
|
126
|
+
name = URI(name).to_s.split('/')[-1]
|
|
127
|
+
set_autoload(:false, name, false)
|
|
128
|
+
@api.enable("no extension #{name}")
|
|
129
|
+
@api.enable("delete extension:#{name}") == [{}]
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
##
|
|
133
|
+
# Configures the extension to persistent on system restarts
|
|
134
|
+
#
|
|
135
|
+
# @param [String] enabled Whether or not the extension is enabled
|
|
136
|
+
# @param [String] name The name of the extension
|
|
137
|
+
# @param[Boolean] force Specifies if the force keyword should be used
|
|
138
|
+
#
|
|
139
|
+
# @return [Boolean] True if the extension was set to autoload or False
|
|
140
|
+
# if it was not
|
|
141
|
+
def set_autoload(enabled, name, force)
|
|
142
|
+
enabled = :true if enabled.nil?
|
|
143
|
+
force = false if force.nil?
|
|
144
|
+
|
|
145
|
+
name = URI(name).to_s.split('/')[-1]
|
|
146
|
+
entry = "#{name}"
|
|
147
|
+
entry << ' force' if force
|
|
148
|
+
|
|
149
|
+
case enabled
|
|
150
|
+
when :true
|
|
151
|
+
if File.open(BOOTEXT).read.scan(/#{name}[\sforce\n|\n]/).size == 0
|
|
152
|
+
File.open(BOOTEXT, 'a') { |f| f << "#{entry}\n" }
|
|
153
|
+
return true
|
|
154
|
+
end
|
|
155
|
+
when :false
|
|
156
|
+
contents = File.readlines(BOOTEXT)
|
|
157
|
+
contents.delete("#{name}\n")
|
|
158
|
+
File.open(BOOTEXT, 'w') do |f|
|
|
159
|
+
f.puts(contents)
|
|
160
|
+
end
|
|
161
|
+
return true
|
|
162
|
+
end
|
|
163
|
+
false
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2014, Arista Networks, Inc.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
|
6
|
+
# modification, are permitted provided that the following conditions are
|
|
7
|
+
# met:
|
|
8
|
+
#
|
|
9
|
+
# Redistributions of source code must retain the above copyright notice,
|
|
10
|
+
# this list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# Redistributions in binary form must reproduce the above copyright
|
|
13
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
14
|
+
# documentation and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# Neither the name of Arista Networks nor the names of its
|
|
17
|
+
# contributors may be used to endorse or promote products derived from
|
|
18
|
+
# this software without specific prior written permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
21
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
22
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
23
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARISTA NETWORKS
|
|
24
|
+
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
27
|
+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
28
|
+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
29
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
30
|
+
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
#
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# PuppetX is the toplevel namespace for working with Arista EOS nodes
|
|
35
|
+
module PuppetX
|
|
36
|
+
##
|
|
37
|
+
# Eos is module namesapce for working with the EOS command API
|
|
38
|
+
module Eos
|
|
39
|
+
##
|
|
40
|
+
# The Interface class provides a base class instance for working with
|
|
41
|
+
# physical and logical interfaces.
|
|
42
|
+
#
|
|
43
|
+
class Interface
|
|
44
|
+
##
|
|
45
|
+
# Initialize instance of Interface
|
|
46
|
+
#
|
|
47
|
+
# @param [PuppetX::Eos::Eapi] api An instance of Eapi
|
|
48
|
+
#
|
|
49
|
+
# @return [PuppetX::Eos::Interface]
|
|
50
|
+
def initialize(api)
|
|
51
|
+
@api = api
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
# Returns the base interface hash representing physical and logical
|
|
56
|
+
# interfaces in EOS using eAPI
|
|
57
|
+
#
|
|
58
|
+
# Example
|
|
59
|
+
# [{
|
|
60
|
+
# "interfaces": {...},
|
|
61
|
+
# "interfaceFlowControls": {...}
|
|
62
|
+
# }]
|
|
63
|
+
#
|
|
64
|
+
# @return [Array<Hash>] returns an Array of Hashes
|
|
65
|
+
def getall
|
|
66
|
+
@api.enable(['show interfaces', 'show interfaces flowcontrol'])
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# Configures the interface object back to system wide defaults using
|
|
71
|
+
# the EOS command api
|
|
72
|
+
#
|
|
73
|
+
# @param [String] name The name of the interface
|
|
74
|
+
#
|
|
75
|
+
# @return [Boolean] True if it succeeds otherwise False
|
|
76
|
+
def default(name)
|
|
77
|
+
@api.config("default interface #{name}") == [{}]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# Creates a new logical interface on the node.
|
|
82
|
+
#
|
|
83
|
+
# @param [String] name The name of the logical interface. It must be
|
|
84
|
+
# a full valid EOS interface name (ie Ethernet, not Et)
|
|
85
|
+
#
|
|
86
|
+
# @return [Boolean] True if the command succeeds or False if the command
|
|
87
|
+
# fails or is not supported (for instance trying to create a physical
|
|
88
|
+
# interface that already exists)
|
|
89
|
+
def create(name)
|
|
90
|
+
return false if name.match(/^[Et|Ma]/)
|
|
91
|
+
@api.config("interface #{name}") == [{}]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
##
|
|
95
|
+
# Deletes an existing logical interface.
|
|
96
|
+
#
|
|
97
|
+
# @param [String] name The name of the interface. It must be a full
|
|
98
|
+
# valid EOS interface name (ie Vlan, not Vl)
|
|
99
|
+
#
|
|
100
|
+
# @return [Boolean] True if the command succeeds or False if the command
|
|
101
|
+
# fails or is not supported (for instance trying to delete a physical
|
|
102
|
+
# interface)
|
|
103
|
+
def delete(name)
|
|
104
|
+
return false if name.match(/^[Et|Ma]/)
|
|
105
|
+
@api.config("no interface #{name}") == [{}]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
##
|
|
109
|
+
# Configures the interface shutdown state
|
|
110
|
+
#
|
|
111
|
+
# @param [String] name The name of the interface to configure
|
|
112
|
+
# @param [Hash] opts The configuration parameters for the interface
|
|
113
|
+
# @option opts [string] :value The value to set the state to
|
|
114
|
+
# @option opts [Boolean] :default The value should be set to default
|
|
115
|
+
#
|
|
116
|
+
# @return [Boolean] True if the commands succeed otherwise False
|
|
117
|
+
def set_shutdown(name, opts = {})
|
|
118
|
+
value = opts[:value] || false
|
|
119
|
+
default = opts[:default] || false
|
|
120
|
+
|
|
121
|
+
cmds = ["interface #{name}"]
|
|
122
|
+
case default
|
|
123
|
+
when true
|
|
124
|
+
cmds << 'default shutdown'
|
|
125
|
+
when false
|
|
126
|
+
cmds << (value ? 'shutdown' : 'no shutdown')
|
|
127
|
+
end
|
|
128
|
+
@api.config(cmds) == [{}, {}]
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
##
|
|
132
|
+
# Configures the interface description
|
|
133
|
+
#
|
|
134
|
+
# @param [String] name The name of the interface to configure
|
|
135
|
+
# @param [Hash] opts The configuration parameters for the interface
|
|
136
|
+
# @option opts [string] :value The value to set the description to
|
|
137
|
+
# @option opts [Boolean] :default The value should be set to default
|
|
138
|
+
#
|
|
139
|
+
# @return [Boolean] True if the commands succeed otherwise False
|
|
140
|
+
def set_description(name, opts = {})
|
|
141
|
+
value = opts[:value]
|
|
142
|
+
default = opts[:default] || false
|
|
143
|
+
|
|
144
|
+
cmds = ["interface #{name}"]
|
|
145
|
+
case default
|
|
146
|
+
when true
|
|
147
|
+
cmds << 'default description'
|
|
148
|
+
when false
|
|
149
|
+
cmds << (value.nil? ? 'no description' : "description #{value}")
|
|
150
|
+
end
|
|
151
|
+
@api.config(cmds) == [{}, {}]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
##
|
|
155
|
+
# Configures the interface flowcontrol
|
|
156
|
+
#
|
|
157
|
+
# @param [String] name The name of the interface to configure
|
|
158
|
+
# @param [String] direction One of tx or rx
|
|
159
|
+
# @param [Hash] opts The configuration parameters for the interface
|
|
160
|
+
# @option opts [string] :value The value to set the description to
|
|
161
|
+
# @option opts [Boolean] :default The value should be set to default
|
|
162
|
+
#
|
|
163
|
+
# @return [Boolean] True if the commands succeed otherwise False
|
|
164
|
+
def set_flowcontrol(name, direction, opts = {})
|
|
165
|
+
value = opts[:value]
|
|
166
|
+
default = opts[:default] || false
|
|
167
|
+
|
|
168
|
+
cmds = ["interface #{name}"]
|
|
169
|
+
case default
|
|
170
|
+
when true
|
|
171
|
+
cmds << "default flowcontrol #{direction}"
|
|
172
|
+
when false
|
|
173
|
+
cmds << (value.nil? ? "no flowcontrol #{direction}" :
|
|
174
|
+
"flowcontrol #{direction} #{value}")
|
|
175
|
+
end
|
|
176
|
+
@api.config(cmds) == [{}, {}]
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|