Skip to content

Commit

Permalink
Merge pull request #9 from ashiqueps/CHEF-12878-provisioner-updates
Browse files Browse the repository at this point in the history
Chef-infra provisioner to use the new omnitruck apis
  • Loading branch information
sanghinitin authored Nov 6, 2024
2 parents dfe1f74 + 31cc921 commit b5a4a7b
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 4 deletions.
1 change: 1 addition & 0 deletions .expeditor/habitat-test.pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ steps:
- FORCE_FFI_YAJL=ext
- EXPIRE_CACHE=true
- CHEF_LICENSE=accept-no-persist
- CHEF_LICENSE_SERVER=http://hosted-license-service-lb-8000-606952349.us-west-2.elb.amazonaws.com:8000/
8 changes: 8 additions & 0 deletions .expeditor/verify.pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ steps:
executor:
docker:
image: ruby:3.1
environment:
- CHEF_LICENSE=accept-no-persist
- CHEF_LICENSE_SERVER=http://hosted-license-service-lb-8000-606952349.us-west-2.elb.amazonaws.com:8000/

- label: run-specs-ruby-3.3
command:
Expand All @@ -25,6 +28,9 @@ steps:
executor:
docker:
image: ruby:3.3
environment:
- CHEF_LICENSE=accept-no-persist
- CHEF_LICENSE_SERVER=http://hosted-license-service-lb-8000-606952349.us-west-2.elb.amazonaws.com:8000/

- label: run-specs-windows-ruby-3.1
command:
Expand All @@ -40,6 +46,7 @@ steps:
- FORCE_FFI_YAJL=ext
- EXPIRE_CACHE=true
- CHEF_LICENSE=accept-no-persist
- CHEF_LICENSE_SERVER=http://hosted-license-service-lb-8000-606952349.us-west-2.elb.amazonaws.com:8000/

- label: run-specs-windows-ruby-3.3
command:
Expand All @@ -55,3 +62,4 @@ steps:
- FORCE_FFI_YAJL=ext
- EXPIRE_CACHE=true
- CHEF_LICENSE=accept-no-persist
- CHEF_LICENSE_SERVER=http://hosted-license-service-lb-8000-606952349.us-west-2.elb.amazonaws.com:8000/
2 changes: 2 additions & 0 deletions kitchen.dokken.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ driver:
provisioner:
name: dokken
chef_license: accept-no-persist
chef_license_server:
- http://hosted-license-service-lb-8000-606952349.us-west-2.elb.amazonaws.com:8000/

transport:
name: dokken
Expand Down
5 changes: 5 additions & 0 deletions lib/kitchen/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ def console
perform("console", "console")
end

desc "license", "Manage the chef licenses"
def license(*args)
perform("license", "license", args)
end

register Kitchen::Generator::Init, "init",
"init", "Adds some configuration to your cookbook so Kitchen can rock"
long_desc <<-D, for: "init"
Expand Down
22 changes: 22 additions & 0 deletions lib/kitchen/command/license.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require_relative "../command"
require "kitchen/licensing/base"

module Kitchen
module Command
# Command to manage the licenses
class License < Kitchen::Command::Base
def call
case args[0]
when "list"
ChefLicensing.list_license_keys_info
when "add"
ChefLicensing.add_license
else
ChefLicensing.fetch_and_persist.each do |key|
puts "License_key: #{key}"
end
end
end
end
end
end
53 changes: 53 additions & 0 deletions lib/kitchen/licensing/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true

# Copyright:: Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require_relative "config"
require "chef-licensing"
require "faraday_middleware"

module Kitchen
module Licensing
class Base

OMNITRUCK_URLS = {
"free" => "https://chefdownload-trial.chef.io",
"trial" => "https://chefdownload-trial.chef.io",
"commercial" => "https://chefdownload-commerical.chef.io",
}.freeze

class << self
def get_license_keys
keys = ChefLicensing.license_keys
raise ChefLicensing::InvalidLicense, "A valid license is required to perform this action." if keys.blank?

client = get_license_client(keys)

[keys.last, client.license_type, install_sh_url(client.license_type, keys)]
end

def get_license_client(keys)
ChefLicensing::Api::Client.info(license_keys: keys)
end

def install_sh_url(type, keys, ext = "sh")
OMNITRUCK_URLS[type] + "/install.#{ext}?license_id=#{keys.join(",")}"
end
end
end
end
end
27 changes: 27 additions & 0 deletions lib/kitchen/licensing/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# frozen_string_literal: true

# Copyright:: Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require "chef-licensing"

ChefLicensing.configure do |config|
config.chef_product_name = "Test Kitchen"
config.chef_entitlement_id = "x6f3bc76-a94f-4b6c-bc97-4b7ed2b045c0"
config.chef_executable_name = "kitchen"
config.license_server_url = "https://services.chef.io/licensing"
# config.license_server_url = "https://licensing-acceptance.chef.co/License"
end
2 changes: 1 addition & 1 deletion lib/kitchen/provisioner/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def sandbox_dirs
# will persist after the process terminates. In other words, cleanup is
# explicit. This method is safe to call multiple times.
def cleanup_sandbox
return if sandbox_path.nil?
return if @sandbox_path.nil?

debug("Cleaning up local sandbox in #{sandbox_path}")
FileUtils.rmtree(sandbox_path)
Expand Down
15 changes: 13 additions & 2 deletions lib/kitchen/provisioner/chef_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def install_options
add_omnibus_directory_option if instance.driver.cache_directory
project = /\s*-P (\w+)\s*/.match(config[:chef_omnibus_install_options])
{
omnibus_url: config[:chef_omnibus_url],
omnibus_url: config[:install_sh_url] || config[:chef_omnibus_url],
project: project.nil? ? nil : project[1],
install_flags: config[:chef_omnibus_install_options],
sudo_command:,
Expand Down Expand Up @@ -544,6 +544,15 @@ def script_for_product
prox.delete_if { |p| %i{https_proxy ftp_proxy no_proxy}.include?(p) } if powershell_shell?
end
opts[:install_command_options].merge!(proxies)

if config[:install_sh_url] || config[:install_ps1_url]
opts[:new_omnibus_download_url] = if powershell_shell?
config[:install_ps1_url]
else
config[:install_sh_url]
end

end
end)
config[:chef_omnibus_root] = installer.root
if powershell_shell?
Expand Down Expand Up @@ -580,8 +589,10 @@ def install_from_file(command)
# @api private
def script_for_omnibus_version
require "mixlib/install/script_generator"
opts = install_options
opts[:omnibus_url] = config[:install_sh_url] if config[:install_sh_url]
installer = Mixlib::Install::ScriptGenerator.new(
config[:require_chef_omnibus], powershell_shell?, install_options
config[:require_chef_omnibus], powershell_shell?, opts
)
config[:chef_omnibus_root] = installer.root
sudo(installer.install_command)
Expand Down
54 changes: 53 additions & 1 deletion lib/kitchen/provisioner/chef_infra.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#
# Author:: Fletcher Nichol (<[email protected]>)
#
Expand All @@ -16,13 +17,15 @@
# limitations under the License.

require_relative "chef_base"
require "kitchen/licensing/base"

module Kitchen
module Provisioner
# Chef Zero provisioner.
#
# @author Fletcher Nichol <[email protected]>
class ChefInfra < ChefBase

kitchen_provisioner_api_version 2

plugin_version Kitchen::VERSION
Expand All @@ -32,6 +35,8 @@ class ChefInfra < ChefBase
default_config :json_attributes, true
default_config :chef_zero_host, nil
default_config :chef_zero_port, 8889
default_config :chef_license_key, nil
default_config :chef_license_server, []

default_config :chef_client_path do |provisioner|
provisioner
Expand All @@ -51,12 +56,47 @@ def create_sandbox
prepare_config_rb
end

def prepare_command
nonce = Base64.encode64(SecureRandom.random_bytes(16)).strip
timestamp = Time.now.utc.to_i.to_s

message = "#{nonce}:#{timestamp}"
signature = OpenSSL::HMAC.hexdigest("SHA256", context_key, message)

file_content = "nonce:#{nonce}\ntimestamp:#{timestamp}\nsignature:#{signature}"
file_location = config[:root_path] + "/#{context_key}"

sudo("echo '#{file_content}' > #{file_location}")
end

def run_command
cmd = "#{sudo(config[:chef_client_path])} --local-mode".tap { |str| str.insert(0, "& ") if powershell_shell? }
cmd = "#{context_env_command} #{sudo(config[:chef_client_path])} --local-mode --chef-license-key=#{config[:chef_license_key]} "

chef_cmd(cmd)
end

def check_license
super

info("Fetching the Chef license key")
unless config[:chef_license_server].nil? || config[:chef_license_server].empty?
ENV["CHEF_LICENSE_SERVER"] = config[:chef_license_server].join(",")
end

key, type, install_sh_url = if config[:chef_license_key].nil?
Licensing::Base.get_license_keys
else
key = config[:chef_license_key]
client = Licensing::Base.get_license_client([key])

[key, client.license_type, Licensing::Base.install_sh_url(client.license_type, [key])]
end

config[:chef_license_key] = key
config[:install_sh_url] = install_sh_url
config[:chef_license_type] = type
end

private

# Adds optional flags to a chef-client command, depending on
Expand Down Expand Up @@ -162,6 +202,18 @@ def shim_command
def supports_policyfile?
true
end

def context_key
@context_key ||= SecureRandom.hex(16)
end

def context_env_command
if powershell_shell?
"$env:TEST_KITCHEN_CONTEXT = '#{context_key}'; &"
else
"export TEST_KITCHEN_CONTEXT=#{context_key};"
end
end
end
end
end
1 change: 1 addition & 0 deletions test-kitchen.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ Gem::Specification.new do |gem|
# Required to run the Chef provisioner local license check for remote systems
# TK is not under Chef EULA
gem.add_dependency "license-acceptance", ">= 1.0.11", "< 3.0" # pinning until we can confirm 3+ works
gem.add_dependency "chef-licensing", "~> 1.0"
end

0 comments on commit b5a4a7b

Please sign in to comment.