summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Ball <tball@chef.io>2019-05-06 12:46:04 -0600
committerGitHub <noreply@github.com>2019-05-06 12:46:04 -0600
commit3ba19c97144832d44a1e77c3183b8b8c9b46f004 (patch)
tree4f66fc2517f70e573675128e5e75f1e2a03226ef
parent12623146e3f64540b81a1a50dfdcf502740c3151 (diff)
parent0c6e3b9f0b45501d3835537bf8ed95ddd779375f (diff)
downloadchef-3ba19c97144832d44a1e77c3183b8b8c9b46f004.tar.gz
Merge pull request #8354 from chef/license_acceptance
Add logic to require acceptannce of the Chef license to run the client
-rw-r--r--.expeditor/config.yml3
-rw-r--r--.travis.yml1
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock6
-rw-r--r--RELEASE_NOTES.md13
-rw-r--r--appveyor.yml1
-rwxr-xr-xchef-bin/bin/chef-apply2
-rwxr-xr-xchef-bin/bin/chef-client2
-rwxr-xr-xchef-bin/bin/chef-solo2
-rw-r--r--chef.gemspec1
-rw-r--r--docs/dev/license_acceptance.md13
-rw-r--r--kitchen-tests/Gemfile2
-rw-r--r--kitchen-tests/cookbooks/end_to_end/Berksfile3
-rw-r--r--kitchen-tests/cookbooks/end_to_end/attributes/default.rb2
-rw-r--r--kitchen-tests/cookbooks/rspec/templates/run-chef-rspec1
-rw-r--r--kitchen-tests/kitchen.yml1
-rw-r--r--lib/chef/application.rb13
-rw-r--r--lib/chef/application/apply.rb3
-rw-r--r--lib/chef/application/client.rb3
-rw-r--r--lib/chef/application/solo.rb3
-rw-r--r--lib/chef/knife/bootstrap.rb4
-rw-r--r--lib/chef/knife/core/bootstrap_context.rb1
-rw-r--r--spec/unit/application/knife_spec.rb6
-rw-r--r--spec/unit/application_spec.rb7
-rw-r--r--spec/unit/knife/bootstrap_spec.rb11
-rw-r--r--spec/unit/knife/core/windows_bootstrap_context_spec.rb6
-rwxr-xr-xtasks/bin/run_external_test6
27 files changed, 99 insertions, 19 deletions
diff --git a/.expeditor/config.yml b/.expeditor/config.yml
index 5a6d9a57ac..55a74e04f2 100644
--- a/.expeditor/config.yml
+++ b/.expeditor/config.yml
@@ -143,3 +143,6 @@ subscriptions:
- workload: ruby_gem_published:cheffish-*
actions:
- bash:.expeditor/update_dep.sh
+# - workload: ruby_gem_published:license-acceptance-*
+# actions:
+# - bash:.expeditor/update_dep.sh
diff --git a/.travis.yml b/.travis.yml
index 18a12e654d..ed538216f7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,6 +30,7 @@ branches:
env:
global:
- FORCE_FFI_YAJL=ext
+ - CHEF_LICENSE=accept-no-persist
matrix:
include:
diff --git a/Gemfile b/Gemfile
index c358744401..1c9e7048bb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -25,7 +25,7 @@ gem "cheffish", "~> 14"
group(:omnibus_package) do
gem "appbundler"
gem "rb-readline"
- gem "inspec-core", ">= 4.0.0.a", "< 5"
+ gem "inspec-core", "~> 4.3"
gem "chef-vault"
gem "ed25519" # ed25519 ssh key support done here as it's a native gem we can't put in train
gem "bcrypt_pbkdf" # ed25519 ssh key support done here as it's a native gem we can't put in train
diff --git a/Gemfile.lock b/Gemfile.lock
index 65302bda1d..8f769b7a73 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -41,6 +41,7 @@ PATH
ffi-yajl (~> 2.2)
highline (>= 1.6.9, < 2)
iniparse (~> 1.4)
+ license-acceptance (~> 1.0)
mixlib-archive (>= 0.4, < 2.0)
mixlib-authentication (~> 2.1)
mixlib-cli (>= 1.7, < 3.0)
@@ -71,6 +72,7 @@ PATH
highline (>= 1.6.9, < 2)
iniparse (~> 1.4)
iso8601 (~> 0.12.1)
+ license-acceptance (~> 1.0)
mixlib-archive (>= 0.4, < 2.0)
mixlib-authentication (~> 2.1)
mixlib-cli (>= 1.7, < 3.0)
@@ -203,7 +205,7 @@ GEM
jaro_winkler (1.5.2)
json (2.2.0)
libyajl2 (1.2.0)
- license-acceptance (1.0.2)
+ license-acceptance (1.0.5)
pastel (~> 0.7)
tomlrb (~> 1.2)
tty-box (~> 0.3)
@@ -416,7 +418,7 @@ DEPENDENCIES
cheffish (~> 14)
chefstyle!
ed25519
- inspec-core (>= 4.0.0.a, < 5)
+ inspec-core (~> 4.3)
ohai!
pry
pry-byebug
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index ea1871d677..5a0cc3244c 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -6,6 +6,19 @@ Chef 15 release notes will be added here as development progresses.
## New Features / Functionality
+### Chef EULA
+
+Chef Client requires a EULA to be accepted by users before it can run. Users can accept the EULA in a variety of ways:
+
+`chef-client --chef-license accept`
+`chef-client --chef-license accept-no-persist`
+`CHEF_LICENSE=accept chef-client`
+`CHEF_LICENSE=accept-no-persist chef-client`
+
+Finally, if users run `chef-client` without any of these options, they will receive an interactive prompt asking for
+license acceptance. If the license is accepted, a marker file will be written to the filesystem (unless
+`accept-no-persist` is specified). Once this marker file is persisted, users no longer need to set any of these flags.
+
### Allow Using --delete-entire-chef-repo in Chef Local Mode
### Data Collection Ground-Up Refactor
diff --git a/appveyor.yml b/appveyor.yml
index 15ab998c80..6ab90e3c2d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -45,6 +45,7 @@ install:
- bundle config --local path vendor/bundle # use the cache we define above
- bundle install || bundle install || bundle install
- SET SPEC_OPTS=--format progress
+ - SET CHEF_LICENSE=accept-no-persist
build: off
diff --git a/chef-bin/bin/chef-apply b/chef-bin/bin/chef-apply
index ddbdc66907..05b975a118 100755
--- a/chef-bin/bin/chef-apply
+++ b/chef-bin/bin/chef-apply
@@ -21,4 +21,4 @@
$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
require "chef/application/apply"
-Chef::Application::Apply.new.run
+Chef::Application::Apply.new.run(enforce_license: true)
diff --git a/chef-bin/bin/chef-client b/chef-bin/bin/chef-client
index af27d7903d..45a6af546a 100755
--- a/chef-bin/bin/chef-client
+++ b/chef-bin/bin/chef-client
@@ -22,4 +22,4 @@ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
require "chef"
require "chef/application/client"
-Chef::Application::Client.new.run
+Chef::Application::Client.new.run(enforce_license: true)
diff --git a/chef-bin/bin/chef-solo b/chef-bin/bin/chef-solo
index 06c0452d26..7a2168230d 100755
--- a/chef-bin/bin/chef-solo
+++ b/chef-bin/bin/chef-solo
@@ -21,4 +21,4 @@
$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
require "chef/application/solo"
-Chef::Application::Solo.new.run
+Chef::Application::Solo.new.run(enforce_license: true)
diff --git a/chef.gemspec b/chef.gemspec
index ebd6d192bb..7c365eeeb4 100644
--- a/chef.gemspec
+++ b/chef.gemspec
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
s.add_dependency "chef-config", "= #{Chef::VERSION}"
s.add_dependency "train-core", "~> 2.0", ">= 2.0.12"
+ s.add_dependency "license-acceptance", "~> 1.0"
s.add_dependency "mixlib-cli", ">= 1.7", "< 3.0"
s.add_dependency "mixlib-log", ">= 2.0.3", "< 4.0"
s.add_dependency "mixlib-authentication", "~> 2.1"
diff --git a/docs/dev/license_acceptance.md b/docs/dev/license_acceptance.md
new file mode 100644
index 0000000000..bb6e8a4e07
--- /dev/null
+++ b/docs/dev/license_acceptance.md
@@ -0,0 +1,13 @@
+# License Acceptance
+
+Starting with Chef Client 15 users are required to accept the [Chef
+EULA](https://www.chef.io/end-user-license-agreement/) to use the Chef Software distribution. This document aims to
+explain how the `license-acceptance` gem and the `chef` gem interact.
+
+The overall goal is that the license acceptance flow is invoked as early as possible in the binary (EG, `chef-client`)
+execution. Failure to accept the license causes the binary to immediately exit with code `172`.
+
+For an explanation of how this is achieved please see the [Ruby
+README](https://github.com/chef/license-acceptance/tree/master/components/ruby) in the license-acceptance repo. For an
+overall view of how the license-acceptance gem works, its specification, how marker files are stored, etc. please see
+the [repo README](https://github.com/chef/license-acceptance).
diff --git a/kitchen-tests/Gemfile b/kitchen-tests/Gemfile
index c2437a307b..a1a438d071 100644
--- a/kitchen-tests/Gemfile
+++ b/kitchen-tests/Gemfile
@@ -6,5 +6,5 @@ gem "ohai", git: "https://github.com/chef/ohai.git", branch: "master" # avoids f
gem "berkshelf", git: "https://github.com/berkshelf/berkshelf.git", branch: "master"
gem "kitchen-dokken", "~> 2.0"
gem "kitchen-inspec", git: "https://github.com/chef/kitchen-inspec.git", branch: "master"
-gem "inspec", git: "https://github.com/inspec/inspec.git", branch: "master" # this goes away when we ship inspec 4
+gem "inspec"
gem "test-kitchen", git: "https://github.com/test-kitchen/test-kitchen.git", branch: "master"
diff --git a/kitchen-tests/cookbooks/end_to_end/Berksfile b/kitchen-tests/cookbooks/end_to_end/Berksfile
deleted file mode 100644
index 967b9a78b6..0000000000
--- a/kitchen-tests/cookbooks/end_to_end/Berksfile
+++ /dev/null
@@ -1,3 +0,0 @@
-source "https://supermarket.chef.io"
-
-metadata
diff --git a/kitchen-tests/cookbooks/end_to_end/attributes/default.rb b/kitchen-tests/cookbooks/end_to_end/attributes/default.rb
index 5e8cee6736..b8ac7f8119 100644
--- a/kitchen-tests/cookbooks/end_to_end/attributes/default.rb
+++ b/kitchen-tests/cookbooks/end_to_end/attributes/default.rb
@@ -62,6 +62,8 @@ default["chef_client"]["splay"] = 1800
# only log what we change
default["chef_client"]["config"]["verbose_logging"] = false
+default["chef_client"]["chef_license"] = "accept-no-persist"
+
#
# resolver cookbook overrides
#
diff --git a/kitchen-tests/cookbooks/rspec/templates/run-chef-rspec b/kitchen-tests/cookbooks/rspec/templates/run-chef-rspec
index 54c4297479..4a1eb54b48 100644
--- a/kitchen-tests/cookbooks/rspec/templates/run-chef-rspec
+++ b/kitchen-tests/cookbooks/rspec/templates/run-chef-rspec
@@ -8,4 +8,5 @@ export PATH=/opt/chef/embedded/bin:$PATH
cd /opt/chef/embedded/apps/chef
/opt/chef/embedded/bin/bundle install
+export CHEF_LICENSE=accept-no-persist
/opt/chef/embedded/bin/bundle exec /opt/chef/embedded/bin/rspec --format progress
diff --git a/kitchen-tests/kitchen.yml b/kitchen-tests/kitchen.yml
index 5fe3b8540f..0b4b1964fc 100644
--- a/kitchen-tests/kitchen.yml
+++ b/kitchen-tests/kitchen.yml
@@ -12,6 +12,7 @@ provisioner:
name: dokken
client_rb:
diff_disabled: true
+ chef_license: "accept-no-persist"
lifecycle:
pre_converge:
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index 549d8b4482..7388e3d22d 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -29,6 +29,7 @@ require "tmpdir"
require "rbconfig"
require "chef/application/exit_code"
require "chef/dist"
+require "license_acceptance/acceptor"
class Chef
class Application
@@ -60,10 +61,11 @@ class Chef
end
# Get this party started
- def run
+ def run(enforce_license: false)
setup_signal_handlers
reconfigure
setup_application
+ check_license_acceptance if enforce_license
run_application
end
@@ -248,6 +250,15 @@ class Chef
raise Chef::Exceptions::Application, "#{self}: you must override setup_application"
end
+ def check_license_acceptance
+ LicenseAcceptance::Acceptor.check_and_persist!(
+ "infra-client",
+ Chef::VERSION.to_s,
+ logger: logger,
+ provided: Chef::Config[:chef_license]
+ )
+ end
+
# Actually run the application
def run_application
raise Chef::Exceptions::Application, "#{self}: you must override run_application"
diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb
index 34f0973b40..715e0152d2 100644
--- a/lib/chef/application/apply.rb
+++ b/lib/chef/application/apply.rb
@@ -214,8 +214,9 @@ class Chef::Application::Apply < Chef::Application
end
# Get this party started
- def run
+ def run(enforce_license = false)
reconfigure
+ check_license_acceptance if enforce_license
run_application
end
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index 390acfba04..31932b812c 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -30,10 +30,12 @@ require "chef-config/mixin/dot_d"
require "mixlib/archive"
require "uri"
require "chef/dist"
+require "license_acceptance/cli_flags/mixlib_cli"
class Chef::Application::Client < Chef::Application
include Chef::Mixin::ShellOut
include ChefConfig::Mixin::DotD
+ include LicenseAcceptance::CLIFlags::MixlibCLI
# Mimic self_pipe sleep from Unicorn to capture signals safely
SELF_PIPE = [] # rubocop:disable Style/MutableConstant
@@ -220,6 +222,7 @@ class Chef::Application::Client < Chef::Application
Chef::RunList::RunListItem.new(item)
end
}
+
option :why_run,
short: "-W",
long: "--why-run",
diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb
index 04cc9265ff..b1957fbf7c 100644
--- a/lib/chef/application/solo.rb
+++ b/lib/chef/application/solo.rb
@@ -217,10 +217,11 @@ class Chef::Application::Solo < Chef::Application
attr_reader :chef_client_json
# Get this party started
- def run
+ def run(enforce_license: false)
setup_signal_handlers
setup_application
reconfigure
+ check_license_acceptance if enforce_license
for_ezra if Chef::Config[:ez]
if !Chef::Config[:solo_legacy_mode]
Chef::Application::Client.new.run
diff --git a/lib/chef/knife/bootstrap.rb b/lib/chef/knife/bootstrap.rb
index 5d76736e06..90dd2417fc 100644
--- a/lib/chef/knife/bootstrap.rb
+++ b/lib/chef/knife/bootstrap.rb
@@ -19,11 +19,14 @@
require "chef/knife"
require "chef/knife/data_bag_secret_options"
require "chef/dist"
+require "license_acceptance/cli_flags/mixlib_cli"
+require "license_acceptance/acceptor"
class Chef
class Knife
class Bootstrap < Knife
include DataBagSecretOptions
+ include LicenseAcceptance::CLIFlags::MixlibCLI
SUPPORTED_CONNECTION_PROTOCOLS = %w{ssh winrm}.freeze
WINRM_AUTH_PROTOCOL_LIST = %w{plaintext kerberos ssl negotiate}.freeze
@@ -413,6 +416,7 @@ class Chef
def initialize(argv = [])
super
+ LicenseAcceptance::Acceptor.check_and_persist!("infra-client", Chef::VERSION.to_s, logger: Chef::Log, provided: Chef::Config[:chef_license])
@client_builder = Chef::Knife::Bootstrap::ClientBuilder.new(
chef_config: Chef::Config,
knife_config: config,
diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb
index 5a27836da8..f9ebf52b31 100644
--- a/lib/chef/knife/core/bootstrap_context.rb
+++ b/lib/chef/knife/core/bootstrap_context.rb
@@ -171,6 +171,7 @@ class Chef
def start_chef
# If the user doesn't have a client path configure, let bash use the PATH for what it was designed for
client_path = @chef_config[:chef_client_path] || "#{Chef::Dist::CLIENT}"
+ # We know we can hardcode CHEF_LICENSE because the user cannot get here without accepting the license locally
s = "CHEF_LICENSE=accept #{client_path} -j /etc/chef/first-boot.json"
if @config[:verbosity] && @config[:verbosity] >= 3
s << " -l trace"
diff --git a/spec/unit/application/knife_spec.rb b/spec/unit/application/knife_spec.rb
index 8a574b4d0f..f8f5560597 100644
--- a/spec/unit/application/knife_spec.rb
+++ b/spec/unit/application/knife_spec.rb
@@ -75,11 +75,7 @@ describe Chef::Application::Knife do
expect(@knife).to receive(:exit).with(0)
@knife.run
end
- if windows?
- expect(Chef::Config[:color]).to be_truthy
- else
- expect(Chef::Config[:color]).to be_truthy
- end
+ expect(Chef::Config[:color]).to be_truthy
end
context "when given fips flags" do
diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb
index e76e21bddc..10dff0e250 100644
--- a/spec/unit/application_spec.rb
+++ b/spec/unit/application_spec.rb
@@ -87,6 +87,13 @@ describe Chef::Application do
@app.run
end
+ describe "when enforce_license is set to true" do
+ it "should check the license acceptance" do
+ expect(@app).to receive(:check_license_acceptance)
+ @app.run(enforce_license: true)
+ end
+ end
+
it "should run the actual application" do
expect(@app).to receive(:run_application).and_return(true)
@app.run
diff --git a/spec/unit/knife/bootstrap_spec.rb b/spec/unit/knife/bootstrap_spec.rb
index 4261a3a166..948fc5b574 100644
--- a/spec/unit/knife/bootstrap_spec.rb
+++ b/spec/unit/knife/bootstrap_spec.rb
@@ -40,6 +40,7 @@ describe Chef::Knife::Bootstrap do
let(:knife) do
Chef::Log.logger = Logger.new(StringIO.new)
Chef::Config[:knife][:bootstrap_template] = bootstrap_template unless bootstrap_template.nil?
+ expect(LicenseAcceptance::Acceptor).to receive(:check_and_persist!)
k = Chef::Knife::Bootstrap.new(bootstrap_cli_options)
allow(k.ui).to receive(:stderr).and_return(stderr)
@@ -49,6 +50,15 @@ describe Chef::Knife::Bootstrap do
k
end
+ it "purposefully fails to prevent Chef Infra from promoting unstable -> current" do
+ expect(0).to eq(1)
+ end
+
+ it "fails when LicenseAcceptance fails" do
+ expect(LicenseAcceptance::Acceptor).to receive(:check_and_persist!).and_raise("foo")
+ expect { k = Chef::Knife::Bootstrap.new(bootstrap_cli_options) }.to raise_error("foo")
+ end
+
context "#bootstrap_template" do
it "should default to chef-full" do
expect(knife.bootstrap_template).to be_a_kind_of(String)
@@ -323,6 +333,7 @@ describe Chef::Knife::Bootstrap do
describe "specifying no_proxy with various entries" do
subject(:knife) do
+ expect(LicenseAcceptance::Acceptor).to receive(:check_and_persist!)
k = described_class.new
Chef::Config[:knife][:bootstrap_template] = template_file
allow(k).to receive(:connection).and_return connection
diff --git a/spec/unit/knife/core/windows_bootstrap_context_spec.rb b/spec/unit/knife/core/windows_bootstrap_context_spec.rb
index 7bc73c113a..561e43eefc 100644
--- a/spec/unit/knife/core/windows_bootstrap_context_spec.rb
+++ b/spec/unit/knife/core/windows_bootstrap_context_spec.rb
@@ -221,6 +221,8 @@ describe Chef::Knife::Core::WindowsBootstrapContext do
let(:bootstrap) { Chef::Knife::Bootstrap.new(["--bootstrap-install-command", "chef-client"]) }
before do
bootstrap.config[:bootstrap_install_command] = "chef-client"
+ @old_env = ENV["CHEF_LICENSE"]
+ ENV["CHEF_LICENSE"] = "accept"
end
it "sets the bootstrap_install_command option under Chef::Config::Knife object" do
@@ -230,6 +232,7 @@ describe Chef::Knife::Core::WindowsBootstrapContext do
after do
bootstrap.config.delete(:bootstrap_install_command)
Chef::Config[:knife].delete(:bootstrap_install_command)
+ ENV["CHEF_LICENSE"] = @old_env
end
end
@@ -246,6 +249,8 @@ describe Chef::Knife::Core::WindowsBootstrapContext do
let(:bootstrap) { Chef::Knife::Bootstrap.new(["--bootstrap-install-command", "chef-client"]) }
before do
bootstrap.config[:bootstrap_install_command] = "chef-client"
+ @old_env = ENV["CHEF_LICENSE"]
+ ENV["CHEF_LICENSE"] = "accept"
end
it "sets the bootstrap_install_command option under Chef::Config::Knife object" do
@@ -255,6 +260,7 @@ describe Chef::Knife::Core::WindowsBootstrapContext do
after do
bootstrap.config.delete(:bootstrap_install_command)
Chef::Config[:knife].delete(:bootstrap_install_command)
+ ENV["CHEF_LICENSE"] = @old_env
end
end
diff --git a/tasks/bin/run_external_test b/tasks/bin/run_external_test
index 5f1ac8f210..04fe5343ba 100755
--- a/tasks/bin/run_external_test
+++ b/tasks/bin/run_external_test
@@ -13,7 +13,11 @@ git_thing = ARGV.shift
build_dir = File.expand_path(ENV["TRAVIS_BUILD_DIR"] || Dir.pwd)
-env = { "GEMFILE_MOD" => "gem 'chef', path: '#{build_dir}'; gem 'ohai', git: 'https://github.com/chef/ohai.git', branch: 'master'" }
+env = {
+ "GEMFILE_MOD" => "gem 'chef', path: '#{build_dir}'; " \
+ "gem 'ohai', git: 'https://github.com/chef/ohai.git'",
+ "CHEF_LICENSE" => "accept-no-persist",
+}
Dir.mktmpdir("chef-external-test") do |dir|
git_url = "https://github.com/#{github_repo}"