arista-eos 1.1.0

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