arista-eos 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. data/.gitignore +41 -0
  2. data/.rubocop.yml +21 -0
  3. data/Gemfile +57 -0
  4. data/Guardfile +21 -0
  5. data/LICENSE +28 -0
  6. data/README.md +178 -0
  7. data/Rakefile +46 -0
  8. data/eos.gemspec +36 -0
  9. data/guide/.gitignore +2 -0
  10. data/guide/Makefile +177 -0
  11. data/guide/_static/arista_logo_jpg-11.jpg +0 -0
  12. data/guide/_static/favicon.ico +0 -0
  13. data/guide/conf.py +282 -0
  14. data/guide/cookbook.rst +135 -0
  15. data/guide/developing.rst +55 -0
  16. data/guide/faq.rst +30 -0
  17. data/guide/index.rst +25 -0
  18. data/guide/installation.rst +174 -0
  19. data/guide/license.rst +5 -0
  20. data/guide/overview.rst +35 -0
  21. data/guide/quickstart.rst +184 -0
  22. data/guide/release-notes-1.0.rst +37 -0
  23. data/guide/release-notes-1.1.rst +25 -0
  24. data/guide/release-notes.rst +10 -0
  25. data/guide/testing.rst +8 -0
  26. data/guide/troubleshooting.rst +26 -0
  27. data/guide/typedoc.rst +928 -0
  28. data/guide/types.rst +44 -0
  29. data/lib/eos.rb +8 -0
  30. data/lib/eos/version.rb +5 -0
  31. data/lib/puppet/provider/eos_acl_entry/default.rb +122 -0
  32. data/lib/puppet/provider/eos_command/default.rb +61 -0
  33. data/lib/puppet/provider/eos_ethernet/default.rb +96 -0
  34. data/lib/puppet/provider/eos_interface/default.rb +89 -0
  35. data/lib/puppet/provider/eos_ipinterface/default.rb +89 -0
  36. data/lib/puppet/provider/eos_mlag/default.rb +86 -0
  37. data/lib/puppet/provider/eos_mlag_interface/default.rb +90 -0
  38. data/lib/puppet/provider/eos_ntp_config/default.rb +68 -0
  39. data/lib/puppet/provider/eos_ntp_server/default.rb +69 -0
  40. data/lib/puppet/provider/eos_portchannel/default.rb +117 -0
  41. data/lib/puppet/provider/eos_snmp/default.rb +77 -0
  42. data/lib/puppet/provider/eos_stp_interface/default.rb +73 -0
  43. data/lib/puppet/provider/eos_switchport/default.rb +100 -0
  44. data/lib/puppet/provider/eos_system/default.rb +63 -0
  45. data/lib/puppet/provider/eos_vlan/default.rb +93 -0
  46. data/lib/puppet/provider/eos_vxlan/default.rb +104 -0
  47. data/lib/puppet/provider/eos_vxlan_vlan/default.rb +89 -0
  48. data/lib/puppet/provider/eos_vxlan_vtep/default.rb +70 -0
  49. data/lib/puppet/type/eos_acl_entry.rb +126 -0
  50. data/lib/puppet/type/eos_command.rb +75 -0
  51. data/lib/puppet/type/eos_ethernet.rb +101 -0
  52. data/lib/puppet/type/eos_interface.rb +79 -0
  53. data/lib/puppet/type/eos_ipinterface.rb +116 -0
  54. data/lib/puppet/type/eos_mlag.rb +133 -0
  55. data/lib/puppet/type/eos_mlag_interface.rb +85 -0
  56. data/lib/puppet/type/eos_ntp_config.rb +70 -0
  57. data/lib/puppet/type/eos_ntp_server.rb +52 -0
  58. data/lib/puppet/type/eos_portchannel.rb +189 -0
  59. data/lib/puppet/type/eos_snmp.rb +127 -0
  60. data/lib/puppet/type/eos_stp_interface.rb +94 -0
  61. data/lib/puppet/type/eos_switchport.rb +150 -0
  62. data/lib/puppet/type/eos_system.rb +69 -0
  63. data/lib/puppet/type/eos_vlan.rb +130 -0
  64. data/lib/puppet/type/eos_vxlan.rb +150 -0
  65. data/lib/puppet/type/eos_vxlan_vlan.rb +78 -0
  66. data/lib/puppet/type/eos_vxlan_vtep.rb +62 -0
  67. data/lib/puppet_x/eos/provider.rb +86 -0
  68. data/lib/puppet_x/eos/utils/helpers.rb +34 -0
  69. data/metadata.json +20 -0
  70. data/spec/fixtures/README +61 -0
  71. data/spec/fixtures/ethernet.json +9 -0
  72. data/spec/fixtures/fixture_stp.yaml +11 -0
  73. data/spec/fixtures/fixture_vxlan_get.yaml +11 -0
  74. data/spec/fixtures/ospf.json +13 -0
  75. data/spec/fixtures/snmp.json +6 -0
  76. data/spec/fixtures/varp.json +11 -0
  77. data/spec/spec_helper.rb +27 -0
  78. data/spec/support/fixtures.rb +74 -0
  79. data/spec/support/shared_examples_for_providers.rb +7 -0
  80. data/spec/support/shared_examples_for_types.rb +451 -0
  81. data/spec/unit/puppet/provider/eos_acl_entry/default_spec.rb +226 -0
  82. data/spec/unit/puppet/provider/eos_acl_entry/fixture_acl_entry.yaml +20 -0
  83. data/spec/unit/puppet/provider/eos_ethernet/default_spec.rb +226 -0
  84. data/spec/unit/puppet/provider/eos_ethernet/fixture_ethernet.yaml +8 -0
  85. data/spec/unit/puppet/provider/eos_interface/default_spec.rb +176 -0
  86. data/spec/unit/puppet/provider/eos_interface/fixture_interfaces.yaml +5 -0
  87. data/spec/unit/puppet/provider/eos_ipinterface/default_spec.rb +223 -0
  88. data/spec/unit/puppet/provider/eos_ipinterface/fixture_ipinterfaces.yaml +5 -0
  89. data/spec/unit/puppet/provider/eos_mlag/default_spec.rb +203 -0
  90. data/spec/unit/puppet/provider/eos_mlag/fixture_mlag.yaml +11 -0
  91. data/spec/unit/puppet/provider/eos_mlag_interface/default_spec.rb +177 -0
  92. data/spec/unit/puppet/provider/eos_mlag_interface/fixture_mlag.yaml +11 -0
  93. data/spec/unit/puppet/provider/eos_ntp_config/default_spec.rb +150 -0
  94. data/spec/unit/puppet/provider/eos_ntp_config/fixture_ntp.yaml +3 -0
  95. data/spec/unit/puppet/provider/eos_ntp_server/default_spec.rb +152 -0
  96. data/spec/unit/puppet/provider/eos_ntp_server/fixture_ntp.yaml +3 -0
  97. data/spec/unit/puppet/provider/eos_portchannel/default_spec.rb +271 -0
  98. data/spec/unit/puppet/provider/eos_portchannel/fixture_portchannels.yaml +10 -0
  99. data/spec/unit/puppet/provider/eos_snmp/default_spec.rb +193 -0
  100. data/spec/unit/puppet/provider/eos_snmp/fixture_snmp.yaml +6 -0
  101. data/spec/unit/puppet/provider/eos_stp_interface/default_spec.rb +138 -0
  102. data/spec/unit/puppet/provider/eos_switchport/default_spec.rb +250 -0
  103. data/spec/unit/puppet/provider/eos_switchport/fixture_switchports.yaml +7 -0
  104. data/spec/unit/puppet/provider/eos_system/default_spec.rb +129 -0
  105. data/spec/unit/puppet/provider/eos_system/fixture_system.yaml +2 -0
  106. data/spec/unit/puppet/provider/eos_vlan/default_spec.rb +228 -0
  107. data/spec/unit/puppet/provider/eos_vlan/fixture_vlans.yaml +6 -0
  108. data/spec/unit/puppet/provider/eos_vxlan/default_spec.rb +229 -0
  109. data/spec/unit/puppet/provider/eos_vxlan/fixture_vxlan.yaml +9 -0
  110. data/spec/unit/puppet/provider/eos_vxlan_vlan/default_spec.rb +148 -0
  111. data/spec/unit/puppet/provider/eos_vxlan_vtep/default_spec.rb +140 -0
  112. data/spec/unit/puppet/type/eos_acl_entry_spec.rb +103 -0
  113. data/spec/unit/puppet/type/eos_command_spec.rb +67 -0
  114. data/spec/unit/puppet/type/eos_ethernet_spec.rb +87 -0
  115. data/spec/unit/puppet/type/eos_interface_spec.rb +67 -0
  116. data/spec/unit/puppet/type/eos_ipinterface_spec.rb +84 -0
  117. data/spec/unit/puppet/type/eos_mlag_interface_spec.rb +62 -0
  118. data/spec/unit/puppet/type/eos_mlag_spec.rb +98 -0
  119. data/spec/unit/puppet/type/eos_ntp_config_spec.rb +58 -0
  120. data/spec/unit/puppet/type/eos_ntp_server_spec.rb +51 -0
  121. data/spec/unit/puppet/type/eos_portchannel_spec.rb +99 -0
  122. data/spec/unit/puppet/type/eos_snmp_spec.rb +87 -0
  123. data/spec/unit/puppet/type/eos_stp_interface_spec.rb +77 -0
  124. data/spec/unit/puppet/type/eos_switchport_spec.rb +88 -0
  125. data/spec/unit/puppet/type/eos_system_spec.rb +57 -0
  126. data/spec/unit/puppet/type/eos_vlan_spec.rb +86 -0
  127. data/spec/unit/puppet/type/eos_vxlan_spec.rb +100 -0
  128. data/spec/unit/puppet/type/eos_vxlan_vlan_spec.rb +73 -0
  129. data/spec/unit/puppet/type/eos_vxlan_vtep_spec.rb +52 -0
  130. data/tests/init.pp +12 -0
  131. metadata +437 -0
@@ -0,0 +1,86 @@
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
+ require 'rbeapi/client'
33
+
34
+ ##
35
+ # PuppetX namespace
36
+ module PuppetX
37
+ ##
38
+ # Eos namesapece
39
+ module Eos
40
+ ##
41
+ # EapiProviderMixin module
42
+ module EapiProviderMixin
43
+ def prefetch(resources)
44
+ provider_hash = instances.each_with_object({}) do |provider, hsh|
45
+ hsh[provider.name] = provider
46
+ end
47
+
48
+ resources.each_pair do |name, resource|
49
+ resource.provider = provider_hash[name] if provider_hash[name]
50
+ end
51
+ end
52
+
53
+ ##
54
+ # Instance of Rbeapi::Client::Node used to sending and receiving
55
+ # eAPI messages. In addition, the node object provides access to
56
+ # Ruby Client for eAPI API modules used to configure EOS resources.
57
+ #
58
+ # @return [Node] An instance of Rbeapi::Client::Node used to send
59
+ # and receive eAPI messages
60
+ def node
61
+ return @node if @node
62
+ Rbeapi::Client.load_config(ENV['RBEAPI_CONF']) if ENV['RBEAPI_CONF']
63
+ connection_name = ENV['RBEAPI_CONNECTION'] || 'localhost'
64
+ @node = Rbeapi::Client.connect_to(connection_name)
65
+ end
66
+
67
+ ##
68
+ # validate checkes the set of opts that have been configured for a
69
+ # resource against the required options. If any of the required options
70
+ # are missing, this method will fail.
71
+ #
72
+ # @api private
73
+ #
74
+ # @param [Hash] :opts The set of options configured on the resource
75
+ #
76
+ # @param [Array] :req The set of required option keys
77
+ def validate(req, opts = {})
78
+ missing = req.reject { |k| opts[k] }
79
+ errors = !missing.empty?
80
+ msg = "Invalid options #{opts.inspect} missing: #{missing.join(', ')}"
81
+ fail Puppet::Error, msg if errors
82
+ end
83
+ private :validate
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,34 @@
1
+ #
2
+ # Copyright (c) 2015, 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
+ IPADDR_REGEXP = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
34
+ (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/x
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "aristanetworks-eos",
3
+ "version": "1.1.0",
4
+ "author": "Arista Networks, EOS+",
5
+ "summary": "Arista Networks types and providers for configuring EOS devices",
6
+ "license": "BSD-3-Clause",
7
+ "source": "https://github.com/arista-eosplus/puppet-eos",
8
+ "project_page": "http://puppet-eos.readthedocs.org/",
9
+ "issues_url": "https://github.com/arista-eosplus/puppet-eos/issues",
10
+ "dependencies": [
11
+ ],
12
+ "operatingsystem_support": [
13
+ {
14
+ "operatingsystem":"AristaEOS",
15
+ "operatingsystemrelease":[ "4.13.7M", "4.14" ]
16
+ }
17
+ ],
18
+ "tags": ["network", "netdev", "arista", "eos"]
19
+ }
20
+
@@ -0,0 +1,61 @@
1
+ # README for fixtures
2
+
3
+ This file contains a list of the fixture files in the fixtures folder along
4
+ with the tests that implement the fixtures. This file needs to be maintained
5
+ in order to void fixture file "bloat" in this folder.
6
+
7
+ The file format is "filename" followed by a list of modules that implement
8
+ that fixture file.
9
+
10
+ ## Fixtures
11
+
12
+ ###vlans.json
13
+ * spec/unit/puppet/provider/eos_vlan_spec.rb
14
+
15
+ ###interfaces.json
16
+ * spec/unit/puppet/provider/eos_interface_spec.rb
17
+
18
+ ###ethernet.json
19
+ * spec/unit/puppet/provider/eos_ethernet_spec.rb
20
+
21
+ ###ipinterfaces.json
22
+ * spec/unit/puppet/provider/eos_ipinterface_spec.rb
23
+
24
+ ###switchports.json
25
+ * spec/unit/puppet/provider/eos_switchport_spec.rb
26
+
27
+ ###portchannels.json
28
+ * spec/unit/puppet/provider/eos_portchannel_spec.rb
29
+
30
+ ###vxlan.json
31
+ * spec/unit/puppet/provider/eos_vxlan_spec.rb
32
+
33
+ ###snmp.json
34
+ * spec/unit/puppet/provider/eos_snmp_spec.rb
35
+
36
+ ###mlag.json
37
+ * spec/unit/puppet/provider/eos_mlag_spec.rb
38
+ * spec/unit/puppet/provider/eos_mlag_interface_spec.rb
39
+
40
+ ###ntp.json
41
+ * spec/unit/puppet/provider/eos_ntp_config_spec.rb
42
+ * spec/unit/puppet/provider/eos_ntp_server_spec.rb
43
+
44
+ ###logging.json
45
+ * spec/unit/puppet/provider/eos_logging_host_spec.rb
46
+
47
+ ###ospf.json
48
+ * spec/unit/puppet/provider/eos_ospf_instnace_spec.rb
49
+ * spec/unit/puppet/provider/eos_ospf_interface_spec.rb
50
+
51
+ ###varp.json
52
+ * spec/unit/puppet/provider/eos_varp_spec.rb
53
+ * spec/unit/puppet/provider/eos_varp_interface_spec.rb
54
+
55
+ ###stp.json
56
+ * spec/unit/puppet/provider/eos_stp_config_spec.rb
57
+
58
+ ###system.json
59
+ * spec/unit/puppet/provider/eos_system_spec.rb
60
+
61
+
@@ -0,0 +1,9 @@
1
+ {
2
+ "Ethernet1": {
3
+ "type": "ethernet",
4
+ "description": "test interface",
5
+ "shutdown": false,
6
+ "flowcontrol_send": "on",
7
+ "flowcontrol_receive": "on"
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ ---
2
+ :mode: mstp
3
+ :interfaces:
4
+ Ethernet1:
5
+ :portfast: true
6
+ :portfast_type: network
7
+ :bpduguard: true
8
+ Ethernet2:
9
+ :portfast: true
10
+ :portfast_type: normal
11
+ :bpduguard: false
@@ -0,0 +1,11 @@
1
+ ---
2
+ :type: vxlan
3
+ :description: test interface
4
+ :shutdown: false
5
+ :source_interface: Loopback0
6
+ :multicast_group: 239.10.10.10
7
+ :udp_port: 4789
8
+ :flood_list: ['1.1.1.1', '3.3.3.3']
9
+ :vlans:
10
+ '10':
11
+ :vni: '10'
@@ -0,0 +1,13 @@
1
+ {
2
+ "1": {
3
+ "router_id": "1.1.1.1",
4
+ "areas": {
5
+ "0.0.0.0": ["192.168.10.0/24"]
6
+ }
7
+ },
8
+ "interfaces": {
9
+ "Ethernet1": {
10
+ "network_type": "point-to-point"
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "contact": "network operations",
3
+ "location": "data center",
4
+ "source_interface": "Loopback0",
5
+ "chassis_id": "1234567890"
6
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mac_address": "aa:bb:cc:dd:ee:ff",
3
+ "interfaces": {
4
+ "Vlan1234": {
5
+ "addresses": [
6
+ "1.1.1.1",
7
+ "2.2.2.2"
8
+ ]
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ require 'simplecov'
3
+ require 'simplecov-json'
4
+ require 'simplecov-rcov'
5
+ SimpleCov.formatters =
6
+ [
7
+ SimpleCov::Formatter::HTMLFormatter,
8
+ SimpleCov::Formatter::JSONFormatter,
9
+ SimpleCov::Formatter::RcovFormatter
10
+ ]
11
+ SimpleCov.start do
12
+ add_filter '/spec/'
13
+ add_filter '/.bundle/'
14
+ end
15
+
16
+ require 'pry'
17
+ require 'puppetlabs_spec_helper/puppet_spec_helper'
18
+
19
+ dir = File.expand_path(File.dirname(__FILE__))
20
+ Dir["#{dir}/support/**/*.rb"].sort.each { |f| require f }
21
+
22
+ RSpec.configure do |config|
23
+ # rspec configuration
24
+ config.mock_with :rspec do |rspec_config|
25
+ rspec_config.syntax = :expect
26
+ end
27
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pathname'
4
+ require 'yaml'
5
+ require 'json'
6
+
7
+ ##
8
+ # Fixtures implements a global container to store fixture data loaded from the
9
+ # filesystem.
10
+ class Fixtures
11
+ def self.[](name)
12
+ @fixtures[name]
13
+ end
14
+
15
+ def self.[]=(name, value)
16
+ @fixtures[name] = value
17
+ end
18
+
19
+ def self.clear
20
+ @fixtures = {}
21
+ end
22
+
23
+ clear
24
+
25
+ ##
26
+ # save an object and saves it as a fixture in the filesystem.
27
+ #
28
+ # @param [Symbol] key The fixture name without the `fixture_` prefix or
29
+ # `.json` suffix.
30
+ #
31
+ # @param [Object] obj The object to serialize to JSON and write to the
32
+ # fixture file.
33
+ #
34
+ # @option opts [String] :dir ('/path/to/fixtures') The fixtures directory,
35
+ # defaults to the full path of spec/fixtures/ relative to the root of the
36
+ # module.
37
+ def self.save(key, obj, opts = {})
38
+ dir = opts[:dir] || File.expand_path('../../fixtures', __FILE__)
39
+ file = Pathname.new(File.join(dir, "fixture_#{key}.yaml"))
40
+ fail ArgumentError, "Error, file #{file} exists" if file.exist?
41
+ File.open(file, 'w+') { |f| f.puts YAML.dump(obj) }
42
+ end
43
+ end
44
+
45
+ ##
46
+ # FixtureHelpers provides instance methods for RSpec test cases that aid in the
47
+ # loading and caching of fixture data.
48
+ module FixtureHelpers
49
+ ##
50
+ # fixture loads a JSON fixture from the spec/fixtures/ directory, prefixed
51
+ # with fixture_. Given the name 'foo' the file
52
+ # `spec/fixtures/fixture_foo.json` will be loaded and returned. This method
53
+ # is memoized across the life of the process.
54
+ #
55
+ # @param [Symbol] key The fixture name without the `fixture_` prefix or
56
+ # `.json` suffix.
57
+ #
58
+ # @option opts [String] :dir ('/path/to/fixtures') The fixtures directory,
59
+ # defaults to the full path of spec/fixtures/ relative to the root of the
60
+ # module.
61
+ def fixture(key, opts = {})
62
+ memo = Fixtures[key]
63
+ return memo if memo
64
+ dir = opts[:dir] || File.expand_path('../../fixtures', __FILE__)
65
+
66
+ yaml = Pathname.new(File.join(dir, "fixture_#{key}.yaml"))
67
+ json = Pathname.new(File.join(dir, "fixture_#{key}.json"))
68
+
69
+ Fixtures[key] = if yaml.exist?; then YAML.load(File.read(yaml))
70
+ elsif json.exist?; then JSON.load(File.read(json))
71
+ else fail "could not load YAML or JSON fixture #{key}"
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,7 @@
1
+ RSpec.shared_examples 'provider resource methods' do |opts = {}|
2
+ opts.each_pair do |method, value|
3
+ it "#{method} is #{value}" do
4
+ expect(subject.send(method)).to eq(value)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,451 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.shared_examples 'property' do
4
+ it 'is a property' do
5
+ expect(described_class.attrtype(attribute)).to eq(:property)
6
+ end
7
+ end
8
+
9
+ RSpec.shared_examples 'parameter' do
10
+ it 'is a parameter' do
11
+ expect(described_class.attrtype(attribute)).to eq(:param)
12
+ end
13
+ end
14
+
15
+ RSpec.shared_examples 'an ensurable type' do |opts = { name: 'emanon' }|
16
+ describe 'ensure' do
17
+ let(:catalog) { Puppet::Resource::Catalog.new }
18
+ let(:type) do
19
+ described_class.new(name: opts[:name], catalog: catalog)
20
+ end
21
+
22
+ let(:attribute) { :ensure }
23
+ subject { described_class.attrclass(attribute) }
24
+
25
+ include_examples 'property'
26
+ include_examples '#doc Documentation'
27
+
28
+ %w(absent present).each do |val|
29
+ it "accepts #{val.inspect}" do
30
+ type[attribute] = val
31
+ end
32
+ end
33
+
34
+ %w(true false).each do |val|
35
+ it "rejects #{val.inspect}" do
36
+ expect { type[attribute] = val }.to raise_error Puppet::ResourceError
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ RSpec.shared_examples 'boolean parameter' do
43
+ it 'is a parameter' do
44
+ expect(described_class.attrtype(attribute)).to eq(:param)
45
+ end
46
+
47
+ include_examples 'boolean value'
48
+ end
49
+
50
+ RSpec.shared_examples 'boolean' do |opts|
51
+ attribute = opts[:attribute]
52
+ fail unless attribute
53
+ name = opts[:name] || 'emanon'
54
+
55
+ describe "#{attribute}" do
56
+ let(:catalog) { Puppet::Resource::Catalog.new }
57
+ let(:attribute) { attribute }
58
+ let(:type) { described_class.new(name: name, catalog: catalog) }
59
+ subject { described_class.attrclass(attribute) }
60
+
61
+ include_examples 'boolean value'
62
+ include_examples '#doc Documentation'
63
+ include_examples 'rejects values', [0, [1], { two: :three }]
64
+ end
65
+ end
66
+
67
+ RSpec.shared_examples 'boolean value' do
68
+ [true, false, 'true', 'false', :true, :false].each do |val|
69
+ it "accepts #{val.inspect}" do
70
+ type[attribute] = val
71
+ end
72
+
73
+ it "munges #{val.inspect} to #{val.to_s.intern.inspect}" do
74
+ type[attribute] = val
75
+ expect(type[attribute]).to eq(val.to_s.intern)
76
+ end
77
+ end
78
+
79
+ [1, -1, { foo: 1 }, [1], 'baz', nil].each do |val|
80
+ it "rejects #{val.inspect} with Puppet::Error" do
81
+ expect { type[attribute] = val }.to raise_error Puppet::Error
82
+ end
83
+ end
84
+ end
85
+
86
+ RSpec.shared_examples 'name is the namevar' do
87
+ describe 'name' do
88
+ let(:catalog) { Puppet::Resource::Catalog.new }
89
+ let(:type) do
90
+ described_class.new(name: 'emanon', catalog: catalog)
91
+ end
92
+
93
+ let(:attribute) { :name }
94
+ subject { described_class.attrclass(attribute) }
95
+
96
+ include_examples '#doc Documentation'
97
+
98
+ it 'is a parameter' do
99
+ expect(described_class.attrtype(:name)).to eq(:param)
100
+ end
101
+
102
+ ['Engineering'].each do |val|
103
+ it "accepts #{val.inspect}" do
104
+ type[attribute] = val
105
+ end
106
+ end
107
+
108
+ [0, %w(Marketing Sales), { two: :three }].each do |val|
109
+ it "rejects #{val.inspect}" do
110
+ expect { type[attribute] = val }
111
+ .to raise_error Puppet::ResourceError, /is invalid, must be a String/
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ RSpec.shared_examples '#doc Documentation' do
118
+ it '#doc is a String' do
119
+ expect(subject.doc).to be_a_kind_of(String)
120
+ end
121
+
122
+ it '#doc is not only whitespace' do
123
+ expect(subject.doc.gsub(/\s+/, '')).not_to be_empty
124
+ end
125
+ end
126
+
127
+ RSpec.shared_examples 'rejected parameter values' do
128
+ [{ two: :three }, nil, :undef, :undefined, 'foobar'].each do |val|
129
+ it "rejects #{val.inspect} with a Puppet::Error" do
130
+ expect { type[attribute] = val }.to raise_error Puppet::Error
131
+ end
132
+ end
133
+ end
134
+
135
+ RSpec.shared_examples 'channel group id value' do
136
+ [1, 10, 100, 1000].each do |val|
137
+ it "accepts #{val.inspect}" do
138
+ type[attribute] = val
139
+ end
140
+ end
141
+
142
+ it 'munges [10, 20] to 10' do
143
+ type[attribute] = [10, 20]
144
+ expect(type[attribute]).to eq('10')
145
+ end
146
+
147
+ [-1, 1001, 8192, 'asdf', { foo: 1 }, true, false, nil].each do |val|
148
+ it "rejects #{val.inspect} with a Puppet::Error" do
149
+ expect { type[attribute] = val }.to raise_error Puppet::Error
150
+ end
151
+ end
152
+ end
153
+
154
+ RSpec.shared_examples 'vlan id value' do
155
+ [1, 10, 100, 4094].each do |val|
156
+ it "accepts #{val.inspect}" do
157
+ type[attribute] = val
158
+ end
159
+ end
160
+
161
+ it 'munges [10, 20] to 10' do
162
+ type[attribute] = [10, 20]
163
+ expect(type[attribute]).to eq(10)
164
+ end
165
+
166
+ [-1, 4096, 8192, 'asdf', { foo: 1 }, true, false, nil].each do |val|
167
+ it "rejects #{val.inspect} with a Puppet::Error" do
168
+ expect { type[attribute] = val }.to raise_error Puppet::Error
169
+ end
170
+ end
171
+ end
172
+
173
+ RSpec.shared_examples 'vlan range value' do
174
+ [1, 10, 100, 4094].each do |val|
175
+ it "munges #{val.inspect} to [#{val}]" do
176
+ type[attribute] = val
177
+ expect(type[attribute]).to eq([val])
178
+ end
179
+ end
180
+
181
+ it 'munges [10, 20] to [10, 20]' do
182
+ type[attribute] = [10, 20]
183
+ expect(type[attribute]).to eq([10, 20])
184
+ end
185
+
186
+ [-1, 4096, 8192, 'asdf', { foo: 1 }, true, false, nil].each do |val|
187
+ it "rejects #{val.inspect} with a Puppet::Error" do
188
+ expect { type[attribute] = val }.to raise_error Puppet::Error
189
+ end
190
+ end
191
+ end
192
+
193
+ RSpec.shared_examples 'vlan range string value' do
194
+ %w(1 10 100 4094).each do |val|
195
+ it "munges #{val.inspect} to [#{val}]" do
196
+ type[attribute] = val
197
+ expect(type[attribute]).to eq([val])
198
+ end
199
+ end
200
+
201
+ it 'munges [10, 20] to ["10", "20"]' do
202
+ type[attribute] = [10, 20]
203
+ expect(type[attribute]).to eq([10, 20])
204
+ end
205
+
206
+ [-1, 4096, '8192', 'asdf', { foo: 1 }, true, false, nil].each do |val|
207
+ it "rejects #{val.inspect} with a Puppet::Error" do
208
+ expect { type[attribute] = val }.to raise_error Puppet::Error
209
+ end
210
+ end
211
+ end
212
+
213
+ RSpec.shared_examples 'interface list value' do
214
+ ['Ethernet1', 'Ethernet2', 'ethernet 4/2'].each do |val|
215
+ it "accepts #{val.inspect}" do
216
+ type[attribute] = val
217
+ expect(type[attribute]).to eq([val])
218
+ end
219
+ end
220
+
221
+ [-1, 4096, 8192, 'asdf', { foo: 1 }, true, false, nil].each do |val|
222
+ it "rejects #{val.inspect} with a Puppet::Error" do
223
+ expect { type[attribute] = val }.to raise_error Puppet::Error
224
+ end
225
+ end
226
+ end
227
+
228
+ RSpec.shared_examples 'array of strings property' do |opts|
229
+ attribute = opts[:attribute]
230
+ name = opts[:name] || 'emanon'
231
+ describe "#{attribute}" do
232
+ let(:catalog) { Puppet::Resource::Catalog.new }
233
+ let(:type) { described_class.new(name: name, catalog: catalog) }
234
+ let(:attribute) { attribute }
235
+ subject { described_class.attrclass(attribute) }
236
+
237
+ include_examples '#doc Documentation'
238
+ include_examples 'array of strings value'
239
+ end
240
+ end
241
+
242
+ RSpec.shared_examples 'array of strings value' do
243
+ ['foo', 'bar', 'foo bar baz'].each do |val|
244
+ it "accepts #{val.inspect}" do
245
+ type[attribute] = val
246
+ expect(type[attribute]).to eq([val])
247
+ end
248
+ end
249
+
250
+ [-1, 4096, 8192, { foo: 1 }, true, false, nil].each do |val|
251
+ it "rejects #{val.inspect} with a Puppet::Error" do
252
+ expect { type[attribute] = val }.to raise_error Puppet::Error
253
+ end
254
+ end
255
+ end
256
+
257
+ RSpec.shared_examples 'numeric parameter' do |opts|
258
+ min = opts[:min]
259
+ max = opts[:max]
260
+ [min, max].each do |val|
261
+ it "accepts #{val.inspect}" do
262
+ type[attribute] = val
263
+ expect(type[attribute]).to eq(val)
264
+ end
265
+ end
266
+
267
+ [min, min.to_s, " #{min}", " #{min} ", "#{min} "].each do |val|
268
+ it "munges #{val.inspect} to #{min}" do
269
+ type[attribute] = val
270
+ expect(type[attribute]).to eq(val.to_i)
271
+ end
272
+ end
273
+
274
+ it "munges [#{min}, #{max}] to #{min}" do
275
+ type[attribute] = [min, max]
276
+ expect(type[attribute]).to eq(min)
277
+ end
278
+ end
279
+
280
+ RSpec.shared_examples 'description property' do
281
+ it 'is a property' do
282
+ expect(described_class.attrtype(attribute)).to eq(:property)
283
+ end
284
+
285
+ ['Engineering VLAN'].each do |desc|
286
+ it "accepts #{desc.inspect}" do
287
+ type[attribute] = desc
288
+ end
289
+ end
290
+
291
+ [0, [1], { two: :three }].each do |val|
292
+ it "rejects #{val.inspect}" do
293
+ expect { type[attribute] = val }.to raise_error Puppet::ResourceError
294
+ end
295
+ end
296
+ end
297
+
298
+ RSpec.shared_examples 'speed property' do
299
+ include_examples 'property'
300
+
301
+ %w(auto 1g 10g 40g 56g 100g 100m 10m).each do |val|
302
+ it "accepts #{val.inspect}" do
303
+ type[attribute] = val
304
+ end
305
+ end
306
+
307
+ [0, 15, '0', '15', { two: :three }, 'abc'].each do |val|
308
+ it "rejects #{val.inspect} with Puppet::ResourceError" do
309
+ expect { type[attribute] = val }.to raise_error Puppet::ResourceError
310
+ end
311
+ end
312
+ end
313
+
314
+ RSpec.shared_examples 'duplex property' do
315
+ include_examples 'property'
316
+
317
+ %w(auto full half).each do |val|
318
+ it "accepts #{val.inspect}" do
319
+ type[attribute] = val
320
+ end
321
+ end
322
+
323
+ [0, 15, '0', '15', { two: :three }, 'abc'].each do |val|
324
+ it "rejects #{val.inspect} with Puppet::ResourceError" do
325
+ expect { type[attribute] = val }.to raise_error Puppet::ResourceError
326
+ end
327
+ end
328
+ end
329
+
330
+ RSpec.shared_examples 'flowcontrol property' do
331
+ it 'is a property' do
332
+ expect(described_class.attrtype(attribute)).to eq(:property)
333
+ end
334
+
335
+ %w(desired on off).each do |val|
336
+ it "accepts #{val.inspect}" do
337
+ type[attribute] = val
338
+ end
339
+
340
+ it "munges #{val.inspect} to #{val.intern.inspect}" do
341
+ type[attribute] = val
342
+ expect(type[attribute]).to eq(val.intern)
343
+ end
344
+ end
345
+
346
+ [0, 15, '0', '15', { two: :three }, 'abc'].each do |val|
347
+ it "rejects #{val.inspect} with Puppet::ResourceError" do
348
+ expect { type[attribute] = val }.to raise_error Puppet::ResourceError
349
+ end
350
+ end
351
+ end
352
+
353
+ RSpec.shared_examples 'enabled type' do
354
+ describe 'enable' do
355
+ let(:catalog) { Puppet::Resource::Catalog.new }
356
+ let(:type) do
357
+ described_class.new(name: 'emanon', catalog: catalog)
358
+ end
359
+
360
+ let(:attribute) { :enable }
361
+ subject { described_class.attrclass(attribute) }
362
+
363
+ it 'is a property' do
364
+ expect(described_class.attrtype(attribute)).to eq(:property)
365
+ end
366
+
367
+ include_examples '#doc Documentation'
368
+ include_examples 'boolean value'
369
+ end
370
+ end
371
+
372
+ RSpec.shared_examples 'string' do |opts|
373
+ attribute = opts[:attribute]
374
+ fail unless attribute
375
+ name = opts[:name] || 'emanon'
376
+
377
+ describe "#{attribute}" do
378
+ let(:catalog) { Puppet::Resource::Catalog.new }
379
+ let(:attribute) { attribute }
380
+ let(:type) { described_class.new(name: name, catalog: catalog) }
381
+ subject { described_class.attrclass(attribute) }
382
+
383
+ include_examples 'string value'
384
+ include_examples '#doc Documentation'
385
+ include_examples 'rejects values', [0, [1], { two: :three }]
386
+ end
387
+ end
388
+
389
+ RSpec.shared_examples 'string value' do
390
+ ['Engineering'].each do |val|
391
+ it "accepts #{val.inspect}" do
392
+ type[attribute] = val
393
+ end
394
+ end
395
+
396
+ [0, [1], { two: :three }].each do |val|
397
+ it "rejects #{val.inspect}" do
398
+ expect { type[attribute] = val }
399
+ .to raise_error Puppet::ResourceError, /is invalid, must be a String/
400
+ end
401
+ end
402
+
403
+ [%w(Marketing Sales)].each do |val|
404
+ it "munges #{val.inspect} to #{val.first.inspect}" do
405
+ type[attribute] = val
406
+ expect(type[attribute]).to eq(val.first)
407
+ end
408
+ end
409
+ end
410
+
411
+ RSpec.shared_examples 'rejects values' do |values|
412
+ [*values].each do |val|
413
+ it "rejects #{val.inspect} with a Puppet::Error" do
414
+ expect { type[attribute] = val }.to raise_error Puppet::Error
415
+ end
416
+ end
417
+ end
418
+
419
+ RSpec.shared_examples 'accepts values' do |values|
420
+ [*values].each do |val|
421
+ it "accepts #{val.inspect}" do
422
+ type[attribute] = val
423
+ end
424
+
425
+ it "munges #{val.inspect} to #{val.intern.inspect}" do
426
+ type[attribute] = val
427
+ expect(type[attribute]).to eq(val.intern)
428
+ end
429
+ end
430
+ end
431
+
432
+ RSpec.shared_examples 'accepts values without munging' do |values|
433
+ [*values].each do |val|
434
+ it "accepts #{val.inspect}" do
435
+ type[attribute] = val
436
+ end
437
+
438
+ it "munges #{val.inspect} to #{val.inspect} (no munging)" do
439
+ type[attribute] = val
440
+ expect(type[attribute]).to eq(val)
441
+ end
442
+ end
443
+ end
444
+
445
+ RSpec.shared_examples 'it has a string property' do |attribute|
446
+ describe "#{attribute}" do
447
+ let(:attribute) { attribute }
448
+ include_examples '#doc Documentation'
449
+ include_examples 'string value'
450
+ end
451
+ end