license-acceptance 1.0.13 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|