
Currently we only allow to use strings as the data type for ports. Due to this we need to cast the data type in the puppet modules because from THT this is configured as a Number. This submission allow to use either string or numbers for the port parameter in the os_transport_url function. Change-Id: I9e56f8e2de542b20fe9e6995506cff5bb435e220 Closes-Bug: #1664561
158 lines
5.0 KiB
Ruby
158 lines
5.0 KiB
Ruby
require 'puppet/parser/functions'
|
|
|
|
Puppet::Parser::Functions.newfunction(:os_transport_url,
|
|
:type => :rvalue,
|
|
:arity => 1,
|
|
:doc => <<-EOS
|
|
This function builds a os_transport_url string from a hash of parameters.
|
|
|
|
Valid hash parameteres:
|
|
* transport - (string) type of transport, 'rabbit' or 'amqp'
|
|
* host - (string) single host
|
|
* hosts - (array) array of hosts to use
|
|
* port - (string | integer) port to connect to
|
|
* username - (string) connection username
|
|
* password - (string) connection password
|
|
* virtual_host - (string) virtual host to connect to
|
|
* ssl - (string) is the connection ssl or not ('1' or '0'). overrides the ssl
|
|
key in the query parameter
|
|
* query - (hash) hash of key,value pairs used to create a query string for
|
|
the transport_url.
|
|
|
|
Only 'transport' and either 'host' or 'hosts' are required keys for the
|
|
parameters hash.
|
|
|
|
The url format that will be generated:
|
|
transport://user:pass@host:port[,userN:passN@hostN:portN]/virtual_host?query
|
|
|
|
NOTE: ipv6 addresses will automatically be bracketed for the URI using the
|
|
normalize_ip_for_uri function.
|
|
|
|
Single Host Example:
|
|
os_transport_url({
|
|
'transport' => 'rabbit',
|
|
'host' => '1.1.1.1',
|
|
'port' => '5672',
|
|
'username' => 'username',
|
|
'password' => 'password',
|
|
'virtual_host' => 'virtual_host',
|
|
'ssl' => '1',
|
|
'query' => { 'key' => 'value' },
|
|
})
|
|
Generates:
|
|
rabbit://username:password@1.1.1.1:5672/virtual_host?key=value&ssl=1
|
|
|
|
Multiple Hosts Example:
|
|
os_transport_url({
|
|
'transport' => 'rabbit',
|
|
'hosts' => [ '1.1.1.1', '2.2.2.2' ],
|
|
'port' => '5672',
|
|
'username' => 'username',
|
|
'password' => 'password',
|
|
'virtual_host' => 'virtual_host',
|
|
'query' => { 'key' => 'value' },
|
|
})
|
|
Generates:
|
|
rabbit://username:password@1.1.1.1:5672,username:password@2.2.2.2:5672/virtual_host?key=value
|
|
EOS
|
|
) do |arguments|
|
|
|
|
require 'uri'
|
|
|
|
v = arguments[0]
|
|
klass = v.class
|
|
|
|
unless klass == Hash
|
|
raise(Puppet::ParseError, "os_transport_url(): Requires an hash, got #{klass}")
|
|
end
|
|
|
|
# type checking for the parameter hash
|
|
v.keys.each do |key|
|
|
v[key] = v[key].to_s if key == 'port'
|
|
klass = (key == 'hosts') ? Array : String
|
|
klass = (key == 'query') ? Hash : klass
|
|
unless (v[key].class == klass) or (v[key] == :undef)
|
|
raise(Puppet::ParseError, "os_transport_url(): #{key} should be a #{klass}")
|
|
end
|
|
end
|
|
|
|
# defaults
|
|
parts = {
|
|
:transport => 'rabbit',
|
|
:hostinfo => 'localhost',
|
|
:path => '/',
|
|
}
|
|
|
|
unless v.include?('transport')
|
|
raise(Puppet::ParseError, 'os_transport_url(): transport is required')
|
|
end
|
|
|
|
unless v.include?('host') or v.include?('hosts')
|
|
raise(Puppet::ParseError, 'os_transport_url(): host or hosts is required')
|
|
end
|
|
|
|
if v.include?('host') and v.include?('hosts')
|
|
raise(Puppet::ParseError, 'os_transport_url(): cannot use both host and hosts.')
|
|
end
|
|
|
|
parts[:transport] = v['transport']
|
|
|
|
if v.include?('username') and (v['username'] != :undef) and (v['username'].to_s != '')
|
|
parts[:userinfo] = URI.escape(v['username'])
|
|
if v.include?('password') and (v['password'] != :undef) and (v['password'].to_s != '')
|
|
parts[:userinfo] += ":#{URI.escape(v['password'])}"
|
|
end
|
|
end
|
|
|
|
if v.include?('host')
|
|
host = function_normalize_ip_for_uri([v['host']])
|
|
host += ":#{v['port'].to_s}" if v.include?('port')
|
|
if parts.include?(:userinfo)
|
|
parts[:hostinfo] = "#{parts[:userinfo]}@#{host}"
|
|
else
|
|
parts[:hostinfo] = "#{host}"
|
|
end
|
|
end
|
|
|
|
if v.include?('hosts')
|
|
hosts = function_normalize_ip_for_uri([v['hosts']])
|
|
# normalize_ip_for_uri may return a string, so check that we still have an
|
|
# array
|
|
hosts = [hosts] if hosts.kind_of?(String)
|
|
hosts = hosts.map{ |h| "#{h}:#{v['port'].to_s}" } if v.include?('port')
|
|
if parts.include?(:userinfo)
|
|
parts[:hostinfo] = hosts.map { |h| "#{parts[:userinfo]}@#{h}" }.join(',')
|
|
else
|
|
parts[:hostinfo] = hosts.join(',')
|
|
end
|
|
end
|
|
|
|
parts[:path] = "/#{v['virtual_host']}" if v.include?('virtual_host')
|
|
|
|
# support previous ssl option on the function. Setting ssl will
|
|
# override ssl if passed in via the query parameters
|
|
if v.include?('ssl')
|
|
# ssl can be passed in as a query paramter but should be 0/1. See
|
|
# http://docs.celeryproject.org/projects/kombu/en/latest/userguide/connections.html#urls
|
|
# so we rely on the stdlib str2bool and bool2num to ensure it's in the
|
|
# format
|
|
ssl_val = function_bool2num([function_str2bool([v['ssl']])])
|
|
if v.include?('query')
|
|
v['query'].merge!({ 'ssl' => ssl_val })
|
|
else
|
|
v['query'] = { 'ssl' => ssl_val }
|
|
end
|
|
end
|
|
|
|
parts[:query] = v['query'].map{ |k,val| "#{k}=#{val}" }.join('&') if v.include?('query')
|
|
|
|
|
|
url_parts = []
|
|
url_parts << parts[:transport]
|
|
url_parts << '://'
|
|
url_parts << parts[:hostinfo]
|
|
url_parts << parts[:path]
|
|
url_parts << '?' << parts[:query] if parts.include?(:query)
|
|
url_parts.join()
|
|
end
|