berkshelf 5.2.0 → 8.0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +19 -47
- data/Rakefile +14 -4
- data/berkshelf.gemspec +61 -40
- data/bin/berks +2 -2
- data/lib/berkshelf/api-client.rb +1 -0
- data/lib/berkshelf/api_client/chef_server_connection.rb +29 -0
- data/lib/berkshelf/api_client/connection.rb +57 -0
- data/lib/berkshelf/api_client/errors.rb +10 -0
- data/lib/berkshelf/api_client/remote_cookbook.rb +56 -0
- data/lib/berkshelf/api_client/version.rb +5 -0
- data/lib/berkshelf/api_client.rb +24 -0
- data/lib/berkshelf/berksfile.rb +149 -122
- data/lib/berkshelf/cached_cookbook.rb +127 -24
- data/lib/berkshelf/chef_config_compat.rb +51 -0
- data/lib/berkshelf/chef_repo_universe.rb +47 -0
- data/lib/berkshelf/cli.rb +143 -174
- data/lib/berkshelf/commands/shelf.rb +20 -19
- data/lib/berkshelf/community_rest.rb +59 -94
- data/lib/berkshelf/config.rb +97 -127
- data/lib/berkshelf/cookbook_store.rb +7 -6
- data/lib/berkshelf/core_ext/file.rb +1 -1
- data/lib/berkshelf/core_ext/file_utils.rb +4 -4
- data/lib/berkshelf/core_ext.rb +1 -1
- data/lib/berkshelf/dependency.rb +25 -32
- data/lib/berkshelf/downloader.rb +66 -39
- data/lib/berkshelf/errors.rb +23 -17
- data/lib/berkshelf/file_syncer.rb +24 -47
- data/lib/berkshelf/formatters/human.rb +7 -5
- data/lib/berkshelf/formatters/json.rb +6 -6
- data/lib/berkshelf/installer.rb +120 -111
- data/lib/berkshelf/location.rb +14 -14
- data/lib/berkshelf/locations/base.rb +1 -1
- data/lib/berkshelf/locations/git.rb +16 -24
- data/lib/berkshelf/locations/github.rb +2 -2
- data/lib/berkshelf/locations/path.rb +2 -2
- data/lib/berkshelf/lockfile.rb +326 -328
- data/lib/berkshelf/logger.rb +64 -1
- data/lib/berkshelf/mixin/git.rb +6 -5
- data/lib/berkshelf/packager.rb +44 -10
- data/lib/berkshelf/resolver/graph.rb +1 -1
- data/lib/berkshelf/resolver.rb +4 -4
- data/lib/berkshelf/ridley_compat.rb +109 -0
- data/lib/berkshelf/shell.rb +2 -1
- data/lib/berkshelf/shell_out.rb +18 -0
- data/lib/berkshelf/source.rb +77 -33
- data/lib/berkshelf/source_uri.rb +4 -4
- data/lib/berkshelf/ssl_policies.rb +38 -0
- data/lib/berkshelf/thor.rb +1 -1
- data/lib/berkshelf/thor_ext/hash_with_indifferent_access.rb +1 -1
- data/lib/berkshelf/thor_ext.rb +1 -1
- data/lib/berkshelf/uploader.rb +106 -70
- data/lib/berkshelf/validator.rb +13 -5
- data/lib/berkshelf/version.rb +1 -1
- data/lib/berkshelf/visualizer.rb +16 -11
- data/lib/berkshelf.rb +106 -81
- data/spec/config/knife.rb +4 -4
- data/spec/data/trusted_certs/example.crt +22 -0
- data/spec/fixtures/Berksfile +3 -3
- data/spec/fixtures/complex-cookbook-path/cookbooks/app/metadata.rb +2 -0
- data/spec/fixtures/complex-cookbook-path/cookbooks/jenkins/metadata.rb +2 -0
- data/spec/fixtures/complex-cookbook-path/cookbooks/jenkins-config/metadata.rb +4 -0
- data/spec/fixtures/cookbook-path/jenkins-config/metadata.rb +3 -3
- data/spec/fixtures/cookbook-path-uploader/apt-2.3.6/metadata.rb +2 -0
- data/spec/fixtures/cookbook-path-uploader/build-essential-1.4.2/metadata.rb +2 -0
- data/spec/fixtures/cookbook-path-uploader/jenkins-2.0.3/metadata.rb +5 -0
- data/spec/fixtures/cookbook-path-uploader/jenkins-config-0.1.0/metadata.rb +4 -0
- data/spec/fixtures/cookbook-path-uploader/runit-1.5.8/metadata.rb +5 -0
- data/spec/fixtures/cookbook-path-uploader/yum-3.0.6/metadata.rb +2 -0
- data/spec/fixtures/cookbook-path-uploader/yum-epel-0.2.0/metadata.rb +3 -0
- data/spec/fixtures/cookbook-store/jenkins-2.0.3/metadata.rb +5 -5
- data/spec/fixtures/cookbook-store/jenkins-2.0.4/metadata.rb +4 -4
- data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +3 -3
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +3 -3
- data/spec/spec_helper.rb +56 -64
- data/spec/support/chef_api.rb +15 -16
- data/spec/support/chef_server.rb +71 -69
- data/spec/support/git.rb +59 -58
- data/spec/support/kitchen.rb +0 -14
- data/spec/support/matchers/file_system_matchers.rb +4 -5
- data/spec/support/matchers/filepath_matchers.rb +2 -2
- data/spec/support/path_helpers.rb +17 -17
- data/spec/support/shared_examples/formatter.rb +1 -1
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/attributes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/files/default/file.h +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/metadata.rb +2 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/recipes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/templates/default/template.erb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/attributes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/files/default/file.h +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/metadata.rb +2 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/recipes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/templates/default/template.erb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/attributes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/files/default/file.h +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/metadata.rb +2 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/recipes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/templates/default/template.erb +0 -0
- data/spec/unit/berkshelf/berksfile_spec.rb +84 -105
- data/spec/unit/berkshelf/berkshelf/api_client/chef_server_connection_spec.rb +65 -0
- data/spec/unit/berkshelf/berkshelf/api_client/connection_spec.rb +157 -0
- data/spec/unit/berkshelf/berkshelf/api_client/remote_cookbook_spec.rb +23 -0
- data/spec/unit/berkshelf/berkshelf/api_client_spec.rb +9 -0
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +45 -47
- data/spec/unit/berkshelf/chef_repo_universe_spec.rb +37 -0
- data/spec/unit/berkshelf/cli_spec.rb +7 -8
- data/spec/unit/berkshelf/community_rest_spec.rb +82 -90
- data/spec/unit/berkshelf/config_spec.rb +51 -22
- data/spec/unit/berkshelf/cookbook_store_spec.rb +41 -41
- data/spec/unit/berkshelf/core_ext/file_utils_spec.rb +7 -8
- data/spec/unit/berkshelf/core_ext/pathname_spec.rb +1 -1
- data/spec/unit/berkshelf/dependency_spec.rb +48 -48
- data/spec/unit/berkshelf/downloader_spec.rb +191 -34
- data/spec/unit/berkshelf/errors_spec.rb +3 -3
- data/spec/unit/berkshelf/file_syncer_spec.rb +87 -87
- data/spec/unit/berkshelf/formatters/base_spec.rb +23 -23
- data/spec/unit/berkshelf/formatters/human_spec.rb +2 -2
- data/spec/unit/berkshelf/formatters/json_spec.rb +2 -2
- data/spec/unit/berkshelf/formatters/null_spec.rb +3 -3
- data/spec/unit/berkshelf/installer_spec.rb +8 -8
- data/spec/unit/berkshelf/location_spec.rb +11 -11
- data/spec/unit/berkshelf/locations/base_spec.rb +35 -36
- data/spec/unit/berkshelf/locations/git_spec.rb +90 -93
- data/spec/unit/berkshelf/locations/path_spec.rb +40 -41
- data/spec/unit/berkshelf/lockfile_parser_spec.rb +71 -71
- data/spec/unit/berkshelf/lockfile_spec.rb +205 -211
- data/spec/unit/berkshelf/logger_spec.rb +3 -3
- data/spec/unit/berkshelf/mixin/logging_spec.rb +5 -5
- data/spec/unit/berkshelf/packager_spec.rb +2 -2
- data/spec/unit/berkshelf/resolver/graph_spec.rb +10 -8
- data/spec/unit/berkshelf/resolver_spec.rb +17 -17
- data/spec/unit/berkshelf/ridley_compat_spec.rb +16 -0
- data/spec/unit/berkshelf/shell_spec.rb +34 -34
- data/spec/unit/berkshelf/source_spec.rb +186 -20
- data/spec/unit/berkshelf/source_uri_spec.rb +1 -1
- data/spec/unit/berkshelf/ssl_policies_spec.rb +86 -0
- data/spec/unit/berkshelf/uploader_spec.rb +146 -64
- data/spec/unit/berkshelf/validator_spec.rb +23 -16
- data/spec/unit/berkshelf/visualizer_spec.rb +24 -15
- data/spec/unit/berkshelf_spec.rb +18 -18
- metadata +138 -289
- data/.gitignore +0 -29
- data/.travis.yml +0 -64
- data/CHANGELOG.legacy.md +0 -307
- data/CHANGELOG.md +0 -1358
- data/CONTRIBUTING.md +0 -64
- data/Gemfile.lock +0 -399
- data/Guardfile +0 -23
- data/PLUGINS.md +0 -25
- data/README.md +0 -70
- data/Thorfile +0 -61
- data/appveyor.yml +0 -31
- data/docs/berkshelf_for_newcomers.md +0 -65
- data/features/berksfile.feature +0 -46
- data/features/commands/apply.feature +0 -41
- data/features/commands/contingent.feature +0 -48
- data/features/commands/cookbook.feature +0 -35
- data/features/commands/info.feature +0 -99
- data/features/commands/init.feature +0 -27
- data/features/commands/install.feature +0 -636
- data/features/commands/list.feature +0 -78
- data/features/commands/outdated.feature +0 -130
- data/features/commands/package.feature +0 -17
- data/features/commands/search.feature +0 -17
- data/features/commands/shelf/list.feature +0 -32
- data/features/commands/shelf/show.feature +0 -143
- data/features/commands/shelf/uninstall.feature +0 -96
- data/features/commands/show.feature +0 -83
- data/features/commands/update.feature +0 -142
- data/features/commands/upload.feature +0 -426
- data/features/commands/vendor.feature +0 -111
- data/features/commands/verify.feature +0 -29
- data/features/commands/viz.feature +0 -66
- data/features/community_site.feature +0 -37
- data/features/config.feature +0 -111
- data/features/help.feature +0 -11
- data/features/json_formatter.feature +0 -161
- data/features/lifecycle.feature +0 -378
- data/features/lockfile.feature +0 -378
- data/features/step_definitions/berksfile_steps.rb +0 -39
- data/features/step_definitions/chef/config_steps.rb +0 -12
- data/features/step_definitions/chef_server_steps.rb +0 -60
- data/features/step_definitions/cli_steps.rb +0 -18
- data/features/step_definitions/config_steps.rb +0 -46
- data/features/step_definitions/environment_steps.rb +0 -7
- data/features/step_definitions/filesystem_steps.rb +0 -269
- data/features/step_definitions/gem_steps.rb +0 -13
- data/features/step_definitions/json_steps.rb +0 -23
- data/features/step_definitions/utility_steps.rb +0 -11
- data/features/support/aruba.rb +0 -12
- data/features/support/env.rb +0 -82
- data/generator_files/Berksfile.erb +0 -11
- data/generator_files/CHANGELOG.md.erb +0 -3
- data/generator_files/Gemfile.erb +0 -8
- data/generator_files/README.md.erb +0 -42
- data/generator_files/Thorfile.erb +0 -11
- data/generator_files/Vagrantfile.erb +0 -117
- data/generator_files/chefignore +0 -94
- data/generator_files/default_recipe.erb +0 -6
- data/generator_files/default_test.rb.erb +0 -11
- data/generator_files/gitignore.erb +0 -23
- data/generator_files/helpers.rb.erb +0 -7
- data/generator_files/licenses/apachev2.erb +0 -13
- data/generator_files/licenses/gplv2.erb +0 -15
- data/generator_files/licenses/gplv3.erb +0 -14
- data/generator_files/licenses/mit.erb +0 -20
- data/generator_files/licenses/reserved.erb +0 -3
- data/generator_files/metadata.rb.erb +0 -11
- data/lib/berkshelf/base_generator.rb +0 -43
- data/lib/berkshelf/commands/test_command.rb +0 -13
- data/lib/berkshelf/cookbook_generator.rb +0 -133
- data/lib/berkshelf/init_generator.rb +0 -195
- data/spec/fixtures/cookbooks/example_cookbook/.gitignore +0 -2
- data/spec/fixtures/cookbooks/example_cookbook/.kitchen.yml +0 -26
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +0 -110
- data/spec/unit/berkshelf/init_generator_spec.rb +0 -263
data/lib/berkshelf/logger.rb
CHANGED
@@ -1,5 +1,68 @@
|
|
1
1
|
module Berkshelf
|
2
|
-
class Logger <
|
2
|
+
class Logger < Logger
|
3
|
+
def initialize(device = STDOUT)
|
4
|
+
super
|
5
|
+
self.level = Logger::WARN
|
6
|
+
@filter_params = []
|
7
|
+
end
|
8
|
+
|
9
|
+
# Reimplements Logger#add adding message filtering. The info,
|
10
|
+
# warn, debug, error, and fatal methods all call add.
|
11
|
+
#
|
12
|
+
# @param [Fixnum] severity
|
13
|
+
# an integer measuing the severity - Logger::INFO, etc.
|
14
|
+
# @param [String] message = nil
|
15
|
+
# the message to log
|
16
|
+
# @param [String] progname = nil
|
17
|
+
# the program name performing the logging
|
18
|
+
# @param &block
|
19
|
+
# a block that will be evaluated (for complicated logging)
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# log.filter_param("hello")
|
23
|
+
# log.info("hello world!") => "FILTERED world!"
|
24
|
+
#
|
25
|
+
# @return [Boolean]
|
26
|
+
def add(severity, message = nil, progname = nil, &block)
|
27
|
+
severity ||= Logger::UNKNOWN
|
28
|
+
if @logdev.nil? || severity < (@level)
|
29
|
+
return true
|
30
|
+
end
|
31
|
+
|
32
|
+
progname ||= @progname
|
33
|
+
if message.nil?
|
34
|
+
if block_given?
|
35
|
+
message = yield
|
36
|
+
else
|
37
|
+
message = progname
|
38
|
+
progname = @progname
|
39
|
+
end
|
40
|
+
end
|
41
|
+
@logdev.write(
|
42
|
+
format_message(format_severity(severity), Time.now, progname, filter(message))
|
43
|
+
)
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
def filter_params
|
48
|
+
@filter_params.dup
|
49
|
+
end
|
50
|
+
|
51
|
+
def filter_param(param)
|
52
|
+
@filter_params << param unless filter_params.include?(param)
|
53
|
+
end
|
54
|
+
|
55
|
+
def clear_filter_params
|
56
|
+
@filter_params.clear
|
57
|
+
end
|
58
|
+
|
59
|
+
def filter(message)
|
60
|
+
filter_params.each do |param|
|
61
|
+
message.gsub!(param.to_s, "FILTERED")
|
62
|
+
end
|
63
|
+
message
|
64
|
+
end
|
65
|
+
|
3
66
|
alias_method :fatal, :error
|
4
67
|
|
5
68
|
def deprecate(message)
|
data/lib/berkshelf/mixin/git.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
|
1
|
+
require_relative "../shell_out"
|
2
2
|
|
3
3
|
module Berkshelf
|
4
4
|
module Mixin
|
5
5
|
module Git
|
6
|
+
include Berkshelf::ShellOut
|
6
7
|
# Perform a git command.
|
7
8
|
#
|
8
9
|
# @param [String] command
|
@@ -12,14 +13,14 @@ module Berkshelf
|
|
12
13
|
#
|
13
14
|
# @raise [String]
|
14
15
|
# the +$stdout+ from the command
|
15
|
-
def git(command, error = true)
|
16
|
-
unless Berkshelf.which(
|
16
|
+
def git(command, error = true, **kwargs)
|
17
|
+
unless Berkshelf.which("git") || Berkshelf.which("git.exe") || Berkshelf.which("git.bat")
|
17
18
|
raise GitNotInstalled.new
|
18
19
|
end
|
19
20
|
|
20
|
-
response =
|
21
|
+
response = shell_out(%{git #{command}}, **kwargs)
|
21
22
|
|
22
|
-
if
|
23
|
+
if response.error?
|
23
24
|
raise GitCommandError.new(command, cache_path, response.stderr)
|
24
25
|
end
|
25
26
|
|
data/lib/berkshelf/packager.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "minitar"
|
2
|
+
require "find" unless defined?(Find)
|
3
|
+
require "zlib" unless defined?(Zlib)
|
3
4
|
|
4
5
|
module Berkshelf
|
5
6
|
# A class for archiving and compressing directory containing one or more cookbooks.
|
@@ -15,7 +16,7 @@ module Berkshelf
|
|
15
16
|
class Packager
|
16
17
|
class << self
|
17
18
|
def validate_destination(path)
|
18
|
-
path
|
19
|
+
path.to_s
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
@@ -40,9 +41,17 @@ module Berkshelf
|
|
40
41
|
# @return [String]
|
41
42
|
# path to the generated archive
|
42
43
|
def run(source)
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
begin
|
45
|
+
dest = Zlib::GzipWriter.open(out_file)
|
46
|
+
tar = RelativeTarWriter.new(dest, source)
|
47
|
+
Find.find(source) do |entry|
|
48
|
+
next if source == entry
|
49
|
+
|
50
|
+
Minitar.pack_file(entry, tar)
|
51
|
+
end
|
52
|
+
ensure
|
53
|
+
tar.close
|
54
|
+
dest.close
|
46
55
|
end
|
47
56
|
|
48
57
|
out_file
|
@@ -64,10 +73,35 @@ module Berkshelf
|
|
64
73
|
|
65
74
|
private
|
66
75
|
|
67
|
-
|
68
|
-
|
76
|
+
# @return [String]
|
77
|
+
attr_reader :out_dir
|
78
|
+
|
79
|
+
# @return [String]
|
80
|
+
attr_reader :filename
|
81
|
+
|
82
|
+
# A private decorator for Minitar::Writer that
|
83
|
+
# turns absolute paths into relative ones.
|
84
|
+
class RelativeTarWriter < SimpleDelegator # :nodoc:
|
85
|
+
def initialize(io, base_path)
|
86
|
+
@base_path = Pathname.new(base_path)
|
87
|
+
super(Minitar::Writer.new(io))
|
88
|
+
end
|
89
|
+
|
90
|
+
%w{add_file add_file_simple mkdir}.each do |method|
|
91
|
+
class_eval <<~RUBY
|
92
|
+
def #{method}(name, *opts, &block)
|
93
|
+
super(relative_path(name), *opts, &block)
|
94
|
+
end
|
95
|
+
RUBY
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
69
99
|
|
70
|
-
|
71
|
-
|
100
|
+
attr_reader :base_path
|
101
|
+
|
102
|
+
def relative_path(path)
|
103
|
+
Pathname.new(path).relative_path_from(base_path).to_s
|
104
|
+
end
|
105
|
+
end
|
72
106
|
end
|
73
107
|
end
|
@@ -50,7 +50,7 @@ module Berkshelf
|
|
50
50
|
# @return [Array<Berkshelf::RemoteCookbook>]
|
51
51
|
def universe(sources)
|
52
52
|
cookbooks = []
|
53
|
-
Array(sources).each { |source| cookbooks
|
53
|
+
Array(sources).each { |source| cookbooks |= source.universe }
|
54
54
|
cookbooks
|
55
55
|
end
|
56
56
|
end
|
data/lib/berkshelf/resolver.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Berkshelf
|
2
2
|
class Resolver
|
3
3
|
|
4
|
-
require_relative
|
4
|
+
require_relative "resolver/graph"
|
5
5
|
|
6
6
|
extend Forwardable
|
7
7
|
|
@@ -21,7 +21,7 @@ module Berkshelf
|
|
21
21
|
def initialize(berksfile, demands = [])
|
22
22
|
@berksfile = berksfile
|
23
23
|
@graph = Graph.new
|
24
|
-
@demands =
|
24
|
+
@demands = []
|
25
25
|
|
26
26
|
Array(demands).each { |demand| add_demand(demand) }
|
27
27
|
compute_solver_engine(berksfile)
|
@@ -75,7 +75,7 @@ module Berkshelf
|
|
75
75
|
graph.populate_store
|
76
76
|
graph.populate(berksfile.sources)
|
77
77
|
|
78
|
-
Solve.it!(graph, demand_array, ENV[
|
78
|
+
Solve.it!(graph, demand_array, ENV["DEBUG_RESOLVER"] ? { ui: Berkshelf.ui } : {}).collect do |name, version|
|
79
79
|
dependency = get_demand(name) || Dependency.new(berksfile, name)
|
80
80
|
dependency.locked_version = version
|
81
81
|
|
@@ -93,7 +93,7 @@ module Berkshelf
|
|
93
93
|
# @return [Dependency]
|
94
94
|
def [](demand)
|
95
95
|
name = demand.respond_to?(:name) ? demand.name : demand.to_s
|
96
|
-
demands.find { |
|
96
|
+
demands.find { |d| d.name == name }
|
97
97
|
end
|
98
98
|
alias_method :get_demand, :[]
|
99
99
|
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require "chef/server_api"
|
2
|
+
require "chef/http/simple_json"
|
3
|
+
require "chef/http/simple"
|
4
|
+
require_relative "api_client/errors"
|
5
|
+
require "chef/config"
|
6
|
+
require "chef/cookbook_manifest"
|
7
|
+
|
8
|
+
module Berkshelf
|
9
|
+
module RidleyCompatAPI
|
10
|
+
def initialize(**opts)
|
11
|
+
opts = opts.dup
|
12
|
+
opts[:ssl] ||= {}
|
13
|
+
chef_opts = {}
|
14
|
+
chef_opts[:rest_timeout] = opts[:timeout] if opts[:timeout] # opts[:open_timeout] is ignored on purpose
|
15
|
+
chef_opts[:headers] = opts[:headers] if opts[:headers]
|
16
|
+
chef_opts[:client_name] = opts[:client_name] if opts[:client_name]
|
17
|
+
chef_opts[:signing_key_filename] = opts[:client_key] if opts[:client_key]
|
18
|
+
chef_opts[:verify_api_cert] = opts[:ssl][:verify] || opts[:ssl][:verify].nil?
|
19
|
+
chef_opts[:ssl_verify_mode] = chef_opts[:verify_api_cert] ? :verify_peer : :verify_none
|
20
|
+
chef_opts[:ssl_ca_path] = opts[:ssl][:ca_path] if opts[:ssl][:ca_path]
|
21
|
+
chef_opts[:ssl_ca_file] = opts[:ssl][:ca_file] if opts[:ssl][:ca_file]
|
22
|
+
chef_opts[:ssl_client_cert] = opts[:ssl][:client_cert] if opts[:ssl][:client_cert]
|
23
|
+
chef_opts[:ssl_client_key] = opts[:ssl][:client_key] if opts[:ssl][:client_key]
|
24
|
+
chef_opts[:version_class] = opts[:version_class] if opts[:version_class]
|
25
|
+
# chef/http/ssl_policies.rb reads only from Chef::Config and not from the opts in the constructor
|
26
|
+
Chef::Config[:verify_api_cert] = chef_opts[:verify_api_cert]
|
27
|
+
Chef::Config[:ssl_verify_mode] = chef_opts[:ssl_verify_mode]
|
28
|
+
super(opts[:server_url].to_s, **chef_opts)
|
29
|
+
end
|
30
|
+
|
31
|
+
# for compat with Ridley::Connection
|
32
|
+
def server_url
|
33
|
+
url
|
34
|
+
end
|
35
|
+
|
36
|
+
def get(url)
|
37
|
+
super(url)
|
38
|
+
rescue Net::HTTPExceptions => e
|
39
|
+
case e.response.code
|
40
|
+
when "404"
|
41
|
+
raise Berkshelf::APIClient::ServiceNotFound, "service not found at: #{url}"
|
42
|
+
when /^5/
|
43
|
+
raise Berkshelf::APIClient::ServiceUnavailable, "service unavailable at: #{url}"
|
44
|
+
else
|
45
|
+
raise Berkshelf::APIClient::BadResponse, "bad response #{e.response}"
|
46
|
+
end
|
47
|
+
rescue Errno::ETIMEDOUT, Timeout::Error
|
48
|
+
raise Berkshelf::APIClient::TimeoutError, "Unable to connect to: #{url}"
|
49
|
+
rescue Errno::EHOSTUNREACH, Errno::ECONNREFUSED => e
|
50
|
+
raise Berkshelf::APIClient::ServiceUnavailable, e
|
51
|
+
end
|
52
|
+
|
53
|
+
module ClassMethods
|
54
|
+
def new_client(**opts, &block)
|
55
|
+
client = new(**opts)
|
56
|
+
yield client
|
57
|
+
# ensure
|
58
|
+
# FIXME: does Chef::HTTP support close anywhere? this will just leak open fds
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.included(klass)
|
63
|
+
klass.extend ClassMethods
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
# This is for simple HTTP
|
69
|
+
class RidleyCompatSimple < ::Chef::ServerAPI
|
70
|
+
use Chef::HTTP::Decompressor
|
71
|
+
use Chef::HTTP::CookieManager
|
72
|
+
use Chef::HTTP::ValidateContentLength
|
73
|
+
|
74
|
+
include RidleyCompatAPI
|
75
|
+
end
|
76
|
+
|
77
|
+
# This is for JSON-REST
|
78
|
+
class RidleyCompatJSON < ::Chef::HTTP::SimpleJSON
|
79
|
+
use Chef::HTTP::JSONInput
|
80
|
+
use Chef::HTTP::JSONOutput
|
81
|
+
use Chef::HTTP::CookieManager
|
82
|
+
use Chef::HTTP::Decompressor
|
83
|
+
use Chef::HTTP::RemoteRequestID
|
84
|
+
use Chef::HTTP::ValidateContentLength
|
85
|
+
|
86
|
+
include RidleyCompatAPI
|
87
|
+
end
|
88
|
+
|
89
|
+
# RidleyCompat is the ServerAPI, but we inherit from Chef::HTTP::Simple and then include all our middlewares
|
90
|
+
# and then need to include our own CompatAPI. The end result is a ridley-esque way of talking to a chef server.
|
91
|
+
class RidleyCompat < ::Chef::HTTP::Simple
|
92
|
+
use Chef::HTTP::JSONInput
|
93
|
+
use Chef::HTTP::JSONOutput
|
94
|
+
use Chef::HTTP::CookieManager
|
95
|
+
use Chef::HTTP::Decompressor
|
96
|
+
use Chef::HTTP::Authenticator
|
97
|
+
use Chef::HTTP::RemoteRequestID
|
98
|
+
use Chef::HTTP::APIVersions if defined?(Chef::HTTP::APIVersions)
|
99
|
+
use Chef::HTTP::ValidateContentLength
|
100
|
+
|
101
|
+
include RidleyCompatAPI
|
102
|
+
|
103
|
+
def initialize(**opts)
|
104
|
+
opts[:version_class] = Chef::CookbookManifestVersions
|
105
|
+
super(**opts)
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
data/lib/berkshelf/shell.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "thor" unless defined?(Thor)
|
2
2
|
|
3
3
|
module Berkshelf
|
4
4
|
# Subclass the current shell (which is different based on the OS)
|
@@ -15,6 +15,7 @@ module Berkshelf
|
|
15
15
|
|
16
16
|
def say(*args)
|
17
17
|
return if quiet?
|
18
|
+
|
18
19
|
super(*args)
|
19
20
|
end
|
20
21
|
alias_method :info, :say
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "mixlib/shellout" unless defined?(Mixlib::ShellOut)
|
2
|
+
|
3
|
+
module Berkshelf
|
4
|
+
module ShellOut
|
5
|
+
def shell_out(*args, **options)
|
6
|
+
cmd = Mixlib::ShellOut.new(*args, **options)
|
7
|
+
cmd.run_command
|
8
|
+
cmd
|
9
|
+
end
|
10
|
+
|
11
|
+
def shell_out!(*args, **options)
|
12
|
+
cmd = Mixlib::ShellOut.new(*args, **options)
|
13
|
+
cmd.run_command
|
14
|
+
cmd.error!
|
15
|
+
cmd
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/berkshelf/source.rb
CHANGED
@@ -1,44 +1,80 @@
|
|
1
|
-
|
1
|
+
require_relative "api-client"
|
2
|
+
require_relative "chef_repo_universe"
|
3
|
+
require_relative "ssl_policies"
|
4
|
+
require "openssl" unless defined?(OpenSSL)
|
2
5
|
|
3
6
|
module Berkshelf
|
4
7
|
class Source
|
5
8
|
include Comparable
|
6
9
|
|
7
|
-
attr_accessor :
|
10
|
+
attr_accessor :type
|
11
|
+
attr_accessor :uri_string
|
12
|
+
attr_accessor :options
|
8
13
|
|
14
|
+
# @param [Berkshelf::Berksfile] berksfile
|
9
15
|
# @param [String, Berkshelf::SourceURI] source
|
10
|
-
def initialize(source)
|
11
|
-
@
|
12
|
-
@
|
16
|
+
def initialize(berksfile, source, **options)
|
17
|
+
@options = { timeout: api_timeout, open_timeout: [(api_timeout / 10), 3].max, ssl: {} }
|
18
|
+
@options.update(options)
|
19
|
+
case source
|
20
|
+
when String
|
21
|
+
# source "https://supermarket.chef.io/"
|
22
|
+
@type = :supermarket
|
23
|
+
@uri_string = source
|
24
|
+
when :chef_server
|
25
|
+
# source :chef_server
|
26
|
+
@type = :chef_server
|
27
|
+
@uri_string = options[:url] || Berkshelf::Config.instance.chef.chef_server_url
|
28
|
+
when Hash
|
29
|
+
# source type: uri, option: value, option: value
|
30
|
+
source = source.dup
|
31
|
+
@type, @uri_string = source.shift
|
32
|
+
@options.update(source)
|
33
|
+
end
|
34
|
+
# Default options for some source types.
|
35
|
+
case @type
|
36
|
+
when :chef_server
|
37
|
+
@options[:client_name] ||= Berkshelf::Config.instance.chef.node_name
|
38
|
+
@options[:client_key] ||= Berkshelf::Config.instance.chef.client_key
|
39
|
+
when :artifactory
|
40
|
+
@options[:api_key] ||= Berkshelf::Config.instance.chef.artifactory_api_key || ENV["ARTIFACTORY_API_KEY"]
|
41
|
+
when :chef_repo
|
42
|
+
@options[:path] = uri_string
|
43
|
+
# If given a relative path, expand it against the Berksfile's folder.
|
44
|
+
@options[:path] = File.expand_path(@options[:path], File.dirname(berksfile ? berksfile.filepath : Dir.pwd))
|
45
|
+
# Lie because this won't actually parse as a URI.
|
46
|
+
@uri_string = "file://#{@options[:path]}"
|
47
|
+
end
|
48
|
+
# Set some default SSL options.
|
49
|
+
Berkshelf::Config.instance.ssl.each do |key, value|
|
50
|
+
@options[:ssl][key.to_sym] = value unless @options[:ssl].include?(key.to_sym)
|
51
|
+
end
|
52
|
+
@options[:ssl][:cert_store] = ssl_policy.store if ssl_policy.store
|
53
|
+
@universe = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def ssl_policy
|
57
|
+
@ssl_policy ||= SSLPolicy.new
|
13
58
|
end
|
14
59
|
|
15
60
|
def api_client
|
16
|
-
@api_client ||=
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
timeout: api_timeout,
|
29
|
-
open_timeout: [(api_timeout / 10), 3].max,
|
30
|
-
ssl: Berkshelf::Config.instance.ssl
|
31
|
-
)
|
32
|
-
end
|
61
|
+
@api_client ||= case type
|
62
|
+
when :chef_server
|
63
|
+
APIClient.chef_server(server_url: uri.to_s, **options)
|
64
|
+
when :artifactory
|
65
|
+
# Don't accidentally mutate the options.
|
66
|
+
client_options = options.dup
|
67
|
+
api_key = client_options.delete(:api_key)
|
68
|
+
APIClient.new(uri, headers: { "X-Jfrog-Art-Api" => api_key }, **client_options)
|
69
|
+
when :chef_repo
|
70
|
+
ChefRepoUniverse.new(uri_string, **options)
|
71
|
+
else
|
72
|
+
APIClient.new(uri, **options)
|
33
73
|
end
|
34
74
|
end
|
35
75
|
|
36
76
|
def uri
|
37
|
-
@uri ||=
|
38
|
-
SourceURI.parse(Berkshelf::Config.instance.chef.chef_server_url)
|
39
|
-
else
|
40
|
-
SourceURI.parse(source)
|
41
|
-
end
|
77
|
+
@uri ||= SourceURI.parse(uri_string)
|
42
78
|
end
|
43
79
|
|
44
80
|
# Forcefully obtain the universe from the API endpoint and assign it to {#universe}. This
|
@@ -48,7 +84,7 @@ module Berkshelf
|
|
48
84
|
def build_universe
|
49
85
|
@universe = api_client.universe
|
50
86
|
rescue => ex
|
51
|
-
@universe =
|
87
|
+
@universe = []
|
52
88
|
raise ex
|
53
89
|
end
|
54
90
|
|
@@ -96,7 +132,7 @@ module Berkshelf
|
|
96
132
|
#
|
97
133
|
# @return [APIClient::RemoteCookbook]
|
98
134
|
def latest(name)
|
99
|
-
versions(name).
|
135
|
+
versions(name).max
|
100
136
|
end
|
101
137
|
|
102
138
|
# @param [String] name
|
@@ -107,20 +143,28 @@ module Berkshelf
|
|
107
143
|
end
|
108
144
|
|
109
145
|
def to_s
|
110
|
-
|
146
|
+
case type
|
147
|
+
when :supermarket
|
148
|
+
uri.to_s
|
149
|
+
when :chef_repo
|
150
|
+
options[:path]
|
151
|
+
else
|
152
|
+
"#{type}: #{uri}"
|
153
|
+
end
|
111
154
|
end
|
112
155
|
|
113
156
|
def inspect
|
114
|
-
"#<#{self.class.name}
|
157
|
+
"#<#{self.class.name} #{type}: #{uri.to_s.inspect}, #{options.map { |k, v| "#{k}: #{v.inspect}" }.join(", ")}>"
|
115
158
|
end
|
116
159
|
|
117
160
|
def hash
|
118
|
-
|
161
|
+
[type, uri_string, options].hash
|
119
162
|
end
|
120
163
|
|
121
164
|
def ==(other)
|
122
165
|
return false unless other.is_a?(self.class)
|
123
|
-
|
166
|
+
|
167
|
+
type == other.type && uri == other.uri
|
124
168
|
end
|
125
169
|
|
126
170
|
private
|
data/lib/berkshelf/source_uri.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "addressable/uri" unless defined?(Addressable::URI)
|
2
2
|
|
3
3
|
module Berkshelf
|
4
4
|
class SourceURI < Addressable::URI
|
@@ -22,14 +22,14 @@ module Berkshelf
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
VALID_SCHEMES =
|
25
|
+
VALID_SCHEMES = %w{http https file}.freeze
|
26
26
|
|
27
27
|
# @raise [Berkshelf::InvalidSourceURI]
|
28
28
|
def validate
|
29
29
|
super
|
30
30
|
|
31
|
-
unless VALID_SCHEMES.include?(
|
32
|
-
raise InvalidSourceURI.new(self, "invalid URI scheme '#{
|
31
|
+
unless VALID_SCHEMES.include?(scheme)
|
32
|
+
raise InvalidSourceURI.new(self, "invalid URI scheme '#{scheme}'. Valid schemes: #{VALID_SCHEMES}")
|
33
33
|
end
|
34
34
|
rescue Addressable::URI::InvalidURIError => ex
|
35
35
|
raise InvalidSourceURI.new(self, ex)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "openssl" unless defined?(OpenSSL)
|
2
|
+
|
3
|
+
module Berkshelf
|
4
|
+
class SSLPolicy
|
5
|
+
|
6
|
+
# @return [Store]
|
7
|
+
# Holds trusted CA certificates used to verify peer certificates
|
8
|
+
attr_reader :store
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@store = OpenSSL::X509::Store.new.tap(&:set_default_paths)
|
12
|
+
|
13
|
+
set_custom_certs if ::File.exist?(trusted_certs_dir)
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_trusted_cert(cert)
|
17
|
+
@store.add_cert(cert)
|
18
|
+
rescue OpenSSL::X509::StoreError => e
|
19
|
+
raise e unless e.message.match(/cert already in hash table/)
|
20
|
+
end
|
21
|
+
|
22
|
+
def trusted_certs_dir
|
23
|
+
config_dir = Berkshelf.config.chef.trusted_certs_dir.to_s.tr("\\", "/")
|
24
|
+
if config_dir.empty? || !::File.exist?(config_dir)
|
25
|
+
File.join(ENV["HOME"], ".chef", "trusted_certs")
|
26
|
+
else
|
27
|
+
config_dir
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_custom_certs
|
32
|
+
::Dir.glob("#{trusted_certs_dir}/{*.crt,*.pem}").each do |cert|
|
33
|
+
cert = OpenSSL::X509::Certificate.new(IO.read(cert))
|
34
|
+
add_trusted_cert(cert)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/berkshelf/thor.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
require_relative "cli"
|
data/lib/berkshelf/thor_ext.rb
CHANGED