Skip to content

Commit

Permalink
(PDK-506) Resource API-based provider template
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidS committed Jan 22, 2018
1 parent 9b3a7f4 commit 1e36264
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
21 changes: 21 additions & 0 deletions object_templates/provider.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'puppet/resource_api'

Puppet::ResourceApi.register_type(
name: '<%= name %>',
docs: <<-EOS,
This type provides Puppet with the capabilities to manage ...
EOS
features: [],
attributes: {
ensure: {
type: 'Enum[present, absent]',
desc: 'Whether this apt key should be present or absent on the target system.',
default: 'present',
},
name: {
type: 'String',
desc: 'The name of the resource you want to manage.',
behaviour: :namevar,
},
},
)
35 changes: 35 additions & 0 deletions object_templates/provider_addon.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'puppet/resource_api'
require 'puppet/resource_api/command'
require 'puppet/resource_api/simple_provider'

# Implementation for the <%= name %> type using the Resource API.
class Puppet::Provider::<%= provider_class %>::<%= provider_class %> < Puppet::ResourceApi::SimpleProvider
def initialize
@echo_cmd = Puppet::ResourceApi::Command.new 'echo'
end

def get(context)
# nonsensical resource emulation for this example
@echo_cmd.run(context).stdout.split('').each do |c|
{
name: c,
ensure: :present,
}
end || []
end

def create(context, name, should)
# nonsensical resource emulation for this example
@echo_cmd.run(context, "create: #{name}, #{should.inspect}")
end

def update(context, name, should)
# nonsensical resource emulation for this example
@echo_cmd.run(context, "update: #{name}, #{should.inspect}")
end

def delete(context, name)
# nonsensical resource emulation for this example
@echo_cmd.run(context, "delete: #{name}")
end
end
84 changes: 84 additions & 0 deletions object_templates/provider_spec.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
require 'spec_helper'

# TODO: needs some cleanup/helper to avoid this misery
module Puppet::Provider::<%= provider_class %>; end
require 'puppet/provider/<%= name %>/<%= name %>'

RSpec.describe Puppet::Provider::<%= provider_class %>::<%= provider_class %> do
subject(:provider) { described_class.new }

let(:context) { instance_double('Puppet::ResourceApi::BaseContext', 'context') }
let(:echo_cmd) { instance_double('Puppet::ResourceApi::Command', 'echo_cmd') }

before(:each) do
allow(context).to receive(:is_a?).with(Puppet::ResourceApi::BaseContext).and_return(true)
allow(Puppet::ResourceApi::Command).to receive(:new).with('echo').and_return(echo_cmd)

# the provider should never call into the system on its own
expect(provider).not_to receive(:`) # rubocop:disable RSpec/ExpectInHook,RSpec/MessageSpies
end

describe '#get' do
before(:each) do
# fake output for the tests
allow(echo_cmd).to receive(:run)
.with(context)
.and_return(OpenStruct.new(stdout: resources))
end

context 'with no resources on the system' do
let(:resources) { '' }

it 'returns an empty list' do
expect(provider.get(context)).to eq []
end
end

context 'with some resources on the system' do
let(:resources) { 'abc' }

it 'processes resources' do
expect(provider.get(context)).to eq %w[a b c]
end
end
end

describe 'create(context, name, should)' do
it 'creates the resource' do
allow(context).to receive(:creating).and_yield
expect(echo_cmd).to receive(:run)
.with(context, 'create: a, {:name=>"a", :ensure=>"present"}')

provider.set(context, a: {
is: { name: 'a', ensure: 'absent' },
should: { name: 'a', ensure: 'present' },
})
end
end

describe 'update(context, name, should)' do
it 'updates the resource' do
allow(context).to receive(:updating).and_yield
expect(echo_cmd).to receive(:run)
.with(context, 'update: a, {:name=>"a", :ensure=>"present"}')

provider.set(context, a: {
is: { name: 'a', ensure: 'present' },
should: { name: 'a', ensure: 'present' },
})
end
end

describe 'delete(context, name, should)' do
it 'deletes the resource' do
allow(context).to receive(:deleting).and_yield
expect(echo_cmd).to receive(:run)
.with(context, 'delete: a')

provider.set(context, a: {
is: { name: 'a', ensure: 'present' },
should: { name: 'a', ensure: 'absent' },
})
end
end
end

0 comments on commit 1e36264

Please sign in to comment.