 710bcb855c
			
		
	
	710bcb855c
	
	
	
		
			
			URI.escape() method has been removed in ruby 3 and the newly added Puppet::Util.rfc2396_escape()[1] has not been released yet. [1]41dcae71c7Closes-Bug: #1928685 Change-Id: I001d579a1b126fc8254f071ddbecda5cc6de7231 (cherry picked from commit0699227b3c)
		
			
				
	
	
		
			197 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # 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
 | |
| Puppet::Functions.create_function(:os_transport_url) do
 | |
|   # TODO(tobias-urdin): Rework and remove this.
 | |
|   # Taken straight from stdlib v5.1.0 module.
 | |
|   def _str2bool(string)
 | |
|     if !!string == string
 | |
|       return string
 | |
|     end
 | |
|     unless string.is_a?(String)
 | |
|       raise(Puppet::ParseError, 'str2bool(): Requires string to work with')
 | |
|     end
 | |
|     result = case string
 | |
|              when %r{^$}, '' then false # Empty string will be false ...
 | |
|              when %r{^(1|t|y|true|yes)$}i  then true
 | |
|              when %r{^(0|f|n|false|no)$}i  then false
 | |
|              when %r{^(undef|undefined)$} then false # This is not likely to happen ...
 | |
|              else
 | |
|                raise(Puppet::ParseError, 'os_transport_url _str2bool(): Unknown type of boolean given')
 | |
|              end
 | |
|     return result
 | |
|   end
 | |
| 
 | |
|   # TODO(tobias-urdin): Rework and remove this.
 | |
|   # Taken straight from stdlib v5.1.0 module.
 | |
|   def _bool2num(val)
 | |
|     value = _str2bool(val)
 | |
|     result = value ? 1 : 0
 | |
|     return result
 | |
|   end
 | |
| 
 | |
|   def os_transport_url(*args)
 | |
|     require 'erb'
 | |
| 
 | |
|     unless args.size == 1
 | |
|       raise(ArgumentError, 'os_transport_url(): Wrong number of arguments')
 | |
|     end
 | |
| 
 | |
|     v_raw = args[0]
 | |
|     klass = v_raw.class
 | |
| 
 | |
|     unless klass == Hash
 | |
|       raise(Puppet::ParseError, "os_transport_url(): Requires an hash, got #{klass}")
 | |
|     end
 | |
| 
 | |
|     v = {}
 | |
|     # type checking for the parameter hash
 | |
|     v_raw.keys.each do |key|
 | |
|       if key == 'port'
 | |
|         v[key] = v_raw[key].to_s
 | |
|       else
 | |
|         v[key] = v_raw[key]
 | |
|       end
 | |
|       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] = ERB::Util.url_encode(v['username'])
 | |
|       if v.include?('password') and (v['password'] != :undef) and (v['password'].to_s != '')
 | |
|         parts[:userinfo] += ":#{ERB::Util.url_encode(v['password'])}"
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     if v.include?('host')
 | |
|       host = call_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 = call_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')
 | |
| 
 | |
|     query = {}
 | |
|     if v.include?('query')
 | |
|       query.merge!(v['query'])
 | |
|     end
 | |
| 
 | |
|     # 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 _str2bool and _bool2num to ensure it's in the
 | |
|       # format
 | |
|       # TODO(tobias-urdin): Rework this to using proper data types and not the
 | |
|       # legacy puppet functions that is copied into this function statement.
 | |
|       # We need to do this right now because it fails testing if we call the
 | |
|       # str2bool or bool2num legacy functions using call_function.
 | |
|       ssl_str = _str2bool(v['ssl'])
 | |
|       ssl_val = _bool2num(v['ssl'])
 | |
| 
 | |
|       query.merge!({ 'ssl' => ssl_val })
 | |
|     end
 | |
| 
 | |
|     parts[:query] = query.map{ |k,val| "#{k}=#{val}" }.join('&') if ! query.empty?
 | |
| 
 | |
|     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
 | |
| end
 |