summaryrefslogtreecommitdiff
path: root/lib/chef
diff options
context:
space:
mode:
authorDerek Groh <derekgroh@gmail.com>2018-09-04 13:08:16 -0500
committerDerek Groh <derekgroh@gmail.com>2018-09-04 13:08:16 -0500
commitf923a7b3297a57506adb265d0c2d8d5671596f32 (patch)
tree00801dc895b91ab308521734a3a216db6247e9a8 /lib/chef
parenteada76335bcf43478b9b3a3d9727c0b127c8bc06 (diff)
parentd06801ff46c0ba2108595bb66da7c638e10eba6c (diff)
downloadchef-f923a7b3297a57506adb265d0c2d8d5671596f32.tar.gz
Merge branch 'master' of https://github.com/chef/chef into feature/windows_ad_join
Diffstat (limited to 'lib/chef')
-rw-r--r--lib/chef/application/client.rb6
-rw-r--r--lib/chef/deprecated.rb9
-rw-r--r--lib/chef/http.rb2
-rw-r--r--lib/chef/knife/core/bootstrap_context.rb2
-rw-r--r--lib/chef/mixin/openssl_helper.rb289
-rw-r--r--lib/chef/node_map.rb7
-rw-r--r--lib/chef/provider/mount/mount.rb4
-rw-r--r--lib/chef/provider/osx_profile.rb6
-rw-r--r--lib/chef/provider/package.rb4
-rw-r--r--lib/chef/provider/package/windows.rb1
-rw-r--r--lib/chef/provider/package/windows/exe.rb2
-rw-r--r--lib/chef/provider/package/yum.rb4
-rw-r--r--lib/chef/provider/package/yum/python_helper.rb3
-rw-r--r--lib/chef/provider/service/debian.rb2
-rw-r--r--lib/chef/provider/user/windows.rb4
-rw-r--r--lib/chef/provider/windows_task.rb11
-rw-r--r--lib/chef/resource.rb26
-rw-r--r--lib/chef/resource/apt_repository.rb4
-rw-r--r--lib/chef/resource/chocolatey_package.rb2
-rw-r--r--lib/chef/resource/cron_access.rb70
-rw-r--r--lib/chef/resource/cron_d.rb238
-rw-r--r--lib/chef/resource/dpkg_package.rb3
-rw-r--r--lib/chef/resource/dsc_resource.rb12
-rw-r--r--lib/chef/resource/dsc_script.rb15
-rw-r--r--lib/chef/resource/execute.rb51
-rw-r--r--lib/chef/resource/file.rb29
-rw-r--r--lib/chef/resource/gem_package.rb36
-rw-r--r--lib/chef/resource/link.rb2
-rw-r--r--lib/chef/resource/lwrp_base.rb6
-rw-r--r--lib/chef/resource/openssl_dhparam.rb17
-rw-r--r--lib/chef/resource/openssl_ec_private_key.rb93
-rw-r--r--lib/chef/resource/openssl_ec_public_key.rb75
-rw-r--r--lib/chef/resource/openssl_rsa_private_key.rb20
-rw-r--r--lib/chef/resource/openssl_rsa_public_key.rb18
-rw-r--r--lib/chef/resource/openssl_x509_certificate.rb221
-rw-r--r--lib/chef/resource/openssl_x509_crl.rb132
-rw-r--r--lib/chef/resource/openssl_x509_request.rb151
-rw-r--r--lib/chef/resource/package.rb34
-rw-r--r--lib/chef/resource/registry_key.rb7
-rw-r--r--lib/chef/resource/rhsm_errata.rb1
-rw-r--r--lib/chef/resource/rhsm_errata_level.rb1
-rw-r--r--lib/chef/resource/rhsm_register.rb3
-rw-r--r--lib/chef/resource/rhsm_repo.rb2
-rw-r--r--lib/chef/resource/rhsm_subscription.rb2
-rw-r--r--lib/chef/resource/sudo.rb14
-rw-r--r--lib/chef/resource/support/cron.d.erb28
-rw-r--r--lib/chef/resource/support/cron_access.erb4
-rw-r--r--lib/chef/resource/swap_file.rb4
-rw-r--r--lib/chef/resource/sysctl.rb42
-rw-r--r--lib/chef/resource/systemd_unit.rb4
-rw-r--r--lib/chef/resource/template.rb2
-rw-r--r--lib/chef/resource/windows_ad_join.rb8
-rw-r--r--lib/chef/resource/windows_auto_run.rb10
-rw-r--r--lib/chef/resource/windows_env.rb4
-rw-r--r--lib/chef/resource/windows_feature_dism.rb9
-rw-r--r--lib/chef/resource/windows_feature_powershell.rb5
-rw-r--r--lib/chef/resource/windows_font.rb6
-rw-r--r--lib/chef/resource/windows_package.rb3
-rw-r--r--lib/chef/resource/windows_printer.rb16
-rw-r--r--lib/chef/resource/windows_printer_port.rb2
-rw-r--r--lib/chef/resource/windows_service.rb47
-rw-r--r--lib/chef/resource/windows_shortcut.rb8
-rw-r--r--lib/chef/resource/windows_task.rb116
-rw-r--r--lib/chef/resource/yum_repository.rb179
-rw-r--r--lib/chef/resource/zypper_package.rb12
-rw-r--r--lib/chef/resource/zypper_repository.rb78
-rw-r--r--lib/chef/resource_inspector.rb7
-rw-r--r--lib/chef/resources.rb9
-rw-r--r--lib/chef/version.rb2
69 files changed, 1943 insertions, 303 deletions
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index 7bea2bd845..0e5584ded3 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -534,14 +534,14 @@ class Chef::Application::Client < Chef::Application
def fetch_recipe_tarball(url, path)
Chef::Log.trace("Download recipes tarball from #{url} to #{path}")
- if url =~ URI.regexp
+ if File.exist?(url)
+ FileUtils.cp(url, path)
+ elsif url =~ URI.regexp
File.open(path, "wb") do |f|
open(url) do |r|
f.write(r.read)
end
end
- elsif File.exist?(url)
- FileUtils.cp(url, path)
else
Chef::Application.fatal! "You specified --recipe-url but the value is neither a valid URL nor a path to a file that exists on disk." +
"Please confirm the location of the tarball and try again."
diff --git a/lib/chef/deprecated.rb b/lib/chef/deprecated.rb
index c0291e057e..1e33fdde0a 100644
--- a/lib/chef/deprecated.rb
+++ b/lib/chef/deprecated.rb
@@ -65,8 +65,13 @@ class Chef
return true if Chef::Config[:silence_deprecation_warnings] == true
# Check if this warning has been silenced by the config.
return true if Chef::Config[:silence_deprecation_warnings].any? do |silence_spec|
- # Just in case someone uses a symbol in the config by mistake.
- silence_spec = silence_spec.to_s
+ if silence_spec.is_a? Integer
+ # Integers can end up matching the line number in the `location` string
+ silence_spec = "CHEF-#{silence_spec}"
+ else
+ # Just in case someone uses a symbol in the config by mistake.
+ silence_spec = silence_spec.to_s
+ end
# Check for a silence by deprecation name, or by location.
self.class.deprecation_key == silence_spec || self.class.deprecation_id.to_s == silence_spec || "chef-#{self.class.deprecation_id}" == silence_spec.downcase || location.include?(silence_spec)
end
diff --git a/lib/chef/http.rb b/lib/chef/http.rb
index 016e81d12c..3f815b9eff 100644
--- a/lib/chef/http.rb
+++ b/lib/chef/http.rb
@@ -215,7 +215,7 @@ class Chef
# you to unlink the tempfile when you're done with it.
#
# @yield [tempfile] block to process the tempfile
- # @yieldparams [tempfile<Tempfile>] tempfile
+ # @yieldparam [tempfile<Tempfile>] tempfile
def streaming_request(path, headers = {}, tempfile = nil)
http_attempts ||= 0
url = create_url(path)
diff --git a/lib/chef/knife/core/bootstrap_context.rb b/lib/chef/knife/core/bootstrap_context.rb
index 4e21564c52..5c736ab01b 100644
--- a/lib/chef/knife/core/bootstrap_context.rb
+++ b/lib/chef/knife/core/bootstrap_context.rb
@@ -45,7 +45,7 @@ class Chef
end
def validation_key
- if @chef_config.key?(:validation_key) &&
+ if @chef_config[:validation_key] &&
File.exist?(File.expand_path(@chef_config[:validation_key]))
IO.read(File.expand_path(@chef_config[:validation_key]))
else
diff --git a/lib/chef/mixin/openssl_helper.rb b/lib/chef/mixin/openssl_helper.rb
index f12a559097..79ab9596e5 100644
--- a/lib/chef/mixin/openssl_helper.rb
+++ b/lib/chef/mixin/openssl_helper.rb
@@ -61,11 +61,48 @@ class Chef
key_content = ::File.exist?(key_file) ? File.read(key_file) : key_file
begin
- key = ::OpenSSL::PKey::RSA.new key_content, key_password
- rescue ::OpenSSL::PKey::RSAError
+ key = ::OpenSSL::PKey.read key_content, key_password
+ rescue ::OpenSSL::PKey::PKeyError, ArgumentError
return false
end
- key.private?
+
+ if key.is_a?(::OpenSSL::PKey::EC)
+ key.private_key?
+ else
+ key.private?
+ end
+ end
+
+ # given a crl file path see if it's actually a crl
+ # @param [String] crl_file the path to the crlfile
+ # @return [Boolean] is the key valid?
+ def crl_file_valid?(crl_file)
+ begin
+ ::OpenSSL::X509::CRL.new ::File.read(crl_file)
+ rescue ::OpenSSL::X509::CRLError, Errno::ENOENT
+ return false
+ end
+ true
+ end
+
+ # check is a serial given is revoked in a crl given
+ # @param [OpenSSL::X509::CRL] crl X509 CRL to check
+ # @param [String, Integer] serial X509 Certificate Serial Number
+ # @return [true, false]
+ def serial_revoked?(crl, serial)
+ raise TypeError, "crl must be a Ruby OpenSSL::X509::CRL object" unless crl.is_a?(::OpenSSL::X509::CRL)
+ raise TypeError, "serial must be a Ruby String or Integer object" unless serial.is_a?(String) || serial.is_a?(Integer)
+
+ serial_to_verify = if serial.is_a?(String)
+ serial.to_i(16)
+ else
+ serial
+ end
+ status = false
+ crl.revoked.each do |revoked|
+ status = true if revoked.serial == serial_to_verify
+ end
+ status
end
# generate a dhparam file
@@ -114,6 +151,252 @@ class Chef
cipher = ::OpenSSL::Cipher.new(key_cipher)
rsa_key.to_pem(cipher, key_password)
end
+
+ # generate an ec private key given curve type
+ # @param [String] curve the kind of curve to use
+ # @return [OpenSSL::PKey::DH]
+ def gen_ec_priv_key(curve)
+ raise TypeError, "curve must be a string" unless curve.is_a?(String)
+ raise ArgumentError, "Specified curve is not available on this system" unless curve == "prime256v1" || curve == "secp384r1" || curve == "secp521r1"
+ ::OpenSSL::PKey::EC.new(curve).generate_key
+ end
+
+ # generate pem format of the public key given a private key
+ # @param [String] priv_key either the contents of the private key or the path to the file
+ # @param [String] priv_key_password optional password for the private key
+ # @return [String] pem format of the public key
+ def gen_ec_pub_key(priv_key, priv_key_password = nil)
+ # if the file exists try to read the content
+ # if not assume we were passed the key and set the string to the content
+ key_content = ::File.exist?(priv_key) ? File.read(priv_key) : priv_key
+ key = ::OpenSSL::PKey::EC.new key_content, priv_key_password
+
+ # Get curve type (prime256v1...)
+ group = ::OpenSSL::PKey::EC::Group.new(key.group.curve_name)
+ # Get Generator point & public point (priv * generator)
+ generator = group.generator
+ pub_point = generator.mul(key.private_key)
+ key.public_key = pub_point
+
+ # Public Key in pem
+ public_key = ::OpenSSL::PKey::EC.new
+ public_key.group = group
+ public_key.public_key = pub_point
+ public_key.to_pem
+ end
+
+ # generate a pem file given a cipher, key, an optional key_password
+ # @param [OpenSSL::PKey::EC] ec_key the private key object
+ # @param [String] key_password the password for the private key
+ # @param [String] key_cipher the cipher to use
+ # @return [String] pem contents
+ def encrypt_ec_key(ec_key, key_password, key_cipher)
+ raise TypeError, "ec_key must be a Ruby OpenSSL::PKey::EC object" unless ec_key.is_a?(::OpenSSL::PKey::EC)
+ raise TypeError, "key_password must be a string" unless key_password.is_a?(String)
+ raise TypeError, "key_cipher must be a string" unless key_cipher.is_a?(String)
+ raise ArgumentError, "Specified key_cipher is not available on this system" unless ::OpenSSL::Cipher.ciphers.include?(key_cipher)
+
+ cipher = ::OpenSSL::Cipher.new(key_cipher)
+ ec_key.to_pem(cipher, key_password)
+ end
+
+ # generate a csr pem file given a subject and a private key
+ # @param [OpenSSL::X509::Name] subject the x509 subject object
+ # @param [OpenSSL::PKey::EC, OpenSSL::PKey::RSA] key the private key object
+ # @return [OpenSSL::X509::Request]
+ def gen_x509_request(subject, key)
+ raise TypeError, "subject must be a Ruby OpenSSL::X509::Name object" unless subject.is_a?(::OpenSSL::X509::Name)
+ raise TypeError, "key must be a Ruby OpenSSL::PKey::EC or a Ruby OpenSSL::PKey::RSA object" unless key.is_a?(::OpenSSL::PKey::EC) || key.is_a?(::OpenSSL::PKey::RSA)
+
+ request = ::OpenSSL::X509::Request.new
+ request.version = 0
+ request.subject = subject
+ request.public_key = key
+
+ # Chef 12 backward compatibility
+ ::OpenSSL::PKey::EC.send(:alias_method, :private?, :private_key?)
+
+ request.sign(key, ::OpenSSL::Digest::SHA256.new)
+ request
+ end
+
+ # generate an array of X509 Extensions given a hash of extensions
+ # @param [Hash] extensions hash of extensions
+ # @return [Array]
+ def gen_x509_extensions(extensions)
+ raise TypeError, "extensions must be a Ruby Hash object" unless extensions.is_a?(Hash)
+
+ exts = []
+ extensions.each do |ext_name, ext_prop|
+ raise TypeError, "#{ext_name} must contain a Ruby Hash" unless ext_prop.is_a?(Hash)
+ raise ArgumentError, "keys in #{ext_name} must be 'values' and 'critical'" unless ext_prop.key?("values") && ext_prop.key?("critical")
+ raise TypeError, "the key 'values' must contain a Ruby Arrays" unless ext_prop["values"].is_a?(Array)
+ raise TypeError, "the key 'critical' must be a Ruby Boolean true/false" unless ext_prop["critical"].is_a?(TrueClass) || ext_prop["critical"].is_a?(FalseClass)
+
+ exts << ::OpenSSL::X509::ExtensionFactory.new.create_extension(ext_name, ext_prop["values"].join(","), ext_prop["critical"])
+ end
+ exts
+ end
+
+ # generate a random Serial
+ # @return [Integer]
+ def gen_serial
+ ::OpenSSL::BN.generate_prime(160)
+ end
+
+ # generate a Certificate given a X509 request
+ # @param [OpenSSL::X509::Request] request X509 Certificate Request
+ # @param [Array] extension Array of X509 Certificate Extension
+ # @param [Hash] info issuer & validity
+ # @param [OpenSSL::PKey::EC, OpenSSL::PKey::RSA] key private key to sign with
+ # @return [OpenSSL::X509::Certificate]
+ def gen_x509_cert(request, extension, info, key)
+ raise TypeError, "request must be a Ruby OpenSSL::X509::Request" unless request.is_a?(::OpenSSL::X509::Request)
+ raise TypeError, "extension must be a Ruby Array" unless extension.is_a?(Array)
+ raise TypeError, "info must be a Ruby Hash" unless info.is_a?(Hash)
+ raise TypeError, "key must be a Ruby OpenSSL::PKey::EC object or a Ruby OpenSSL::PKey::RSA object" unless key.is_a?(::OpenSSL::PKey::EC) || key.is_a?(::OpenSSL::PKey::RSA)
+
+ raise ArgumentError, "info must contain a validity" unless info.key?("validity")
+ raise TypeError, "info['validity'] must be a Ruby Integer object" unless info["validity"].is_a?(Integer)
+
+ cert = ::OpenSSL::X509::Certificate.new
+ ef = ::OpenSSL::X509::ExtensionFactory.new
+
+ cert.serial = gen_serial()
+ cert.version = 2
+ cert.subject = request.subject
+ cert.public_key = request.public_key
+ cert.not_before = Time.now
+ cert.not_after = cert.not_before + info["validity"] * 24 * 60 * 60
+
+ if info["issuer"].nil?
+ cert.issuer = request.subject
+ ef.issuer_certificate = cert
+ extension << ef.create_extension("basicConstraints", "CA:TRUE", true)
+ else
+ raise TypeError, "info['issuer'] must be a Ruby OpenSSL::X509::Certificate object" unless info["issuer"].is_a?(::OpenSSL::X509::Certificate)
+ cert.issuer = info["issuer"].subject
+ ef.issuer_certificate = info["issuer"]
+ end
+ ef.subject_certificate = cert
+ ef.config = ::OpenSSL::Config.load(::OpenSSL::Config::DEFAULT_CONFIG_FILE)
+
+ cert.extensions = extension
+ cert.add_extension ef.create_extension("subjectKeyIdentifier", "hash")
+ cert.add_extension ef.create_extension("authorityKeyIdentifier",
+ "keyid:always,issuer:always")
+
+ cert.sign(key, ::OpenSSL::Digest::SHA256.new)
+ cert
+ end
+
+ # generate a X509 CRL given a CA
+ # @param [OpenSSL::PKey::EC, OpenSSL::PKey::RSA] ca_private_key private key from the CA
+ # @param [Hash] info issuer & validity
+ # @return [OpenSSL::X509::CRL]
+ def gen_x509_crl(ca_private_key, info)
+ raise TypeError, "ca_private_key must be a Ruby OpenSSL::PKey::EC object or a Ruby OpenSSL::PKey::RSA object" unless ca_private_key.is_a?(::OpenSSL::PKey::EC) || ca_private_key.is_a?(::OpenSSL::PKey::RSA)
+ raise TypeError, "info must be a Ruby Hash" unless info.is_a?(Hash)
+
+ raise ArgumentError, "info must contain a issuer and a validity" unless info.key?("issuer") && info.key?("validity")
+ raise TypeError, "info['issuer'] must be a Ruby OpenSSL::X509::Certificate object" unless info["issuer"].is_a?(::OpenSSL::X509::Certificate)
+ raise TypeError, "info['validity'] must be a Ruby Integer object" unless info["validity"].is_a?(Integer)
+
+ crl = ::OpenSSL::X509::CRL.new
+ ef = ::OpenSSL::X509::ExtensionFactory.new
+
+ crl.version = 1
+ crl.issuer = info["issuer"].subject
+ crl.last_update = Time.now
+ crl.next_update = Time.now + 3600 * 24 * info["validity"]
+
+ ef.config = ::OpenSSL::Config.load(::OpenSSL::Config::DEFAULT_CONFIG_FILE)
+ ef.issuer_certificate = info["issuer"]
+
+ crl.add_extension ::OpenSSL::X509::Extension.new("crlNumber", ::OpenSSL::ASN1::Integer(1))
+ crl.add_extension ef.create_extension("authorityKeyIdentifier",
+ "keyid:always,issuer:always")
+ crl.sign(ca_private_key, ::OpenSSL::Digest::SHA256.new)
+ crl
+ end
+
+ # generate the next CRL number available for a X509 CRL given
+ # @param [OpenSSL::X509::CRL] crl x509 CRL
+ # @return [Integer]
+ def get_next_crl_number(crl)
+ raise TypeError, "crl must be a Ruby OpenSSL::X509::CRL object" unless crl.is_a?(::OpenSSL::X509::CRL)
+ crlnum = 1
+ crl.extensions.each do |e|
+ crlnum = e.value if e.oid == "crlNumber"
+ end
+ crlnum.to_i + 1
+ end
+
+ # add a serial given in the crl given
+ # @param [Hash] revoke_info serial to revoke & revokation reason
+ # @param [OpenSSL::X509::CRL] crl X509 CRL
+ # @param [OpenSSL::PKey::EC, OpenSSL::PKey::RSA] ca_private_key private key from the CA
+ # @param [Hash] info issuer & validity
+ # @return [OpenSSL::X509::CRL]
+ def revoke_x509_crl(revoke_info, crl, ca_private_key, info)
+ raise TypeError, "revoke_info must be a Ruby Hash oject" unless revoke_info.is_a?(Hash)
+ raise TypeError, "crl must be a Ruby OpenSSL::X509::CRL object" unless crl.is_a?(::OpenSSL::X509::CRL)
+ raise TypeError, "ca_private_key must be a Ruby OpenSSL::PKey::EC object or a Ruby OpenSSL::PKey::RSA object" unless ca_private_key.is_a?(::OpenSSL::PKey::EC) || ca_private_key.is_a?(::OpenSSL::PKey::RSA)
+ raise TypeError, "info must be a Ruby Hash" unless info.is_a?(Hash)
+
+ raise ArgumentError, "revoke_info must contain a serial and a reason" unless revoke_info.key?("serial") && revoke_info.key?("reason")
+ raise TypeError, "revoke_info['serial'] must be a Ruby String or Integer object" unless revoke_info["serial"].is_a?(String) || revoke_info["serial"].is_a?(Integer)
+ raise TypeError, "revoke_info['reason'] must be a Ruby Integer object" unless revoke_info["reason"].is_a?(Integer)
+
+ raise ArgumentError, "info must contain a issuer and a validity" unless info.key?("issuer") && info.key?("validity")
+ raise TypeError, "info['issuer'] must be a Ruby OpenSSL::X509::Certificate object" unless info["issuer"].is_a?(::OpenSSL::X509::Certificate)
+ raise TypeError, "info['validity'] must be a Ruby Integer object" unless info["validity"].is_a?(Integer)
+
+ revoked = ::OpenSSL::X509::Revoked.new
+ revoked.serial = if revoke_info["serial"].is_a?(String)
+ revoke_info["serial"].to_i(16)
+ else
+ revoke_info["serial"]
+ end
+ revoked.time = Time.now
+
+ ext = ::OpenSSL::X509::Extension.new("CRLReason",
+ ::OpenSSL::ASN1::Enumerated(revoke_info["reason"]))
+ revoked.add_extension(ext)
+ crl.add_revoked(revoked)
+
+ crl = renew_x509_crl(crl, ca_private_key, info)
+ crl
+ end
+
+ # renew a X509 crl given
+ # @param [OpenSSL::X509::CRL] crl CRL to renew
+ # @param [OpenSSL::PKey::EC, OpenSSL::PKey::RSA] ca_private_key private key from the CA
+ # @param [Hash] info issuer & validity
+ # @return [OpenSSL::X509::CRL]
+ def renew_x509_crl(crl, ca_private_key, info)
+ raise TypeError, "crl must be a Ruby OpenSSL::X509::CRL object" unless crl.is_a?(::OpenSSL::X509::CRL)
+ raise TypeError, "ca_private_key must be a Ruby OpenSSL::PKey::EC object or a Ruby OpenSSL::PKey::RSA object" unless ca_private_key.is_a?(::OpenSSL::PKey::EC) || ca_private_key.is_a?(::OpenSSL::PKey::RSA)
+ raise TypeError, "info must be a Ruby Hash" unless info.is_a?(Hash)
+
+ raise ArgumentError, "info must contain a issuer and a validity" unless info.key?("issuer") && info.key?("validity")
+ raise TypeError, "info['issuer'] must be a Ruby OpenSSL::X509::Certificate object" unless info["issuer"].is_a?(::OpenSSL::X509::Certificate)
+ raise TypeError, "info['validity'] must be a Ruby Integer object" unless info["validity"].is_a?(Integer)
+
+ crl.last_update = Time.now
+ crl.next_update = crl.last_update + 3600 * 24 * info["validity"]
+
+ ef = ::OpenSSL::X509::ExtensionFactory.new
+ ef.config = ::OpenSSL::Config.load(::OpenSSL::Config::DEFAULT_CONFIG_FILE)
+ ef.issuer_certificate = info["issuer"]
+
+ crl.extensions = [ ::OpenSSL::X509::Extension.new("crlNumber",
+ ::OpenSSL::ASN1::Integer(get_next_crl_number(crl)))]
+ crl.add_extension ef.create_extension("authorityKeyIdentifier",
+ "keyid:always,issuer:always")
+ crl.sign(ca_private_key, ::OpenSSL::Digest::SHA256.new)
+ crl
+ end
end
end
end
diff --git a/lib/chef/node_map.rb b/lib/chef/node_map.rb
index 62efbc12d6..a4891234f5 100644
--- a/lib/chef/node_map.rb
+++ b/lib/chef/node_map.rb
@@ -66,12 +66,13 @@ EOH
# override from cookbooks is allowed.
# @param __core_override__ [Boolean] Advanced-mode override to add to a key
# even in locked mode.
+ # @param chef_version [String] version constraint to match against the running Chef::VERSION
#
# @yield [node] Arbitrary node filter as a block which takes a node argument
#
# @return [NodeMap] Returns self for possible chaining
#
- def set(key, klass, platform: nil, platform_version: nil, platform_family: nil, os: nil, canonical: nil, override: nil, allow_cookbook_override: false, __core_override__: false, &block) # rubocop:disable Lint/UnderscorePrefixedVariableName
+ def set(key, klass, platform: nil, platform_version: nil, platform_family: nil, os: nil, canonical: nil, override: nil, allow_cookbook_override: false, __core_override__: false, chef_version: nil, &block) # rubocop:disable Lint/UnderscorePrefixedVariableName
new_matcher = { klass: klass }
new_matcher[:platform] = platform if platform
new_matcher[:platform_version] = platform_version if platform_version
@@ -83,6 +84,10 @@ EOH
new_matcher[:cookbook_override] = allow_cookbook_override
new_matcher[:core_override] = __core_override__
+ if chef_version && Chef::VERSION !~ chef_version
+ return map
+ end
+
# Check if the key is already present and locked, unless the override is allowed.
# The checks to see if we should reject, in order:
# 1. Core override mode is not set.
diff --git a/lib/chef/provider/mount/mount.rb b/lib/chef/provider/mount/mount.rb
index 55be15d8c5..7852c8dfdf 100644
--- a/lib/chef/provider/mount/mount.rb
+++ b/lib/chef/provider/mount/mount.rb
@@ -53,6 +53,10 @@ class Chef
def enabled?
# Check to see if there is a entry in /etc/fstab. Last entry for a volume wins.
enabled = false
+ unless ::File.exist?("/etc/fstab")
+ logger.debug "/etc/fstab not found, treating mount as not-enabled"
+ return
+ end
::File.foreach("/etc/fstab") do |line|
case line
when /^[#\s]/
diff --git a/lib/chef/provider/osx_profile.rb b/lib/chef/provider/osx_profile.rb
index 66b5c26137..531d822334 100644
--- a/lib/chef/provider/osx_profile.rb
+++ b/lib/chef/provider/osx_profile.rb
@@ -188,14 +188,14 @@ class Chef
end
def install_profile(profile_path)
- cmd = [ "profiles", "-I", "-F", profile_path ]
+ cmd = [ "/usr/bin/profiles", "-I", "-F", profile_path ]
logger.trace("cmd: #{cmd.join(" ")}")
shellout_results = shell_out(*cmd)
shellout_results.exitstatus
end
def remove_profile
- cmd = [ "profiles", "-R", "-p", @new_profile_identifier ]
+ cmd = [ "/usr/bin/profiles", "-R", "-p", @new_profile_identifier ]
logger.trace("cmd: #{cmd.join(" ")}")
shellout_results = shell_out(*cmd)
shellout_results.exitstatus
@@ -225,7 +225,7 @@ class Chef
end
def write_installed_profiles(tempfile)
- shell_out!( "profiles", "-P", "-o", tempfile )
+ shell_out!( "/usr/bin/profiles", "-P", "-o", tempfile )
end
def read_plist(xml_file)
diff --git a/lib/chef/provider/package.rb b/lib/chef/provider/package.rb
index 01d8829dd2..113d33a2fc 100644
--- a/lib/chef/provider/package.rb
+++ b/lib/chef/provider/package.rb
@@ -500,11 +500,13 @@ class Chef
end
when :install
-
if new_version
if version_requirement_satisfied?(current_version, new_version)
logger.trace("#{new_resource} #{package_name} #{current_version} satisifies #{new_version} requirement")
target_version_array.push(nil)
+ elsif current_version && !allow_downgrade && version_compare(current_version, new_version) == 1
+ logger.warn("#{new_resource} #{package_name} has installed version #{current_version}, which is newer than available version #{new_version}. Skipping...)")
+ target_version_array.push(nil)
else
logger.trace("#{new_resource} #{package_name} #{current_version} needs updating to #{new_version}")
target_version_array.push(new_version)
diff --git a/lib/chef/provider/package/windows.rb b/lib/chef/provider/package/windows.rb
index d203adafe2..f011ebf909 100644
--- a/lib/chef/provider/package/windows.rb
+++ b/lib/chef/provider/package/windows.rb
@@ -229,6 +229,7 @@ class Chef
r.timeout(new_resource.timeout)
r.returns(new_resource.returns)
r.options(new_resource.options)
+ r.sensitive(new_resource.sensitive)
end
end
diff --git a/lib/chef/provider/package/windows/exe.rb b/lib/chef/provider/package/windows/exe.rb
index 6499d0cfeb..e43cd02b08 100644
--- a/lib/chef/provider/package/windows/exe.rb
+++ b/lib/chef/provider/package/windows/exe.rb
@@ -64,7 +64,7 @@ class Chef
unattended_flags,
expand_options(new_resource.options),
"& exit %%%%ERRORLEVEL%%%%",
- ].join(" "), timeout: new_resource.timeout, returns: new_resource.returns
+ ].join(" "), timeout: new_resource.timeout, returns: new_resource.returns, sensitive: new_resource.sensitive
)
end
diff --git a/lib/chef/provider/package/yum.rb b/lib/chef/provider/package/yum.rb
index 029d9dc2e0..e991e4541e 100644
--- a/lib/chef/provider/package/yum.rb
+++ b/lib/chef/provider/package/yum.rb
@@ -237,9 +237,9 @@ class Chef
def installed_version(index)
@installed_version ||= []
@installed_version[index] ||= if new_resource.source
- python_helper.package_query(:whatinstalled, available_version(index).name, version: safe_version_array[index], arch: safe_arch_array[index])
+ python_helper.package_query(:whatinstalled, available_version(index).name, arch: safe_arch_array[index])
else
- python_helper.package_query(:whatinstalled, package_name_array[index], version: safe_version_array[index], arch: safe_arch_array[index])
+ python_helper.package_query(:whatinstalled, package_name_array[index], arch: safe_arch_array[index])
end
@installed_version[index]
end
diff --git a/lib/chef/provider/package/yum/python_helper.rb b/lib/chef/provider/package/yum/python_helper.rb
index 47caf46f57..3da4bb92e8 100644
--- a/lib/chef/provider/package/yum/python_helper.rb
+++ b/lib/chef/provider/package/yum/python_helper.rb
@@ -112,10 +112,11 @@ class Chef
parameters = { "provides" => provides, "version" => version, "arch" => arch }
repo_opts = options_params(options || {})
parameters.merge!(repo_opts)
+ # XXX: for now we restart before and after every query with an enablerepo/disablerepo to clean the helpers internal state
+ restart unless repo_opts.empty?
query_output = query(action, parameters)
version = parse_response(query_output.lines.last)
Chef::Log.trace "parsed #{version} from python helper"
- # XXX: for now we restart after every query with an enablerepo/disablerepo to clean the helpers internal state
restart unless repo_opts.empty?
version
end
diff --git a/lib/chef/provider/service/debian.rb b/lib/chef/provider/service/debian.rb
index 09af9f224f..351075111b 100644
--- a/lib/chef/provider/service/debian.rb
+++ b/lib/chef/provider/service/debian.rb
@@ -78,7 +78,7 @@ class Chef
if line =~ /^### BEGIN INIT INFO/
in_info = true
elsif line =~ /^### END INIT INFO/
- in_info = false
+ break acc
elsif in_info
if line =~ /Default-(Start|Stop):\s+(\d.*)/
acc << $2.split(" ")
diff --git a/lib/chef/provider/user/windows.rb b/lib/chef/provider/user/windows.rb
index 994f1a6774..849382b363 100644
--- a/lib/chef/provider/user/windows.rb
+++ b/lib/chef/provider/user/windows.rb
@@ -45,7 +45,7 @@ class Chef
user_info = @net_user.get_info
current_resource.uid(user_info[:user_id])
- current_resource.comment(user_info[:full_name])
+ current_resource.comment(user_info[:comment])
current_resource.home(user_info[:home_dir])
current_resource.shell(user_info[:script_path])
rescue Chef::Exceptions::UserIDNotFound => e
@@ -100,7 +100,7 @@ class Chef
opts = { name: new_resource.username }
field_list = {
- "comment" => "full_name",
+ "comment" => "comment",
"home" => "home_dir",
"uid" => "user_id",
"shell" => "script_path",
diff --git a/lib/chef/provider/windows_task.rb b/lib/chef/provider/windows_task.rb
index 045e418c7a..98dd8795fa 100644
--- a/lib/chef/provider/windows_task.rb
+++ b/lib/chef/provider/windows_task.rb
@@ -330,7 +330,9 @@ class Chef
flag = (task.account_information != new_resource.user ||
task.application_name != new_resource.command ||
task.parameters != new_resource.command_arguments.to_s ||
- task.principals[:run_level] != run_level)
+ task.principals[:run_level] != run_level ||
+ task.settings[:disallow_start_if_on_batteries] != new_resource.disallow_start_if_on_batteries ||
+ task.settings[:stop_if_going_on_batteries] != new_resource.stop_if_going_on_batteries)
else
current_task_trigger = task.trigger(0)
new_task_trigger = trigger
@@ -353,8 +355,9 @@ class Chef
task.working_directory != new_resource.cwd.to_s ||
task.principals[:logon_type] != logon_type ||
task.principals[:run_level] != run_level ||
- PRIORITY[task.priority] != new_resource.priority
-
+ PRIORITY[task.priority] != new_resource.priority ||
+ task.settings[:disallow_start_if_on_batteries] != new_resource.disallow_start_if_on_batteries ||
+ task.settings[:stop_if_going_on_batteries] != new_resource.stop_if_going_on_batteries
if trigger_type == TaskScheduler::MONTHLYDATE
flag = true if current_task_trigger[:run_on_last_day_of_month] != new_task_trigger[:run_on_last_day_of_month]
end
@@ -552,6 +555,8 @@ class Chef
settings[:idle_duration] = new_resource.idle_time if new_resource.idle_time
settings[:run_only_if_idle] = true if new_resource.idle_time
settings[:priority] = new_resource.priority
+ settings[:disallow_start_if_on_batteries] = new_resource.disallow_start_if_on_batteries
+ settings[:stop_if_going_on_batteries] = new_resource.stop_if_going_on_batteries
settings
end
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index d341e401de..1440b2eb61 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -1305,6 +1305,28 @@ class Chef
end
#
+ # This API can be used for backcompat to do:
+ #
+ # chef_version_for_provides "< 14.0" if defined?(:chef_version_for_provides)
+ #
+ # For core chef versions that do not support chef_version: in provides lines.
+ #
+ # Since resource_name calls provides the generally correct way of doing this is
+ # to do `chef_version_for_provides` first, then `resource_name` and then
+ # any additional options `provides` lines. Calling `resource_name` is somewhat
+ # important to have the canonical_dsl removed or else that'll stick around
+ # and chef_version won't get applied to it.
+ #
+ # Once we no longer care about supporting chef < 14.4 then we can deprecate
+ # this API.
+ #
+ # @param arg [String] version constrant to match against (e.g. "> 14")
+ #
+ def self.chef_version_for_provides(constraint)
+ @chef_version_for_provides = constraint
+ end
+
+ #
# Mark this resource as providing particular DSL.
#
# Resources have an automatic DSL based on their resource_name, equivalent to
@@ -1327,6 +1349,10 @@ class Chef
options[:allow_cookbook_override] = true
end
+ if @chef_version_for_provides && !options.include?(:chef_version)
+ options[:chef_version] = @chef_version_for_provides
+ end
+
result = Chef.resource_handler_map.set(name, self, options, &block)
Chef::DSL::Resources.add_resource_dsl(name)
result
diff --git a/lib/chef/resource/apt_repository.rb b/lib/chef/resource/apt_repository.rb
index 0ed38e61d3..a0d24a646b 100644
--- a/lib/chef/resource/apt_repository.rb
+++ b/lib/chef/resource/apt_repository.rb
@@ -42,11 +42,11 @@ class Chef
description: "The base of the Debian distribution."
property :distribution, [ String, nil, FalseClass ],
- description: "Usually a distribution’s codename, such as trusty, xenial or bionic. Default value: the codename of the node’s distro.",
+ description: "Usually a distribution's codename, such as trusty, xenial or bionic. Default value: the codename of the node's distro.",
default: lazy { node["lsb"]["codename"] }
property :components, Array,
- description: "Package groupings, such as ‘main’ and ‘stable’.",
+ description: "Package groupings, such as 'main' and 'stable'.",
default: lazy { [] }
property :arch, [String, nil, FalseClass],
diff --git a/lib/chef/resource/chocolatey_package.rb b/lib/chef/resource/chocolatey_package.rb
index 5f63f4b5b5..0aa8a41613 100644
--- a/lib/chef/resource/chocolatey_package.rb
+++ b/lib/chef/resource/chocolatey_package.rb
@@ -34,7 +34,7 @@ class Chef
description: "One (or more) additional options that are passed to the command."
property :package_name, [String, Array],
- description: "The name of the package. Default value: the name of the resource block See “Syntax” section above for more information.",
+ description: "The name of the package. Default value: the name of the resource block.",
coerce: proc { |x| [x].flatten }
property :version, [String, Array],
diff --git a/lib/chef/resource/cron_access.rb b/lib/chef/resource/cron_access.rb
new file mode 100644
index 0000000000..b6b822ba40
--- /dev/null
+++ b/lib/chef/resource/cron_access.rb
@@ -0,0 +1,70 @@
+#
+# Author:: Sander Botman <sbotman@schubergphilis.com>
+# Author:: Tim Smith <tsmith@chef.io>
+#
+# Copyright:: 2014-2018, Sander Botman
+# Copyright:: 2018, Chef Software, Inc.
+#
+# 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/resource"
+
+class Chef
+ class Resource
+ class CronAccess < Chef::Resource
+ preview_resource true
+ resource_name :cron_access
+ provides(:cron_manage) # legacy name @todo in Chef 15 we should { true } this so it wins over the cookbook
+
+ introduced "14.4"
+ description "Use the cron_access resource to manage the /etc/cron.allow and /etc/cron.deny files."
+
+ property :user, String,
+ description: "The user to allow or deny. If not provided we'll use the resource name.",
+ name_property: true
+
+ action :allow do
+ description "Add the user to the cron.allow file."
+
+ with_run_context :root do
+ edit_resource(:template, "/etc/cron.allow") do |new_resource|
+ source ::File.expand_path("../support/cron_access.erb", __FILE__)
+ local true
+ mode "0600"
+ variables["users"] ||= []
+ variables["users"] << new_resource.user
+ action :nothing
+ delayed_action :create
+ end
+ end
+ end
+
+ action :deny do
+ description "Add the user to the cron.deny file."
+
+ with_run_context :root do
+ edit_resource(:template, "/etc/cron.deny") do |new_resource|
+ source ::File.expand_path("../support/cron_access.erb", __FILE__)
+ local true
+ mode "0600"
+ variables["users"] ||= []
+ variables["users"] << new_resource.user
+ action :nothing
+ delayed_action :create
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resource/cron_d.rb b/lib/chef/resource/cron_d.rb
new file mode 100644
index 0000000000..ab6d600a16
--- /dev/null
+++ b/lib/chef/resource/cron_d.rb
@@ -0,0 +1,238 @@
+#
+# Copyright:: 2008-2018, 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/resource"
+require "shellwords"
+
+class Chef
+ class Resource
+ class CronD < Chef::Resource
+ preview_resource true
+ resource_name :cron_d
+
+ introduced "14.4"
+ description "Use the cron_d resource to manage cron definitions in /etc/cron.d. This is similar to the 'cron' resource, but it does not use the monolithic /etc/crontab file."
+
+ # validate a provided value is between two other provided values
+ # we also allow * as a valid input
+ # @param spec the value to validate
+ # @param min the lowest value allowed
+ # @param max the highest value allowed
+ # @return [Boolean] valid or not?
+ def self.validate_numeric(spec, min, max)
+ return true if spec == "*"
+ # binding.pry
+ if spec.respond_to? :to_int
+ return false unless spec >= min && spec <= max
+ return true
+ end
+
+ # Lists of invidual values, ranges, and step values all share the validity range for type
+ spec.split(%r{\/|-|,}).each do |x|
+ next if x == "*"
+ return false unless x =~ /^\d+$/
+ x = x.to_i
+ return false unless x >= min && x <= max
+ end
+ true
+ end
+
+ # validate the provided month value to be jan - dec, 1 - 12, or *
+ # @param spec the value to validate
+ # @return [Boolean] valid or not?
+ def self.validate_month(spec)
+ return true if spec == "*"
+ if spec.respond_to? :to_int
+ validate_numeric(spec, 1, 12)
+ elsif spec.respond_to? :to_str
+ return true if spec == "*"
+ # Named abbreviations are permitted but not as part of a range or with stepping
+ return true if %w{jan feb mar apr may jun jul aug sep oct nov dec}.include? spec.downcase
+ # 1-12 are legal for months
+ validate_numeric(spec, 1, 12)
+ else
+ false
+ end
+ end
+
+ # validate the provided day of the week is sun-sat, 0-7, or *
+ # @param spec the value to validate
+ # @return [Boolean] valid or not?
+ def self.validate_dow(spec)
+ return true if spec == "*"
+ if spec.respond_to? :to_int
+ validate_numeric(spec, 0, 7)
+ elsif spec.respond_to? :to_str
+ return true if spec == "*"
+ # Named abbreviations are permitted but not as part of a range or with stepping
+ return true if %w{sun mon tue wed thu fri sat}.include? spec.downcase
+ # 0-7 are legal for days of week
+ validate_numeric(spec, 0, 7)
+ else
+ false
+ end
+ end
+
+ property :cron_name, String,
+ description: "Set the name of the cron job. If this isn't specified we'll use the resource name.",
+ name_property: true
+
+ property :cookbook, String
+
+ property :predefined_value, String,
+ description: 'Schedule your cron job with one of the special predefined value instead of ** * pattern. This correspond to "@reboot", "@yearly", "@annually", "@monthly", "@weekly", "@daily", "@midnight" or "@hourly".',
+ equal_to: %w{ @reboot @yearly @annually @monthly @weekly @daily @midnight @hourly }
+
+ property :minute, [Integer, String],
+ description: "The minute to schedule the cron job to run at. Valid values: 0-59.",
+ default: "*", callbacks: {
+ "should be a valid minute spec" => ->(spec) { validate_numeric(spec, 0, 59) },
+ }
+
+ property :hour, [Integer, String],
+ description: "The hour to schedule the cron job to run at. Valid values: 0-23.",
+ default: "*", callbacks: {
+ "should be a valid hour spec" => ->(spec) { validate_numeric(spec, 0, 23) },
+ }
+
+ property :day, [Integer, String],
+ description: "The day to schedule the cron job to run at. Valid values: 1-31.",
+ default: "*", callbacks: {
+ "should be a valid day spec" => ->(spec) { validate_numeric(spec, 1, 31) },
+ }
+
+ property :month, [Integer, String],
+ description: "The month to schedule the cron job to run at. Valid values: 1-12, jan-dec, or *.",
+ default: "*", callbacks: {
+ "should be a valid month spec" => ->(spec) { validate_month(spec) },
+ }
+
+ property :weekday, [Integer, String],
+ description: "The day to schedule the cron job to run at. Valid values: 0-7, mon-sun, or *.",
+ default: "*", callbacks: {
+ "should be a valid weekday spec" => ->(spec) { validate_dow(spec) },
+ }
+
+ property :command, String,
+ description: "The command to run.",
+ required: true
+
+ property :user, String,
+ description: "The user to run the cron job as.",
+ default: "root"
+
+ property :mailto, String,
+ description: "Set the MAILTO environment variable in the cron.d file."
+
+ property :path, String,
+ description: "Set the PATH environment variable in the cron.d file."
+
+ property :home, String,
+ description: "Set the HOME environment variable in the cron.d file."
+
+ property :shell, String,
+ description: "Set the SHELL environment variable in the cron.d file."
+
+ property :comment, String,
+ description: "A comment to place in the cron.d file."
+
+ property :environment, Hash,
+ description: "A Hash containing additional arbitrary environment variables under which the cron job will be run.",
+ default: lazy { Hash.new }
+
+ property :mode, [String, Integer],
+ description: "The octal mode of the generated crontab file.",
+ default: "0600"
+
+ property :random_delay, Integer,
+ description: "Set the RANDOM_DELAY environment variable in the cron.d file."
+
+ # warn if someone passes the deprecated cookbook property
+ def after_created
+ raise ArgumentError, "The 'cookbook' property for the cron_d resource is no longer supported now that this resource ships in Chef itself." if cookbook
+ end
+
+ action :create do
+ description "Add a cron definition file to /etc/cron.d."
+
+ create_template(:create)
+ end
+
+ action :create_if_missing do
+ description "Add a cron definition file to /etc/cron.d, but do not update an existing file."
+
+ create_template(:create_if_missing)
+ end
+
+ action :delete do
+ description "Remove a cron definition file from /etc/cron.d if it exists."
+
+ # cleanup the legacy named job if it exists
+ file "legacy named cron.d file" do
+ path "/etc/cron.d/#{new_resource.cron_name}"
+ action :delete
+ end
+
+ file "/etc/cron.d/#{sanitized_name}" do
+ action :delete
+ end
+ end
+
+ action_class do
+ # @return [String] cron_name property with . replaced with -
+ def sanitized_name
+ new_resource.cron_name.tr(".", "-")
+ end
+
+ def create_template(create_action)
+ # cleanup the legacy named job if it exists
+ file "#{new_resource.cron_name} legacy named cron.d file" do
+ path "/etc/cron.d/#{new_resource.cron_name}"
+ action :delete
+ only_if { new_resource.cron_name != sanitized_name }
+ end
+
+ # @todo this is Chef 12 era cleanup. Someday we should remove it all
+ template "/etc/cron.d/#{sanitized_name}" do
+ source ::File.expand_path("../support/cron.d.erb", __FILE__)
+ local true
+ mode new_resource.mode
+ variables(
+ name: sanitized_name,
+ predefined_value: new_resource.predefined_value,
+ minute: new_resource.minute,
+ hour: new_resource.hour,
+ day: new_resource.day,
+ month: new_resource.month,
+ weekday: new_resource.weekday,
+ command: new_resource.command,
+ user: new_resource.user,
+ mailto: new_resource.mailto,
+ path: new_resource.path,
+ home: new_resource.home,
+ shell: new_resource.shell,
+ comment: new_resource.comment,
+ random_delay: new_resource.random_delay,
+ environment: new_resource.environment
+ )
+ action create_action
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resource/dpkg_package.rb b/lib/chef/resource/dpkg_package.rb
index bdf761888e..e60764ba8d 100644
--- a/lib/chef/resource/dpkg_package.rb
+++ b/lib/chef/resource/dpkg_package.rb
@@ -28,7 +28,8 @@ class Chef
" When a package is installed from a local file, it must be added to the"\
" node using the remote_file or cookbook_file resources."
- property :source, [ String, Array, nil ]
+ property :source, [ String, Array, nil ],
+ description: "The path to a package in the local file system."
end
end
end
diff --git a/lib/chef/resource/dsc_resource.rb b/lib/chef/resource/dsc_resource.rb
index 9c703b81cc..8381698dc1 100644
--- a/lib/chef/resource/dsc_resource.rb
+++ b/lib/chef/resource/dsc_resource.rb
@@ -74,7 +74,9 @@ class Chef
end
end
- property :module_version, String
+ property :module_version, String,
+ introduced: "12.21",
+ description: "The version number of the module to use. Powershell 5.0.10018.0 (or higher) supports having multiple versions of a module installed. This should be specified along with the module_name."
def property(property_name, value = nil)
if not property_name.is_a?(Symbol)
@@ -99,9 +101,13 @@ class Chef
# If the set method of the DSC resource indicate that a reboot
# is necessary, reboot_action provides the mechanism for a reboot to
# be requested.
- property :reboot_action, Symbol, default: :nothing, equal_to: [:nothing, :reboot_now, :request_reboot]
+ property :reboot_action, Symbol, default: :nothing, equal_to: [:nothing, :reboot_now, :request_reboot],
+ introduced: "12.6",
+ description: "Use to request an immediate reboot or to queue a reboot using the :reboot_now (immediate reboot) or :request_reboot (queued reboot) actions built into the reboot resource."
- property :timeout, Integer
+ property :timeout, Integer,
+ introduced: "12.6",
+ description: "The amount of time (in seconds) a command is to wait before timing out."
private
diff --git a/lib/chef/resource/dsc_script.rb b/lib/chef/resource/dsc_script.rb
index 86be3ddd70..e941e4e918 100644
--- a/lib/chef/resource/dsc_script.rb
+++ b/lib/chef/resource/dsc_script.rb
@@ -115,10 +115,17 @@ class Chef
end
end
- property :flags, Hash
- property :cwd, String
- property :environment, Hash
- property :timeout, Integer
+ property :flags, Hash,
+ description: "Pass parameters to the DSC script that is specified by the command property. Parameters are defined as key-value pairs, where the value of each key is the parameter to pass. This property may not be used in the same recipe as the code property."
+
+ property :cwd, String,
+ description: "The current working directory."
+
+ property :environment, Hash,
+ description: "A Hash of environment variables in the form of ({'ENV_VARIABLE' => 'VALUE'}). (These variables must exist for a command to be run successfully)."
+
+ property :timeout, Integer,
+ description: "The amount of time (in seconds) a command is to wait before timing out."
end
end
end
diff --git a/lib/chef/resource/execute.rb b/lib/chef/resource/execute.rb
index dfccfeb138..93f8063d5d 100644
--- a/lib/chef/resource/execute.rb
+++ b/lib/chef/resource/execute.rb
@@ -55,28 +55,53 @@ class Chef
kind_of: [ String, Array ]
)
end
- property :umask, [ String, Integer ]
- property :creates, String
- property :cwd, String
- property :environment, Hash
+ property :umask, [ String, Integer ],
+ description: "The file mode creation mask, or umask."
+
+ property :creates, String,
+ description: "Prevent a command from creating a file when that file already exists."
+
+ property :cwd, String,
+ description: "Set the current working directory before running a command."
+
+ property :environment, Hash,
+ description: "Specify a Hash of environment variables to be set."
alias :env :environment
- property :group, [ String, Integer ]
- property :live_stream, [ TrueClass, FalseClass ], default: false
+ property :group, [ String, Integer ],
+ description: "The group name or group ID that must be changed before running a command."
+
+ property :live_stream, [ TrueClass, FalseClass ], default: false,
+ description: "Send the output of the command run by this execute resource block to the chef-client event stream."
+
# default_env defaults to `false` so that the command execution more exactly matches what the user gets on the command line without magic
property :default_env, [ TrueClass, FalseClass ], desired_state: false, default: false,
- description: "When true this enables ENV magic to add path_sanity to the PATH and force the locale to English+UTF-8 for parsing output"
- property :returns, [ Integer, Array ], default: 0
- property :timeout, [ Integer, Float ]
- property :user, [ String, Integer ]
- property :domain, String
- property :password, String, sensitive: true
+ introduced: "14.2",
+ description: "When true this enables ENV magic to add path_sanity to the PATH and force the locale to English+UTF-8 for parsing output"
+
+ property :returns, [ Integer, Array ], default: 0,
+ description: "The return value for a command. This may be an array of accepted values. An exception is raised when the return value(s) do not match."
+
+ property :timeout, [ Integer, Float ],
+ description: "The amount of time (in seconds) a command is to wait before timing out."
+
+ property :user, [ String, Integer ],
+ description: "The user name of the user identity with which to launch the new process. The user name may optionally be specifed with a domain, i.e. domainuser or user@my.dns.domain.com via Universal Principal Name (UPN)format. It can also be specified without a domain simply as user if the domain is instead specified using the domain attribute. On Windows only, if this property is specified, the password property must be specified."
+
+ property :domain, String,
+ introduced: "12.21",
+ description: "Windows only: The domain of the user user specified by the user property. If not specified, the user name and password specified by the user and password properties will be used to resolve that user against the domain in which the system running Chef client is joined, or if that system is not joined to a domain it will resolve the user as a local account on that system. An alternative way to specify the domain is to leave this property unspecified and specify the domain as part of the user property."
+
+ property :password, String, sensitive: true,
+ introduced: "12.21",
+ description: "Windows only: The password of the user specified by the user property. This property is mandatory if user is specified on Windows and may only be specified if user is specified. The sensitive property for this resource will automatically be set to true if password is specified."
# lazy used to set default value of sensitive to true if password is set
property :sensitive, [ TrueClass, FalseClass ], default: lazy { |r| r.password ? true : false }
- property :elevated, [ TrueClass, FalseClass ], default: false
+ property :elevated, [ TrueClass, FalseClass ], default: false,
+ introduced: "13.3"
def self.set_guard_inherited_attributes(*inherited_attributes)
@class_inherited_attributes = inherited_attributes
diff --git a/lib/chef/resource/file.rb b/lib/chef/resource/file.rb
index 341b106720..cac20f2356 100644
--- a/lib/chef/resource/file.rb
+++ b/lib/chef/resource/file.rb
@@ -51,14 +51,29 @@ class Chef
default_action :create
allowed_actions :create, :delete, :touch, :create_if_missing
- property :path, String, name_property: true, identity: true
- property :atomic_update, [ TrueClass, FalseClass ], desired_state: false, default: lazy { |r| r.docker? && r.special_docker_files?(r.path) ? false : Chef::Config[:file_atomic_update] }
- property :backup, [ Integer, false ], desired_state: false, default: 5
- property :checksum, [ /^[a-zA-Z0-9]{64}$/, nil ]
- property :content, [ String, nil ], desired_state: false
+ property :path, String, name_property: true, identity: true,
+ description: "The full path to the file, including the file name and its extension. For example: /files/file.txt. Default value: the name of the resource block. Microsoft Windows: A path that begins with a forward slash (/) will point to the root of the current working directory of the chef-client process. This path can vary from system to system. Therefore, using a path that begins with a forward slash (/) is not recommended."
+
+ property :atomic_update, [ TrueClass, FalseClass ], desired_state: false, default: lazy { |r| r.docker? && r.special_docker_files?(r.path) ? false : Chef::Config[:file_atomic_update] },
+ description: "Perform atomic file updates on a per-resource basis. Set to true for atomic file updates. Set to false for non-atomic file updates. This setting overrides file_atomic_update, which is a global setting found in the client.rb file."
+
+ property :backup, [ Integer, FalseClass ], desired_state: false, default: 5,
+ description: "The number of backups to be kept in /var/chef/backup (for UNIX- and Linux-based platforms) or C:/chef/backup (for the Microsoft Windows platform). Set to false to prevent backups from being kept."
+
+ property :checksum, [ /^[a-zA-Z0-9]{64}$/, nil ],
+ description: "The SHA-256 checksum of the file. Use to ensure that a specific file is used. If the checksum does not match, the file is not used."
+
+ property :content, [ String, nil ], desired_state: false,
+ description: "A string that is written to the file. The contents of this property replace any previous content when this property has something other than the default value. The default behavior will not modify content."
+
property :diff, [ String, nil ], desired_state: false
- property :force_unlink, [ TrueClass, FalseClass ], desired_state: false, default: false
- property :manage_symlink_source, [ TrueClass, FalseClass ], desired_state: false
+
+ property :force_unlink, [ TrueClass, FalseClass ], desired_state: false, default: false,
+ description: "How the chef-client handles certain situations when the target file turns out not to be a file. For example, when a target file is actually a symlink. Set to true for the chef-client delete the non-file target and replace it with the specified file. Set to false for the chef-client to raise an error."
+
+ property :manage_symlink_source, [ TrueClass, FalseClass ], desired_state: false,
+ description: "Change the behavior of the file resource if it is pointed at a symlink. When this value is set to true, the Chef client will manage the symlink's permissions or will replace the symlink with a normal file if the resource has content. When this value is set to false, Chef will follow the symlink and will manage the permissions and content of symlink's target file. The default behavior is true but emits a warning that the default value will be changed to false in a future version; setting this explicitly to true or false suppresses this warning."
+
property :verifications, Array, default: lazy { [] }
def verify(command = nil, opts = {}, &block)
diff --git a/lib/chef/resource/gem_package.rb b/lib/chef/resource/gem_package.rb
index f2e1867322..0f6fd413ca 100644
--- a/lib/chef/resource/gem_package.rb
+++ b/lib/chef/resource/gem_package.rb
@@ -23,10 +23,7 @@ class Chef
class GemPackage < Chef::Resource::Package
resource_name :gem_package
- description "Use the gem_package resource to manage gem packages that are only"\
- " included in recipes. When a package is installed from a local file,"\
- " it must be added to the node using the remote_file or cookbook_file"\
- " resources."
+ description "Use the gem_package resource to manage gem packages that are only included in recipes. When a package is installed from a local file, it must be added to the node using the remote_file or cookbook_file resources."
# the source can either be a path to a package source like:
# source /var/tmp/mygem-1.2.3.4.gem
@@ -39,22 +36,23 @@ class Chef
#
# FIXME? the array form of installing paths most likely does not work?
#
- property :source, [ String, Array ]
- property :clear_sources, [ TrueClass, FalseClass ], default: lazy { Chef::Config[:clear_gem_sources] }, desired_state: false
- # Sets a custom gem_binary to run for gem commands.
- property :gem_binary, String, desired_state: false
-
- # set to false to avoid including Chef::Config[:rubygems_url] in the sources
- property :include_default_source, [ TrueClass, FalseClass ], default: true
-
- ##
- # Options for the gem install, either a Hash or a String. When a hash is
- # given, the options are passed to Gem::DependencyInstaller.new, and the
- # gem will be installed via the gems API. When a String is given, the gem
- # will be installed by shelling out to the gem command. Using a Hash of
- # options with an explicit gem_binary will result in undefined behavior.
- property :options, [ String, Hash, Array, nil ], desired_state: false
+ property :source, [ String, Array ],
+ description: "Optional. The URL, or list of URLs, at which the gem package is located. This list is added to the source configured in Chef::Config[:rubygems_url] (see also include_default_source) to construct the complete list of rubygems sources. Users in an 'airgapped' environment should set Chef::Config[:rubygems_url] to their local RubyGems mirror."
+ property :clear_sources, [ TrueClass, FalseClass ],
+ description: "Set to 'true' to download a gem from the path specified by the source property (and not from RubyGems).",
+ default: lazy { Chef::Config[:clear_gem_sources] }, desired_state: false
+
+ property :gem_binary, String, desired_state: false,
+ description: "The path of a gem binary to use for the installation. By default, the same version of Ruby that is used by the chef-client will be installed."
+
+ property :include_default_source, [ TrueClass, FalseClass ],
+ description: "Set to 'false' to not include 'Chef::Config[:rubygems_url]'' in the sources.",
+ default: true, introduced: "13.0"
+
+ property :options, [ String, Hash, Array, nil ],
+ description: "Options for the gem install, either a Hash or a String. When a hash is given, the options are passed to Gem::DependencyInstaller.new, and the gem will be installed via the gems API. When a String is given, the gem will be installed by shelling out to the gem command. Using a Hash of options with an explicit gem_binary will result in undefined behavior.",
+ desired_state: false
end
end
end
diff --git a/lib/chef/resource/link.rb b/lib/chef/resource/link.rb
index 487befde2e..00ce69dddd 100644
--- a/lib/chef/resource/link.rb
+++ b/lib/chef/resource/link.rb
@@ -48,7 +48,7 @@ class Chef
end
property :target_file, String,
- description: "The name of the link. Default value: the name of the resource block See “Syntax” section above for more information.",
+ description: "The name of the link. Default value: the name of the resource block.",
name_property: true, identity: true
property :to, String,
diff --git a/lib/chef/resource/lwrp_base.rb b/lib/chef/resource/lwrp_base.rb
index c0f6f835ad..ed8a3b205d 100644
--- a/lib/chef/resource/lwrp_base.rb
+++ b/lib/chef/resource/lwrp_base.rb
@@ -49,9 +49,7 @@ class Chef
resource_name = filename_to_qualified_string(cookbook_name, filename)
- # We load the class first to give it a chance to set its own name
resource_class = Class.new(self)
- resource_class.resource_name resource_name.to_sym
resource_class.run_context = run_context
resource_class.class_from_file(filename)
@@ -67,6 +65,10 @@ class Chef
LWRPBase.loaded_lwrps[filename] = true
+ # wire up the default resource name after the class is parsed only if we haven't declared one.
+ # (this ordering is important for MapCollision deprecation warnings)
+ resource_class.resource_name resource_name.to_sym if resource_class.resource_name.nil?
+
resource_class
end
diff --git a/lib/chef/resource/openssl_dhparam.rb b/lib/chef/resource/openssl_dhparam.rb
index b7bc8438f2..3b0d264f8b 100644
--- a/lib/chef/resource/openssl_dhparam.rb
+++ b/lib/chef/resource/openssl_dhparam.rb
@@ -26,10 +26,7 @@ class Chef
resource_name :openssl_dhparam
provides(:openssl_dhparam) { true }
- description "Use the openssl_dhparam resource to generate dhparam.pem files. If a"\
- " valid dhparam.pem file is found at the specified location, no new file"\
- " will be created. If a file is found at the specified location but it is"\
- " not a valid dhparam file, it will be overwritten."
+ description "Use the openssl_dhparam resource to generate dhparam.pem files. If a valid dhparam.pem file is found at the specified location, no new file will be created. If a file is found at the specified location but it is not a valid dhparam file, it will be overwritten."
introduced "14.0"
property :path, String,
@@ -48,14 +45,14 @@ class Chef
description: "The desired Diffie-Hellmann generator.",
default: 2
- property :owner, [String, nil],
- description: "The owner of all files created by the resource."
+ property :owner, String,
+ description: "The owner applied to all files created by the resource."
- property :group, [String, nil],
- description: "The group of all files created by the resource."
+ property :group, String,
+ description: "The group ownership applied to all files created by the resource."
property :mode, [Integer, String],
- description: "The permission mode of all files created by the resource.",
+ description: "The permission mode applied to all files created by the resource.",
default: "0640"
action :create do
@@ -65,7 +62,7 @@ class Chef
converge_by("Create a dhparam file #{new_resource.path}") do
dhparam_content = gen_dhparam(new_resource.key_length, new_resource.generator).to_pem
- declare_resource(:file, new_resource.path) do
+ file new_resource.path do
action :create
owner new_resource.owner unless new_resource.owner.nil?
group new_resource.group unless new_resource.group.nil?
diff --git a/lib/chef/resource/openssl_ec_private_key.rb b/lib/chef/resource/openssl_ec_private_key.rb
new file mode 100644
index 0000000000..77e98f9c2d
--- /dev/null
+++ b/lib/chef/resource/openssl_ec_private_key.rb
@@ -0,0 +1,93 @@
+#
+# Copyright:: Copyright 2018, Chef Software Inc.
+# Author:: Julien Huon
+# 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/resource"
+
+class Chef
+ class Resource
+ class OpensslEcPrivateKey < Chef::Resource
+ require "chef/mixin/openssl_helper"
+ include Chef::Mixin::OpenSSLHelper
+
+ preview_resource true
+ resource_name :openssl_ec_private_key
+
+ description "Use the openssl_ec_private_key resource to generate an elliptic curve (EC) private key file. If a valid EC key file can be opened at the specified location, no new file will be created. If the EC key file cannot be opened, either because it does not exist or because the password to the EC key file does not match the password in the recipe, then it will be overwritten."
+ introduced "14.4"
+
+ property :path, String,
+ description: "The path to write the file to it's different than the resource name.",
+ name_property: true
+
+ property :key_curve, String,
+ equal_to: %w{secp384r1 secp521r1 prime256v1 secp224r1 secp256k1},
+ description: "The desired curve of the generated key (if key_type is equal to 'ec'). Run openssl ecparam -list_curves to see available options.",
+ default: "prime256v1"
+
+ property :key_pass, String,
+ description: "The desired passphrase for the key."
+
+ property :key_cipher, String,
+ equal_to: OpenSSL::Cipher.ciphers,
+ validation_message: "key_cipher must be a cipher known to openssl. Run `openssl list-cipher-algorithms` to see available options.",
+ description: "The designed cipher to use when generating your key. Run `openssl list-cipher-algorithms` to see available options.",
+ default: "des3"
+
+ property :owner, String,
+ description: "The owner applied to all files created by the resource."
+
+ property :group, String,
+ description: "The group ownership applied to all files created by the resource."
+
+ property :mode, [Integer, String],
+ description: "The permission mode applied to all files created by the resource.",
+ default: "0600"
+
+ property :force, [TrueClass, FalseClass],
+ description: "Force creation of the key even if the same key already exists on the node.",
+ default: false, desired_state: false
+
+ action :create do
+ description "Generate the ec private key"
+
+ unless new_resource.force || priv_key_file_valid?(new_resource.path, new_resource.key_pass)
+ converge_by("Create an EC private key #{new_resource.path}") do
+ log "Generating an #{new_resource.key_curve} "\
+ "EC key file at #{new_resource.name}, this may take some time"
+
+ if new_resource.key_pass
+ unencrypted_ec_key = gen_ec_priv_key(new_resource.key_curve)
+ ec_key_content = encrypt_ec_key(unencrypted_ec_key, new_resource.key_pass, new_resource.key_cipher)
+ else
+ ec_key_content = gen_ec_priv_key(new_resource.key_curve).to_pem
+ end
+
+ file new_resource.path do
+ action :create
+ owner new_resource.owner unless new_resource.owner.nil?
+ group new_resource.group unless new_resource.group.nil?
+ mode new_resource.mode
+ sensitive true
+ content ec_key_content
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resource/openssl_ec_public_key.rb b/lib/chef/resource/openssl_ec_public_key.rb
new file mode 100644
index 0000000000..9b1ded4043
--- /dev/null
+++ b/lib/chef/resource/openssl_ec_public_key.rb
@@ -0,0 +1,75 @@
+#
+# Copyright:: Copyright 2018, Chef Software Inc.
+# Author:: Julien Huon
+# 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/resource"
+
+class Chef
+ class Resource
+ class OpensslEcPublicKey < Chef::Resource
+ require "chef/mixin/openssl_helper"
+ include Chef::Mixin::OpenSSLHelper
+
+ preview_resource true
+ resource_name :openssl_ec_public_key
+
+ description "Use the openssl_ec_public_key resource to generate elliptic curve (EC) public key files given a private key."
+ introduced "14.4"
+
+ property :path, String,
+ description: "The path to write the file to if different than the resource's name.",
+ name_property: true
+
+ property :private_key_path, String,
+ description: "The path to the private key file."
+
+ property :private_key_content, String,
+ description: "The content of the private key including new lines. This property is used in place of private_key_path to avoid having to first write a key to disk."
+
+ property :private_key_pass, String,
+ description: "The passphrase of the provided private key."
+
+ property :owner, String,
+ description: "The owner applied to all files created by the resource."
+
+ property :group, String,
+ description: "The group ownership applied to all files created by the resource."
+
+ property :mode, [Integer, String],
+ description: "The permission mode applied to all files created by the resource.",
+ default: "0640"
+
+ action :create do
+ description "Generate the ec public key from a private key"
+
+ raise ArgumentError, "You cannot specify both 'private_key_path' and 'private_key_content' properties at the same time." if new_resource.private_key_path && new_resource.private_key_content
+ raise ArgumentError, "You must specify the private key with either 'private_key_path' or 'private_key_content' properties." unless new_resource.private_key_path || new_resource.private_key_content
+ raise "#{new_resource.private_key_path} not a valid private EC key or password is invalid" unless priv_key_file_valid?((new_resource.private_key_path || new_resource.private_key_content), new_resource.private_key_pass)
+
+ ec_key_content = gen_ec_pub_key((new_resource.private_key_path || new_resource.private_key_content), new_resource.private_key_pass)
+
+ file new_resource.path do
+ action :create
+ owner new_resource.owner unless new_resource.owner.nil?
+ group new_resource.group unless new_resource.group.nil?
+ mode new_resource.mode
+ content ec_key_content
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resource/openssl_rsa_private_key.rb b/lib/chef/resource/openssl_rsa_private_key.rb
index 1bc8f73f47..f2c1400a30 100644
--- a/lib/chef/resource/openssl_rsa_private_key.rb
+++ b/lib/chef/resource/openssl_rsa_private_key.rb
@@ -27,11 +27,7 @@ class Chef
provides(:openssl_rsa_private_key) { true }
provides(:openssl_rsa_key) { true } # legacy cookbook resource name
- description "Use the openssl_rsa_private_key resource to generate RSA private key files."\
- " If a valid RSA key file can be opened at the specified location, no new file"\
- " will be created. If the RSA key file cannot be opened, either because it does"\
- " not exist or because the password to the RSA key file does not match the"\
- " password in the recipe, it will be overwritten."
+ description "Use the openssl_rsa_private_key resource to generate RSA private key files. If a valid RSA key file can be opened at the specified location, no new file will be created. If the RSA key file cannot be opened, either because it does not exist or because the password to the RSA key file does not match the password in the recipe, it will be overwritten."
introduced "14.0"
property :path, String,
@@ -53,18 +49,18 @@ class Chef
description: "The designed cipher to use when generating your key. Run `openssl list-cipher-algorithms` to see available options.",
default: "des3"
- property :owner, [String, nil],
- description: "The owner of all files created by the resource."
+ property :owner, String,
+ description: "The owner applied to all files created by the resource."
- property :group, [String, nil],
- description: "The group of all files created by the resource."
+ property :group, String,
+ description: "The group ownership applied to all files created by the resource."
property :mode, [Integer, String],
- description: "The permission mode of all files created by the resource.",
+ description: "The permission mode applied to all files created by the resource.",
default: "0600"
property :force, [TrueClass, FalseClass],
- description: "Force creating the key even if the existing key exists.",
+ description: "Force creation of the key even if the same key already exists on the node.",
default: false, desired_state: false
action :create do
@@ -80,7 +76,7 @@ class Chef
rsa_key_content = gen_rsa_priv_key(new_resource.key_length).to_pem
end
- declare_resource(:file, new_resource.path) do
+ file new_resource.path do
action :create
owner new_resource.owner unless new_resource.owner.nil?
group new_resource.group unless new_resource.group.nil?
diff --git a/lib/chef/resource/openssl_rsa_public_key.rb b/lib/chef/resource/openssl_rsa_public_key.rb
index fa00404999..c213284235 100644
--- a/lib/chef/resource/openssl_rsa_public_key.rb
+++ b/lib/chef/resource/openssl_rsa_public_key.rb
@@ -26,7 +26,7 @@ class Chef
resource_name :openssl_rsa_public_key
provides(:openssl_rsa_public_key) { true }
- description "Use the openssl_rsa_public_key resource to generate RSA public key files given a RSA private key"
+ description "Use the openssl_rsa_public_key resource to generate RSA public key files given a RSA private key."
introduced "14.0"
property :path, String,
@@ -34,22 +34,22 @@ class Chef
name_property: true
property :private_key_path, String,
- description: "The path to the private key."
+ description: "The path to the private key file."
property :private_key_content, String,
- description: "The content of the private key including new lines. Used instead of private_key_path to avoid having to first write a key to disk."
+ description: "The content of the private key including new lines. This property is used in place of private_key_path to avoid having to first write a key to disk."
property :private_key_pass, String,
description: "The passphrase of the provided private key."
- property :owner, [String, nil],
- description: "The owner of all files created by the resource."
+ property :owner, String,
+ description: "The owner applied to all files created by the resource."
- property :group, [String, nil],
- description: "The group of all files created by the resource."
+ property :group, String,
+ description: "The group ownership applied to all files created by the resource."
property :mode, [Integer, String],
- description: "The permission mode of all files created by the resource.",
+ description: "The permission mode applied to all files created by the resource.",
default: "0640"
action :create do
@@ -61,7 +61,7 @@ class Chef
rsa_key_content = gen_rsa_pub_key((new_resource.private_key_path || new_resource.private_key_content), new_resource.private_key_pass)
- declare_resource(:file, new_resource.path) do
+ file new_resource.path do
action :create
owner new_resource.owner unless new_resource.owner.nil?
group new_resource.group unless new_resource.group.nil?
diff --git a/lib/chef/resource/openssl_x509_certificate.rb b/lib/chef/resource/openssl_x509_certificate.rb
new file mode 100644
index 0000000000..fcbcc650a0
--- /dev/null
+++ b/lib/chef/resource/openssl_x509_certificate.rb
@@ -0,0 +1,221 @@
+#
+# License:: Apache License, Version 2.0
+# Author:: Julien Huon
+# Copyright:: Copyright 2018, Chef Software Inc.
+#
+# 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/resource"
+
+class Chef
+ class Resource
+ class OpensslX509Certificate < Chef::Resource
+ require "chef/mixin/openssl_helper"
+ include Chef::Mixin::OpenSSLHelper
+
+ preview_resource true
+ resource_name :openssl_x509_certificate
+ # provides(:openssl_x509) { true } # legacy cookbook name. Cookbook will win for now. @todo Uncomment this for Chef 15
+
+ description "Use the openssl_x509_certificate resource to generate signed or self-signed, PEM-formatted x509 certificates. If no existing key is specified, the resource will automatically generate a passwordless key with the certificate. If a CA private key and certificate are provided, the certificate will be signed with them. Note: This resource was renamed from openssl_x509 to openssl_x509_certificate. The legacy name will continue to function, but cookbook code should be updated for the new resource name."
+ introduced "14.4"
+
+ property :path, String,
+ description: "Optional path to write the file to if you'd like to specify it here instead of in the resource name.",
+ name_property: true
+
+ property :owner, String,
+ description: "The owner applied to all files created by the resource."
+
+ property :group, String,
+ description: "The group ownership applied to all files created by the resource."
+
+ property :expire, Integer,
+ description: "Value representing the number of days from now through which the issued certificate cert will remain valid. The certificate will expire after this period.",
+ default: 365
+
+ property :mode, [Integer, String],
+ description: "The permission mode applied to all files created by the resource."
+
+ property :country, String,
+ description: "Value for the C certificate field."
+
+ property :state, String,
+ description: "Value for the ST certificate field."
+
+ property :city, String,
+ description: "Value for the L certificate field."
+
+ property :org, String,
+ description: "Value for the O certificate field."
+
+ property :org_unit, String,
+ description: "Value for the OU certificate field."
+
+ property :common_name, String,
+ description: "Value for the CN certificate field."
+
+ property :email, String,
+ description: "Value for the email certificate field."
+
+ property :extensions, Hash,
+ description: "Hash of X509 Extensions entries, in format { 'keyUsage' => { 'values' => %w( keyEncipherment digitalSignature), 'critical' => true } }.",
+ default: lazy { Hash.new }
+
+ property :subject_alt_name, Array,
+ description: "Array of Subject Alternative Name entries, in format DNS:example.com or IP:1.2.3.4.",
+ default: lazy { [] }
+
+ property :key_file, String,
+ description: "The path to a certificate key file on the filesystem. If the key_file property is specified, the resource will attempt to source a key from this location. If no key file is found, the resource will generate a new key file at this location. If the key_file property is not specified, the resource will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate."
+
+ property :key_pass, String,
+ description: "The passphrase for an existing key's passphrase."
+
+ property :key_type, String,
+ equal_to: %w{rsa ec},
+ description: "The desired type of the generated key (rsa or ec).",
+ default: "rsa"
+
+ property :key_length, Integer,
+ equal_to: [1024, 2048, 4096, 8192],
+ description: "The desired bit length of the generated key (if key_type is equal to 'rsa').",
+ default: 2048
+
+ property :key_curve, String,
+ description: "The desired curve of the generated key (if key_type is equal to 'ec'). Run openssl ecparam -list_curves to see available options.",
+ equal_to: %w{secp384r1 secp521r1 prime256v1},
+ default: "prime256v1"
+
+ property :csr_file, String,
+ description: "The path to a X509 Certificate Request (CSR) on the filesystem. If the csr_file property is specified, the resource will attempt to source a CSR from this location. If no CSR file is found, the resource will generate a Self-Signed Certificate and the certificate fields must be specified (common_name at last)."
+
+ property :ca_cert_file, String,
+ description: "The path to the CA X509 Certificate on the filesystem. If the ca_cert_file property is specified, the ca_key_file property must also be specified, the certificate will be signed with them."
+
+ property :ca_key_file, String,
+ description: "The path to the CA private key on the filesystem. If the ca_key_file property is specified, the 'ca_cert_file' property must also be specified, the certificate will be signed with them."
+
+ property :ca_key_pass, String,
+ description: "The passphrase for CA private key's passphrase."
+
+ action :create do
+ description "Generate a certificate"
+
+ unless ::File.exist? new_resource.path
+ converge_by("Create #{@new_resource}") do
+ file new_resource.path do
+ action :create_if_missing
+ owner new_resource.owner unless new_resource.owner.nil?
+ group new_resource.group unless new_resource.group.nil?
+ mode new_resource.mode unless new_resource.mode.nil?
+ sensitive true
+ content cert.to_pem
+ end
+
+ if new_resource.csr_file.nil?
+ file new_resource.key_file do
+ action :create_if_missing
+ owner new_resource.owner unless new_resource.owner.nil?
+ group new_resource.group unless new_resource.group.nil?
+ mode new_resource.mode unless new_resource.mode.nil?
+ sensitive true
+ content key.to_pem
+ end
+ end
+ end
+ end
+ end
+
+ action_class do
+ def generate_key_file
+ unless new_resource.key_file
+ path, file = ::File.split(new_resource.path)
+ filename = ::File.basename(file, ::File.extname(file))
+ new_resource.key_file path + "/" + filename + ".key"
+ end
+ new_resource.key_file
+ end
+
+ def key
+ @key ||= if priv_key_file_valid?(generate_key_file, new_resource.key_pass)
+ OpenSSL::PKey.read ::File.read(generate_key_file), new_resource.key_pass
+ elsif new_resource.key_type == "rsa"
+ gen_rsa_priv_key(new_resource.key_length)
+ else
+ gen_ec_priv_key(new_resource.key_curve)
+ end
+ @key
+ end
+
+ def request
+ request = if new_resource.csr_file.nil?
+ gen_x509_request(subject, key)
+ else
+ OpenSSL::X509::Request.new ::File.read(new_resource.csr_file)
+ end
+ request
+ end
+
+ def subject
+ subject = OpenSSL::X509::Name.new()
+ subject.add_entry("C", new_resource.country) unless new_resource.country.nil?
+ subject.add_entry("ST", new_resource.state) unless new_resource.state.nil?
+ subject.add_entry("L", new_resource.city) unless new_resource.city.nil?
+ subject.add_entry("O", new_resource.org) unless new_resource.org.nil?
+ subject.add_entry("OU", new_resource.org_unit) unless new_resource.org_unit.nil?
+ subject.add_entry("CN", new_resource.common_name)
+ subject.add_entry("emailAddress", new_resource.email) unless new_resource.email.nil?
+ subject
+ end
+
+ def ca_private_key
+ ca_private_key = if new_resource.csr_file.nil?
+ key
+ else
+ OpenSSL::PKey.read ::File.read(new_resource.ca_key_file), new_resource.ca_key_pass
+ end
+ ca_private_key
+ end
+
+ def ca_info
+ # Will contain issuer (if any) & expiration
+ ca_info = {}
+
+ unless new_resource.ca_cert_file.nil?
+ ca_info["issuer"] = OpenSSL::X509::Certificate.new ::File.read(new_resource.ca_cert_file)
+ end
+ ca_info["validity"] = new_resource.expire
+
+ ca_info
+ end
+
+ def extensions
+ extensions = gen_x509_extensions(new_resource.extensions)
+
+ unless new_resource.subject_alt_name.empty?
+ extensions += gen_x509_extensions("subjectAltName" => { "values" => new_resource.subject_alt_name, "critical" => false })
+ end
+
+ extensions
+ end
+
+ def cert
+ cert = gen_x509_cert(request, extensions, ca_info, ca_private_key)
+ cert
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resource/openssl_x509_crl.rb b/lib/chef/resource/openssl_x509_crl.rb
new file mode 100644
index 0000000000..06f73bdd51
--- /dev/null
+++ b/lib/chef/resource/openssl_x509_crl.rb
@@ -0,0 +1,132 @@
+#
+# License:: Apache License, Version 2.0
+# Author:: Julien Huon
+# Copyright:: Copyright 2018, Chef Software Inc.
+#
+# 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/resource"
+
+class Chef
+ class Resource
+ class OpensslX509Crl < Chef::Resource
+ require "chef/mixin/openssl_helper"
+ include Chef::Mixin::OpenSSLHelper
+
+ preview_resource true
+ resource_name :openssl_x509_crl
+
+ description "Use the openssl_x509_crl resource to generate PEM-formatted x509 certificate revocation list (CRL) files."
+ introduced "14.4"
+
+ property :path, String,
+ description: "Optional path to write the file to if you'd like to specify it here instead of in the resource name.",
+ name_property: true
+
+ property :serial_to_revoke, [Integer, String],
+ description: "Serial of the X509 Certificate to revoke."
+
+ property :revocation_reason, Integer,
+ description: "Reason for the revocation.",
+ default: 0
+
+ property :expire, Integer,
+ description: "Value representing the number of days from now through which the issued CRL will remain valid. The CRL will expire after this period.",
+ default: 8
+
+ property :renewal_threshold, Integer,
+ description: "Number of days before the expiration. It this threshold is reached, the CRL will be renewed.",
+ default: 1
+
+ property :ca_cert_file, String,
+ description: "The path to the CA X509 Certificate on the filesystem. If the ca_cert_file property is specified, the ca_key_file property must also be specified, the CRL will be signed with them.",
+ required: true
+
+ property :ca_key_file, String,
+ description: "The path to the CA private key on the filesystem. If the ca_key_file property is specified, the ca_cert_file property must also be specified, the CRL will be signed with them.",
+ required: true
+
+ property :ca_key_pass, String,
+ description: "The passphrase for CA private key's passphrase."
+
+ property :owner, String,
+ description: "The owner permission for the CRL file."
+
+ property :group, String,
+ description: "The group permission for the CRL file."
+
+ property :mode, [Integer, String],
+ description: "The permission mode of the CRL file."
+
+ action :create do
+ description "Create the CRL file."
+
+ file new_resource.path do
+ owner new_resource.owner unless new_resource.owner.nil?
+ group new_resource.group unless new_resource.group.nil?
+ mode new_resource.mode unless new_resource.mode.nil?
+ content crl.to_pem
+ action :create
+ end
+ end
+
+ action_class do
+ def crl_info
+ # Will contain issuer & expiration
+ crl_info = {}
+
+ crl_info["issuer"] = ::OpenSSL::X509::Certificate.new ::File.read(new_resource.ca_cert_file)
+ crl_info["validity"] = new_resource.expire
+
+ crl_info
+ end
+
+ def revoke_info
+ # Will contain Serial to revoke & reason
+ revoke_info = {}
+
+ revoke_info["serial"] = new_resource.serial_to_revoke
+ revoke_info["reason"] = new_resource.revocation_reason
+
+ revoke_info
+ end
+
+ def ca_private_key
+ ca_private_key = ::OpenSSL::PKey.read ::File.read(new_resource.ca_key_file), new_resource.ca_key_pass
+ ca_private_key
+ end
+
+ def crl
+ if crl_file_valid?(new_resource.path)
+ crl = ::OpenSSL::X509::CRL.new ::File.read(new_resource.path)
+ else
+ log "Creating a CRL #{new_resource.path} for CA #{new_resource.ca_cert_file}"
+ crl = gen_x509_crl(ca_private_key, crl_info)
+ end
+
+ if !new_resource.serial_to_revoke.nil? && serial_revoked?(crl, new_resource.serial_to_revoke) == false
+ log "Revoking serial #{new_resource.serial_to_revoke} in CRL #{new_resource.path}"
+ crl = revoke_x509_crl(revoke_info, crl, ca_private_key, crl_info)
+ elsif crl.next_update <= Time.now + 3600 * 24 * new_resource.renewal_threshold
+ log "Renewing CRL for CA #{new_resource.ca_cert_file}"
+ crl = renew_x509_crl(crl, ca_private_key, crl_info)
+ end
+
+ crl
+ end
+ end
+
+ end
+ end
+end
diff --git a/lib/chef/resource/openssl_x509_request.rb b/lib/chef/resource/openssl_x509_request.rb
new file mode 100644
index 0000000000..a553e38a89
--- /dev/null
+++ b/lib/chef/resource/openssl_x509_request.rb
@@ -0,0 +1,151 @@
+#
+# License:: Apache License, Version 2.0
+# Author:: Julien Huon
+# Copyright:: Copyright 2018, Chef Software Inc.
+#
+# 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/resource"
+
+class Chef
+ class Resource
+ class OpensslX509Request < Chef::Resource
+ require "chef/mixin/openssl_helper"
+ include Chef::Mixin::OpenSSLHelper
+
+ preview_resource true
+ resource_name :openssl_x509_request
+
+ description "Use the openssl_x509_request resource to generate PEM-formatted x509 certificates requests. If no existing key is specified, the resource will automatically generate a passwordless key with the certificate."
+ introduced "14.4"
+
+ property :path, String, name_property: true,
+ description: "The optional path to write the file to if you'd like to specify it here instead of in the resource name."
+
+ property :owner, String,
+ description: "The owner applied to all files created by the resource."
+
+ property :group, String,
+ description: "The group ownership applied to all files created by the resource."
+
+ property :mode, [Integer, String],
+ description: "The permission mode applied to all files created by the resource."
+
+ property :country, String,
+ description: "Value for the C certificate field."
+
+ property :state, String,
+ description: "Value for the ST certificate field."
+
+ property :city, String,
+ description: "Value for the L certificate field."
+
+ property :org, String,
+ description: "Value for the O certificate field."
+
+ property :org_unit, String,
+ description: "Value for the OU certificate field."
+
+ property :common_name, String,
+ required: true,
+ description: "Value for the CN certificate field."
+
+ property :email, String,
+ description: "Value for the email certificate field."
+
+ property :key_file, String,
+ description: "The path to a certificate key file on the filesystem. If the key_file property is specified, the resource will attempt to source a key from this location. If no key file is found, the resource will generate a new key file at this location. If the key_file property is not specified, the resource will generate a key file in the same directory as the generated certificate, with the same name as the generated certificate."
+
+ property :key_pass, String,
+ description: "The passphrase for an existing key's passphrase."
+
+ property :key_type, String,
+ equal_to: %w{rsa ec}, default: "ec",
+ description: "The desired type of the generated key (rsa or ec)."
+
+ property :key_length, Integer,
+ equal_to: [1024, 2048, 4096, 8192], default: 2048,
+ description: "The desired bit length of the generated key (if key_type is equal to 'rsa')."
+
+ property :key_curve, String,
+ equal_to: %w{secp384r1 secp521r1 prime256v1}, default: "prime256v1",
+ description: "The desired curve of the generated key (if key_type is equal to 'ec'). Run openssl ecparam -list_curves to see available options."
+
+ default_action :create
+
+ action :create do
+ description "Generate a certificate request."
+
+ unless ::File.exist? new_resource.path
+ converge_by("Create CSR #{@new_resource}") do
+ file new_resource.name do
+ owner new_resource.owner unless new_resource.owner.nil?
+ group new_resource.group unless new_resource.group.nil?
+ mode new_resource.mode unless new_resource.mode.nil?
+ content csr.to_pem
+ action :create
+ end
+
+ file new_resource.key_file do
+ owner new_resource.owner unless new_resource.owner.nil?
+ group new_resource.group unless new_resource.group.nil?
+ mode new_resource.mode unless new_resource.mode.nil?
+ content key.to_pem
+ sensitive true
+ action :create_if_missing
+ end
+ end
+ end
+ end
+
+ action_class do
+ def generate_key_file
+ unless new_resource.key_file
+ path, file = ::File.split(new_resource.path)
+ filename = ::File.basename(file, ::File.extname(file))
+ new_resource.key_file path + "/" + filename + ".key"
+ end
+ new_resource.key_file
+ end
+
+ def key
+ @key ||= if priv_key_file_valid?(generate_key_file, new_resource.key_pass)
+ OpenSSL::PKey.read ::File.read(generate_key_file), new_resource.key_pass
+ elsif new_resource.key_type == "rsa"
+ gen_rsa_priv_key(new_resource.key_length)
+ else
+ gen_ec_priv_key(new_resource.key_curve)
+ end
+ @key
+ end
+
+ def subject
+ csr_subject = OpenSSL::X509::Name.new()
+ csr_subject.add_entry("C", new_resource.country) unless new_resource.country.nil?
+ csr_subject.add_entry("ST", new_resource.state) unless new_resource.state.nil?
+ csr_subject.add_entry("L", new_resource.city) unless new_resource.city.nil?
+ csr_subject.add_entry("O", new_resource.org) unless new_resource.org.nil?
+ csr_subject.add_entry("OU", new_resource.org_unit) unless new_resource.org_unit.nil?
+ csr_subject.add_entry("CN", new_resource.common_name)
+ csr_subject.add_entry("emailAddress", new_resource.email) unless new_resource.email.nil?
+ csr_subject
+ end
+
+ def csr
+ gen_x509_request(subject, key)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resource/package.rb b/lib/chef/resource/package.rb
index 8362dde47e..bbad5f7696 100644
--- a/lib/chef/resource/package.rb
+++ b/lib/chef/resource/package.rb
@@ -41,14 +41,32 @@ class Chef
super
end
- property :package_name, [ String, Array ], identity: true
-
- property :version, [ String, Array ]
- property :options, [ String, Array ], coerce: proc { |x| x.is_a?(String) ? x.shellsplit : x }
- property :response_file, String, desired_state: false
- property :response_file_variables, Hash, default: lazy { {} }, desired_state: false
- property :source, String, desired_state: false
- property :timeout, [ String, Integer ], desired_state: false
+ property :package_name, [ String, Array ],
+ description: "The name of the package. Defaults to the name of the resourse block unless specified.",
+ identity: true
+
+ property :version, [ String, Array ],
+ description: "The version of a package to be installed or upgraded."
+
+ property :options, [ String, Array ],
+ description: "One (or more) additional command options that are passed to the command.",
+ coerce: proc { |x| x.is_a?(String) ? x.shellsplit : x }
+
+ property :response_file, String,
+ description: "",
+ desired_state: false
+
+ property :response_file_variables, Hash,
+ description: "",
+ default: lazy { {} }, desired_state: false
+
+ property :source, String,
+ description: "The direct path to a the package on the host.",
+ desired_state: false
+
+ property :timeout, [ String, Integer ],
+ description: "The amount of time (in seconds) to wait before timing out.",
+ desired_state: false
end
end
diff --git a/lib/chef/resource/registry_key.rb b/lib/chef/resource/registry_key.rb
index 36a6db1100..30233ddc8b 100644
--- a/lib/chef/resource/registry_key.rb
+++ b/lib/chef/resource/registry_key.rb
@@ -74,9 +74,12 @@ class Chef
def values(arg = nil)
if not arg.nil?
if arg.is_a?(Hash)
- @values = [ arg ]
+ @values = [ Mash.new(arg).symbolize_keys ]
elsif arg.is_a?(Array)
- @values = arg
+ @values = []
+ arg.each do |value|
+ @values << Mash.new(value).symbolize_keys
+ end
else
raise ArgumentError, "Bad type for RegistryKey resource, use Hash or Array"
end
diff --git a/lib/chef/resource/rhsm_errata.rb b/lib/chef/resource/rhsm_errata.rb
index 15b6dab8bc..11aa49c34a 100644
--- a/lib/chef/resource/rhsm_errata.rb
+++ b/lib/chef/resource/rhsm_errata.rb
@@ -37,6 +37,7 @@ class Chef
execute "Install errata packages for #{new_resource.errata_id}" do
command "yum update --advisory #{new_resource.errata_id} -y"
+ default_env true
action :run
end
end
diff --git a/lib/chef/resource/rhsm_errata_level.rb b/lib/chef/resource/rhsm_errata_level.rb
index ee94a3e60f..baf1abfc9c 100644
--- a/lib/chef/resource/rhsm_errata_level.rb
+++ b/lib/chef/resource/rhsm_errata_level.rb
@@ -44,6 +44,7 @@ class Chef
execute "Install any #{new_resource.errata_level} errata" do
command "yum update --sec-severity=#{new_resource.errata_level.capitalize} -y"
+ default_env true
action :run
end
end
diff --git a/lib/chef/resource/rhsm_register.rb b/lib/chef/resource/rhsm_register.rb
index f0c86ccaac..cf1a131c44 100644
--- a/lib/chef/resource/rhsm_register.rb
+++ b/lib/chef/resource/rhsm_register.rb
@@ -87,6 +87,7 @@ class Chef
execute "Register to RHSM" do
sensitive new_resource.sensitive
command register_command
+ default_env true
action :run
not_if { registered_with_rhsm? } unless new_resource.force
end
@@ -102,6 +103,7 @@ class Chef
execute "Unregister from RHSM" do
command "subscription-manager unregister"
+ default_env true
action :run
only_if { registered_with_rhsm? }
notifies :run, "execute[Clean RHSM Config]", :immediately
@@ -109,6 +111,7 @@ class Chef
execute "Clean RHSM Config" do
command "subscription-manager clean"
+ default_env true
action :nothing
end
end
diff --git a/lib/chef/resource/rhsm_repo.rb b/lib/chef/resource/rhsm_repo.rb
index 54f829e79e..86857be211 100644
--- a/lib/chef/resource/rhsm_repo.rb
+++ b/lib/chef/resource/rhsm_repo.rb
@@ -36,6 +36,7 @@ class Chef
execute "Enable repository #{new_resource.repo_name}" do
command "subscription-manager repos --enable=#{new_resource.repo_name}"
+ default_env true
action :run
not_if { repo_enabled?(new_resource.repo_name) }
end
@@ -46,6 +47,7 @@ class Chef
execute "Enable repository #{new_resource.repo_name}" do
command "subscription-manager repos --disable=#{new_resource.repo_name}"
+ default_env true
action :run
only_if { repo_enabled?(new_resource.repo_name) }
end
diff --git a/lib/chef/resource/rhsm_subscription.rb b/lib/chef/resource/rhsm_subscription.rb
index 1f6eb9edee..f00f801afa 100644
--- a/lib/chef/resource/rhsm_subscription.rb
+++ b/lib/chef/resource/rhsm_subscription.rb
@@ -37,6 +37,7 @@ class Chef
execute "Attach subscription pool #{new_resource.pool_id}" do
command "subscription-manager attach --pool=#{new_resource.pool_id}"
+ default_env true
action :run
not_if { subscription_attached?(new_resource.pool_id) }
end
@@ -47,6 +48,7 @@ class Chef
execute "Remove subscription pool #{new_resource.pool_id}" do
command "subscription-manager remove --serial=#{pool_serial(new_resource.pool_id)}"
+ default_env true
action :run
only_if { subscription_attached?(new_resource.pool_id) }
end
diff --git a/lib/chef/resource/sudo.rb b/lib/chef/resource/sudo.rb
index 87799e5bbb..c417a4d26c 100644
--- a/lib/chef/resource/sudo.rb
+++ b/lib/chef/resource/sudo.rb
@@ -56,15 +56,15 @@ class Chef
default: ["ALL"]
property :host, String,
- description: "The host to set in the sudo config.",
+ description: "The host to set in the sudo configuration.",
default: "ALL"
property :runas, String,
- description: "User the command(s) can be run as.",
+ description: "User that the command(s) can be run as.",
default: "ALL"
property :nopasswd, [TrueClass, FalseClass],
- description: "Allow running sudo without specifying a password sudo.",
+ description: "Allow sudo to be run without specifying a password.",
default: false
property :noexec, [TrueClass, FalseClass],
@@ -83,11 +83,11 @@ class Chef
default: lazy { [] }
property :command_aliases, Array,
- description: "Command aliases that can be used as allowed commands later in the config.",
+ description: "Command aliases that can be used as allowed commands later in the configuration.",
default: lazy { [] }
property :setenv, [TrueClass, FalseClass],
- description: "Whether to permit the preserving of environment with sudo -E.",
+ description: "Determines whether or not to permit preservation of the environment with 'sudo -E'.",
default: false
property :env_keep_add, Array,
@@ -102,11 +102,11 @@ class Chef
description: "Deprecated property. Do not use."
property :visudo_binary, String,
- description: "The path to visudo for config verification.",
+ description: "The path to visudo for configuration verification.",
default: "/usr/sbin/visudo"
property :config_prefix, String,
- description: "The directory containing the sudoers config file.",
+ description: "The directory that contains the sudoers configuration file",
default: lazy { platform_config_prefix }
# handle legacy cookbook property
diff --git a/lib/chef/resource/support/cron.d.erb b/lib/chef/resource/support/cron.d.erb
new file mode 100644
index 0000000000..2f27ecb36b
--- /dev/null
+++ b/lib/chef/resource/support/cron.d.erb
@@ -0,0 +1,28 @@
+# Generated by Chef. Changes will be overwritten.
+<% if @mailto -%>
+MAILTO=<%= @mailto %>
+<% end -%>
+<% if @path -%>
+PATH=<%= @path %>
+<% end -%>
+<% if @shell -%>
+SHELL=<%= @shell %>
+<% end -%>
+<% if @home -%>
+HOME=<%= @home %>
+<% end -%>
+<% if @random_delay -%>
+RANDOM_DELAY=<%= @random_delay %>
+<% end -%>
+<% @environment.each do |key, val| -%>
+<%= key %>=<%= val.to_s.shellescape %>
+<% end -%>
+
+<% if @comment -%>
+# <%= @comment %>
+<% end -%>
+<% if @predefined_value -%>
+<%= @predefined_value %> <%= @user %> <%= @command %>
+<% else -%>
+<%= @minute %> <%= @hour %> <%= @day %> <%= @month %> <%= @weekday %> <%= @user %> <%= @command %>
+<% end -%>
diff --git a/lib/chef/resource/support/cron_access.erb b/lib/chef/resource/support/cron_access.erb
new file mode 100644
index 0000000000..fdf61172ab
--- /dev/null
+++ b/lib/chef/resource/support/cron_access.erb
@@ -0,0 +1,4 @@
+# Generated by Chef. Changes will be overwritten.
+<% @users.sort.uniq.each do |user| -%>
+<%= user %>
+<% end -%>
diff --git a/lib/chef/resource/swap_file.rb b/lib/chef/resource/swap_file.rb
index ea7440a890..c42c7b6d59 100644
--- a/lib/chef/resource/swap_file.rb
+++ b/lib/chef/resource/swap_file.rb
@@ -31,14 +31,14 @@ class Chef
name_property: true
property :size, Integer,
- description: "The size (in MBs) for the swap file."
+ description: "The size (in MBs) of the swap file."
property :persist, [TrueClass, FalseClass],
description: "Persist the swapon.",
default: false
property :timeout, Integer,
- description: "Timeout for dd/fallocate.",
+ description: "Timeout for 'dd' / 'fallocate' commands.",
default: 600
property :swappiness, Integer,
diff --git a/lib/chef/resource/sysctl.rb b/lib/chef/resource/sysctl.rb
index e03b7a362c..10d6177221 100644
--- a/lib/chef/resource/sysctl.rb
+++ b/lib/chef/resource/sysctl.rb
@@ -25,7 +25,7 @@ class Chef
provides(:sysctl_param) { true }
description "Use the sysctl resource to set kernel parameters using the sysctl"\
- " command line tool and configuration files in the system's sysctl.d directory."\
+ " command line tool and configuration files in the system's sysctl.d directory. "\
"Configuration files managed by this resource are named 99-chef-KEYNAME.conf. If"\
" an existing value was already set for the value it will be backed up to the node"\
" and restored if the :remove action is used later."
@@ -63,12 +63,12 @@ class Chef
end
end
- # shellout to sysctl to get the current value
- # ignore missing keys by using '-e'
- # convert tabs to spaces since sysctl tab deliminates multivalue parameters
- # strip the newline off the end of the output as well
load_current_value do
- value shell_out!("sysctl -n -e #{key}").stdout.tr("\t", " ").strip
+ begin
+ value get_sysctl_value(key)
+ rescue
+ current_value_does_not_exist!
+ end
end
action :apply do
@@ -116,6 +116,36 @@ class Chef
shell_out!("sysctl #{'-e ' if new_resource.ignore_error}-w \"#{key}=#{value}\"")
end
end
+
+ private
+
+ # shellout to sysctl to get the current value
+ # ignore missing keys by using '-e'
+ # convert tabs to spaces since sysctl tab deliminates multivalue parameters
+ # strip the newline off the end of the output as well
+ #
+ # Chef creates a file in sysctld with parameter configuration
+ # Thus this config will persists even after rebooting the system
+ # User can be in a half configured state, where he has already updated the value
+ # which he wants to be configured from the resource
+ # Therefore we need an extra check with sysctld to ensure a correct idempotency
+ #
+ def get_sysctl_value(key)
+ val = shell_out!("sysctl -n -e #{key}").stdout.tr("\t", " ").strip
+ raise unless val == get_sysctld_value(key)
+ val
+ end
+
+ # Check if chef has already configured a value for the given key and
+ # return the value. Raise in case this conf file needs to be created
+ # or updated
+ def get_sysctld_value(key)
+ raise unless ::File.exist?("/etc/sysctl.d/99-chef-#{key}.conf")
+ k, v = ::File.read("/etc/sysctl.d/99-chef-#{key}.conf").match(/(.*) = (.*)/).captures
+ raise "Unknown sysctl key!" if k.nil?
+ raise "Unknown sysctl value!" if v.nil?
+ v
+ end
end
end
end
diff --git a/lib/chef/resource/systemd_unit.rb b/lib/chef/resource/systemd_unit.rb
index 02194927ba..a4c3c3f180 100644
--- a/lib/chef/resource/systemd_unit.rb
+++ b/lib/chef/resource/systemd_unit.rb
@@ -61,7 +61,9 @@ class Chef
content.each_pair do |sect, opts|
doc.section(sect) do |section|
opts.each_pair do |opt, val|
- section.option(opt, val)
+ [val].flatten.each do |v|
+ section.option(opt, v)
+ end
end
end
end
diff --git a/lib/chef/resource/template.rb b/lib/chef/resource/template.rb
index 45879db8e6..26e85cc679 100644
--- a/lib/chef/resource/template.rb
+++ b/lib/chef/resource/template.rb
@@ -26,7 +26,7 @@ class Chef
# A cookbook template is an Embedded Ruby (ERB) template that is used to dynamically generate static text files.
# Templates may contain Ruby expressions and statements, and are a great way to manage configuration files. Use the
# template resource to add cookbook templates to recipes; place the corresponding Embedded Ruby (ERB) template file
- # in a cookbook’s /templates directory.
+ # in a cookbook's /templates directory.
#
# Use the template resource to manage the contents of a file using an Embedded Ruby (ERB) template by transferring
# files from a sub-directory of COOKBOOK_NAME/templates/ to a specified path located on a host that is running the
diff --git a/lib/chef/resource/windows_ad_join.rb b/lib/chef/resource/windows_ad_join.rb
index 4917fa6be1..d2848c71cd 100644
--- a/lib/chef/resource/windows_ad_join.rb
+++ b/lib/chef/resource/windows_ad_join.rb
@@ -30,21 +30,21 @@ class Chef
introduced "14.0"
property :domain_name, String,
- description: "The FQDN of the AD domain to join.",
+ description: "The FQDN of the Active Directory domain to join.",
validation_message: "The 'domain_name' property must be a FQDN.",
regex: /.\../, # anything.anything
name_property: true
property :domain_user, String,
- description: "The domain user to use to join the host to the domain.",
+ description: "The domain user that will be used to join the domain.",
required: true
property :domain_password, String,
- description: "The password for the domain user.",
+ description: "The password for the domain user. Note that this resource is set to hide sensitive information by default. ",
required: true
property :ou_path, String,
- description: "The path to the OU where you would like to place the host."
+ description: "The path to the Organizational Unit where the host will be placed."
property :reboot, Symbol,
equal_to: [:immediate, :delayed, :never, :request_reboot, :reboot_now],
diff --git a/lib/chef/resource/windows_auto_run.rb b/lib/chef/resource/windows_auto_run.rb
index e483462670..0ff8c24bfc 100644
--- a/lib/chef/resource/windows_auto_run.rb
+++ b/lib/chef/resource/windows_auto_run.rb
@@ -24,7 +24,7 @@ class Chef
resource_name :windows_auto_run
provides(:windows_auto_run) { true }
- description "Use the windows_auto_run resource to set applications to run at logon."
+ description "Use the windows_auto_run resource to set applications to run at login."
introduced "14.0"
property :program_name, String,
@@ -33,10 +33,10 @@ class Chef
property :path, String,
coerce: proc { |x| x.tr("/", "\\") }, # make sure we have windows paths for the registry
- description: "The path to the program to be run at login."
+ description: "The path to the program that will run at login. "
property :args, String,
- description: "Any arguments for the program."
+ description: "Any arguments to be used with the program."
property :root, Symbol,
description: "The registry root key to put the entry under.",
@@ -51,7 +51,7 @@ class Chef
data = "\"#{new_resource.path}\""
data << " #{new_resource.args}" if new_resource.args
- declare_resource(:registry_key, registry_path) do
+ registry_key registry_path do
values [{
name: new_resource.program_name,
type: :string,
@@ -64,7 +64,7 @@ class Chef
action :remove do
description "Remove an item that was previously setup to run at login"
- declare_resource(:registry_key, registry_path) do
+ registry_key registry_path do
values [{
name: new_resource.program_name,
type: :string,
diff --git a/lib/chef/resource/windows_env.rb b/lib/chef/resource/windows_env.rb
index 3f1c13ecef..781a09fed7 100644
--- a/lib/chef/resource/windows_env.rb
+++ b/lib/chef/resource/windows_env.rb
@@ -26,9 +26,7 @@ class Chef
provides :windows_env
provides :env # backwards compat with the pre-Chef 14 resource name
- description "Use the env resource to manage environment keys in Microsoft Windows."\
- " After an environment key is set, Microsoft Windows must be restarted"\
- " before the environment key will be available to the Task Scheduler."
+ description "Use the env resource to manage environment keys in Microsoft Windows. After an environment key is set, Microsoft Windows must be restarted before the environment key will be available to the Task Scheduler."
default_action :create
allowed_actions :create, :delete, :modify
diff --git a/lib/chef/resource/windows_feature_dism.rb b/lib/chef/resource/windows_feature_dism.rb
index c5bdc6fdfa..ce818f494e 100644
--- a/lib/chef/resource/windows_feature_dism.rb
+++ b/lib/chef/resource/windows_feature_dism.rb
@@ -25,20 +25,19 @@ class Chef
resource_name :windows_feature_dism
provides(:windows_feature_dism) { true }
- description "Using the windows_feature_dism resource to add, remove or"\
- " delete Windows features and roles using DISM"
+ description "Use the windows_feature_dism resource to add, remove or delete Windows features and roles using DISM"
introduced "14.0"
property :feature_name, [Array, String],
- description: "The name of the feature/role(s) to install if it differs from the resource name.",
+ description: "The name of the feature(s) or role(s) to install, if it differs from the resource name.",
coerce: proc { |x| to_formatted_array(x) },
name_property: true
property :source, String,
- description: "Use a local repository for the feature install."
+ description: "Specify a local repository for the feature install."
property :all, [TrueClass, FalseClass],
- description: "Install all sub features. This is the equivalent of specifying the /All switch to dism.exe",
+ description: "Install all sub-features. When set to 'true', this is the equivalent of specifying the /All switch to dism.exe",
default: false
property :timeout, Integer,
diff --git a/lib/chef/resource/windows_feature_powershell.rb b/lib/chef/resource/windows_feature_powershell.rb
index 6141ff40ba..551fd9ad6f 100644
--- a/lib/chef/resource/windows_feature_powershell.rb
+++ b/lib/chef/resource/windows_feature_powershell.rb
@@ -43,8 +43,7 @@ class Chef
description: "Use a local repository for the feature install."
property :all, [TrueClass, FalseClass],
- description: "Install all sub features. This is equivalent to using the"\
- " -InstallAllSubFeatures switch with Add-WindowsFeature.",
+ description: "Install all sub features. This is equivalent to using the -InstallAllSubFeatures switch with Add-WindowsFeature.",
default: false
property :timeout, Integer,
@@ -52,7 +51,7 @@ class Chef
default: 600
property :management_tools, [TrueClass, FalseClass],
- description: "",
+ description: "Install all applicable management tools for the roles, role services, or features.",
default: false
# Converts strings of features into an Array. Array objects are lowercased unless we're on < 8/2k12+.
diff --git a/lib/chef/resource/windows_font.rb b/lib/chef/resource/windows_font.rb
index 9f4366338a..2f61876e9a 100644
--- a/lib/chef/resource/windows_font.rb
+++ b/lib/chef/resource/windows_font.rb
@@ -25,9 +25,7 @@ class Chef
resource_name :windows_font
provides(:windows_font) { true }
- description "Use the windows_font resource to install font files on Windows."\
- " By default, the font is sourced from the cookbook using the resource, but a URI"\
- " source can be specified as well."
+ description "Use the windows_font resource to install font files on Windows. By default, the font is sourced from the cookbook using the resource, but a URI source can be specified as well."
introduced "14.0"
property :font_name, String,
@@ -35,7 +33,7 @@ class Chef
name_property: true
property :source, String,
- description: "A local filesystem path or URI to source the font file from.",
+ description: "A local filesystem path or URI that is used to source the font file.",
coerce: proc { |x| x =~ /^.:.*/ ? x.tr('\\', "/").gsub("//", "/") : x }
action :install do
diff --git a/lib/chef/resource/windows_package.rb b/lib/chef/resource/windows_package.rb
index 49496aed9a..9bfa51b9fd 100644
--- a/lib/chef/resource/windows_package.rb
+++ b/lib/chef/resource/windows_package.rb
@@ -30,8 +30,7 @@ class Chef
provides(:windows_package) { true }
provides :package, os: "windows"
- description "Use the windows_package resource to manage Microsoft Installer Package"\
- " (MSI) packages for the Microsoft Windows platform."
+ description "Use the windows_package resource to manage Microsoft Installer Package (MSI) packages for the Microsoft Windows platform."
introduced "11.12"
allowed_actions :install, :remove
diff --git a/lib/chef/resource/windows_printer.rb b/lib/chef/resource/windows_printer.rb
index c58e02b994..7d596a9691 100644
--- a/lib/chef/resource/windows_printer.rb
+++ b/lib/chef/resource/windows_printer.rb
@@ -27,20 +27,18 @@ class Chef
resource_name :windows_printer
provides(:windows_printer) { true }
- description "Use the windows_printer resource to setup Windows printers. Note"\
- " that this doesn't currently install a printer driver. You must"\
- " already have the driver installed on the system."
+ description "Use the windows_printer resource to setup Windows printers. Note that this doesn't currently install a printer driver. You must already have the driver installed on the system."
introduced "14.0"
property :device_id, String,
- description: "Printer queue name, e.g. 'HP LJ 5200 in fifth floor copy room'.",
+ description: "Printer queue name, such as 'HP LJ 5200 in fifth floor copy room'.",
name_property: true
property :comment, String,
description: "Optional descriptor for the printer queue."
property :default, [TrueClass, FalseClass],
- description: "Should this be the system's default printer.",
+ description: "Determines whether or not this should be the system's default printer.",
default: false
property :driver_name, String,
@@ -48,17 +46,17 @@ class Chef
required: true
property :location, String,
- description: "Printer location, e.g. 'Fifth floor copy room'."
+ description: "Printer location, such as 'Fifth floor copy room'."
property :shared, [TrueClass, FalseClass],
- description: "Should the printer be shared.",
+ description: "Determines whether or not the printer is shared.",
default: false
property :share_name, String,
- description: "The name to share the printer as."
+ description: "The name used to identify the shared printer."
property :ipv4_address, String,
- description: "Printer IPv4 address, e.g. '10.4.64.23'.",
+ description: "The IPv4 address of the printer, such as '10.4.64.23'",
validation_message: "The ipv4_address property must be in the IPv4 format of WWW.XXX.YYY.ZZZ",
regex: Resolv::IPv4::Regex
diff --git a/lib/chef/resource/windows_printer_port.rb b/lib/chef/resource/windows_printer_port.rb
index 75b18a41dd..3d54c72f47 100644
--- a/lib/chef/resource/windows_printer_port.rb
+++ b/lib/chef/resource/windows_printer_port.rb
@@ -47,7 +47,7 @@ class Chef
description: "The description of the port."
property :snmp_enabled, [TrueClass, FalseClass],
- description: "Should SNMP be enabled on the port.",
+ description: "Determines if SNMP is enabled on the port.",
default: false
property :port_protocol, Integer,
diff --git a/lib/chef/resource/windows_service.rb b/lib/chef/resource/windows_service.rb
index 7e265c57c3..1e7271b1fe 100644
--- a/lib/chef/resource/windows_service.rb
+++ b/lib/chef/resource/windows_service.rb
@@ -36,18 +36,21 @@ class Chef
provides(:windows_service) { true }
provides :service, os: "windows"
- description "Use the windows_service resource to manage a service on the Microsoft Windows platform."
+ description "Use the windows_service resource to create, delete, or manage a service on the Microsoft Windows platform."
introduced "12.0"
allowed_actions :configure_startup, :create, :delete, :configure
state_attrs :enabled, :running
- property :service_name, name_property: true, identity: true
+ property :service_name, String,
+ description: "The name of the service.",
+ name_property: true, identity: true
# The display name to be used by user interface programs to identify the
# service. This string has a maximum length of 256 characters.
- property :display_name, String, regex: /^.{1,256}$/
+ property :display_name, String, regex: /^.{1,256}$/,
+ introduced: "14.0"
# https://github.com/djberg96/win32-service/blob/ffi/lib/win32/windows/constants.rb#L19-L29
property :desired_access, Integer, default: SERVICE_ALL_ACCESS
@@ -76,27 +79,26 @@ class Chef
# This only applies if startup_type is :automatic
# 1 == delayed start is enabled
# 0 == NO delayed start
- property :delayed_start, [TrueClass, FalseClass], default: false, coerce: proc { |x|
- if x.is_a?(Integer)
- x == 0 ? false : true
- else
- x
- end
- }
+ property :delayed_start, [TrueClass, FalseClass],
+ introduced: "14.0",
+ default: false, coerce: proc { |x|
+ if x.is_a?(Integer)
+ x == 0 ? false : true
+ else
+ x
+ end
+ }
# https://github.com/djberg96/win32-service/blob/ffi/lib/win32/windows/constants.rb#L43-L47
property :error_control, Integer, default: SERVICE_ERROR_NORMAL
- # The fully qualified path to the service binary file. The path can also
- # include arguments for an auto-start service.
- #
- # This is required for :create and :configure actions -- intentionally
- # not setting required: true here to support other actions
- property :binary_path_name, String
+ property :binary_path_name, String,
+ introduced: "14.0",
+ description: "The fully qualified path to the service binary file. The path can also include arguments for an auto-start service. This is required for ':create' and ':configure' actions"
- # The names of the load ordering group of which this service is a member.
- # Specify nil or an empty string if the service does not belong to a group.
- property :load_order_group, String
+ property :load_order_group, String,
+ introduced: "14.0",
+ description: "The names of the load ordering group of which this service is a member. Don't set this property if the service does not belong to a group."
# A pointer to a double null-terminated array of null-separated names of
# services or load ordering groups that the system must start before this
@@ -104,9 +106,12 @@ class Chef
# dependencies. Dependency on a group means that this service can run if
# at least one member of the group is running after an attempt to start
# all members of the group.
- property :dependencies, [String, Array]
+ property :dependencies, [String, Array],
+ introduced: "14.0"
- property :description, String
+ property :description, String,
+ description: "Description of the service.",
+ introduced: "14.0"
property :run_as_user, String, default: "LocalSystem"
property :run_as_password, String, default: ""
diff --git a/lib/chef/resource/windows_shortcut.rb b/lib/chef/resource/windows_shortcut.rb
index 60eb9f9b24..7f7cfd3fe9 100644
--- a/lib/chef/resource/windows_shortcut.rb
+++ b/lib/chef/resource/windows_shortcut.rb
@@ -24,15 +24,15 @@ class Chef
resource_name :windows_shortcut
provides(:windows_shortcut) { true }
- description "Use the windows_shortcut resource to create shortcut files on Windows"
+ description "Use the windows_shortcut resource to create shortcut files on Windows."
introduced "14.0"
property :shortcut_name, String,
- description: "The name for the shortcut if it differs from the resource name.",
+ description: "The name for the shortcut, if it differs from the resource name.",
name_property: true
property :target, String,
- description: "Where the shortcut links to."
+ description: "The destination that the shortcut links to."
property :arguments, String,
description: "Arguments to pass to the target when the shortcut is executed."
@@ -44,7 +44,7 @@ class Chef
description: "Working directory to use when the target is executed."
property :iconlocation, String,
- description: "Icon to use for the shortcut, in the format of 'path, index'. Index is the icon file to use. See https://msdn.microsoft.com/en-us/library/3s9bx7at.aspx for details"
+ description: "Icon to use for the shortcut. Accepts the format of 'path, index', where index is the icon file to use. See https://msdn.microsoft.com/en-us/library/3s9bx7at.aspx for details"
load_current_value do |desired|
require "win32ole" if RUBY_PLATFORM =~ /mswin|mingw32|windows/
diff --git a/lib/chef/resource/windows_task.rb b/lib/chef/resource/windows_task.rb
index 97ade20774..0232fe3064 100644
--- a/lib/chef/resource/windows_task.rb
+++ b/lib/chef/resource/windows_task.rb
@@ -24,43 +24,95 @@ class Chef
resource_name :windows_task
provides(:windows_task) { true }
- description "Use the windows_task resource to create, delete or run a Windows"\
- " scheduled task. Requires Windows Server 2008 or later due to API usage."
+ description "Use the windows_task resource to create, delete or run a Windows scheduled task. Requires Windows Server 2008 or later due to API usage."
introduced "13.0"
allowed_actions :create, :delete, :run, :end, :enable, :disable, :change
default_action :create
- property :task_name, String, regex: [/\A[^\/\:\*\?\<\>\|]+\z/], name_property: true
- property :command, String
- property :cwd, String
- property :user, String, default: "SYSTEM"
- property :password, String
- property :run_level, equal_to: [:highest, :limited], default: :limited
- property :force, [TrueClass, FalseClass], default: false
- property :interactive_enabled, [TrueClass, FalseClass], default: false
- property :frequency_modifier, [Integer, String], default: 1
- property :frequency, equal_to: [:minute,
- :hourly,
- :daily,
- :weekly,
- :monthly,
- :once,
- :on_logon,
- :onstart,
- :on_idle,
- :none]
- property :start_day, String
- property :start_time, String
- property :day, [String, Integer]
- property :months, String
- property :idle_time, Integer
- property :random_delay, [String, Integer]
- property :execution_time_limit, [String, Integer], default: "PT72H" # 72 hours in ISO8601 duration format
- property :minutes_duration, [String, Integer]
- property :minutes_interval, [String, Integer]
- property :priority, Integer, description: "Use to set Priority Levels range from 0 to 10.", default: 7,
- callbacks: { "should be in range of 0 to 10" => proc { |v| v >= 0 && v <= 10 } }
+ property :task_name, String, regex: [/\A[^\/\:\*\?\<\>\|]+\z/],
+ description: "The task name, such as 'Task Name' or '/Task Name'",
+ name_property: true
+
+ property :command, String,
+ description: "The command to be executed by the windows scheduled task."
+
+ property :cwd, String,
+ description: "The directory the task will be run from."
+
+ property :user, String,
+ description: "The user to run the task as.",
+ default: "SYSTEM"
+
+ property :password, String,
+ description: "The user’s password. The user property must be set if using this property."
+
+ property :run_level, Symbol, equal_to: [:highest, :limited],
+ description: "Run with ':limited' or ':highest' privileges.",
+ default: :limited
+
+ property :force, [TrueClass, FalseClass],
+ description: "When used with create, will update the task.",
+ default: false
+
+ property :interactive_enabled, [TrueClass, FalseClass],
+ description: "Allow task to run interactively or non-interactively. Requires user and password to also be set.",
+ default: false
+
+ property :frequency_modifier, [Integer, String],
+ default: 1
+
+ property :frequency, Symbol, equal_to: [:minute,
+ :hourly,
+ :daily,
+ :weekly,
+ :monthly,
+ :once,
+ :on_logon,
+ :onstart,
+ :on_idle,
+ :none],
+ description: "The frequency with which to run the task."
+
+ property :start_day, String,
+ description: "Specifies the first date on which the task runs in MM/DD/YYYY format."
+
+ property :start_time, String,
+ description: "Specifies the start time to run the task, in HH:mm format."
+
+ property :day, [String, Integer],
+ description: "The day(s) on which the task runs."
+
+ property :months, String,
+ description: "The Months of the year on which the task runs, such as: 'JAN, FEB' or '\*'. Multiple months should be comma delimited. e.g. 'Jan, Feb, Mar, Dec'."
+
+ property :idle_time, Integer,
+ description: "For :on_idle frequency, the time (in minutes) without user activity that must pass to trigger the task, from 1 - 999."
+
+ property :random_delay, [String, Integer],
+ description: "Delays the task up to a given time (in seconds)."
+
+ property :execution_time_limit, [String, Integer],
+ description: "The maximum time (in seconds) the task will run.",
+ default: "PT72H" # 72 hours in ISO8601 duration format
+
+ property :minutes_duration, [String, Integer],
+ description: ""
+
+ property :minutes_interval, [String, Integer],
+ description: ""
+
+ property :priority, Integer,
+ description: "Use to set Priority Levels range from 0 to 10.",
+ default: 7, callbacks: { "should be in range of 0 to 10" => proc { |v| v >= 0 && v <= 10 } }
+
+ property :disallow_start_if_on_batteries, [TrueClass, FalseClass],
+ introduced: "14.4", default: false,
+ description: "Disallow start of the task if the system is running on battery power."
+
+ property :stop_if_going_on_batteries, [TrueClass, FalseClass],
+ introduced: "14.4", default: false,
+ description: "Scheduled task option when system is switching on battery."
attr_accessor :exists, :task, :command_arguments
diff --git a/lib/chef/resource/yum_repository.rb b/lib/chef/resource/yum_repository.rb
index 8d88f12ed0..ba7fb53ad1 100644
--- a/lib/chef/resource/yum_repository.rb
+++ b/lib/chef/resource/yum_repository.rb
@@ -32,54 +32,142 @@ class Chef
# http://linux.die.net/man/5/yum.conf as well as
# http://dnf.readthedocs.io/en/latest/conf_ref.html
- property :baseurl, [String, Array]
- property :clean_headers, [TrueClass, FalseClass], default: false # deprecated
- property :clean_metadata, [TrueClass, FalseClass], default: true
- property :cost, String, regex: /^\d+$/
- property :description, String, default: "Yum Repository"
- property :enabled, [TrueClass, FalseClass], default: true
- property :enablegroups, [TrueClass, FalseClass]
- property :exclude, String
- property :failovermethod, String, equal_to: %w{priority roundrobin}
- property :fastestmirror_enabled, [TrueClass, FalseClass]
- property :gpgcheck, [TrueClass, FalseClass], default: true
- property :gpgkey, [String, Array]
- property :http_caching, String, equal_to: %w{packages all none}
- property :include_config, String
- property :includepkgs, String
- property :keepalive, [TrueClass, FalseClass]
- property :make_cache, [TrueClass, FalseClass], default: true
- property :max_retries, [String, Integer]
- property :metadata_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/, /never/]
- property :metalink, String
- property :mirror_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/]
- property :mirrorexpire, String
- property :mirrorlist_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/]
- property :mirrorlist, String
- property :mode, default: "0644"
- property :options, Hash
- property :password, String
- property :priority, String, regex: /^(\d?[1-9]|[0-9][0-9])$/
- property :proxy_password, String
- property :proxy_username, String
- property :proxy, String
- property :repo_gpgcheck, [TrueClass, FalseClass]
- property :report_instanceid, [TrueClass, FalseClass]
-
- property :repositoryid, String,
- regex: [/^[^\/]+$/],
+ property :baseurl, [String, Array],
+ description: "URL to the directory where the Yum repository's 'repodata' directory lives. Can be an http://, https:// or a ftp:// URL. You can specify multiple URLs in one baseurl statement."
+
+ property :clean_headers, [TrueClass, FalseClass],
+ description: "Specifies whether you want to purge the package data files that are downloaded from a Yum repository and held in a cache directory.",
+ deprecated: true,
+ default: false # deprecated
+
+ property :clean_metadata, [TrueClass, FalseClass],
+ description: "Specifies whether you want to purge all of the packages downloaded from a Yum repository and held in a cache directory.",
+ default: true
+
+ property :cost, String, regex: /^\d+$/,
+ description: "Relative cost of accessing this repository. Useful for weighing one repo's packages as greater/less than any other."
+
+ property :description, String,
+ description: "Descriptive name for the repository channel and maps to the 'name' parameter in a repository .conf.",
+ default: "Yum Repository"
+
+ property :enabled, [TrueClass, FalseClass],
+ description: "Specifies whether or not Yum should use this repository.",
+ default: true
+
+ property :enablegroups, [TrueClass, FalseClass],
+ description: "Specifies whether Yum will allow the use of package groups for this repository."
+
+ property :exclude, String,
+ description: "List of packages to exclude from updates or installs. This should be a space separated list. Shell globs using wildcards (eg. * and ?) are allowed."
+
+ property :failovermethod, String,
+ description: "Method to determine how to switch to a new server if the current one fails, which can either be ``roundrobin`` or ``priority``. ``roundrobin`` randomly selects a URL out of the list of URLs to start with and proceeds through each of them as it encounters a failure contacting the host. ``priority`` starts from the first ``baseurl`` listed and reads through them sequentially.",
+ equal_to: %w{priority roundrobin}
+
+ property :fastestmirror_enabled, [TrueClass, FalseClass],
+ description: "Specifies whether to use the fastest mirror from a repository configuration when more than one mirror is listed in that configuration."
+
+ property :gpgcheck, [TrueClass, FalseClass],
+ description: "Specifies whether or not Yum should perform a GPG signature check on the packages received from a repository.",
+ default: true
+
+ property :gpgkey, [String, Array],
+ description: "URL pointing to the ASCII-armored GPG key file for the repository. This is used if Yum needs a public key to verify a package and the required key hasn't been imported into the RPM database. If this option is set, Yum will automatically import the key from the specified URL. Multiple URLs may be specified in the same manner as the baseurl option. If a GPG key is required to install a package from a repository, all keys specified for that repository will be installed."
+
+ property :http_caching, String, equal_to: %w{packages all none},
+ description: "Determines how upstream HTTP caches are instructed to handle any HTTP downloads that Yum does. This option can take the following values: all (all HTTP downloads should be cached), packages (only RPM package downloads should be cached, but not repository metadata downloads), or none (no HTTP downloads should be cached)"
+
+ property :include_config, String,
+ description: "An external configuration file using the format 'url://to/some/location'."
+
+ property :includepkgs, String,
+ description: "Inverse of exclude property. This is a list of packages you want to use from a repository. If this option lists only one package then that is all Yum will ever see from the repository."
+
+ property :keepalive, [TrueClass, FalseClass],
+ description: "Determines whether or not HTTP/1.1 ``keep-alive`` should be used with this repository."
+
+ property :make_cache, [TrueClass, FalseClass],
+ description: "Determines whether package files downloaded by Yum stay in cache directories. By using cached data, you can carry out certain operations without a network connection.",
+ default: true
+
+ property :max_retries, [String, Integer],
+ description: "Number of times any attempt to retrieve a file should retry before returning an error. Setting this to '0' makes Yum try forever."
+
+ property :metadata_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/, /never/],
+ description: "Time (in seconds) after which the metadata will expire. If the current metadata downloaded is less than the value specified, then Yum will not update the metadata against the repository. If you find that Yum is not downloading information on updates as often as you would like lower the value of this option. You can also change from the default of using seconds to using days, hours or minutes by appending a 'd', 'h' or 'm' respectively. The default is six hours to compliment yum-updates running once per hour. It is also possible to use the word ``never``, meaning that the metadata will never expire. Note: When using a metalink file, the metalink must always be newer than the metadata for the repository due to the validation, so this timeout also applies to the metalink file."
+
+ property :metalink, String,
+ description: "Specifies a URL to a metalink file for the repomd.xml, a list of mirrors for the entire repository are generated by converting the mirrors for the repomd.xml file to a baseurl."
+
+ property :mirror_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/],
+ description: "Time (in seconds) after which the mirrorlist locally cached will expire. If the current mirrorlist is less than this many seconds old then Yum will not download another copy of the mirrorlist, it has the same extra format as metadata_expire. If you find that Yum is not downloading the mirrorlists as often as you would like lower the value of this option."
+
+ property :mirrorlist_expire, String, regex: [/^\d+$/, /^\d+[mhd]$/],
+ description: "Specifies the time (in seconds) after which the mirrorlist locally cached will expire. If the current mirrorlist is less than the value specified, then Yum will not download another copy of the mirrorlist."
+
+ property :mirrorlist, String,
+ description: "URL to a file containing a list of baseurls. This can be used instead of or with the baseurl option. Substitution variables, described below, can be used with this option."
+
+ property :mode, [String, Integer],
+ description: "Permissions mode of .repo file on disk. This is useful for scenarios where secrets are in the repo file. If this value is set to '600', normal users will not be able to use Yum search, Yum info, etc.",
+ default: "0644"
+
+ property :options, Hash,
+ description: "Specifies the repository options."
+
+ property :password, String,
+ description: "Password to use with the username for basic authentication."
+
+ property :priority, String, regex: /^(\d?[1-9]|[0-9][0-9])$/,
+ description: "Assigns a priority to a repository where the priority value is between '1' and '99' inclusive. Priorities are used to enforce ordered protection of repositories. Packages from repositories with a lower priority (higher numerical value) will never be used to upgrade packages that were installed from a repository with a higher priority (lower numerical value). The repositories with the lowest numerical priority number have the highest priority."
+
+ property :proxy_password, String,
+ description: "Password for this proxy."
+
+ property :proxy_username, String,
+ description: "Username to use for proxy."
+
+ property :proxy, String,
+ description: "URL to the proxy server that Yum should use."
+
+ property :repo_gpgcheck, [TrueClass, FalseClass],
+ description: "Determines whether or not Yum should perform a GPG signature check on the repodata from this repository."
+
+ property :report_instanceid, [TrueClass, FalseClass],
+ description: "Determines whether to report the instance ID when using Amazon Linux AMIs and repositories."
+
+ property :repositoryid, String, regex: [/^[^\/]+$/],
+ description: "Specifies a unique name for each repository, one word. Defaults to name attribute.",
validation_message: "repositoryid property cannot contain a forward slash '/'",
name_property: true
- property :skip_if_unavailable, [TrueClass, FalseClass]
- property :source, String
- property :sslcacert, String
- property :sslclientcert, String
- property :sslclientkey, String
- property :sslverify, [TrueClass, FalseClass]
- property :throttle, [String, Integer]
- property :timeout, String, regex: /^\d+$/
- property :username, String
+ property :skip_if_unavailable, [TrueClass, FalseClass],
+ description: ""
+
+ property :source, String,
+ description: "Use a custom template source instead of the default one."
+
+ property :sslcacert, String,
+ description: "Path to the directory containing the databases of the certificate authorities Yum should use to verify SSL certificates."
+
+ property :sslclientcert, String,
+ description: "Path to the SSL client certificate Yum should use to connect to repos/remote sites."
+
+ property :sslclientkey, String,
+ description: "Path to the SSL client key Yum should use to connect to repos/remote sites."
+
+ property :sslverify, [TrueClass, FalseClass],
+ description: "Determines whether Yum will verify SSL certificates/hosts."
+
+ property :throttle, [String, Integer],
+ description: "Enable bandwidth throttling for downloads."
+
+ property :timeout, String, regex: /^\d+$/,
+ description: "Number of seconds to wait for a connection before timing out. Defaults to 30 seconds. This may be too short of a time for extremely overloaded sites."
+
+ property :username, String,
+ description: "Username to use for basic authentication to a repository."
default_action :create
allowed_actions :create, :remove, :makecache, :add, :delete
@@ -87,6 +175,7 @@ class Chef
# provide compatibility with the yum cookbook < 3.0 properties
alias_method :url, :baseurl
alias_method :keyurl, :gpgkey
+ alias_method :mirrorexpire, :mirror_expire
end
end
end
diff --git a/lib/chef/resource/zypper_package.rb b/lib/chef/resource/zypper_package.rb
index 23b8779f25..b04668472f 100644
--- a/lib/chef/resource/zypper_package.rb
+++ b/lib/chef/resource/zypper_package.rb
@@ -25,11 +25,15 @@ class Chef
resource_name :zypper_package
provides :package, platform_family: "suse"
- description "Use the zypper_package resource to install, upgrade, and remove"\
- " packages with Zypper for the SUSE Enterprise and OpenSUSE platforms."
+ description "Use the zypper_package resource to install, upgrade, and remove packages with Zypper for the SUSE Enterprise and OpenSUSE platforms."
- property :gpg_check, [ TrueClass, FalseClass ], default: lazy { Chef::Config[:zypper_check_gpg] }
- property :allow_downgrade, [ TrueClass, FalseClass ], default: false
+ property :gpg_check, [ TrueClass, FalseClass ],
+ description: "Verify the package's GPG signature",
+ default: lazy { Chef::Config[:zypper_check_gpg] }
+
+ property :allow_downgrade, [ TrueClass, FalseClass ],
+ description: "",
+ default: false
end
end
end
diff --git a/lib/chef/resource/zypper_repository.rb b/lib/chef/resource/zypper_repository.rb
index 018f03e6b0..b3e1db6b83 100644
--- a/lib/chef/resource/zypper_repository.rb
+++ b/lib/chef/resource/zypper_repository.rb
@@ -25,33 +25,71 @@ class Chef
provides(:zypper_repository) { true }
provides(:zypper_repo) { true }
- description "Use the zypper_repository resource to create Zypper package repositories"\
- " on SUSE Enterprise Linux and openSUSE systems. This resource maintains"\
- " full compatibility with the zypper_repository resource in the existing"\
- " zypper cookbook."
+ description "Use the zypper_repository resource to create Zypper package repositories on SUSE Enterprise Linux and openSUSE systems. This resource maintains full compatibility with the zypper_repository resource in the existing zypper cookbook."
introduced "13.3"
property :repo_name, String,
regex: [/^[^\/]+$/],
+ description: "Specifies the repository name, if it differs from the resource name.",
validation_message: "repo_name property cannot contain a forward slash '/'",
name_property: true
- property :description, String
- property :type, String, default: "NONE"
- property :enabled, [TrueClass, FalseClass], default: true
- property :autorefresh, [TrueClass, FalseClass], default: true
- property :gpgcheck, [TrueClass, FalseClass], default: true
- property :gpgkey, String
- property :baseurl, String
- property :mirrorlist, String
- property :path, String
- property :priority, Integer, default: 99
- property :keeppackages, [TrueClass, FalseClass], default: false
- property :mode, default: "0644"
- property :refresh_cache, [TrueClass, FalseClass], default: true
- property :source, String
- property :cookbook, String
- property :gpgautoimportkeys, [TrueClass, FalseClass], default: true
+ property :description, String,
+ description: "The description of the repository that will be shown by the 'zypper repos' command."
+
+ property :type, String,
+ description: "Specifies the repository type.",
+ default: "NONE"
+
+ property :enabled, [TrueClass, FalseClass],
+ description: "Determines whether or not the repository should be enabled.",
+ default: true
+
+ property :autorefresh, [TrueClass, FalseClass],
+ description: "Determines whether or not the repository should be refreshed automatically.",
+ default: true
+
+ property :gpgcheck, [TrueClass, FalseClass],
+ description: "Determines whether or not to perform a GPG signature check on the repository.",
+ default: true
+
+ property :gpgkey, String,
+ description: "The location of the repository key to be imported."
+
+ property :baseurl, String,
+ description: "The base URL for the Zypper repository, such as 'http://download.opensuse.org'."
+
+ property :mirrorlist, String,
+ description: "The URL of the mirror list that will be used."
+
+ property :path, String,
+ description: "The relative path from the repository's base URL."
+
+ property :priority, Integer,
+ description: "Determines the priority of the Zypper repository. ",
+ default: 99
+
+ property :keeppackages, [TrueClass, FalseClass],
+ description: "Determines whether or not packages should be saved.",
+ default: false
+
+ property :mode, [String, Integer],
+ description: "The file mode of the repository file.",
+ default: "0644"
+
+ property :refresh_cache, [TrueClass, FalseClass],
+ description: "Determines whether or not the package cache should be refreshed.",
+ default: true
+
+ property :source, String,
+ description: "The name of the template for the repository file. Only necessary if you're not using the built in template."
+
+ property :cookbook, String,
+ description: "The cookbook to source the repository template file from. Only necessary if you're not using the built in template."
+
+ property :gpgautoimportkeys, [TrueClass, FalseClass],
+ description: "Automatically import the specified key when setting up the repository.",
+ default: true
default_action :create
allowed_actions :create, :remove, :add, :refresh
diff --git a/lib/chef/resource_inspector.rb b/lib/chef/resource_inspector.rb
index 10fa42c842..1559932940 100644
--- a/lib/chef/resource_inspector.rb
+++ b/lib/chef/resource_inspector.rb
@@ -81,7 +81,8 @@ module ResourceInspector
# otherwise, if we have a path then extract all the resources from the cookbook
# or else do a list of built in resources
#
- # @param complete [TrueClass, FalseClass] Whether to show properties defined in the base Resource class
+ # @param complete [TrueClass, FalseClass] Whether to show properties defined in the base Resource class
+ # @return [String] JSON formatting of all resources
def self.inspect(arguments = [], complete: false)
output = if arguments.empty?
ObjectSpace.each_object(Class).select { |k| k < Chef::Resource }.each_with_object({}) { |klass, acc| acc[klass.resource_name] = extract_resource(klass) }
@@ -96,11 +97,11 @@ module ResourceInspector
end
end
- puts Chef::JSONCompat.to_json_pretty(output)
+ Chef::JSONCompat.to_json_pretty(output)
end
def self.start
- inspect(ARGV, complete: true)
+ puts inspect(ARGV, complete: true)
end
end
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index 3ae47a3a4a..43dc8c9e75 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -1,6 +1,6 @@
#
# Author:: Daniel DeLeo (<dan@chef.io>)
-# Copyright:: Copyright 2010-2016, Chef Software, Inc.
+# Copyright:: Copyright 2010-2018, Chef Software, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,6 +31,8 @@ require "chef/resource/chocolatey_config"
require "chef/resource/chocolatey_package"
require "chef/resource/chocolatey_source"
require "chef/resource/cron"
+require "chef/resource/cron_access"
+require "chef/resource/cron_d"
require "chef/resource/csh"
require "chef/resource/directory"
require "chef/resource/dmg_package"
@@ -64,8 +66,13 @@ require "chef/resource/ohai"
require "chef/resource/ohai_hint"
require "chef/resource/openbsd_package"
require "chef/resource/openssl_dhparam"
+require "chef/resource/openssl_ec_private_key"
+require "chef/resource/openssl_ec_public_key"
require "chef/resource/openssl_rsa_private_key"
require "chef/resource/openssl_rsa_public_key"
+require "chef/resource/openssl_x509_certificate"
+require "chef/resource/openssl_x509_crl"
+require "chef/resource/openssl_x509_request"
require "chef/resource/package"
require "chef/resource/pacman_package"
require "chef/resource/paludis_package"
diff --git a/lib/chef/version.rb b/lib/chef/version.rb
index 2df8d812a8..6357f35abc 100644
--- a/lib/chef/version.rb
+++ b/lib/chef/version.rb
@@ -23,7 +23,7 @@ require "chef/version_string"
class Chef
CHEF_ROOT = File.expand_path("../..", __FILE__)
- VERSION = Chef::VersionString.new("14.4.17")
+ VERSION = Chef::VersionString.new("14.4.63")
end
#