Skip to content

Commit df0122e

Browse files
authored
Merge pull request #154 from da-ar/transport_fixes
Transport support for device specific providers
2 parents 92988d9 + 203f633 commit df0122e

File tree

5 files changed

+71
-5
lines changed

5 files changed

+71
-5
lines changed

lib/puppet/resource_api.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
require 'puppet/resource_api/puppet_context' unless RUBY_PLATFORM == 'java'
77
require 'puppet/resource_api/read_only_parameter'
88
require 'puppet/resource_api/transport'
9+
require 'puppet/resource_api/transport/wrapper'
910
require 'puppet/resource_api/type_definition'
1011
require 'puppet/resource_api/value_creator'
1112
require 'puppet/resource_api/version'
@@ -40,7 +41,12 @@ def register_type(definition)
4041
# Keeps a copy of the provider around. Weird naming to avoid clashes with puppet's own `provider` member
4142
define_singleton_method(:my_provider) do
4243
@my_provider ||= Hash.new { |hash, key| hash[key] = Puppet::ResourceApi.load_provider(definition[:name]).new }
43-
@my_provider[Puppet::Util::NetworkDevice.current.class]
44+
45+
if Puppet::Util::NetworkDevice.current.is_a? Puppet::ResourceApi::Transport::Wrapper
46+
@my_provider[Puppet::Util::NetworkDevice.current.transport.class]
47+
else
48+
@my_provider[Puppet::Util::NetworkDevice.current.class]
49+
end
4450
end
4551

4652
# make the provider available in the instance's namespace
@@ -412,8 +418,10 @@ def load_provider(type_name)
412418
type_name_sym = type_name.to_sym
413419
device_name = if Puppet::Util::NetworkDevice.current.nil?
414420
nil
415-
else
421+
elsif Puppet::Util::NetworkDevice.current.is_a? Puppet::ResourceApi::Transport::Wrapper
416422
# extract the device type from the currently loaded device's class
423+
Puppet::Util::NetworkDevice.current.schema.name
424+
else
417425
Puppet::Util::NetworkDevice.current.class.name.split('::')[-2].downcase
418426
end
419427
device_class_name = class_name_from_type_name(device_name)

lib/puppet/resource_api/transport.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def connect(name, connection_info)
3737

3838
def self.validate(name, connection_info)
3939
init_transports
40-
require "puppet/transport/schema/#{name}" unless @transports.key? name
40+
require "puppet/transport/schema/#{name}" unless @transports[@environment].key? name
4141
transport_schema = @transports[@environment][name]
4242
if transport_schema.nil?
4343
raise Puppet::DevError, 'Transport for `%{target}` not registered with `%{environment}`' % {

lib/puppet/resource_api/transport/wrapper.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ def respond_to_missing?(name, _include_private)
3232

3333
def method_missing(method_name, *args, &block)
3434
if @transport.respond_to? method_name
35-
puts "Delegating #{method_name}"
3635
@transport.send(method_name, *args, &block)
3736
else
3837
super

spec/puppet/resource_api/transport_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ def change_environment(name = nil)
268268

269269
described_class.register(schema)
270270

271-
expect(described_class).to receive(:require).with('puppet/transport/schema/validate')
271+
expect(described_class).not_to receive(:require).with('puppet/transport/schema/validate')
272272
expect(schema_def).to receive(:check_schema).with('connection_info').and_return(nil)
273273
expect(schema_def).to receive(:validate).with('connection_info').and_return(nil)
274274

spec/puppet/resource_api_spec.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,37 @@ class OtherDevice; end
12161216
it('loads the device provider') { expect(described_class.load_provider('multi_provider').name).to eq 'Puppet::Provider::MultiProvider::SomeDevice' }
12171217
end
12181218
end
1219+
1220+
context 'with a transport configured' do
1221+
let(:definition) { { name: 'multi_provider', attributes: {} } }
1222+
let(:transport) { instance_double('Puppet::ResourceApi::Transport::Wrapper', 'transport') }
1223+
let(:schema_def) { instance_double('Puppet::ResourceApi::TransportSchemaDef', 'schema_def') }
1224+
1225+
before(:each) do
1226+
allow(Puppet::Util::NetworkDevice).to receive(:current).with(no_args).and_return(transport)
1227+
allow(transport).to receive(:is_a?).with(Puppet::ResourceApi::Transport::Wrapper).and_return(true)
1228+
allow(transport).to receive(:schema).and_return(schema_def)
1229+
allow(schema_def).to receive(:name).and_return(schema_name)
1230+
1231+
module ::Puppet::Provider::MultiProvider
1232+
class MultiProvider; end
1233+
class SomeDevice; end
1234+
class OtherDevice; end
1235+
end
1236+
end
1237+
1238+
context 'with no device-specific provider' do
1239+
let(:schema_name) { 'multi_provider' }
1240+
1241+
it('loads the default provider') { expect(described_class.load_provider('multi_provider').name).to eq 'Puppet::Provider::MultiProvider::MultiProvider' }
1242+
end
1243+
1244+
context 'with a device-specific provider' do
1245+
let(:schema_name) { 'some_device' }
1246+
1247+
it('loads the device provider') { expect(described_class.load_provider('multi_provider').name).to eq 'Puppet::Provider::MultiProvider::SomeDevice' }
1248+
end
1249+
end
12191250
end
12201251

12211252
context 'with a provider that does canonicalization', agent_test: true do
@@ -1601,6 +1632,10 @@ def set(_context, changes)
16011632
stub_const('Puppet::Provider::Remoter::Remoter', provider_class)
16021633
allow(provider_class).to receive(:new).and_return(provider)
16031634
Puppet.settings[:strict] = :warning
1635+
1636+
module ::Puppet::Transport
1637+
class Wibble; end
1638+
end
16041639
end
16051640

16061641
it 'is seen as a supported feature' do
@@ -1618,6 +1653,30 @@ def set(_context, changes)
16181653
expect(type.context.type).to be_feature('remote_resource')
16191654
end
16201655
end
1656+
1657+
describe '#self.my_provider' do
1658+
subject(:type) { Puppet::Type.type(:remoter) }
1659+
1660+
let(:instance) { type.new(name: 'remote_thing', test_string: 'wibble') }
1661+
let(:wrapper) { instance_double('Puppet::ResourceApi::Transport::Wrapper', 'wrapper') }
1662+
let(:transport) { instance_double('Puppet::Transport::Wibble', 'transport') }
1663+
1664+
before(:each) do
1665+
allow(described_class).to receive(:load_provider).and_return(provider)
1666+
allow(provider).to receive(:new).and_return(provider)
1667+
end
1668+
1669+
context 'when a transport is returned by NetworkDevice.current' do
1670+
it 'stores the provider with the the name of the transport' do
1671+
allow(Puppet::Util::NetworkDevice).to receive(:current).and_return(wrapper)
1672+
allow(wrapper).to receive(:is_a?).with(Puppet::ResourceApi::Transport::Wrapper).and_return(true)
1673+
allow(wrapper).to receive(:transport).and_return(transport)
1674+
allow(transport).to receive(:class).and_return(Puppet::Transport::Wibble)
1675+
1676+
expect(instance.my_provider).to eq provider
1677+
end
1678+
end
1679+
end
16211680
end
16221681

16231682
context 'with a `supports_noop` provider', agent_test: true do

0 commit comments

Comments
 (0)