Add utility function to compose URL from elements

This change introduces the generic function to compose URL from
elements. This can be used to compose endpoint url or coordination
backend url.

Change-Id: I77469f9dca817c4ab2af939de9bd74dce122c3d8
This commit is contained in:
Takashi Kajinami 2023-03-20 17:15:12 +09:00
parent cf3f23fc09
commit 5cb78b4d25
3 changed files with 187 additions and 0 deletions

View File

@ -0,0 +1,66 @@
Puppet::Functions.create_function(:os_url) do
def os_url(*args)
require 'erb'
if (args.size != 1) then
raise(Puppet::ParseError, "os_url(): Wrong number of arguments " +
"given (#{args.size} for 1)")
end
v = args[0]
klass = v.class
unless klass == Hash
raise(Puppet::ParseError, "os_url(): Requires an hash, got #{klass}")
end
v.keys.each do |key|
klass = (key == 'query') ? Hash : String
unless (v[key].class == klass) or (v[key] == :undef)
raise(Puppet::ParseError, "os_url(): #{key} should be a #{klass}")
end
end
parts = {}
if v.include?('scheme')
parts[:scheme] = v['scheme']
else
parts[:scheme] = 'http'
end
if v.include?('host')
parts[:host] = v['host']
end
if v.include?('port')
if v.include?('host')
parts[:port] = v['port'].to_i
else
raise(Puppet::ParseError, 'os_url(): host is required with port')
end
end
if v.include?('path')
parts[:path] = v['path']
end
userinfo = ''
if v.include?('username') and (v['username'] != :undef) and (v['username'].to_s != '')
userinfo = ERB::Util.url_encode(v['username'])
end
if v.include?('password') and (v['password'] != :undef) and (v['password'].to_s != '')
userinfo += ":#{ERB::Util.url_encode(v['password'])}"
end
if userinfo != ''
parts[:userinfo] = userinfo
end
if v.include?('query') and ! v['query'].empty?
parts[:query] = v['query'].map{ |k,v| "#{k}=#{v}" }.join('&')
end
URI::Generic.build(parts).to_s
end
end

View File

@ -0,0 +1,4 @@
---
features:
- |
The new ``os_url`` function has been added.

View File

@ -0,0 +1,117 @@
require 'spec_helper'
describe 'os_url' do
it 'refuses String' do
is_expected.to run.with_params('foo').\
and_raise_error(Puppet::ParseError, /Requires an hash/)
end
it 'refuses Array' do
is_expected.to run.with_params(['foo']).\
and_raise_error(Puppet::ParseError, /Requires an hash/)
end
it 'refuses without at least one argument' do
is_expected.to run.with_params().\
and_raise_error(Puppet::ParseError, /Wrong number of arguments/)
end
it 'refuses too many arguments' do
is_expected.to run.with_params('foo', 'bar').\
and_raise_error(Puppet::ParseError, /Wrong number of arguments/)
end
it 'refuses query params passed as String' do
is_expected.to run.with_params({
'query' => 'key=value'
}).and_raise_error(Puppet::ParseError, /query should be a Hash/)
end
it 'fails if port is provided with missing host' do
is_expected.to run.with_params({
'port' => '8080',
}).and_raise_error(Puppet::ParseError, /host is required with port/)
end
context 'creates the correct connection URI' do
it 'with all parameters' do
is_expected.to run.with_params({
'scheme' => 'https',
'host' => '127.0.0.1',
'port' => '443',
'path' => '/test',
'username' => 'guest',
'password' => 's3cr3t',
'query' => { 'key1' => 'value1', 'key2' => 'value2' }
}).and_return('https://guest:s3cr3t@127.0.0.1:443/test?key1=value1&key2=value2')
end
it 'without port' do
is_expected.to run.with_params({
'host' => '127.0.0.1',
'path' => '/test',
'username' => 'guest',
'password' => 's3cr3t',
}).and_return('http://guest:s3cr3t@127.0.0.1/test')
end
it 'without host and port' do
is_expected.to run.with_params({
'scheme' => 'file',
'path' => '/test',
}).and_return('file:///test')
end
it 'without username and password' do
is_expected.to run.with_params({
'host' => '127.0.0.1',
}).and_return('http://127.0.0.1')
end
it 'with username set to undef' do
is_expected.to run.with_params({
'host' => '127.0.0.1',
'username' => :undef,
}).and_return('http://127.0.0.1')
end
it 'with username set to an empty string' do
is_expected.to run.with_params({
'host' => '127.0.0.1',
'username' => '',
}).and_return('http://127.0.0.1')
end
it 'without password' do
is_expected.to run.with_params({
'host' => '127.0.0.1',
'username' => 'guest',
}).and_return('http://guest@127.0.0.1')
end
it 'with password' do
is_expected.to run.with_params({
'host' => '127.0.0.1',
'password' => 's3cr3t',
}).and_return('http://:s3cr3t@127.0.0.1')
end
it 'with password set to undef' do
is_expected.to run.with_params({
'host' => '127.0.0.1',
'username' => 'guest',
'password' => :undef,
}).and_return('http://guest@127.0.0.1')
end
it 'with password set to an empty string' do
is_expected.to run.with_params({
'host' => '127.0.0.1',
'username' => 'guest',
'password' => '',
}).and_return('http://guest@127.0.0.1')
end
end
end