Revision 51e26e56
Added by Dominic Cleal about 8 years ago
.sync.yml | ||
---|---|---|
options:
|
||
platforms:
|
||
- 'ruby_18'
|
||
- gem: oauth
|
||
Rakefile:
|
||
param_docs_pattern:
|
||
- manifests/cli.pp
|
Gemfile | ||
---|---|---|
gem 'json'
|
||
gem 'webmock'
|
||
gem 'addressable', '< 2.4', {"platforms"=>["ruby_18"]}
|
||
gem 'oauth'
|
||
|
||
# vim:ft=ruby
|
README.md | ||
---|---|---|
`foreman_smartproxy` can create and manage registered smart proxies in
|
||
Foreman's database. Providers:
|
||
|
||
* `rest_v2` provider uses API v2 with apipie-bindings and OAuth (default)
|
||
* `rest_v3` provider uses API v2 with Ruby HTTP library, OAuth and JSON (default)
|
||
* `rest_v2` provider uses API v2 with apipie-bindings and OAuth
|
||
* `rest` provider uses API v1 with the foreman_api gem and OAuth (deprecated)
|
||
|
||
# Contributing
|
lib/puppet/feature/json.rb | ||
---|---|---|
require 'puppet/util/feature'
|
||
|
||
Puppet.features.add(:json, :libs => %{json})
|
lib/puppet/feature/oauth.rb | ||
---|---|---|
require 'puppet/util/feature'
|
||
|
||
Puppet.features.add(:oauth, :libs => %{oauth})
|
lib/puppet/provider/foreman_resource/rest_v3.rb | ||
---|---|---|
# Base provider for other Puppet types managing Foreman resources
|
||
#
|
||
# This provider uses Net::HTTP from Ruby stdlib, JSON (stdlib on 1.9+ or the
|
||
# gem on 1.8) and the oauth gem for auth, so requiring minimal dependencies.
|
||
|
||
require 'uri'
|
||
|
||
Puppet::Type.type(:foreman_resource).provide(:rest_v3) do
|
||
# when previous providers are installed, use this one
|
||
def self.specificity
|
||
super + 2
|
||
end
|
||
|
||
def oauth_consumer_key
|
||
@oauth_consumer_key ||= begin
|
||
if resource[:consumer_key]
|
||
resource[:consumer_key]
|
||
else
|
||
begin
|
||
YAML.load_file('/etc/foreman/settings.yaml')[:oauth_consumer_key]
|
||
rescue
|
||
fail "Resource #{resource[:name]} cannot be managed: No OAuth Consumer Key available"
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
def oauth_consumer_secret
|
||
@oauth_consumer_secret ||= begin
|
||
if resource[:consumer_secret]
|
||
resource[:consumer_secret]
|
||
else
|
||
begin
|
||
YAML.load_file('/etc/foreman/settings.yaml')[:oauth_consumer_secret]
|
||
rescue
|
||
fail "Resource #{resource[:name]} cannot be managed: No OAuth consumer secret available"
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
def oauth_consumer
|
||
@consumer ||= OAuth::Consumer.new(oauth_consumer_key, oauth_consumer_secret, {
|
||
:site => resource[:base_url],
|
||
:request_token_path => '',
|
||
:authorize_path => '',
|
||
:access_token_path => '',
|
||
:timeout => resource[:timeout],
|
||
:ca_file => resource[:ssl_ca]
|
||
})
|
||
end
|
||
|
||
def generate_token
|
||
OAuth::AccessToken.new(oauth_consumer)
|
||
end
|
||
|
||
def request(method, path, params = {}, data = nil, headers = {})
|
||
base_url = resource[:base_url]
|
||
base_url += '/' unless base_url.end_with?('/')
|
||
|
||
uri = URI.join(base_url, path)
|
||
uri.query = params.map { |p,v| "#{URI.escape(p.to_s)}=#{URI.escape(v.to_s)}" }.join('&') unless params.empty?
|
||
|
||
headers = {
|
||
'Accept' => 'application/json',
|
||
'Content-Type' => 'application/json',
|
||
'foreman_user' => resource[:effective_user]
|
||
}.merge(headers)
|
||
|
||
attempts = 0
|
||
begin
|
||
debug("Making #{method} request to #{uri}")
|
||
response = oauth_consumer.request(method, uri.to_s, generate_token, {}, data, headers)
|
||
debug("Received response #{response.code} from request to #{uri}")
|
||
response
|
||
rescue Timeout::Error => te
|
||
attempts = attempts + 1
|
||
if attempts < 5
|
||
warning("Timeout calling API at #{uri}. Retrying ..")
|
||
retry
|
||
else
|
||
raise Puppet::Error.new("Timeout calling API at #{uri}", te)
|
||
end
|
||
rescue Exception => ex
|
||
raise Puppet::Error.new("Exception #{ex} in #{method} request to: #{uri}", ex)
|
||
end
|
||
end
|
||
|
||
def success?(response)
|
||
(200..299).include?(response.code.to_i)
|
||
end
|
||
|
||
def error_message(response)
|
||
JSON.parse(response.body)['error']['full_messages'].join(' ') rescue "unknown error (response #{response.code})"
|
||
end
|
||
end
|
lib/puppet/provider/foreman_smartproxy/rest_v3.rb | ||
---|---|---|
Puppet::Type.type(:foreman_smartproxy).provide(:rest_v3, :parent => Puppet::Type.type(:foreman_resource).provider(:rest_v3)) do
|
||
confine :feature => [:json, :oauth]
|
||
|
||
def proxy
|
||
@proxy ||= begin
|
||
r = request(:get, 'api/v2/smart_proxies', :search => %{name="#{resource[:name]}"})
|
||
raise Puppet::Error.new("Proxy #{resource[:name]} cannot be retrieved: #{error_message(r)}") unless success?(r)
|
||
JSON.load(r.body)['results'][0]
|
||
end
|
||
end
|
||
|
||
def id
|
||
proxy ? proxy['id'] : nil
|
||
end
|
||
|
||
def exists?
|
||
!id.nil?
|
||
end
|
||
|
||
def create
|
||
post_data = {:smart_proxy => {:name => resource[:name], :url => resource[:url]}}.to_json
|
||
r = request(:post, 'api/v2/smart_proxies', {}, post_data)
|
||
raise Puppet::Error.new("Proxy #{resource[:name]} cannot be registered: #{error_message(r)}") unless success?(r)
|
||
end
|
||
|
||
def destroy
|
||
r = request(:delete, "api/v2/smart_proxies/#{id}")
|
||
raise Puppet::Error.new("Proxy #{resource[:name]} cannot be removed: #{error_message(r)}") unless success?(r)
|
||
@proxy = nil
|
||
end
|
||
|
||
def url
|
||
proxy ? proxy['url'] : nil
|
||
end
|
||
|
||
def url=(value)
|
||
post_data = {:smart_proxy => {:url => value}}.to_json
|
||
r = request(:put, "api/v2/smart_proxies/#{id}", {}, post_data)
|
||
raise Puppet::Error.new("Proxy #{resource[:name]} cannot be updated: #{error_message(r)}") unless success?(r)
|
||
end
|
||
|
||
def refresh_features!
|
||
r = request(:put, "api/v2/smart_proxies/#{id}/refresh")
|
||
raise Puppet::Error.new("Proxy #{resource[:name]} cannot be refreshed: #{error_message(r)}") unless success?(r)
|
||
end
|
||
end
|
lib/puppet/type/foreman_resource.rb | ||
---|---|---|
Puppet::Type.newtype(:foreman_resource) do
|
||
desc 'Abstract type for Foreman resources.'
|
||
end
|
lib/puppet/type/foreman_smartproxy.rb | ||
---|---|---|
desc 'Foreman oauth consumer_secret'
|
||
end
|
||
|
||
newparam(:ssl_ca) do
|
||
desc 'Foreman SSL CA (certificate authority) for verification'
|
||
end
|
||
|
||
newproperty(:url) do
|
||
desc 'The url of the smartproxy'
|
||
isrequired
|
manifests/providers.pp | ||
---|---|---|
#
|
||
# === Parameters:
|
||
#
|
||
# $oauth:: Install oauth dependency
|
||
# type:boolean
|
||
#
|
||
# $oauth_package:: Name of oauth package
|
||
#
|
||
# $json:: Install json dependency, not required on Ruby 1.9 or higher
|
||
# type:boolean
|
||
#
|
||
# $json_package:: Name of json package
|
||
#
|
||
# $apipie_bindings:: Install apipie-bindings dependency
|
||
# type:boolean
|
||
#
|
||
... | ... | |
# $foreman_api_package:: Name of foreman_api package
|
||
#
|
||
class foreman::providers(
|
||
$oauth = $::foreman::providers::params::oauth,
|
||
$oauth_package = $::foreman::providers::params::oauth_package,
|
||
$json = $::foreman::providers::params::json,
|
||
$json_package = $::foreman::providers::params::json_package,
|
||
$apipie_bindings = $::foreman::providers::params::apipie_bindings,
|
||
$apipie_bindings_package = $::foreman::providers::params::apipie_bindings_package,
|
||
$foreman_api = $::foreman::providers::params::foreman_api,
|
||
$foreman_api_package = $::foreman::providers::params::foreman_api_package,
|
||
) inherits foreman::providers::params {
|
||
validate_bool($apipie_bindings, $foreman_api)
|
||
validate_string($apipie_bindings_package, $foreman_api_package)
|
||
validate_bool($oauth, $json, $apipie_bindings, $foreman_api)
|
||
validate_string($oauth_package, $json_package, $apipie_bindings_package, $foreman_api_package)
|
||
|
||
if $oauth {
|
||
package { $oauth_package:
|
||
ensure => installed,
|
||
}
|
||
}
|
||
|
||
if $json {
|
||
package { $json_package:
|
||
ensure => installed,
|
||
}
|
||
}
|
||
|
||
if $apipie_bindings {
|
||
package { $apipie_bindings_package:
|
manifests/providers/params.pp | ||
---|---|---|
# foreman::providers default parameters
|
||
class foreman::providers::params {
|
||
# Dependency packages for different providers supplied in this module
|
||
$apipie_bindings = true
|
||
$oauth = true
|
||
$json = (versioncmp($::rubyversion, '1.9') < 0)
|
||
$apipie_bindings = false
|
||
$foreman_api = false
|
||
|
||
# OS specific package names
|
||
case $::osfamily {
|
||
'RedHat': {
|
||
if versioncmp($::puppetversion, '4.0') >= 0 {
|
||
$oauth_package = 'puppet-agent-oauth'
|
||
} else {
|
||
$oauth_package = 'rubygem-oauth'
|
||
}
|
||
$json_package = 'rubygem-json'
|
||
$apipie_bindings_package = 'rubygem-apipie-bindings'
|
||
$foreman_api_package = 'rubygem-foreman_api'
|
||
}
|
||
'Debian': {
|
||
if versioncmp($::puppetversion, '4.0') >= 0 {
|
||
$oauth_package = 'puppet-agent-oauth'
|
||
} else {
|
||
$oauth_package = 'ruby-oauth'
|
||
}
|
||
$json_package = 'ruby-json'
|
||
$apipie_bindings_package = 'ruby-apipie-bindings'
|
||
$foreman_api_package = 'ruby-foreman-api'
|
||
}
|
||
'FreeBSD': {
|
||
$oauth_package = 'rubygem-oauth'
|
||
$json_package = 'rubygem-json'
|
||
$apipie_bindings_package = 'rubygem-apipie-bindings'
|
||
$foreman_api_package = 'rubygem-foreman_api'
|
||
}
|
||
'Linux': {
|
||
case $::operatingsystem {
|
||
'Amazon': {
|
||
if versioncmp($::puppetversion, '4.0') >= 0 {
|
||
$oauth_package = 'puppet-agent-oauth'
|
||
} else {
|
||
$oauth_package = 'rubygem-oauth'
|
||
}
|
||
$json_package = 'rubygem-json'
|
||
$apipie_bindings_package = 'rubygem-apipie-bindings'
|
||
$foreman_api_package = 'rubygem-foreman_api'
|
||
}
|
spec/classes/foreman_providers_spec.rb | ||
---|---|---|
|
||
case facts[:osfamily]
|
||
when 'RedHat'
|
||
oauth_os = 'rubygem-oauth'
|
||
json = 'rubygem-json'
|
||
apipie_bindings = 'rubygem-apipie-bindings'
|
||
foreman_api = 'rubygem-foreman_api'
|
||
when 'Debian'
|
||
oauth_os = 'ruby-oauth'
|
||
json = 'ruby-json'
|
||
apipie_bindings = 'ruby-apipie-bindings'
|
||
foreman_api = 'ruby-foreman-api'
|
||
end
|
||
|
||
context 'with defaults' do
|
||
it { should contain_package(apipie_bindings).with_ensure('installed') }
|
||
if facts[:rubyversion].start_with?('1.8')
|
||
it { should contain_package(json).with_ensure('installed') }
|
||
else
|
||
it { should_not contain_package(json) }
|
||
end
|
||
it { should_not contain_package(apipie_bindings) }
|
||
it { should_not contain_package(foreman_api) }
|
||
end
|
||
|
||
context 'with defaults on Puppet 3' do
|
||
let(:facts) { facts.merge(:puppetversion => '3.8.6') }
|
||
it { should contain_package(oauth_os).with_ensure('installed') }
|
||
end
|
||
|
||
context 'with defaults on Puppet 4' do
|
||
let(:facts) { facts.merge(:puppetversion => '4.0.0') }
|
||
it { should contain_package('puppet-agent-oauth').with_ensure('installed') }
|
||
end
|
||
|
||
context 'with foreman_api only' do
|
||
let(:params) do {
|
||
'apipie_bindings' => false,
|
||
... | ... | |
it { should_not contain_package(apipie_bindings) }
|
||
it { should contain_package(foreman_api).with_ensure('installed') }
|
||
end
|
||
|
||
context 'with apipie_bindings => true' do
|
||
let(:params) do {
|
||
'apipie_bindings' => true,
|
||
} end
|
||
|
||
it { should contain_package(apipie_bindings).with_ensure('installed') }
|
||
end
|
||
|
||
context 'with json => true' do
|
||
let(:params) do {
|
||
'json' => true,
|
||
} end
|
||
|
||
it { should contain_package(json).with_ensure('installed') }
|
||
end
|
||
|
||
context 'with oauth => true' do
|
||
let(:facts) { facts.merge(:puppetversion => '3.8.6') }
|
||
let(:params) do {
|
||
'oauth' => true,
|
||
} end
|
||
|
||
it { should contain_package(oauth_os).with_ensure('installed') }
|
||
end
|
||
end
|
||
end
|
||
end
|
spec/classes/foreman_spec.rb | ||
---|---|---|
let :pre_condition do
|
||
"class { 'foreman': }
|
||
class { 'foreman::providers':
|
||
apipie_bindings => true,
|
||
apipie_bindings_package => 'apipie-bindings',
|
||
}"
|
||
end
|
spec/unit/foreman_resource_rest_v3_spec.rb | ||
---|---|---|
require 'spec_helper'
|
||
require 'oauth'
|
||
|
||
provider_class = Puppet::Type.type(:foreman_resource).provider(:rest_v3)
|
||
describe provider_class do
|
||
let(:resource) do
|
||
mock('resource')
|
||
end
|
||
|
||
let(:provider) do
|
||
provider = provider_class.new
|
||
provider.resource = resource
|
||
provider
|
||
end
|
||
|
||
describe '#generate_token' do
|
||
it 'returns an OAuth::AccessToken' do
|
||
provider.expects(:oauth_consumer).returns(OAuth::Consumer.new('test', 'test'))
|
||
expect(provider.generate_token).to be_an(OAuth::AccessToken)
|
||
end
|
||
end
|
||
|
||
describe '#oauth_consumer' do
|
||
it 'returns an OAuth::Consumer' do
|
||
provider.expects(:oauth_consumer_key).returns('oauth_key')
|
||
provider.expects(:oauth_consumer_secret).returns('oauth_secret')
|
||
resource.expects(:[]).with(:base_url).returns('https://foreman.example.com')
|
||
resource.expects(:[]).with(:ssl_ca).returns('/etc/foreman/ssl/ca.pem')
|
||
resource.expects(:[]).with(:timeout).returns(500)
|
||
consumer = provider.oauth_consumer
|
||
expect(consumer).to be_an(OAuth::Consumer)
|
||
expect(consumer.site).to eq('https://foreman.example.com')
|
||
expect(consumer.options[:ca_file]).to eq('/etc/foreman/ssl/ca.pem')
|
||
expect(consumer.options[:timeout]).to eq(500)
|
||
end
|
||
end
|
||
|
||
describe '#oauth_consumer_key' do
|
||
it 'uses resource consumer_key' do
|
||
resource.expects(:[]).twice.with(:consumer_key).returns('oauth_key')
|
||
expect(provider.oauth_consumer_key).to eq('oauth_key')
|
||
end
|
||
|
||
it 'uses settings.yaml if resource has no consumer_key' do
|
||
resource.expects(:[]).with(:consumer_key).returns(nil)
|
||
YAML.expects(:load_file).with('/etc/foreman/settings.yaml').returns(:oauth_consumer_key => 'oauth_key')
|
||
expect(provider.oauth_consumer_key).to eq('oauth_key')
|
||
end
|
||
end
|
||
|
||
describe '#oauth_consumer_secret' do
|
||
it 'uses resource consumer_secret' do
|
||
resource.expects(:[]).twice.with(:consumer_secret).returns('oauth_secret')
|
||
expect(provider.oauth_consumer_secret).to eq('oauth_secret')
|
||
end
|
||
|
||
it 'uses settings.yaml if resource has no consumer_secret' do
|
||
resource.expects(:[]).with(:consumer_secret).returns(nil)
|
||
YAML.expects(:load_file).with('/etc/foreman/settings.yaml').returns(:oauth_consumer_secret => 'oauth_secret')
|
||
expect(provider.oauth_consumer_secret).to eq('oauth_secret')
|
||
end
|
||
end
|
||
|
||
describe '#request' do
|
||
before do
|
||
resource.expects(:[]).with(:base_url).returns(base_url)
|
||
resource.expects(:[]).with(:effective_user).returns(effective_user)
|
||
provider.expects(:oauth_consumer).at_least_once.returns(consumer)
|
||
end
|
||
|
||
let(:base_url) { 'https://foreman.example.com' }
|
||
let(:consumer) { mock('oauth_consumer') }
|
||
let(:effective_user) { 'admin' }
|
||
|
||
it 'makes request via consumer and returns response' do
|
||
response = mock(:code => '200')
|
||
consumer.expects(:request).with(:get, 'https://foreman.example.com/api/v2/example', is_a(OAuth::AccessToken), {}, nil, is_a(Hash)).returns(response)
|
||
expect(provider.request(:get, 'api/v2/example')).to eq(response)
|
||
end
|
||
|
||
it 'specifies foreman_user header' do
|
||
consumer.expects(:request).with(:get, anything, anything, anything, anything, has_entry('foreman_user', 'admin')).returns(mock(:code => '200'))
|
||
provider.request(:get, 'api/v2/example')
|
||
end
|
||
|
||
it 'passes parameters' do
|
||
consumer.expects(:request).with(:get, 'https://foreman.example.com/api/v2/example?test=value', anything, anything, anything, anything).returns(mock(:code => '200'))
|
||
provider.request(:get, 'api/v2/example', :test => 'value')
|
||
end
|
||
|
||
it 'passes data' do
|
||
consumer.expects(:request).with(:get, anything, anything, anything, 'test', anything).returns(mock(:code => '200'))
|
||
provider.request(:get, 'api/v2/example', {}, 'test')
|
||
end
|
||
|
||
it 'merges headers' do
|
||
consumer.expects(:request).with(:get, anything, anything, anything, anything, has_entries('test' => 'value', 'Accept' => 'application/json')).returns(mock(:code => '200'))
|
||
provider.request(:get, 'api/v2/example', {}, nil, {'test' => 'value'})
|
||
end
|
||
|
||
describe 'with non-root base URL' do
|
||
let(:base_url) { 'https://foreman.example.com/foreman' }
|
||
it 'concatenates the base and request URLs' do
|
||
consumer.expects(:request).with(:get, 'https://foreman.example.com/foreman/api/v2/example', anything, anything, anything, anything).returns(mock(:code => '200'))
|
||
provider.request(:get, 'api/v2/example')
|
||
end
|
||
end
|
||
|
||
it 'retries on timeout' do
|
||
consumer.expects(:request).twice.with(any_parameters).raises(Timeout::Error).then.returns(mock(:code => '200'))
|
||
provider.request(:get, 'api/v2/example')
|
||
end
|
||
|
||
it 'fails resource after multiple timeouts' do
|
||
consumer.expects(:request).times(5).with(any_parameters).
|
||
raises(Timeout::Error).then.
|
||
raises(Timeout::Error).then.
|
||
raises(Timeout::Error).then.
|
||
raises(Timeout::Error).then.
|
||
raises(Timeout::Error)
|
||
expect { provider.request(:get, 'api/v2/example') }.to raise_error(Puppet::Error, /Timeout/)
|
||
end
|
||
|
||
it 'fails resource with network errors' do
|
||
consumer.expects(:request).raises(Errno::ECONNRESET)
|
||
expect { provider.request(:get, 'api/v2/example') }.to raise_error(Puppet::Error, /Exception/)
|
||
end
|
||
end
|
||
|
||
describe '#success?(response)' do
|
||
it 'returns true for response code in 2xx' do
|
||
expect(provider.success?(mock(:code => '256'))).to eq(true)
|
||
end
|
||
|
||
it 'returns false for non-2xx response code' do
|
||
expect(provider.success?(mock(:code => '404'))).to eq(false)
|
||
end
|
||
end
|
||
|
||
describe '#error_message(response)' do
|
||
it 'returns array of errors from JSON' do
|
||
expect(provider.error_message(mock(:body => '{"error":{"full_messages":["error1","error2"]}}'))).to eq('error1 error2')
|
||
end
|
||
|
||
it 'returns message for missing error messages' do
|
||
expect(provider.error_message(mock(:body => '{}', :code => 404))).to eq('unknown error (response 404)')
|
||
end
|
||
end
|
||
end
|
spec/unit/foreman_smartproxy_rest_v3_spec.rb | ||
---|---|---|
require 'spec_helper'
|
||
|
||
provider_class = Puppet::Type.type(:foreman_smartproxy).provider(:rest_v3)
|
||
describe provider_class do
|
||
let(:resource) do
|
||
Puppet::Type.type(:foreman_smartproxy).new(
|
||
:name => 'proxy.example.com',
|
||
:url => 'https://proxy.example.com:8443',
|
||
:base_url => 'https://foreman.example.com',
|
||
:consumer_key => 'oauth_key',
|
||
:consumer_secret => 'oauth_secret',
|
||
:effective_user => 'admin'
|
||
)
|
||
end
|
||
|
||
let(:provider) do
|
||
provider = provider_class.new
|
||
provider.resource = resource
|
||
provider
|
||
end
|
||
|
||
describe '#create' do
|
||
it 'sends POST request' do
|
||
provider.expects(:request).with(:post, 'api/v2/smart_proxies', {}, is_a(String)).returns(mock(:code => '201'))
|
||
provider.create
|
||
end
|
||
end
|
||
|
||
describe '#destroy' do
|
||
it 'sends DELETE request' do
|
||
provider.expects(:id).returns(1)
|
||
provider.expects(:request).with(:delete, 'api/v2/smart_proxies/1').returns(mock(:code => '200'))
|
||
provider.destroy
|
||
end
|
||
end
|
||
|
||
describe '#exists?' do
|
||
it 'returns true when ID is present' do
|
||
provider.expects(:id).returns(1)
|
||
expect(provider.exists?).to be true
|
||
end
|
||
|
||
it 'returns nil when ID is absent' do
|
||
provider.expects(:id).returns(nil)
|
||
expect(provider.exists?).to be false
|
||
end
|
||
end
|
||
|
||
describe '#id' do
|
||
it 'returns ID from proxy hash' do
|
||
provider.expects(:proxy).twice.returns({'id' => 1, 'name' => 'proxy.example.com'})
|
||
expect(provider.id).to eq(1)
|
||
end
|
||
|
||
it 'returns nil when proxy is absent' do
|
||
provider.expects(:proxy).returns(nil)
|
||
expect(provider.id).to be_nil
|
||
end
|
||
end
|
||
|
||
describe '#proxy' do
|
||
it 'returns proxy hash from API results' do
|
||
provider.expects(:request).with(:get, 'api/v2/smart_proxies', :search => 'name="proxy.example.com"').returns(
|
||
mock('response', :body => {:results => [{:id => 1, :name => 'proxy.example.com'}]}.to_json, :code => '200')
|
||
)
|
||
expect(provider.proxy['id']).to eq(1)
|
||
expect(provider.proxy['name']).to eq('proxy.example.com')
|
||
end
|
||
end
|
||
|
||
describe '#refresh_features!' do
|
||
it 'sends PUT request to /refresh' do
|
||
provider.expects(:id).returns(1)
|
||
provider.expects(:request).with(:put, 'api/v2/smart_proxies/1/refresh').returns(mock(:code => '200'))
|
||
provider.refresh_features!
|
||
end
|
||
end
|
||
|
||
describe '#url' do
|
||
it 'returns ID from proxy hash' do
|
||
provider.expects(:proxy).twice.returns({'id' => 1, 'url' => 'https://proxy.example.com:8443'})
|
||
expect(provider.url).to eq('https://proxy.example.com:8443')
|
||
end
|
||
|
||
it 'returns nil when proxy is absent' do
|
||
provider.expects(:proxy).returns(nil)
|
||
expect(provider.url).to be_nil
|
||
end
|
||
end
|
||
|
||
describe '#url=' do
|
||
it 'sends PUT request' do
|
||
provider.expects(:id).returns(1)
|
||
provider.expects(:request).with(:put, 'api/v2/smart_proxies/1', {}, includes('"url":"https://new.example.com:8443"')).returns(mock(:code => '200'))
|
||
provider.url = 'https://new.example.com:8443'
|
||
end
|
||
end
|
||
end
|
Also available in: Unified diff
fixes #14455 - add rest_v3 smart proxy provider using OAuth gem
The new provider has fewer dependencies than rest_v2 (with
apipie-bindings), therefore it's easier to package the dependencies for
an AIO version of Puppet. puppet-agent-oauth will be provided by the
Foreman repositories to install the oauth gem into the AIO environment.
All Ruby 1.9+ installations, including Puppet AIO packages, won't need
a JSON package as they include a bundled 'json' library.
The provider's been split into a base type+provider (supported as per
PUP-2458) to make it easier to add and update other types in future.
The addition of the SSL CA in the type is required with the OAuth gem's
HTTP request support, as it enables verification by default when it
detects CA bundles in common locations.
Thanks to @liamjbennett, whose work this is partly based on.
closes GH-432