license-acceptance 1.0.11 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +23 -1
- data/config/product_info.toml +1 -1
- data/lib/license_acceptance/acceptor.rb +28 -25
- data/lib/license_acceptance/cli_flags/mixlib_cli.rb +2 -2
- data/lib/license_acceptance/cli_flags/thor.rb +3 -3
- data/lib/license_acceptance/config.rb +5 -4
- data/lib/license_acceptance/product.rb +8 -6
- data/lib/license_acceptance/product_reader.rb +7 -3
- data/lib/license_acceptance/strategy/argument.rb +4 -3
- data/lib/license_acceptance/strategy/environment.rb +3 -2
- data/lib/license_acceptance/strategy/file.rb +8 -8
- data/lib/license_acceptance/strategy/prompt.rb +23 -23
- data/lib/license_acceptance/version.rb +1 -1
- metadata +6 -132
- data/Gemfile.lock +0 -94
- data/Rakefile +0 -6
- data/spec/license_acceptance/acceptor_spec.rb +0 -301
- data/spec/license_acceptance/cli_flags/mixlib_cli_spec.rb +0 -14
- data/spec/license_acceptance/cli_flags/thor_spec.rb +0 -14
- data/spec/license_acceptance/config_spec.rb +0 -111
- data/spec/license_acceptance/product_reader_spec.rb +0 -155
- data/spec/license_acceptance/product_spec.rb +0 -15
- data/spec/license_acceptance/strategy/argument_spec.rb +0 -82
- data/spec/license_acceptance/strategy/environment_spec.rb +0 -76
- data/spec/license_acceptance/strategy/file_spec.rb +0 -127
- data/spec/license_acceptance/strategy/prompt_spec.rb +0 -100
- data/spec/license_acceptance/strategy/provided_value_spec.rb +0 -55
- data/spec/spec_helper.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eee8ab3bdb6b370c3b0c2dddb7a86f22cea5240eae5df17e58e4c367fc08a0fe
|
4
|
+
data.tar.gz: 7f25c5f59f833808115dead1157b33f09c9fe4e4000c3c4e70dee586466d74a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef3af6247b87811c3796838e707d47b153c7828160a4dee699b3e95f2bef534c055fa34e828548a7e0dc9830b146014c2a8a7a4ac2cca4d94388e180d4fa5581
|
7
|
+
data.tar.gz: aa6d132e77ecfb95a8c4e263d29d7731a44f2c8d40d4cd7eeb48fbf8964c5a9e807c6cde3fec5f757af3cb9de2e5fbfc1e8d60c5729598f204fa2829d6e1c42c
|
data/Gemfile
CHANGED
@@ -1,6 +1,28 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
3
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in license-acceptance.gemspec
|
6
6
|
gemspec
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem "chefstyle", "1.2.1"
|
10
|
+
gem "climate_control", "~> 0.2"
|
11
|
+
gem "mixlib-cli", "~> 1.7"
|
12
|
+
gem "rake", ">= 10.1.0"
|
13
|
+
gem "rspec", "~> 3.0"
|
14
|
+
gem "thor", ">= 0.20", "< 2.0" # validate 2.0 when it ships
|
15
|
+
end
|
16
|
+
|
17
|
+
group :docs do
|
18
|
+
gem "yard"
|
19
|
+
gem "redcarpet"
|
20
|
+
gem "github-markup"
|
21
|
+
end
|
22
|
+
|
23
|
+
group :debug do
|
24
|
+
gem "pry"
|
25
|
+
gem "pry-byebug"
|
26
|
+
gem "pry-stack_explorer", "~> 0.4.0" # pin until we drop ruby < 2.6
|
27
|
+
gem "rb-readline"
|
28
|
+
end
|
data/config/product_info.toml
CHANGED
@@ -52,7 +52,7 @@ license_required_version = "0.4"
|
|
52
52
|
|
53
53
|
[relationships]
|
54
54
|
"infra-client" = ["inspec"]
|
55
|
-
"infra-server" = ["infra-client"]
|
55
|
+
"infra-server" = ["infra-client", "inspec"]
|
56
56
|
"push-jobs-server" = ["infra-client", "infra-server"]
|
57
57
|
"push-jobs-client" = ["infra-client"]
|
58
58
|
"chef-dk" = ["infra-client", "inspec"]
|
@@ -11,9 +11,9 @@ require "license_acceptance/strategy/provided_value"
|
|
11
11
|
|
12
12
|
module LicenseAcceptance
|
13
13
|
|
14
|
-
ACCEPT = "accept"
|
15
|
-
ACCEPT_SILENT = "accept-silent"
|
16
|
-
ACCEPT_NO_PERSIST = "accept-no-persist"
|
14
|
+
ACCEPT = "accept".freeze
|
15
|
+
ACCEPT_SILENT = "accept-silent".freeze
|
16
|
+
ACCEPT_NO_PERSIST = "accept-no-persist".freeze
|
17
17
|
|
18
18
|
class Acceptor
|
19
19
|
extend Forwardable
|
@@ -21,7 +21,7 @@ module LicenseAcceptance
|
|
21
21
|
|
22
22
|
attr_reader :config, :product_reader, :env_strategy, :file_strategy, :arg_strategy, :prompt_strategy, :provided_strategy
|
23
23
|
|
24
|
-
def initialize(opts={})
|
24
|
+
def initialize(opts = {})
|
25
25
|
@config = Config.new(opts)
|
26
26
|
Logger.initialize(config.logger)
|
27
27
|
@product_reader = ProductReader.new
|
@@ -74,28 +74,28 @@ module LicenseAcceptance
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
@acceptance_value = accepted_silent? ? ACCEPT_SILENT : ACCEPT
|
77
|
-
|
77
|
+
true
|
78
78
|
elsif config.output.isatty && prompt_strategy.request(missing_licenses) do
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
79
|
+
# We have to infer the acceptance value if they use the prompt to accept
|
80
|
+
if config.persist
|
81
|
+
@acceptance_value = ACCEPT # rubocop: disable Lint/AssignmentInCondition
|
82
|
+
file_strategy.persist(product_relationship, missing_licenses)
|
83
|
+
else
|
84
|
+
@acceptance_value = ACCEPT_NO_PERSIST # rubocop: disable Lint/AssignmentInCondition
|
85
|
+
[]
|
87
86
|
end
|
88
|
-
|
87
|
+
end
|
88
|
+
true
|
89
89
|
else
|
90
90
|
raise LicenseNotAcceptedError.new(product_relationship.parent, missing_licenses)
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
def self.check_and_persist!(product_id, version, opts={})
|
94
|
+
def self.check_and_persist!(product_id, version, opts = {})
|
95
95
|
new(opts).check_and_persist!(product_id, version)
|
96
96
|
end
|
97
97
|
|
98
|
-
def self.check_and_persist(product_id, version, opts={})
|
98
|
+
def self.check_and_persist(product_id, version, opts = {})
|
99
99
|
new(opts).check_and_persist(product_id, version)
|
100
100
|
end
|
101
101
|
|
@@ -104,7 +104,9 @@ module LicenseAcceptance
|
|
104
104
|
product = product_reader.lookup_by_mixlib(mixlib_name)
|
105
105
|
return false if product.nil?
|
106
106
|
# If they don't pass a version we assume they want latest
|
107
|
-
|
107
|
+
# All versions in all channels require license acceptance
|
108
|
+
return true if %w{latest unstable current stable}.include?(version.to_s) || version.nil?
|
109
|
+
|
108
110
|
Gem::Version.new(version) >= Gem::Version.new(product.license_required_version)
|
109
111
|
end
|
110
112
|
|
@@ -113,6 +115,7 @@ module LicenseAcceptance
|
|
113
115
|
def id_from_mixlib(mixlib_name)
|
114
116
|
product = product_reader.lookup_by_mixlib(mixlib_name)
|
115
117
|
return nil if product.nil?
|
118
|
+
|
116
119
|
product.id
|
117
120
|
end
|
118
121
|
|
@@ -140,20 +143,20 @@ module LicenseAcceptance
|
|
140
143
|
# In the case where users accept with a command line argument or environment variable
|
141
144
|
# we still want to output the fact that the filesystem was changed.
|
142
145
|
def output_num_persisted(count)
|
143
|
-
s = count > 1 ? "s": ""
|
146
|
+
s = count > 1 ? "s" : ""
|
144
147
|
output.puts <<~EOM
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
+
#{Strategy::Prompt::BORDER}
|
149
|
+
#{Strategy::Prompt::CHECK} #{count} product license#{s} accepted.
|
150
|
+
#{Strategy::Prompt::BORDER}
|
148
151
|
EOM
|
149
152
|
end
|
150
153
|
|
151
154
|
def output_persist_failed(errs)
|
152
155
|
output.puts <<~EOM
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
156
|
+
#{Strategy::Prompt::BORDER}
|
157
|
+
#{Strategy::Prompt::CHECK} Product license accepted.
|
158
|
+
Could not persist acceptance:\n\t* #{errs.map(&:message).join("\n\t* ")}
|
159
|
+
#{Strategy::Prompt::BORDER}
|
157
160
|
EOM
|
158
161
|
end
|
159
162
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
begin
|
2
|
-
require
|
3
|
-
rescue
|
2
|
+
require "thor"
|
3
|
+
rescue
|
4
4
|
raise "Must have thor gem installed to use this mixin"
|
5
5
|
end
|
6
6
|
|
@@ -12,7 +12,7 @@ module LicenseAcceptance
|
|
12
12
|
def self.included(klass)
|
13
13
|
klass.class_option :chef_license,
|
14
14
|
type: :string,
|
15
|
-
desc:
|
15
|
+
desc: "Accept the license for this product and any contained products: accept, accept-no-persist, accept-silent"
|
16
16
|
end
|
17
17
|
|
18
18
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require "logger"
|
2
2
|
|
3
3
|
module LicenseAcceptance
|
4
4
|
class Config
|
5
5
|
attr_accessor :output, :logger, :license_locations, :persist_location, :persist
|
6
6
|
|
7
|
-
def initialize(opts={})
|
7
|
+
def initialize(opts = {})
|
8
8
|
@output = opts.fetch(:output, $stdout)
|
9
9
|
@logger = opts.fetch(:logger, ::Logger.new(IO::NULL))
|
10
10
|
@license_locations = opts.fetch(:license_locations, default_license_locations)
|
@@ -21,7 +21,7 @@ module LicenseAcceptance
|
|
21
21
|
|
22
22
|
def default_license_locations
|
23
23
|
if windows?
|
24
|
-
root = ENV.fetch("SYSTEMDRIVE","C:")
|
24
|
+
root = ENV.fetch("SYSTEMDRIVE", "C:")
|
25
25
|
l = [ File.join(root, "chef/accepted_licenses/") ]
|
26
26
|
unless is_root?
|
27
27
|
# Look through a list of possible user locations and pick the first one that exists
|
@@ -32,6 +32,7 @@ module LicenseAcceptance
|
|
32
32
|
possible_dirs << ENV["HOMESHARE"] + ENV["HOMEPATH"] if ENV["HOMESHARE"] && ENV["HOMEPATH"]
|
33
33
|
possible_dirs << ENV["USERPROFILE"] if ENV["USERPROFILE"]
|
34
34
|
raise NoValidEnvironmentVar if possible_dirs.empty?
|
35
|
+
|
35
36
|
possible_dirs.each do |possible_dir|
|
36
37
|
if Dir.exist?(possible_dir)
|
37
38
|
full_possible_dir = File.join(possible_dir, ".chef/accepted_licenses/")
|
@@ -42,7 +43,7 @@ module LicenseAcceptance
|
|
42
43
|
end
|
43
44
|
else
|
44
45
|
l = [ "/etc/chef/accepted_licenses/" ]
|
45
|
-
l << File.join(ENV[
|
46
|
+
l << File.join(ENV["HOME"], ".chef/accepted_licenses/") unless is_root?
|
46
47
|
end
|
47
48
|
l
|
48
49
|
end
|
@@ -14,14 +14,16 @@ module LicenseAcceptance
|
|
14
14
|
|
15
15
|
def ==(other)
|
16
16
|
return false if other.class != Product
|
17
|
+
|
17
18
|
if other.id == id &&
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
other.pretty_name == pretty_name &&
|
20
|
+
other.filename == filename &&
|
21
|
+
other.mixlib_name == mixlib_name &&
|
22
|
+
other.license_required_version == license_required_version
|
23
|
+
return true
|
23
24
|
end
|
24
|
-
|
25
|
+
|
26
|
+
false
|
25
27
|
end
|
26
28
|
|
27
29
|
end
|
@@ -18,7 +18,7 @@ module LicenseAcceptance
|
|
18
18
|
toml = Tomlrb.load_file(location, symbolize_keys: false)
|
19
19
|
raise InvalidProductInfo.new(location) if toml.empty? || toml["products"].nil? || toml["relationships"].nil?
|
20
20
|
|
21
|
-
|
21
|
+
toml["products"].each do |product|
|
22
22
|
products[product["id"]] = Product.new(
|
23
23
|
product["id"], product["pretty_name"],
|
24
24
|
product["filename"], product["mixlib_name"],
|
@@ -26,7 +26,7 @@ module LicenseAcceptance
|
|
26
26
|
)
|
27
27
|
end
|
28
28
|
|
29
|
-
|
29
|
+
toml["relationships"].each do |parent_id, children|
|
30
30
|
parent = products[parent_id]
|
31
31
|
raise UnknownParent.new(parent_id) if parent.nil?
|
32
32
|
# Its fine to not have a relationship entry, but not fine to have
|
@@ -34,9 +34,11 @@ module LicenseAcceptance
|
|
34
34
|
if children.nil? || children.empty? || !children.is_a?(Array)
|
35
35
|
raise NoChildRelationships.new(parent)
|
36
36
|
end
|
37
|
+
|
37
38
|
children.map! do |child_id|
|
38
39
|
child = products[child_id]
|
39
40
|
raise UnknownChild.new(child_id) if child.nil?
|
41
|
+
|
40
42
|
child
|
41
43
|
end
|
42
44
|
relationships[parent] = children
|
@@ -52,6 +54,7 @@ module LicenseAcceptance
|
|
52
54
|
if ENV["CHEF_LICENSE_PRODUCT_INFO"]
|
53
55
|
return ENV["CHEF_LICENSE_PRODUCT_INFO"]
|
54
56
|
end
|
57
|
+
|
55
58
|
File.absolute_path(File.join(__FILE__, "../../../config/product_info.toml"))
|
56
59
|
end
|
57
60
|
|
@@ -60,9 +63,10 @@ module LicenseAcceptance
|
|
60
63
|
raise UnknownProduct.new(parent_id)
|
61
64
|
end
|
62
65
|
children = relationships.fetch(parent_product, [])
|
63
|
-
|
66
|
+
unless parent_version.is_a? String
|
64
67
|
raise ProductVersionTypeError.new(parent_version)
|
65
68
|
end
|
69
|
+
|
66
70
|
ProductRelationship.new(parent_product, children, parent_version)
|
67
71
|
end
|
68
72
|
|
@@ -30,14 +30,15 @@ module LicenseAcceptance
|
|
30
30
|
if argv.include?("--chef-license=#{sought}")
|
31
31
|
return true
|
32
32
|
end
|
33
|
+
|
33
34
|
i = argv.index("--chef-license")
|
34
35
|
unless i.nil?
|
35
|
-
val = argv[i+1]
|
36
|
-
if val
|
36
|
+
val = argv[i + 1]
|
37
|
+
if !val.nil? && val.downcase == sought
|
37
38
|
return true
|
38
39
|
end
|
39
40
|
end
|
40
|
-
|
41
|
+
false
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
@@ -27,10 +27,11 @@ module LicenseAcceptance
|
|
27
27
|
private
|
28
28
|
|
29
29
|
def look_for_value(sought)
|
30
|
-
if env[
|
30
|
+
if env["CHEF_LICENSE"] && env["CHEF_LICENSE"].downcase == sought
|
31
31
|
return true
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
|
+
false
|
34
35
|
end
|
35
36
|
|
36
37
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "date"
|
2
|
+
require "yaml"
|
3
|
+
require "fileutils"
|
4
|
+
require "etc"
|
5
5
|
require "license_acceptance/logger"
|
6
6
|
require "license_acceptance/strategy/base"
|
7
7
|
|
@@ -49,7 +49,7 @@ module LicenseAcceptance
|
|
49
49
|
parent_version = product_relationship.parent_version
|
50
50
|
root_dir = config.persist_location
|
51
51
|
|
52
|
-
|
52
|
+
unless Dir.exist?(root_dir)
|
53
53
|
begin
|
54
54
|
FileUtils.mkdir_p(root_dir)
|
55
55
|
rescue StandardError => e
|
@@ -70,7 +70,7 @@ module LicenseAcceptance
|
|
70
70
|
errs << err unless err.nil?
|
71
71
|
end
|
72
72
|
end
|
73
|
-
|
73
|
+
errs
|
74
74
|
end
|
75
75
|
|
76
76
|
private
|
@@ -91,11 +91,11 @@ module LicenseAcceptance
|
|
91
91
|
contents = Hash[contents.map { |k, v| [k.to_s, v] }]
|
92
92
|
license_file << YAML.dump(contents)
|
93
93
|
end
|
94
|
-
|
94
|
+
nil
|
95
95
|
rescue StandardError => e
|
96
96
|
msg = "Could not persist license to #{path}"
|
97
97
|
logger.info "#{msg}\n\t#{e.message}\n\t#{e.backtrace.join("\n\t")}"
|
98
|
-
|
98
|
+
e
|
99
99
|
end
|
100
100
|
|
101
101
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "tty-prompt"
|
2
|
+
require "pastel"
|
3
3
|
require "license_acceptance/logger"
|
4
4
|
require "license_acceptance/strategy/base"
|
5
5
|
require "timeout"
|
@@ -7,7 +7,7 @@ require "timeout"
|
|
7
7
|
module LicenseAcceptance
|
8
8
|
module Strategy
|
9
9
|
|
10
|
-
# Interactive prompt for accepting and
|
10
|
+
# Interactive prompt for accepting and persistence license acceptance, or failing with custom exit code
|
11
11
|
class Prompt < Base
|
12
12
|
include Logger
|
13
13
|
|
@@ -17,30 +17,30 @@ module LicenseAcceptance
|
|
17
17
|
@output = config.output
|
18
18
|
end
|
19
19
|
|
20
|
-
WIDTH = 50
|
20
|
+
WIDTH = 50
|
21
21
|
PASTEL = Pastel.new
|
22
22
|
BORDER = "+---------------------------------------------+".freeze
|
23
23
|
YES = PASTEL.green.bold("yes")
|
24
|
-
CHECK
|
24
|
+
CHECK = PASTEL.green("✔")
|
25
25
|
|
26
26
|
def request(missing_licenses, &persist_callback)
|
27
27
|
logger.debug("Requesting a license for #{missing_licenses.map(&:id)}")
|
28
28
|
c = missing_licenses.size
|
29
|
-
s = c > 1 ? "s": ""
|
29
|
+
s = c > 1 ? "s" : ""
|
30
30
|
|
31
31
|
acceptance_question = "Do you accept the #{c} product license#{s} (#{YES}/no)?"
|
32
32
|
output.puts <<~EOM
|
33
|
-
|
34
|
-
|
33
|
+
#{BORDER}
|
34
|
+
Chef License Acceptance
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
Before you can continue, #{c} product license#{s}
|
37
|
+
must be accepted. View the license at
|
38
|
+
https://www.chef.io/end-user-license-agreement/
|
39
39
|
|
40
|
-
|
41
|
-
|
40
|
+
License#{s} that need accepting:
|
41
|
+
* #{missing_licenses.map(&:pretty_name).join("\n * ")}
|
42
42
|
|
43
|
-
|
43
|
+
#{acceptance_question}
|
44
44
|
|
45
45
|
EOM
|
46
46
|
|
@@ -51,10 +51,10 @@ module LicenseAcceptance
|
|
51
51
|
|
52
52
|
output.puts <<~EOM
|
53
53
|
|
54
|
-
|
55
|
-
|
54
|
+
If you do not accept this license you will
|
55
|
+
not be able to use Chef products.
|
56
56
|
|
57
|
-
|
57
|
+
#{acceptance_question}
|
58
58
|
|
59
59
|
EOM
|
60
60
|
|
@@ -62,7 +62,7 @@ module LicenseAcceptance
|
|
62
62
|
if answer != "yes"
|
63
63
|
output.puts BORDER
|
64
64
|
end
|
65
|
-
|
65
|
+
answer
|
66
66
|
end
|
67
67
|
|
68
68
|
private
|
@@ -73,12 +73,12 @@ module LicenseAcceptance
|
|
73
73
|
|
74
74
|
answer = "no"
|
75
75
|
begin
|
76
|
-
Timeout
|
76
|
+
Timeout.timeout(60, PromptTimeout) do
|
77
77
|
answer = prompt.ask(">") do |q|
|
78
78
|
q.modify :down, :trim
|
79
79
|
q.required true
|
80
80
|
q.messages[:required?] = "You must enter 'yes' or 'no'"
|
81
|
-
q.validate
|
81
|
+
q.validate(/^\s*(yes|no)\s*$/i)
|
82
82
|
q.messages[:valid?] = "You must enter 'yes' or 'no'"
|
83
83
|
end
|
84
84
|
end
|
@@ -95,13 +95,13 @@ module LicenseAcceptance
|
|
95
95
|
output.puts "#{CHECK} #{c} product license#{s} persisted.\n\n"
|
96
96
|
else
|
97
97
|
output.puts <<~EOM
|
98
|
-
|
99
|
-
|
98
|
+
#{CHECK} #{c} product license#{s} accepted.
|
99
|
+
Could not persist acceptance:\n\t* #{errs.map(&:message).join("\n\t* ")}
|
100
100
|
EOM
|
101
101
|
end
|
102
102
|
return true
|
103
103
|
end
|
104
|
-
|
104
|
+
false
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|