summaryrefslogtreecommitdiff
path: root/lib/chef
diff options
context:
space:
mode:
authorTim Smith <tsmith@chef.io>2018-06-12 18:44:23 -0700
committerTim Smith <tsmith@chef.io>2018-06-26 22:36:02 -0700
commit21a1a909ffe0819c884c58da7298b49df9099f70 (patch)
treed0218bb12a67a24ac745d97781eedefd98fdf664 /lib/chef
parent28140f6bc9e54172dac52f470497e09a2699f4e6 (diff)
downloadchef-21a1a909ffe0819c884c58da7298b49df9099f70.tar.gz
Add chocolatey_config and chocolatey_source resources
Allow a user to fully manage chocolatey and get it setup for airgapped environments using chef out of the box. Signed-off-by: Tim Smith <tsmith@chef.io>
Diffstat (limited to 'lib/chef')
-rw-r--r--lib/chef/resource/chocolatey_config.rb83
-rw-r--r--lib/chef/resource/chocolatey_source.rb88
-rw-r--r--lib/chef/resources.rb2
3 files changed, 173 insertions, 0 deletions
diff --git a/lib/chef/resource/chocolatey_config.rb b/lib/chef/resource/chocolatey_config.rb
new file mode 100644
index 0000000000..87ba3af66d
--- /dev/null
+++ b/lib/chef/resource/chocolatey_config.rb
@@ -0,0 +1,83 @@
+#
+# 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.
+#
+
+class Chef
+ class Resource
+ class ChocolateyConfig < Chef::Resource
+ preview_resource true
+ resource_name :chocolatey_config
+
+ description "Use the chocolatey_config resource to add or remove Chocolatey configuration keys."
+ introduced "14.3"
+
+ property :config_key, String, name_property: true,
+ description: "The name of the config. We'll use the resource's name if this isn't provided."
+
+ property :value, String,
+ description: "The value to set."
+
+ load_current_value do
+ current_val = fetch_config_element(config_key)
+ current_value_does_not_exist! if current_val.nil?
+
+ config_key config_key
+ value current_val
+ end
+
+ # @param [String] id the config name
+ # @return [String] the element's value field
+ def fetch_config_element(id)
+ require "rexml/document"
+ config_file = 'C:\ProgramData\chocolatey\config\chocolatey.config'
+ raise "Could not find the Chocolatey config at #{config_file}!" unless ::File.exist?(config_file)
+
+ contents = REXML::Document.new(::File.read(config_file))
+ data = REXML::XPath.first(contents, "//config/add[@key=\"#{id}\"]")
+ data ? data.attribute("value").to_s : nil # REXML just returns nil if it can't find anything so avoid an undefined method error
+ end
+
+ action :set do
+ description "Sets a Chocolatey config value."
+
+ raise "#{new_resource}: When adding a Chocolatey config you must pass the 'value' property!" unless new_resource.value
+
+ converge_if_changed do
+ shell_out!(choco_cmd("set"))
+ end
+ end
+
+ action :unset do
+ description "Unsets a Chocolatey config value."
+
+ if current_resource
+ converge_by("unset Chocolatey config '#{new_resource.config_key}'") do
+ shell_out!(choco_cmd("unset"))
+ end
+ end
+ end
+
+ action_class do
+ # @param [String] action the name of the action to perform
+ # @return [String] the choco config command string
+ def choco_cmd(action)
+ cmd = "C:\\ProgramData\\chocolatey\\bin\\choco config #{action} --name #{new_resource.config_key}"
+ cmd << " --value #{new_resource.value}" if action == "set"
+ cmd
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resource/chocolatey_source.rb b/lib/chef/resource/chocolatey_source.rb
new file mode 100644
index 0000000000..9308a07587
--- /dev/null
+++ b/lib/chef/resource/chocolatey_source.rb
@@ -0,0 +1,88 @@
+#
+# 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.
+#
+
+class Chef
+ class Resource
+ class ChocolateySource < Chef::Resource
+ preview_resource true
+ resource_name :chocolatey_source
+
+ description "Use the chocolatey_source resource to add or remove Chocolatey sources."
+ introduced "14.3"
+
+ property :source_name, String, name_property: true
+ property :source, String
+ property :bypass_proxy, [TrueClass, FalseClass], default: false
+ property :priority, Integer, default: 0
+
+ load_current_value do
+ element = fetch_source_element(source_name)
+ current_value_does_not_exist! if element.nil?
+
+ source_name element["id"]
+ source element["value"]
+ bypass_proxy element["bypassProxy"] == "true"
+ priority element["priority"].to_i
+ end
+
+ # @param [String] id the source name
+ # @return [REXML::Attributes] finds the source element with the
+ def fetch_source_element(id)
+ require "rexml/document"
+
+ config_file = 'C:\ProgramData\chocolatey\config\chocolatey.config'
+ raise "Could not find the Chocolatey config at #{config_file}!" unless ::File.exist?(config_file)
+
+ config_contents = REXML::Document.new(::File.read(config_file))
+ data = REXML::XPath.first(config_contents, "//sources/source[@id=\"#{id}\"]")
+ data ? data.attributes : nil # REXML just returns nil if it can't find anything so avoid an undefined method error
+ end
+
+ action :add do
+ description "Adds a Chocolatey source."
+
+ raise "#{new_resource}: When adding a Chocolatey source you must pass the 'source' property!" unless new_resource.source
+
+ converge_if_changed do
+ shell_out!(choco_cmd("add"))
+ end
+ end
+
+ action :remove do
+ description "Removes a Chocolatey source."
+
+ if current_resource
+ converge_by("remove Chocolatey source '#{new_resource.source_name}'") do
+ shell_out!(choco_cmd("remove"))
+ end
+ end
+ end
+
+ action_class do
+ # @param [String] action the name of the action to perform
+ # @return [String] the choco source command string
+ def choco_cmd(action)
+ cmd = "C:\\ProgramData\\chocolatey\\bin\\choco source #{action} -n \"#{new_resource.source_name}\""
+ if action == "add"
+ cmd << " -s #{new_resource.source} --priority=#{new_resource.priority}"
+ cmd << " --bypassproxy" if new_resource.bypass_proxy
+ end
+ cmd
+ end
+ end
+ end
+ end
+end
diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb
index b21f2fe6f7..c13a01c352 100644
--- a/lib/chef/resources.rb
+++ b/lib/chef/resources.rb
@@ -27,7 +27,9 @@ require "chef/resource/build_essential"
require "chef/resource/cookbook_file"
require "chef/resource/chef_gem"
require "chef/resource/chef_handler"
+require "chef/resource/chocolatey_config"
require "chef/resource/chocolatey_package"
+require "chef/resource/chocolatey_source"
require "chef/resource/cron"
require "chef/resource/csh"
require "chef/resource/directory"