knife 18.6.13 → 18.8.13
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/knife.gemspec +7 -5
- data/lib/chef/knife/bootstrap/client_builder.rb +1 -1
- data/lib/chef/knife/bootstrap.rb +9 -2
- data/lib/chef/knife/config_use.rb +1 -1
- data/lib/chef/knife/configure_client.rb +1 -1
- data/lib/chef/knife/core/bootstrap_context.rb +2 -2
- data/lib/chef/knife/core/cookbook_scm_repo.rb +1 -1
- data/lib/chef/knife/core/object_loader.rb +1 -1
- data/lib/chef/knife/core/ui.rb +1 -1
- data/lib/chef/knife/core/windows_bootstrap_context.rb +6 -8
- data/lib/chef/knife/edit.rb +1 -1
- data/lib/chef/knife/exec.rb +1 -1
- data/lib/chef/knife/raw.rb +1 -1
- data/lib/chef/knife/ssl_check.rb +1 -1
- data/lib/chef/knife/user_edit.rb +2 -2
- data/lib/chef/knife/version.rb +1 -1
- data/lib/chef/knife/xargs.rb +1 -1
- data/lib/chef/knife/yaml_convert.rb +1 -1
- data/lib/chef/utils/licensing_handler.rb +21 -2
- data/spec/functional/cookbook_delete_spec.rb +1 -0
- data/spec/tiny_server.rb +5 -2
- data/spec/unit/knife/bootstrap_spec.rb +24 -1
- data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +45 -1
- data/spec/unit/knife/license_spec.rb +5 -0
- data/spec/unit/utils/licensing_handler_spec.rb +140 -0
- metadata +33 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 947a92dbe3f969e49b8a064a00d3f48e9e2ea21668ac06a7ec30516ed152084c
|
4
|
+
data.tar.gz: 94ce940ff4591d74d0f4ac11a6d94d05f0865ae3173e1a1e88359395cddd534a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fedb26a1a3e59e4bd36a3aa48960f2aa3b1552e9b080bf8d55a4410afb1b6fb67f9232b98f2215099e338e3e63a11bc79e3b9d5ad03475b88b0b45590a436f93
|
7
|
+
data.tar.gz: 2fd51a2cec9d9b39bd86008a49b2bd52db896f177400661a4213f2c11778b33c481c8c52f4f8f70161cdcfa19619736e04e4e6e9673450de3f25bbcf229c814a
|
data/knife.gemspec
CHANGED
@@ -15,12 +15,12 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.required_ruby_version = ">= 3.1.0"
|
17
17
|
|
18
|
-
s.add_dependency "chef-config", "~> 18.
|
19
|
-
s.add_dependency "chef-utils", "~> 18.
|
20
|
-
s.add_dependency "chef", "~> 18.
|
21
|
-
s.add_dependency "chef-bin", "~> 18.
|
18
|
+
s.add_dependency "chef-config", "~> 18.0"
|
19
|
+
s.add_dependency "chef-utils", "~> 18.0"
|
20
|
+
s.add_dependency "chef", "~> 18.0"
|
21
|
+
s.add_dependency "chef-bin", "~> 18.0"
|
22
22
|
s.add_dependency "train-core", "~> 3.10" # 3.2.28 fixes sudo prompts. See https://github.com/chef/chef/pull/9635
|
23
|
-
s.add_dependency "train-winrm", "
|
23
|
+
s.add_dependency "train-winrm", "~> 0.2.17"
|
24
24
|
s.add_dependency "license-acceptance", ">= 1.0.5", "< 3"
|
25
25
|
s.add_dependency "mixlib-cli", ">= 2.1.1", "< 3.0"
|
26
26
|
s.add_dependency "mixlib-archive", ">= 0.4", "< 2.0"
|
@@ -47,6 +47,8 @@ Gem::Specification.new do |s|
|
|
47
47
|
|
48
48
|
s.add_dependency "chef-licensing", "~> 1.0"
|
49
49
|
|
50
|
+
s.add_dependency "chef-zero", "~> 15.0.21" # for knife zero
|
51
|
+
|
50
52
|
s.bindir = "bin"
|
51
53
|
s.executables = %w{ knife }
|
52
54
|
|
data/lib/chef/knife/bootstrap.rb
CHANGED
@@ -456,6 +456,10 @@ class Chef
|
|
456
456
|
end
|
457
457
|
end
|
458
458
|
|
459
|
+
# This method was renamed to check_eula_license to better reflect its purpose.
|
460
|
+
# Some of the knife plugins may still be using the old name, so we keep it for backward compatibility.
|
461
|
+
alias_method :check_license, :check_eula_license
|
462
|
+
|
459
463
|
# The default bootstrap template to use to bootstrap a server.
|
460
464
|
# This is a public API hook which knife plugins use or inherit and override.
|
461
465
|
#
|
@@ -547,7 +551,7 @@ class Chef
|
|
547
551
|
require "erubis" unless defined?(Erubis)
|
548
552
|
@config[:first_boot_attributes] = first_boot_attributes
|
549
553
|
template_file = find_template
|
550
|
-
template =
|
554
|
+
template = File.read(template_file).chomp
|
551
555
|
Erubis::Eruby.new(template).evaluate(bootstrap_context)
|
552
556
|
end
|
553
557
|
|
@@ -1199,10 +1203,13 @@ class Chef
|
|
1199
1203
|
config[:license_url] = license.install_sh_url
|
1200
1204
|
config[:license_id] = license.license_key
|
1201
1205
|
config[:license_type] = license.license_type
|
1206
|
+
config[:omnitruck_url] = license.omnitruck_url
|
1202
1207
|
end
|
1203
1208
|
|
1204
1209
|
def warn_license_usage
|
1205
|
-
|
1210
|
+
# remove the dependency on .present? from activesupport since this is the one usage
|
1211
|
+
license_type = config[:license_type]
|
1212
|
+
return unless license_type.nil? || (license_type.respond_to?(:empty?) && license_type.empty?)
|
1206
1213
|
|
1207
1214
|
ui.warn(<<~MSG
|
1208
1215
|
|
@@ -39,7 +39,7 @@ class Chef
|
|
39
39
|
end
|
40
40
|
ui.info("Writing validation.pem")
|
41
41
|
File.open(File.join(@config_dir, "validation.pem"), "w") do |validation|
|
42
|
-
validation.puts(
|
42
|
+
validation.puts(File.read(Chef::Config[:validation_key]))
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -50,7 +50,7 @@ class Chef
|
|
50
50
|
def validation_key
|
51
51
|
if chef_config[:validation_key] &&
|
52
52
|
File.exist?(File.expand_path(chef_config[:validation_key]))
|
53
|
-
|
53
|
+
File.read(File.expand_path(chef_config[:validation_key]))
|
54
54
|
else
|
55
55
|
false
|
56
56
|
end
|
@@ -242,7 +242,7 @@ class Chef
|
|
242
242
|
if chef_config[:trusted_certs_dir]
|
243
243
|
Dir.glob(File.join(ChefConfig::PathHelper.escape_glob_dir(chef_config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert|
|
244
244
|
content << "cat > /etc/chef/trusted_certs/#{File.basename(cert)} <<'EOP'\n" +
|
245
|
-
|
245
|
+
File.read(File.expand_path(cert)) + "\nEOP\n"
|
246
246
|
end
|
247
247
|
end
|
248
248
|
content
|
@@ -102,7 +102,7 @@ class Chef
|
|
102
102
|
def merge_updates_from(cookbook_name, version)
|
103
103
|
branch = "chef-vendor-#{cookbook_name}"
|
104
104
|
Dir.chdir(repo_path) do
|
105
|
-
if system("git merge
|
105
|
+
if system("git", "merge", branch)
|
106
106
|
ui.info("Cookbook #{cookbook_name} version #{version} successfully installed")
|
107
107
|
else
|
108
108
|
ui.error("You have merge conflicts - please resolve manually")
|
@@ -87,7 +87,7 @@ class Chef
|
|
87
87
|
def object_from_file(filename)
|
88
88
|
case filename
|
89
89
|
when /\.(js|json)$/
|
90
|
-
r = FFI_Yajl::Parser.parse(
|
90
|
+
r = FFI_Yajl::Parser.parse(File.read(filename))
|
91
91
|
|
92
92
|
# Chef::DataBagItem doesn't work well with the json_create method
|
93
93
|
if @klass == Chef::DataBagItem
|
data/lib/chef/knife/core/ui.rb
CHANGED
@@ -236,7 +236,7 @@ class Chef
|
|
236
236
|
tf.close
|
237
237
|
raise "Please set EDITOR environment variable. See https://docs.chef.io/workstation/knife_setup/#setting-your-text-editor for details." unless system("#{config[:editor]} #{tf.path}")
|
238
238
|
|
239
|
-
output =
|
239
|
+
output = File.read(tf.path)
|
240
240
|
end
|
241
241
|
end
|
242
242
|
|
@@ -44,7 +44,7 @@ class Chef
|
|
44
44
|
|
45
45
|
def validation_key
|
46
46
|
if File.exist?(File.expand_path(chef_config[:validation_key]))
|
47
|
-
|
47
|
+
File.read(File.expand_path(chef_config[:validation_key]))
|
48
48
|
else
|
49
49
|
false
|
50
50
|
end
|
@@ -330,16 +330,14 @@ class Chef
|
|
330
330
|
# Build a URL that will redirect to the correct Chef Infra msi download.
|
331
331
|
def msi_url(machine_os = nil, machine_arch = nil, download_context = nil)
|
332
332
|
if config[:msi_url].nil? || config[:msi_url].empty?
|
333
|
-
url = if config[:
|
334
|
-
format(config[:
|
333
|
+
url = if config[:license_id] && !config[:omnitruck_url].empty?
|
334
|
+
format(config[:omnitruck_url], config[:channel] + "/chef/download") + "&p=windows"
|
335
335
|
else
|
336
|
-
"https://omnitruck.chef.io/chef/download?p=windows"
|
336
|
+
"https://omnitruck.chef.io/chef/download?p=windows&channel=#{config[:channel]}"
|
337
337
|
end
|
338
338
|
url += "&pv=#{machine_os}" unless machine_os.nil?
|
339
339
|
url += "&m=#{machine_arch}" unless machine_arch.nil?
|
340
340
|
url += "&DownloadContext=#{download_context}" unless download_context.nil?
|
341
|
-
url += "&channel=#{config[:channel]}" if config[:license_url].blank?
|
342
|
-
url += "&license_id=#{config[:license_id]}" unless config[:license_id].blank?
|
343
341
|
url += "&v=#{version_to_install}"
|
344
342
|
else
|
345
343
|
config[:msi_url]
|
@@ -370,7 +368,7 @@ class Chef
|
|
370
368
|
if chef_config[:trusted_certs_dir]
|
371
369
|
Dir.glob(File.join(ChefConfig::PathHelper.escape_glob_dir(chef_config[:trusted_certs_dir]), "*.{crt,pem}")).each do |cert|
|
372
370
|
content << "> #{bootstrap_directory}/trusted_certs/#{File.basename(cert)} (\n" +
|
373
|
-
escape_and_echo(
|
371
|
+
escape_and_echo(File.read(File.expand_path(cert))) + "\n)\n"
|
374
372
|
end
|
375
373
|
end
|
376
374
|
content
|
@@ -388,7 +386,7 @@ class Chef
|
|
388
386
|
content << "mkdir #{file_on_node}\n"
|
389
387
|
else
|
390
388
|
content << "> #{file_on_node} (\n" +
|
391
|
-
escape_and_echo(
|
389
|
+
escape_and_echo(File.read(File.expand_path(f))) + "\n)\n"
|
392
390
|
end
|
393
391
|
end
|
394
392
|
end
|
data/lib/chef/knife/edit.rb
CHANGED
@@ -77,7 +77,7 @@ class Chef
|
|
77
77
|
raise "Please set EDITOR environment variable. See https://docs.chef.io/workstation/knife_setup/#setting-your-text-editor for details."
|
78
78
|
end
|
79
79
|
|
80
|
-
result_text =
|
80
|
+
result_text = File.read(file.path)
|
81
81
|
|
82
82
|
return result_text if result_text != text
|
83
83
|
end
|
data/lib/chef/knife/exec.rb
CHANGED
@@ -57,7 +57,7 @@ class Chef::Knife::Exec < Chef::Knife
|
|
57
57
|
elsif !scripts.empty?
|
58
58
|
scripts.each do |script|
|
59
59
|
file = find_script(script)
|
60
|
-
context.instance_eval(
|
60
|
+
context.instance_eval(File.read(file), file, 0)
|
61
61
|
end
|
62
62
|
else
|
63
63
|
puts "An interactive shell is opened"
|
data/lib/chef/knife/raw.rb
CHANGED
data/lib/chef/knife/ssl_check.rb
CHANGED
@@ -267,7 +267,7 @@ class Chef
|
|
267
267
|
|
268
268
|
def check_X509_certificate(cert_file)
|
269
269
|
store = OpenSSL::X509::Store.new
|
270
|
-
cert = OpenSSL::X509::Certificate.new(
|
270
|
+
cert = OpenSSL::X509::Certificate.new(File.read(File.expand_path(cert_file)))
|
271
271
|
begin
|
272
272
|
store.add_cert(cert)
|
273
273
|
# test if the store can verify the cert we just added
|
data/lib/chef/knife/user_edit.rb
CHANGED
@@ -69,7 +69,7 @@ class Chef
|
|
69
69
|
# return updated user
|
70
70
|
def get_updated_user(original_user)
|
71
71
|
if config[:input]
|
72
|
-
edited_user = JSON.parse(
|
72
|
+
edited_user = JSON.parse(File.read(config[:input]))
|
73
73
|
elsif config[:filename]
|
74
74
|
file = config[:filename]
|
75
75
|
unless File.exist?(file) ? File.writable?(file) : File.writable?(File.dirname(file))
|
@@ -83,7 +83,7 @@ class Chef
|
|
83
83
|
f.close
|
84
84
|
raise "Please set EDITOR environment variable. See https://docs.chef.io/workstation/knife_setup/#setting-your-text-editor for details." unless system("#{config[:editor]} #{f.path}")
|
85
85
|
|
86
|
-
edited_user = JSON.parse(
|
86
|
+
edited_user = JSON.parse(File.read(f.path))
|
87
87
|
end
|
88
88
|
end
|
89
89
|
else
|
data/lib/chef/knife/version.rb
CHANGED
data/lib/chef/knife/xargs.rb
CHANGED
@@ -238,7 +238,7 @@ class Chef
|
|
238
238
|
# Check if the output is different
|
239
239
|
tempfiles.each_pair do |tempfile, file|
|
240
240
|
# Read the new output
|
241
|
-
new_value =
|
241
|
+
new_value = File.binread(tempfile.path)
|
242
242
|
|
243
243
|
# Upload the output if different
|
244
244
|
if config[:force] || new_value != file[:value]
|
@@ -48,7 +48,7 @@ class Chef::Knife::YamlConvert < Chef::Knife
|
|
48
48
|
ui.fatal!("Output Ruby file '#{ruby_file}' already exists")
|
49
49
|
end
|
50
50
|
|
51
|
-
yaml_contents =
|
51
|
+
yaml_contents = File.read(yaml_file)
|
52
52
|
|
53
53
|
# YAML can contain multiple documents (--- is the separator), let's not support that.
|
54
54
|
if ::YAML.load_stream(yaml_contents).length > 1
|
@@ -1,3 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
1
18
|
require_relative "licensing_config"
|
2
19
|
|
3
20
|
class Chef
|
@@ -19,9 +36,11 @@ class Chef
|
|
19
36
|
end
|
20
37
|
|
21
38
|
def omnitruck_url
|
22
|
-
url = OMNITRUCK_URLS[license_type]
|
39
|
+
url = OMNITRUCK_URLS[license_type]
|
40
|
+
is_legacy = url.nil?
|
41
|
+
url ||= LEGACY_OMNITRUCK_URL
|
23
42
|
|
24
|
-
"#{url}/%s#{
|
43
|
+
"#{url}/%s#{is_legacy ? "" : "?license_id=#{license_key}"}"
|
25
44
|
end
|
26
45
|
|
27
46
|
def install_sh_url
|
data/spec/tiny_server.rb
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
require "webrick"
|
20
20
|
require "webrick/https"
|
21
21
|
require "rack"
|
22
|
+
require "rackup"
|
22
23
|
require "singleton"
|
23
24
|
require "open-uri"
|
24
25
|
require "chef/config"
|
@@ -91,7 +92,7 @@ module TinyServer
|
|
91
92
|
|
92
93
|
def create_server(**extra_options)
|
93
94
|
server = WEBrick::HTTPServer.new(**options, **extra_options)
|
94
|
-
server.mount("/",
|
95
|
+
server.mount("/", Rackup::Handler::WEBrick, API.instance)
|
95
96
|
server
|
96
97
|
end
|
97
98
|
end
|
@@ -172,7 +173,9 @@ module TinyServer
|
|
172
173
|
|
173
174
|
def initialize(response_code = 200, data = nil, headers = nil, &block)
|
174
175
|
@response_code, @data = response_code, data
|
175
|
-
|
176
|
+
# .merge creates a new hash, headers is sometimes passed as nil, @response_headers gets mutated somewhere
|
177
|
+
# in processing
|
178
|
+
@response_headers = HEADERS.merge(headers || {})
|
176
179
|
@block = block_given? ? block : nil
|
177
180
|
end
|
178
181
|
|
@@ -75,6 +75,29 @@ describe Chef::Knife::Bootstrap do
|
|
75
75
|
expect(Chef::Config[:chef_license]).to eq("accept-no-persist")
|
76
76
|
end
|
77
77
|
end
|
78
|
+
|
79
|
+
describe "alias" do
|
80
|
+
before do
|
81
|
+
expect(acceptor).to receive(:license_required?).and_return(false)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should be aliased to check_license" do
|
85
|
+
expect(knife).to respond_to(:check_license)
|
86
|
+
expect(knife).to respond_to(:check_eula_license)
|
87
|
+
|
88
|
+
knife.check_license
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should logs check_eula_license using check_license" do
|
92
|
+
expect(Chef::Log).to receive(:debug).with("Checking if we need to accept Chef license to bootstrap node")
|
93
|
+
knife.check_license
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should logs the same with check_eula_license" do
|
97
|
+
expect(Chef::Log).to receive(:debug).with("Checking if we need to accept Chef license to bootstrap node")
|
98
|
+
knife.check_eula_license
|
99
|
+
end
|
100
|
+
end
|
78
101
|
end
|
79
102
|
|
80
103
|
context "#bootstrap_template" do
|
@@ -368,7 +391,7 @@ describe Chef::Knife::Bootstrap do
|
|
368
391
|
allow(::File).to receive(:read).and_return('{ "foo" : "bar" }')
|
369
392
|
knife.parse_options(["--hint", "openstack=hints/openstack.json"])
|
370
393
|
knife.merge_configs
|
371
|
-
expect(knife.render_template).to match(/\{\"foo\"
|
394
|
+
expect(knife.render_template).to match(/\{ \"foo\" : \"bar\"\ }/)
|
372
395
|
end
|
373
396
|
end
|
374
397
|
|
@@ -209,7 +209,7 @@ describe Chef::Knife::Core::WindowsBootstrapContext do
|
|
209
209
|
end
|
210
210
|
|
211
211
|
it "returns a chef.io msi url with provided url parameters substituted" do
|
212
|
-
reference_url = "https://omnitruck.chef.io/chef/download?p=windows&pv=machine&m=arch&DownloadContext=ctx&
|
212
|
+
reference_url = "https://omnitruck.chef.io/chef/download?p=windows&channel=stable&pv=machine&m=arch&DownloadContext=ctx&v=something"
|
213
213
|
expect(bootstrap_context.msi_url("machine", "arch", "ctx")).to eq(reference_url)
|
214
214
|
end
|
215
215
|
|
@@ -234,5 +234,49 @@ describe Chef::Knife::Core::WindowsBootstrapContext do
|
|
234
234
|
expect(bootstrap_context.msi_url("machine", "arch", "ctx")).to eq(custom_url)
|
235
235
|
end
|
236
236
|
end
|
237
|
+
|
238
|
+
context "with licensing changes" do
|
239
|
+
let(:config) { { channel: "stable", bootstrap_version: "latest" } }
|
240
|
+
|
241
|
+
it "should return the old omnitruck api in case license not present" do
|
242
|
+
nil_license_obj = Chef::Utils::LicensingHandler.new(nil, nil)
|
243
|
+
expect(Chef::Utils::LicensingHandler).to receive(:validate!).and_return(nil_license_obj)
|
244
|
+
b = Chef::Knife::Bootstrap.new([])
|
245
|
+
b.send(:fetch_license)
|
246
|
+
config.merge!(b.config)
|
247
|
+
|
248
|
+
expect(bootstrap_context.msi_url).to eq("https://omnitruck.chef.io/chef/download?p=windows&channel=stable&v=latest")
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should return the correct msi_url for trial license" do
|
252
|
+
license_obj_trial = Chef::Utils::LicensingHandler.new("key-trial-123", "trial")
|
253
|
+
expect(Chef::Utils::LicensingHandler).to receive(:validate!).and_return(license_obj_trial)
|
254
|
+
|
255
|
+
b = Chef::Knife::Bootstrap.new([])
|
256
|
+
b.send(:fetch_license)
|
257
|
+
config.merge!(b.config)
|
258
|
+
expect(bootstrap_context.msi_url).to eq("https://chefdownload-trial.chef.io/stable/chef/download?license_id=key-trial-123&p=windows&v=latest")
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should return the correct msi_url for commercial license" do
|
262
|
+
license_obj_commercial = Chef::Utils::LicensingHandler.new("key-commercial-123", "commercial")
|
263
|
+
expect(Chef::Utils::LicensingHandler).to receive(:validate!).and_return(license_obj_commercial)
|
264
|
+
|
265
|
+
b = Chef::Knife::Bootstrap.new([])
|
266
|
+
b.send(:fetch_license)
|
267
|
+
config.merge!(b.config)
|
268
|
+
expect(bootstrap_context.msi_url).to eq("https://chefdownload-commerical.chef.io/stable/chef/download?license_id=key-commercial-123&p=windows&v=latest")
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should return the omnitruck url in case of airgapped env" do
|
272
|
+
# In case of connection issues with the licensing service, the library will raise this exception
|
273
|
+
expect(ChefLicensing::LicenseKeyFetcher).to receive(:fetch).and_raise(ChefLicensing::RestfulClientConnectionError)
|
274
|
+
|
275
|
+
b = Chef::Knife::Bootstrap.new([])
|
276
|
+
b.send(:fetch_license)
|
277
|
+
config.merge!(b.config)
|
278
|
+
expect(bootstrap_context.msi_url).to eq("https://omnitruck.chef.io/chef/download?p=windows&channel=stable&v=latest")
|
279
|
+
end
|
280
|
+
end
|
237
281
|
end
|
238
282
|
end
|
@@ -50,6 +50,11 @@ describe Chef::Knife::License do
|
|
50
50
|
c.output = STDOUT
|
51
51
|
end
|
52
52
|
|
53
|
+
# Stubbing the fetch_and_persist method to simulate a failure
|
54
|
+
expect(ChefLicensing).to receive(:fetch_and_persist).and_raise(
|
55
|
+
ChefLicensing::LicenseKeyFetcher::LicenseKeyNotFetchedError.new("Unable to obtain a License Key.")
|
56
|
+
)
|
57
|
+
|
53
58
|
expect { knife.run }.to raise_error(ChefLicensing::LicenseKeyFetcher::LicenseKeyNotFetchedError, "Unable to obtain a License Key.")
|
54
59
|
end
|
55
60
|
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "knife_spec_helper"
|
19
|
+
require "chef/utils/licensing_handler"
|
20
|
+
|
21
|
+
describe Chef::Utils::LicensingHandler do
|
22
|
+
let(:license_key) { "abc123" }
|
23
|
+
let(:license_type) { "commercial" }
|
24
|
+
let(:handler) { described_class.new(license_key, license_type) }
|
25
|
+
|
26
|
+
describe "#initialize" do
|
27
|
+
it "sets the license key and type" do
|
28
|
+
expect(handler.license_key).to eq(license_key)
|
29
|
+
expect(handler.license_type).to eq(license_type)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#omnitruck_url" do
|
34
|
+
context "with a commercial license" do
|
35
|
+
it "returns the commercial URL with the license key" do
|
36
|
+
expected_url = "https://chefdownload-commerical.chef.io/%s?license_id=abc123"
|
37
|
+
expect(handler.omnitruck_url).to eq(expected_url)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with a trial license" do
|
42
|
+
let(:license_type) { "trial" }
|
43
|
+
|
44
|
+
it "returns the trial URL with the license key" do
|
45
|
+
expected_url = "https://chefdownload-trial.chef.io/%s?license_id=abc123"
|
46
|
+
expect(handler.omnitruck_url).to eq(expected_url)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with a free license" do
|
51
|
+
let(:license_type) { "free" }
|
52
|
+
|
53
|
+
it "returns the free (trial) URL with the license key" do
|
54
|
+
expected_url = "https://chefdownload-trial.chef.io/%s?license_id=abc123"
|
55
|
+
expect(handler.omnitruck_url).to eq(expected_url)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with an unknown license type" do
|
60
|
+
let(:license_type) { "unknown" }
|
61
|
+
|
62
|
+
it "returns the legacy URL without the license key" do
|
63
|
+
expected_url = "https://omnitruck.chef.io/%s"
|
64
|
+
expect(handler.omnitruck_url).to eq(expected_url)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with no license key" do
|
69
|
+
let(:license_key) { nil }
|
70
|
+
let(:license_type) { nil }
|
71
|
+
|
72
|
+
it "returns the legacy URL without a license ID parameter" do
|
73
|
+
expected_url = "https://omnitruck.chef.io/%s"
|
74
|
+
expect(handler.omnitruck_url).to eq(expected_url)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#install_sh_url" do
|
80
|
+
it "formats the omnitruck URL with install.sh" do
|
81
|
+
expect(handler).to receive(:omnitruck_url).and_return("https://example.com/%s?license_id=abc123")
|
82
|
+
expect(handler.install_sh_url).to eq("https://example.com/install.sh?license_id=abc123")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe ".validate!" do
|
87
|
+
let(:license_keys) { ["abc123"] }
|
88
|
+
let(:license_metadata) do
|
89
|
+
double("license_metadata", id: license_key, license_type: license_type)
|
90
|
+
end
|
91
|
+
let(:licenses_metadata) { [license_metadata] }
|
92
|
+
|
93
|
+
before do
|
94
|
+
allow(ChefLicensing::LicenseKeyFetcher).to receive(:fetch).and_return(license_keys)
|
95
|
+
allow(ChefLicensing::Api::Describe).to receive(:list).and_return(licenses_metadata)
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when license keys are available" do
|
99
|
+
it "returns a new handler with the license key and type" do
|
100
|
+
handler = described_class.validate!
|
101
|
+
expect(handler.license_key).to eq(license_key)
|
102
|
+
expect(handler.license_type).to eq(license_type)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "fetches license keys using ChefLicensing::LicenseKeyFetcher" do
|
106
|
+
expect(ChefLicensing::LicenseKeyFetcher).to receive(:fetch).and_return(license_keys)
|
107
|
+
described_class.validate!
|
108
|
+
end
|
109
|
+
|
110
|
+
it "gets license metadata using ChefLicensing::Api::Describe" do
|
111
|
+
expect(ChefLicensing::Api::Describe).to receive(:list).with({
|
112
|
+
license_keys: license_keys,
|
113
|
+
}).and_return(licenses_metadata)
|
114
|
+
described_class.validate!
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when no license keys are available" do
|
119
|
+
let(:license_keys) { [] }
|
120
|
+
|
121
|
+
it "returns a new handler with nil license key and type" do
|
122
|
+
handler = described_class.validate!
|
123
|
+
expect(handler.license_key).to be_nil
|
124
|
+
expect(handler.license_type).to be_nil
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "when ChefLicensing::RestfulClientConnectionError is raised" do
|
129
|
+
before do
|
130
|
+
allow(ChefLicensing::LicenseKeyFetcher).to receive(:fetch).and_raise(ChefLicensing::RestfulClientConnectionError)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "returns a new handler with nil license key and type" do
|
134
|
+
handler = described_class.validate!
|
135
|
+
expect(handler.license_key).to be_nil
|
136
|
+
expect(handler.license_type).to be_nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 18.
|
4
|
+
version: 18.8.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Jacob
|
8
|
+
autorequire:
|
8
9
|
bindir: bin
|
9
10
|
cert_chain: []
|
10
|
-
date: 2025-
|
11
|
+
date: 2025-08-18 00:00:00.000000000 Z
|
11
12
|
dependencies:
|
12
13
|
- !ruby/object:Gem::Dependency
|
13
14
|
name: chef-config
|
@@ -15,56 +16,56 @@ dependencies:
|
|
15
16
|
requirements:
|
16
17
|
- - "~>"
|
17
18
|
- !ruby/object:Gem::Version
|
18
|
-
version: '18.
|
19
|
+
version: '18.0'
|
19
20
|
type: :runtime
|
20
21
|
prerelease: false
|
21
22
|
version_requirements: !ruby/object:Gem::Requirement
|
22
23
|
requirements:
|
23
24
|
- - "~>"
|
24
25
|
- !ruby/object:Gem::Version
|
25
|
-
version: '18.
|
26
|
+
version: '18.0'
|
26
27
|
- !ruby/object:Gem::Dependency
|
27
28
|
name: chef-utils
|
28
29
|
requirement: !ruby/object:Gem::Requirement
|
29
30
|
requirements:
|
30
31
|
- - "~>"
|
31
32
|
- !ruby/object:Gem::Version
|
32
|
-
version: '18.
|
33
|
+
version: '18.0'
|
33
34
|
type: :runtime
|
34
35
|
prerelease: false
|
35
36
|
version_requirements: !ruby/object:Gem::Requirement
|
36
37
|
requirements:
|
37
38
|
- - "~>"
|
38
39
|
- !ruby/object:Gem::Version
|
39
|
-
version: '18.
|
40
|
+
version: '18.0'
|
40
41
|
- !ruby/object:Gem::Dependency
|
41
42
|
name: chef
|
42
43
|
requirement: !ruby/object:Gem::Requirement
|
43
44
|
requirements:
|
44
45
|
- - "~>"
|
45
46
|
- !ruby/object:Gem::Version
|
46
|
-
version: '18.
|
47
|
+
version: '18.0'
|
47
48
|
type: :runtime
|
48
49
|
prerelease: false
|
49
50
|
version_requirements: !ruby/object:Gem::Requirement
|
50
51
|
requirements:
|
51
52
|
- - "~>"
|
52
53
|
- !ruby/object:Gem::Version
|
53
|
-
version: '18.
|
54
|
+
version: '18.0'
|
54
55
|
- !ruby/object:Gem::Dependency
|
55
56
|
name: chef-bin
|
56
57
|
requirement: !ruby/object:Gem::Requirement
|
57
58
|
requirements:
|
58
59
|
- - "~>"
|
59
60
|
- !ruby/object:Gem::Version
|
60
|
-
version: '18.
|
61
|
+
version: '18.0'
|
61
62
|
type: :runtime
|
62
63
|
prerelease: false
|
63
64
|
version_requirements: !ruby/object:Gem::Requirement
|
64
65
|
requirements:
|
65
66
|
- - "~>"
|
66
67
|
- !ruby/object:Gem::Version
|
67
|
-
version: '18.
|
68
|
+
version: '18.0'
|
68
69
|
- !ruby/object:Gem::Dependency
|
69
70
|
name: train-core
|
70
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -83,16 +84,16 @@ dependencies:
|
|
83
84
|
name: train-winrm
|
84
85
|
requirement: !ruby/object:Gem::Requirement
|
85
86
|
requirements:
|
86
|
-
- - "
|
87
|
+
- - "~>"
|
87
88
|
- !ruby/object:Gem::Version
|
88
|
-
version: 0.2.
|
89
|
+
version: 0.2.17
|
89
90
|
type: :runtime
|
90
91
|
prerelease: false
|
91
92
|
version_requirements: !ruby/object:Gem::Requirement
|
92
93
|
requirements:
|
93
|
-
- - "
|
94
|
+
- - "~>"
|
94
95
|
- !ruby/object:Gem::Version
|
95
|
-
version: 0.2.
|
96
|
+
version: 0.2.17
|
96
97
|
- !ruby/object:Gem::Dependency
|
97
98
|
name: license-acceptance
|
98
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -395,6 +396,20 @@ dependencies:
|
|
395
396
|
- - "~>"
|
396
397
|
- !ruby/object:Gem::Version
|
397
398
|
version: '1.0'
|
399
|
+
- !ruby/object:Gem::Dependency
|
400
|
+
name: chef-zero
|
401
|
+
requirement: !ruby/object:Gem::Requirement
|
402
|
+
requirements:
|
403
|
+
- - "~>"
|
404
|
+
- !ruby/object:Gem::Version
|
405
|
+
version: 15.0.21
|
406
|
+
type: :runtime
|
407
|
+
prerelease: false
|
408
|
+
version_requirements: !ruby/object:Gem::Requirement
|
409
|
+
requirements:
|
410
|
+
- - "~>"
|
411
|
+
- !ruby/object:Gem::Version
|
412
|
+
version: 15.0.21
|
398
413
|
description: The knife CLI for Chef Infra.
|
399
414
|
email: adam@chef.io
|
400
415
|
executables:
|
@@ -1151,6 +1166,7 @@ files:
|
|
1151
1166
|
- spec/unit/knife/user_reregister_spec.rb
|
1152
1167
|
- spec/unit/knife/user_show_spec.rb
|
1153
1168
|
- spec/unit/knife_spec.rb
|
1169
|
+
- spec/unit/utils/licensing_handler_spec.rb
|
1154
1170
|
homepage: https://www.chef.io
|
1155
1171
|
licenses:
|
1156
1172
|
- Apache-2.0
|
@@ -1161,6 +1177,7 @@ metadata:
|
|
1161
1177
|
homepage_uri: https://www.chef.io
|
1162
1178
|
mailing_list_uri: https://discourse.chef.io/
|
1163
1179
|
source_code_uri: https://github.com/chef/chef/
|
1180
|
+
post_install_message:
|
1164
1181
|
rdoc_options: []
|
1165
1182
|
require_paths:
|
1166
1183
|
- lib
|
@@ -1175,7 +1192,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1175
1192
|
- !ruby/object:Gem::Version
|
1176
1193
|
version: '0'
|
1177
1194
|
requirements: []
|
1178
|
-
rubygems_version: 3.
|
1195
|
+
rubygems_version: 3.3.7
|
1196
|
+
signing_key:
|
1179
1197
|
specification_version: 4
|
1180
1198
|
summary: The knife CLI for Chef Infra.
|
1181
1199
|
test_files: []
|