-
Notifications
You must be signed in to change notification settings - Fork 271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add domains and subnets as puppet resources that interact with the Foreman API #1047
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
Puppet::Type.type(:foreman_domain).provide(:rest_v3, :parent => Puppet::Type.type(:foreman_resource).provider(:rest_v3)) do | ||
confine :feature => [:json, :oauth] | ||
|
||
def exists? | ||
!id.nil? | ||
end | ||
|
||
def create | ||
path = "api/v2/domains" | ||
payload = { | ||
:domain => { | ||
:name => resource[:name], | ||
:fullname => resource[:fullname], | ||
:dns_id => search('smart_proxies', resource[:dns_id]), | ||
} | ||
} | ||
|
||
req = request(:post, path, {}, payload.to_json) | ||
|
||
unless success?(req) | ||
error_string = "Error making POST request to Foreman at #{request_uri(path)}: #{error_message(req)}" | ||
raise Puppet::Error.new(error_string) | ||
end | ||
end | ||
|
||
def destroy | ||
req = request(:delete, destroy_path, {}) | ||
|
||
unless success?(req) | ||
error_string = "Error making DELETE request to Foreman at #{request_uri(path)}: #{error_message(req)}" | ||
raise Puppet::Error.new(error_string) | ||
end | ||
end | ||
|
||
def id | ||
domain['id'] if domain | ||
end | ||
|
||
def domain | ||
@domain ||= begin | ||
path = 'api/v2/domains' | ||
req = request(:get, path, :search => %{name="#{resource[:name]}"}) | ||
|
||
unless success?(req) | ||
error_string = "Error making GET request to Foreman at #{request_uri(path)}: #{error_message(req)}" | ||
raise Puppet::Error.new(error_string) | ||
end | ||
|
||
JSON.load(req.body)['results'].first | ||
end | ||
end | ||
|
||
private | ||
|
||
def destroy_path | ||
"api/v2/domains/#{id}" | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
Puppet::Type.type(:foreman_subnet).provide(:rest_v3, :parent => Puppet::Type.type(:foreman_resource).provider(:rest_v3)) do | ||
confine :feature => [:json, :oauth] | ||
|
||
def exists? | ||
!id.nil? | ||
end | ||
|
||
def create | ||
path = "api/v2/subnets" | ||
payload = { | ||
:subnet => { | ||
:name => resource[:name], | ||
:description => resource[:description], | ||
:network_type => resource[:network_type], | ||
:network => resource[:network], | ||
:cidr => resource[:cidr], | ||
:mask => resource[:mask], | ||
:gateway => resource[:gateway], | ||
:dns_primary => resource[:dns_primary], | ||
:dns_secondary => resource[:dns_secondary], | ||
:ipam => !resource[:ipam].nil? ? resource[:ipam] : 'None', | ||
:from => resource[:from], | ||
:to => resource[:to], | ||
:vlanid => resource[:vlanid], | ||
:domain_ids => resource[:domain_ids].map {|s| search('domains', s)}, | ||
:dhcp_id => search('smart_proxies', resource[:dhcp_id]), | ||
:tftp_id => search('smart_proxies', resource[:tftp_id]), | ||
:httpboot_id => search('smart_proxies', resource[:httpboot_id]), | ||
:dns_id => search('smart_proxies', resource[:dns_id]), | ||
:template_id => search('smart_proxies', resource[:template_id]), | ||
:bmc_id => search('smart_proxies', resource[:bmc_id]), | ||
} | ||
} | ||
|
||
req = request(:post, path, {}, payload.to_json) | ||
|
||
unless success?(req) | ||
error_string = "Error making POST request to Foreman at #{request_uri(path)}: #{error_message(req)}" | ||
raise Puppet::Error.new(error_string) | ||
end | ||
end | ||
|
||
def destroy | ||
req = request(:delete, destroy_path, {}) | ||
|
||
unless success?(req) | ||
error_string = "Error making DELETE request to Foreman at #{request_uri(path)}: #{error_message(req)}" | ||
raise Puppet::Error.new(error_string) | ||
end | ||
end | ||
|
||
def id | ||
subnet['id'] if subnet | ||
end | ||
|
||
def subnet | ||
@subnet ||= begin | ||
path = 'api/v2/subnets' | ||
req = request(:get, path, :search => %{name="#{resource[:name]}"}) | ||
|
||
unless success?(req) | ||
error_string = "Error making GET request to Foreman at #{request_uri(path)}: #{error_message(req)}" | ||
raise Puppet::Error.new(error_string) | ||
end | ||
|
||
JSON.load(req.body)['results'].first | ||
end | ||
end | ||
|
||
private | ||
|
||
def destroy_path | ||
"api/v2/subnets/#{id}" | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require_relative '../../puppet_x/foreman/common' | ||
|
||
Puppet::Type.newtype(:foreman_domain) do | ||
desc 'foreman_domain creates a domain in foreman.' | ||
|
||
instance_eval(&PuppetX::Foreman::Common::REST_API_COMMON_PARAMS) | ||
instance_eval(&PuppetX::Foreman::Common::FOREMAN_DOMAIN_PARAMS) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you're not reusing these (and it looks like you're not), it's better to inline them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you help me out here with what you're looking for? I'm more of a C, C++, Python programmer, very new to Ruby. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The request is to move the methods being generated by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stated another way, the methods in |
||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require_relative '../../puppet_x/foreman/common' | ||
|
||
Puppet::Type.newtype(:foreman_subnet) do | ||
desc 'foreman_subnet creates a subnet in foreman.' | ||
|
||
instance_eval(&PuppetX::Foreman::Common::REST_API_COMMON_PARAMS) | ||
instance_eval(&PuppetX::Foreman::Common::FOREMAN_SUBNET_PARAMS) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can also be inlined, like domain. |
||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
require 'spec_helper' | ||
|
||
describe Puppet::Type.type(:foreman_domain).provider(:rest_v3) do | ||
let(:resource) do | ||
Puppet::Type.type(:foreman_domain).new( | ||
:name => 'example.com', | ||
:fullname => 'domain entry for example.com', | ||
:base_url => 'https://foreman.example.com', | ||
:consumer_key => 'oauth_key', | ||
:consumer_secret => 'oauth_secret', | ||
:effective_user => 'admin' | ||
) | ||
end | ||
|
||
let(:provider) do | ||
provider = described_class.new | ||
provider.resource = resource | ||
provider | ||
end | ||
|
||
describe '#create' do | ||
it 'sends POST request' do | ||
expect(provider).to receive(:request).with(:post, 'api/v2/domains', {}, kind_of(String)).and_return( | ||
double(:code => '201', :body => {'id' => 1, 'name' => 'example.com', 'fullname' => 'domain entry for example.com'}) | ||
) | ||
provider.create | ||
end | ||
end | ||
|
||
describe '#destroy' do | ||
it 'sends DELETE request' do | ||
expect(provider).to receive(:id).and_return(1) | ||
expect(provider).to receive(:request).with(:delete, 'api/v2/domains/1', {}).and_return(double(:code => '204')) | ||
provider.destroy | ||
end | ||
end | ||
|
||
describe '#exists?' do | ||
it 'returns true when domain is marked as a foreman domain' do | ||
expect(provider).to receive(:domain).twice.and_return({"id" => 1}) | ||
expect(provider.exists?).to be true | ||
end | ||
|
||
it 'returns nil when domain does not exist' do | ||
expect(provider).to receive(:domain).and_return(nil) | ||
expect(provider.exists?).to be false | ||
end | ||
end | ||
|
||
describe '#id' do | ||
it 'returns ID from domain hash' do | ||
expect(provider).to receive(:domain).twice.and_return({'id' => 1}) | ||
expect(provider.id).to eq(1) | ||
end | ||
|
||
it 'returns nil when domain is absent' do | ||
expect(provider).to receive(:domain).and_return(nil) | ||
expect(provider.id).to be_nil | ||
end | ||
end | ||
|
||
describe '#domain' do | ||
it 'returns domain hash from API results' do | ||
expect(provider).to receive(:request).with(:get, 'api/v2/domains', :search => 'name="example.com"').and_return( | ||
double('response', :body => {:results => [{:id => 1, :name => 'example.com'}]}.to_json, :code => '200') | ||
) | ||
expect(provider.domain['id']).to eq(1) | ||
expect(provider.domain['name']).to eq('example.com') | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this creates some redundancy. We already have
request
which accepts aparams
hash so if anything this should pass search as a hash. That properly escapes it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ekohl is there an example of using
request
I could have a look at to test with and make sure this works with it?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some examples of using #request in its spec coverage: https://github.com/theforeman/puppet-foreman/blob/master/spec/unit/foreman_resource_rest_v3_spec.rb#L64-L131