Class: Berkshelf::Source

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/berkshelf/source.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(berksfile, source, **options) ⇒ Source

Returns a new instance of Source.

Parameters:



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
# File 'lib/berkshelf/source.rb', line 16

def initialize(berksfile, source, **options)
  @options = { timeout: api_timeout, open_timeout: [(api_timeout / 10), 3].max, ssl: {} }
  @options.update(options)
  case source
  when String
    # source "https://supermarket.chef.io/"
    @type = :supermarket
    @uri_string = source
  when :chef_server
    # source :chef_server
    @type = :chef_server
    @uri_string = options[:url] || Berkshelf::Config.instance.chef.chef_server_url
  when Hash
    # source type: uri, option: value, option: value
    source = source.dup
    @type, @uri_string = source.shift
    @options.update(source)
  end
  # Default options for some source types.
  case @type
  when :chef_server
    @options[:client_name] ||= Berkshelf::Config.instance.chef.node_name
    @options[:client_key] ||= Berkshelf::Config.instance.chef.client_key
  when :artifactory
    @options[:api_key] ||= Berkshelf::Config.instance.chef.artifactory_api_key || ENV["ARTIFACTORY_API_KEY"]
  when :chef_repo
    @options[:path] = uri_string
    # If given a relative path, expand it against the Berksfile's folder.
    @options[:path] = File.expand_path(@options[:path], File.dirname(berksfile ? berksfile.filepath : Dir.pwd))
    # Lie because this won't actually parse as a URI.
    @uri_string = "file://#{@options[:path]}"
  end
  # Set some default SSL options.
  Berkshelf::Config.instance.ssl.each do |key, value|
    @options[:ssl][key.to_sym] = value unless @options[:ssl].include?(key.to_sym)
  end
  @options[:ssl][:cert_store] = ssl_policy.store if ssl_policy.store
  @universe = nil
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



12
13
14
# File 'lib/berkshelf/source.rb', line 12

def options
  @options
end

#typeObject

Returns the value of attribute type.



10
11
12
# File 'lib/berkshelf/source.rb', line 10

def type
  @type
end

#uri_stringObject

Returns the value of attribute uri_string.



11
12
13
# File 'lib/berkshelf/source.rb', line 11

def uri_string
  @uri_string
end

Instance Method Details

#==(other) ⇒ Object



164
165
166
167
168
# File 'lib/berkshelf/source.rb', line 164

def ==(other)
  return false unless other.is_a?(self.class)

  type == other.type && uri == other.uri
end

#api_clientObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/berkshelf/source.rb', line 60

def api_client
  @api_client ||= case type
                  when :chef_server
                    APIClient.chef_server(server_url: uri.to_s, **options)
                  when :artifactory
                    # Don't accidentally mutate the options.
                    client_options = options.dup
                    api_key = client_options.delete(:api_key)
                    APIClient.new(uri, headers: { "X-Jfrog-Art-Api" => api_key }, **client_options)
                  when :chef_repo
                    ChefRepoUniverse.new(uri_string, **options)
                  else
                    APIClient.new(uri, **options)
                  end
end

#build_universeArray<APIClient::RemoteCookbook>

Forcefully obtain the universe from the API endpoint and assign it to #universe. This will reload the value of #universe even if it has been loaded before.

Returns:



84
85
86
87
88
89
# File 'lib/berkshelf/source.rb', line 84

def build_universe
  @universe = api_client.universe
rescue => ex
  @universe = []
  raise ex
end

#cookbook(name, version) ⇒ APIClient::RemoteCookbook

Parameters:

Returns:



106
107
108
# File 'lib/berkshelf/source.rb', line 106

def cookbook(name, version)
  universe.find { |cookbook| cookbook.name == name && cookbook.version == version }
end

#default?true, false

Determine if this source is a “default” source, as defined in the Berksfile.

Returns:

  • (true, false)

    true if this a default source, false otherwise



127
128
129
# File 'lib/berkshelf/source.rb', line 127

def default?
  @default_ ||= uri.host == URI.parse(Berksfile::DEFAULT_API_URL).host
end

#hashObject



160
161
162
# File 'lib/berkshelf/source.rb', line 160

def hash
  [type, uri_string, options].hash
end

#inspectObject



156
157
158
# File 'lib/berkshelf/source.rb', line 156

def inspect
  "#<#{self.class.name} #{type}: #{uri.to_s.inspect}, #{options.map { |k, v| "#{k}: #{v.inspect}" }.join(", ")}>"
end

#latest(name) ⇒ APIClient::RemoteCookbook

Parameters:

Returns:



134
135
136
# File 'lib/berkshelf/source.rb', line 134

def latest(name)
  versions(name).sort.last
end

#search(name) ⇒ Array<APIClient::RemoteCookbook]

The list of remote cookbooks that match the given query.

Parameters:

Returns:



115
116
117
118
119
120
# File 'lib/berkshelf/source.rb', line 115

def search(name)
  universe
    .select { |cookbook| cookbook.name =~ Regexp.new(name) }
    .group_by(&:name)
    .collect { |_, versions| versions.max_by { |v| Semverse::Version.new(v.version) } }
end

#ssl_policyObject



56
57
58
# File 'lib/berkshelf/source.rb', line 56

def ssl_policy
  @ssl_policy ||= SSLPolicy.new
end

#to_sObject



145
146
147
148
149
150
151
152
153
154
# File 'lib/berkshelf/source.rb', line 145

def to_s
  case type
  when :supermarket
    uri.to_s
  when :chef_repo
    options[:path]
  else
    "#{type}: #{uri}"
  end
end

#universeArray<APIClient::RemoteCookbook>

Return the universe from the API endpoint.

This is lazily loaded so the universe will be retrieved from the API endpoint on the first call and cached for future calls. Send the #build_universe message if you want to reload the cached universe.

Returns:



98
99
100
# File 'lib/berkshelf/source.rb', line 98

def universe
  @universe || build_universe
end

#uriObject



76
77
78
# File 'lib/berkshelf/source.rb', line 76

def uri
  @uri ||= SourceURI.parse(uri_string)
end

#versions(name) ⇒ Array<APIClient::RemoteCookbook>

Parameters:

Returns:



141
142
143
# File 'lib/berkshelf/source.rb', line 141

def versions(name)
  universe.select { |cookbook| cookbook.name == name }
end