Skip to content

Commit 8039157

Browse files
authored
Merge pull request #155 from da-ar/transport_to_device
(PDK-1271) Allow a transport to be wrapped and used like a device
2 parents df0122e + 9baf1c8 commit 8039157

File tree

6 files changed

+85
-11
lines changed

6 files changed

+85
-11
lines changed

lib/puppet/resource_api/transport.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,22 @@ def connect(name, connection_info)
3131
validate(name, connection_info)
3232
require "puppet/transport/#{name}"
3333
class_name = name.split('_').map { |e| e.capitalize }.join
34+
# passing the copy as it may have been stripped on invalid key/values by validate
3435
Puppet::Transport.const_get(class_name).new(get_context(name), connection_info)
3536
end
3637
module_function :connect # rubocop:disable Style/AccessModifierDeclarations
3738

39+
def inject_device(name, transport)
40+
transport_wrapper = Puppet::ResourceApi::Transport::Wrapper.new(name, transport)
41+
42+
if Puppet::Util::NetworkDevice.respond_to?(:set_device)
43+
Puppet::Util::NetworkDevice.set_device(name, transport_wrapper)
44+
else
45+
Puppet::Util::NetworkDevice.instance_variable_set(:@current, transport_wrapper)
46+
end
47+
end
48+
module_function :inject_device # rubocop:disable Style/AccessModifierDeclarations
49+
3850
def self.validate(name, connection_info)
3951
init_transports
4052
require "puppet/transport/schema/#{name}" unless @transports[@environment].key? name

lib/puppet/resource_api/transport/wrapper.rb

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,28 @@
66
class Puppet::ResourceApi::Transport::Wrapper
77
attr_reader :transport, :schema
88

9-
def initialize(name, url_or_config)
10-
if url_or_config.is_a? String
11-
url = URI.parse(url_or_config)
12-
raise "Unexpected url '#{url_or_config}' found. Only file:/// URLs for configuration supported at the moment." unless url.scheme == 'file'
9+
def initialize(name, url_or_config_or_transport)
10+
if url_or_config_or_transport.is_a? String
11+
url = URI.parse(url_or_config_or_transport)
12+
raise "Unexpected url '#{url_or_config_or_transport}' found. Only file:/// URLs for configuration supported at the moment." unless url.scheme == 'file'
1313
raise "Trying to load config from '#{url.path}, but file does not exist." if url && !File.exist?(url.path)
1414
config = self.class.deep_symbolize(Hocon.load(url.path, syntax: Hocon::ConfigSyntax::HOCON) || {})
15-
else
16-
config = url_or_config
15+
elsif url_or_config_or_transport.is_a? Hash
16+
config = url_or_config_or_transport
17+
elsif transport_class?(name, url_or_config_or_transport)
18+
@transport = url_or_config_or_transport
1719
end
1820

19-
@transport = Puppet::ResourceApi::Transport.connect(name, config)
21+
@transport ||= Puppet::ResourceApi::Transport.connect(name, config)
2022
@schema = Puppet::ResourceApi::Transport.list[name]
2123
end
2224

25+
def transport_class?(name, transport)
26+
class_name = name.split('_').map { |e| e.capitalize }.join
27+
expected = Puppet::Transport.const_get(class_name).to_s
28+
expected == transport.class.to_s
29+
end
30+
2331
def facts
2432
context = Puppet::ResourceApi::PuppetContext.new(@schema)
2533
# @transport.facts + custom_facts # look into custom facts work by TP

lib/puppet/resource_api/type_definition.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,10 @@ def check_schema(resource)
154154
end
155155

156156
# Returns an array of keys that where not found in the type schema
157-
# Modifies the resource passed in, leaving only valid attributes
157+
# No longer modifies the resource passed in
158158
def check_schema_keys(resource)
159159
rejected = []
160-
resource.reject! { |key| rejected << key if key != :title && attributes.key?(key) == false }
160+
resource.reject { |key| rejected << key if key != :title && attributes.key?(key) == false }
161161
rejected
162162
end
163163

spec/puppet/resource_api/base_type_definition_spec.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,16 @@
3838

3939
context 'when resource contains invalid keys' do
4040
let(:resource) { { name: 'test_string', wibble: '1', foo: '2' } }
41+
let(:resource_copy) { { name: 'test_string', wibble: '1', foo: '2' } }
4142

4243
it 'returns an array containing the bad keys' do
4344
expect(type.check_schema_keys(resource)).to eq([:wibble, :foo])
4445
end
46+
47+
it 'does not modify the resource passed in' do
48+
type.check_schema_keys(resource)
49+
expect(resource).to eq(resource_copy)
50+
end
4551
end
4652
end
4753

@@ -84,7 +90,7 @@
8490
it 'displays up to 100 warnings' do
8591
expect(Puppet).to receive(:warning).with(message).exactly(100).times
8692
110.times do
87-
type.check_schema(resource.dup)
93+
type.check_schema(resource)
8894
end
8995
end
9096
end
@@ -121,7 +127,7 @@
121127
it 'displays up to 100 warnings' do
122128
expect(Puppet).to receive(:warning).with(message).exactly(100).times
123129
110.times do
124-
type.check_schema(resource.dup)
130+
type.check_schema(resource)
125131
end
126132
end
127133
end

spec/puppet/resource_api/transport/wrapper_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@
3232
described_class.new('wibble', config)
3333
end
3434
end
35+
36+
before(:each) do
37+
module Puppet::Transport
38+
class SomethingSomethingDarkside; end
39+
end
40+
end
41+
42+
context 'when called with a transport class' do
43+
let(:transport) { Puppet::Transport::SomethingSomethingDarkside.new }
44+
let(:instance) { described_class.new('something_something_darkside', transport) }
45+
46+
it 'will set the @transport class variable' do
47+
expect(instance.instance_variable_get(:@transport)).to eq(transport)
48+
end
49+
end
3550
end
3651

3752
describe '#facts' do

spec/puppet/resource_api/transport_spec.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,39 @@ def change_environment(name = nil)
247247
end
248248
end
249249

250+
describe '#inject_device(name, transport)' do
251+
let(:device_name) { 'wibble' }
252+
let(:transport) { instance_double(Puppet::Transport::Wibble, 'transport') }
253+
let(:wrapper) { instance_double(Puppet::ResourceApi::Transport::Wrapper, 'wrapper') }
254+
255+
before(:each) do
256+
module Puppet::Transport
257+
class Wibble; end
258+
end
259+
end
260+
261+
context 'when puppet has set_device' do
262+
it 'wraps the transport and calls set_device within NetworkDevice' do
263+
expect(Puppet::ResourceApi::Transport::Wrapper).to receive(:new).with(device_name, transport).and_return(wrapper)
264+
allow(Puppet::Util::NetworkDevice).to receive(:respond_to?).with(:set_device).and_return(true)
265+
expect(Puppet::Util::NetworkDevice).to receive(:set_device).with(device_name, wrapper)
266+
267+
described_class.inject_device(device_name, transport)
268+
end
269+
end
270+
271+
context 'when puppet does not have set_device' do
272+
it 'wraps the transport and sets it as current in NetworkDevice' do
273+
expect(Puppet::ResourceApi::Transport::Wrapper).to receive(:new).with(device_name, transport).and_return(wrapper)
274+
expect(Puppet::Util::NetworkDevice).to receive(:respond_to?).with(:set_device).and_return(false)
275+
276+
described_class.inject_device(device_name, transport)
277+
278+
expect(Puppet::Util::NetworkDevice.current).to eq(wrapper)
279+
end
280+
end
281+
end
282+
250283
describe '#validate(name, connection_info)', agent_test: true do
251284
context 'when the transport does not exist' do
252285
it { expect { described_class.send(:validate, 'wibble', {}) }.to raise_error LoadError, %r{(no such file to load|cannot load such file) -- puppet/transport/schema/wibble} }

0 commit comments

Comments
 (0)