license-acceptance 1.0.13 → 2.1.2
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/lib/license_acceptance/acceptor.rb +44 -28
- 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 +8 -4
- data/lib/license_acceptance/strategy/argument.rb +16 -15
- data/lib/license_acceptance/strategy/environment.rb +10 -9
- data/lib/license_acceptance/strategy/file.rb +8 -10
- data/lib/license_acceptance/strategy/prompt.rb +24 -24
- data/lib/license_acceptance/strategy/provided_value.rb +7 -4
- data/lib/license_acceptance/version.rb +1 -1
- metadata +6 -132
- data/Gemfile.lock +0 -91
- data/Rakefile +0 -6
- data/spec/license_acceptance/acceptor_spec.rb +0 -302
- 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: d82f01f1176a863816de18e547817c501d796873019601fc84a6c01a2e97c713
|
4
|
+
data.tar.gz: eab594e87a7613d6126e124757f63f2acc35fcbf24485a50d84e96f2609c6f51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9ed6dd65f3fb274f110157fab725a9b2cc0b341aff313f38a4a30809fd19aaef0dd52d9eabeb95a8f1738c45fff0f3efdf39a9d681fb4b9ed3118b0eeb0090e
|
7
|
+
data.tar.gz: 3fe1ba49289e95c77ffc863deea1221bd418cb5a111262904349d4c92e3dc2a5a760e5c562175d0a167916c3f028bcf8d0a346e038e8b935a69aadc6d147f3f6
|
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.3.2"
|
10
|
+
gem "climate_control", "~> 0.2"
|
11
|
+
gem "mixlib-cli", "~> 2.1"
|
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
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require "forwardable"
|
1
|
+
require "forwardable" unless defined?(Forwardable)
|
2
2
|
require "license_acceptance/config"
|
3
3
|
require "license_acceptance/logger"
|
4
4
|
require "license_acceptance/product_reader"
|
@@ -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
|
@@ -75,37 +75,48 @@ module LicenseAcceptance
|
|
75
75
|
end
|
76
76
|
@acceptance_value = accepted_silent? ? ACCEPT_SILENT : ACCEPT
|
77
77
|
return true
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
else
|
84
|
-
@acceptance_value = ACCEPT_NO_PERSIST
|
85
|
-
[]
|
86
|
-
end
|
87
|
-
end
|
88
|
-
return true
|
89
|
-
else
|
78
|
+
end
|
79
|
+
|
80
|
+
if acceptance_value_provided?
|
81
|
+
value = provided_strategy.value || env_strategy.value || arg_strategy.value
|
82
|
+
output.puts("Unrecognized license acceptance value '#{value}', expected one of: '#{ACCEPT}', '#{ACCEPT_SILENT}', '#{ACCEPT_NO_PERSIST}'")
|
90
83
|
raise LicenseNotAcceptedError.new(product_relationship.parent, missing_licenses)
|
91
84
|
end
|
85
|
+
|
86
|
+
return true if output.isatty && accepted_license_prompt?(product_relationship, missing_licenses)
|
87
|
+
|
88
|
+
raise LicenseNotAcceptedError.new(product_relationship.parent, missing_licenses)
|
92
89
|
end
|
93
90
|
|
94
|
-
def self.check_and_persist!(product_id, version, opts={})
|
91
|
+
def self.check_and_persist!(product_id, version, opts = {})
|
95
92
|
new(opts).check_and_persist!(product_id, version)
|
96
93
|
end
|
97
94
|
|
98
|
-
def self.check_and_persist(product_id, version, opts={})
|
95
|
+
def self.check_and_persist(product_id, version, opts = {})
|
99
96
|
new(opts).check_and_persist(product_id, version)
|
100
97
|
end
|
101
98
|
|
99
|
+
def accepted_license_prompt?(product_relationship, missing_licenses)
|
100
|
+
prompt_strategy.request(missing_licenses) do
|
101
|
+
# We have to infer the acceptance value if they use the prompt to accept
|
102
|
+
if config.persist
|
103
|
+
@acceptance_value = ACCEPT
|
104
|
+
file_strategy.persist(product_relationship, missing_licenses)
|
105
|
+
else
|
106
|
+
@acceptance_value = ACCEPT_NO_PERSIST
|
107
|
+
[]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
102
112
|
# Check whether the specified product requires license acceptance for the given version.
|
103
113
|
def license_required?(mixlib_name, version)
|
104
114
|
product = product_reader.lookup_by_mixlib(mixlib_name)
|
105
115
|
return false if product.nil?
|
106
116
|
# If they don't pass a version we assume they want latest
|
107
117
|
# All versions in all channels require license acceptance
|
108
|
-
return true if
|
118
|
+
return true if %w{latest unstable current stable}.include?(version.to_s) || version.nil?
|
119
|
+
|
109
120
|
Gem::Version.new(version) >= Gem::Version.new(product.license_required_version)
|
110
121
|
end
|
111
122
|
|
@@ -114,6 +125,7 @@ module LicenseAcceptance
|
|
114
125
|
def id_from_mixlib(mixlib_name)
|
115
126
|
product = product_reader.lookup_by_mixlib(mixlib_name)
|
116
127
|
return nil if product.nil?
|
128
|
+
|
117
129
|
product.id
|
118
130
|
end
|
119
131
|
|
@@ -138,23 +150,27 @@ module LicenseAcceptance
|
|
138
150
|
provided_strategy.silent? || env_strategy.silent? || arg_strategy.silent?
|
139
151
|
end
|
140
152
|
|
153
|
+
def acceptance_value_provided?
|
154
|
+
provided_strategy.value? || env_strategy.value? || arg_strategy.value?
|
155
|
+
end
|
156
|
+
|
141
157
|
# In the case where users accept with a command line argument or environment variable
|
142
158
|
# we still want to output the fact that the filesystem was changed.
|
143
159
|
def output_num_persisted(count)
|
144
|
-
s = count > 1 ? "s": ""
|
160
|
+
s = count > 1 ? "s" : ""
|
145
161
|
output.puts <<~EOM
|
146
|
-
|
147
|
-
|
148
|
-
|
162
|
+
#{Strategy::Prompt::BORDER}
|
163
|
+
#{Strategy::Prompt::CHECK} #{count} product license#{s} accepted.
|
164
|
+
#{Strategy::Prompt::BORDER}
|
149
165
|
EOM
|
150
166
|
end
|
151
167
|
|
152
168
|
def output_persist_failed(errs)
|
153
169
|
output.puts <<~EOM
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
170
|
+
#{Strategy::Prompt::BORDER}
|
171
|
+
#{Strategy::Prompt::CHECK} Product license accepted.
|
172
|
+
Could not persist acceptance:\n\t* #{errs.map(&:message).join("\n\t* ")}
|
173
|
+
#{Strategy::Prompt::BORDER}
|
158
174
|
EOM
|
159
175
|
end
|
160
176
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
begin
|
2
|
-
require
|
3
|
-
rescue
|
2
|
+
require "thor" unless defined?(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
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
autoload :Tomlrb, "tomlrb"
|
2
2
|
require "license_acceptance/logger"
|
3
3
|
require "license_acceptance/product"
|
4
4
|
require "license_acceptance/product_relationship"
|
@@ -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
|
|
@@ -6,6 +6,8 @@ module LicenseAcceptance
|
|
6
6
|
# Look for acceptance values in the ARGV
|
7
7
|
class Argument < Base
|
8
8
|
|
9
|
+
FLAG = "--chef-license".freeze
|
10
|
+
|
9
11
|
attr_reader :argv
|
10
12
|
|
11
13
|
def initialize(argv)
|
@@ -13,31 +15,30 @@ module LicenseAcceptance
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def accepted?
|
16
|
-
|
18
|
+
String(value).downcase == ACCEPT
|
17
19
|
end
|
18
20
|
|
19
21
|
def silent?
|
20
|
-
|
22
|
+
String(value).downcase == ACCEPT_SILENT
|
21
23
|
end
|
22
24
|
|
23
25
|
def no_persist?
|
24
|
-
|
26
|
+
String(value).downcase == ACCEPT_NO_PERSIST
|
25
27
|
end
|
26
28
|
|
27
|
-
|
29
|
+
def value?
|
30
|
+
argv.any? { |s| s == FLAG || s.start_with?("#{FLAG}=") }
|
31
|
+
end
|
28
32
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
val = argv[i+1]
|
36
|
-
if val != nil && val.downcase == sought
|
37
|
-
return true
|
38
|
-
end
|
33
|
+
def value
|
34
|
+
match = argv.detect { |s| s.start_with?("#{FLAG}=") }
|
35
|
+
return match.split("=").last if match
|
36
|
+
|
37
|
+
argv.each_cons(2) do |arg, value|
|
38
|
+
return value if arg == FLAG
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
|
+
nil
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
@@ -6,6 +6,8 @@ module LicenseAcceptance
|
|
6
6
|
# Look for acceptance values in the environment
|
7
7
|
class Environment < Base
|
8
8
|
|
9
|
+
ENV_KEY = "CHEF_LICENSE".freeze
|
10
|
+
|
9
11
|
attr_reader :env
|
10
12
|
|
11
13
|
def initialize(env)
|
@@ -13,24 +15,23 @@ module LicenseAcceptance
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def accepted?
|
16
|
-
|
18
|
+
String(value).downcase == ACCEPT
|
17
19
|
end
|
18
20
|
|
19
21
|
def silent?
|
20
|
-
|
22
|
+
String(value).downcase == ACCEPT_SILENT
|
21
23
|
end
|
22
24
|
|
23
25
|
def no_persist?
|
24
|
-
|
26
|
+
String(value).downcase == ACCEPT_NO_PERSIST
|
25
27
|
end
|
26
28
|
|
27
|
-
|
29
|
+
def value?
|
30
|
+
env.key?(ENV_KEY)
|
31
|
+
end
|
28
32
|
|
29
|
-
def
|
30
|
-
|
31
|
-
return true
|
32
|
-
end
|
33
|
-
return false
|
33
|
+
def value
|
34
|
+
env[ENV_KEY]
|
34
35
|
end
|
35
36
|
|
36
37
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "date"
|
2
|
+
autoload :YAML, "yaml"
|
3
|
+
require "fileutils" unless defined?(FileUtils)
|
4
|
+
require "etc" unless defined?(Etc)
|
5
5
|
require "license_acceptance/logger"
|
6
6
|
require "license_acceptance/strategy/base"
|
7
7
|
|
@@ -28,11 +28,9 @@ module LicenseAcceptance
|
|
28
28
|
logger.debug("Searching for the following licenses: #{missing_licenses.map(&:id)}")
|
29
29
|
|
30
30
|
searching.each do |product|
|
31
|
-
found = false
|
32
31
|
config.license_locations.each do |loc|
|
33
32
|
f = ::File.join(loc, product.filename)
|
34
33
|
if ::File.exist?(f)
|
35
|
-
found = true
|
36
34
|
logger.debug("Found license #{product.filename} at #{f}")
|
37
35
|
missing_licenses.delete(product)
|
38
36
|
break
|
@@ -49,7 +47,7 @@ module LicenseAcceptance
|
|
49
47
|
parent_version = product_relationship.parent_version
|
50
48
|
root_dir = config.persist_location
|
51
49
|
|
52
|
-
|
50
|
+
unless Dir.exist?(root_dir)
|
53
51
|
begin
|
54
52
|
FileUtils.mkdir_p(root_dir)
|
55
53
|
rescue StandardError => e
|
@@ -70,7 +68,7 @@ module LicenseAcceptance
|
|
70
68
|
errs << err unless err.nil?
|
71
69
|
end
|
72
70
|
end
|
73
|
-
|
71
|
+
errs
|
74
72
|
end
|
75
73
|
|
76
74
|
private
|
@@ -91,11 +89,11 @@ module LicenseAcceptance
|
|
91
89
|
contents = Hash[contents.map { |k, v| [k.to_s, v] }]
|
92
90
|
license_file << YAML.dump(contents)
|
93
91
|
end
|
94
|
-
|
92
|
+
nil
|
95
93
|
rescue StandardError => e
|
96
94
|
msg = "Could not persist license to #{path}"
|
97
95
|
logger.info "#{msg}\n\t#{e.message}\n\t#{e.backtrace.join("\n\t")}"
|
98
|
-
|
96
|
+
e
|
99
97
|
end
|
100
98
|
|
101
99
|
end
|