Puppet Function: fetch_from_url

Defined in:
lib/puppet/parser/functions/fetch_from_url.rb
Function type:
Ruby 3.x API

Overview

fetch_from_url()Any

Fetch something from the given URL, handle redirects and errors.

Expects one has argument with the following keys:

  • url: URL to fetch

  • limit: Limit of fetches (for redirects, defaults to 10)

  • use_auth: Use Basic Auth

  • username: Username for auth

  • password: Password for auth

  • ignore_redirect: Ignore redirect, just return the new location

    (defaults to false)
    

Returns:

  • (Any)


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/puppet/parser/functions/fetch_from_url.rb', line 2

newfunction(:fetch_from_url, :type => :rvalue, :doc => <<-EOS
Fetch something from the given URL, handle redirects and errors.

Expects one has argument with the following keys:

* url: URL to fetch
* limit: Limit of fetches (for redirects, defaults to 10)
* use_auth: Use Basic Auth
* username: Username for auth
* password: Password for auth
* ignore_redirect: Ignore redirect, just return the new location 
                 (defaults to false)
EOS
) do |args|

  raise(
      Puppet::ParseError,
      'Not enough arguments'
  ) unless args.size == 1

  arguments = {
      :limit => 10,
      :use_auth => false,
      :ignore_redirect => false
  }.merge(args[0])

  uri_str = arguments[:url]
  limit = arguments[:limit]

  raise(
      ArgumentError,
      'Too many HTTP redirects downloading release info'
  ) if limit == 0

  uri = URI(uri_str)

  request = Net::HTTP::Get.new(uri.path)

  if arguments[:use_auth]
    debug(sprintf('Authenticating as %s', arguments[:username]))
    request.basic_auth(
        arguments[:username],
        arguments[:password]
    )
  end

  debug(sprintf('Fetching %s. Limit: %d', uri_str, limit))

  response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => true) { |http|
    http.request(request)
  }

  case response
    when Net::HTTPRedirection then
      debug('Redirecting...')

      if arguments[:ignore_redirect]
        response['location']
      else
        arguments[:url] = response['location']
        arguments[:limit] -= 1
        function_fetch_from_url([arguments])
      end
    when Net::HTTPSuccess
      debug('Success. Returning body.')
      response.body
    else
      raise(
          ArgumentError,
          sprintf(
              'Can not download release info: %s',
              response.value
          )
      )
  end

end