class Object
Constants
- LOG_LEVEL
-
Ohai::Config defines its own log_level and log_location. When loaded, it will override the default ChefConfig::Config values. We save them here before loading ohai/config so that we can override them again inside
Chef::Config
.REMOVEME once these configurables are removed from the top level of Ohai.
- LOG_LOCATION
- Mash
-
For historical reasons we inject
Mash
directly into the top level class namespace - MonoLogger
- TIMEOUT_OPTS
- TIMEOUT_REGEX
- WEEKDAYS
Public Instance Methods
Source
# File lib/chef/resource/_rest_resource.rb, line 350 def api_connection Chef.run_context.transport.connection end
Source
# File lib/chef/resource/_rest_resource.rb, line 373 def bury(path, value) raise TypeError unless path.is_a?(String) arr = path.split(".") ret = {} if arr.count == 1 ret[arr.first] = value ret else partial_path = arr[0..-2].join(".") bury(partial_path, bury(arr.last, value)) end end
Create nested hashes from JMESPath syntax.
Source
# File lib/chef/resource/_rest_resource.rb, line 115 def changed_value(property) new_value = new_resource.send(property) return new_value if current_resource.nil? current_value = current_resource.send(property) return current_value if required_properties.include? property new_value == current_value ? nil : new_value end
Return changed value or nil for delta current->new
Source
# File lib/chef/resource/_rest_resource.rb, line 187 def conditionally_require_on_setting(property, dependent_properties) dependent_properties = Array(dependent_properties) requirements.assert(:configure) do |a| a.assertion do # Needs to be set and truthy to require dependent properties if new_resource.send(property) dependent_properties.all? { |dep_prop| new_resource.property_is_set?(dep_prop) } else true end end message = format("Setting property :%<property>s requires properties :%<properties>s to be set as well on resource %<resource_name>s", property: property, properties: dependent_properties.join(", :"), resource_name: current_resource.to_s) a.failure_message message end end
Convenience method for conditional requires
Source
# File lib/chef/resource/_rest_resource.rb, line 356 def deep_compact!(hsh) raise TypeError unless hsh.is_a? Hash hsh.each do |_, v| deep_compact!(v) if v.is_a? Hash end.reject! { |_, v| v.nil? || (v.respond_to?(:empty?) && v.empty?) } end
Remove all empty keys (recursively) from Hash. @see stackoverflow.com/questions/56457020/#answer-56458673
Source
# File lib/chef/resource/_rest_resource.rb, line 366 def deep_merge!(hsh1, hsh2) raise TypeError unless hsh1.is_a?(Hash) && hsh2.is_a?(Hash) hsh1.merge!(hsh2) { |_, v1, v2| deep_merge!(v1, v2) } end
Deep merge two hashes @see stackoverflow.com/questions/41109599#answer-41109737
Source
# File lib/chef/resource/habitat/_habitat_shared.rb, line 17 def hab(*command) # Windows shell_out does not support arrays, so manually cleaning and joining hab_cmd = if windows? (["hab"] + command).flatten.compact.join(" ") else (["hab"] + command) end shell_out!(hab_cmd) rescue Errno::ENOENT Chef::Log.fatal("'hab' binary not found, use the 'habitat_install' resource to install it first") raise end
- Copyright
-
Chef
Software, Inc. - License
-
Apache License, Version 2.0
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and li
Source
# File lib/chef/resource/_rest_resource.rb, line 126 def id_property current_resource.class.identity_attr end
Source
# File lib/chef/resource/_rest_resource.rb, line 146 def json_to_property(match_instruction, property, resource_data) case match_instruction when String JMESPath.search(match_instruction, resource_data) when Symbol function = "#{property}_from_json".to_sym raise "#{new_resource.name} missing #{function} method" unless self.class.protected_method_defined?(function) send(function, resource_data) || {} else raise TypeError, "Did not expect match type #{match_instruction.class}" end end
Map part of a JSON (Hash) to resource property via JMESPath or user-supplied function
Source
# File lib/chef/resource/_rest_resource.rb, line 26 def load_current_resource @current_resource = new_resource.class.new(new_resource.name) required_properties.each do |name| requested = new_resource.send(name) current_resource.send(name, requested) end return @current_resource if rest_get_all.data.empty? resource_data = rest_get.data rescue nil return @current_resource if resource_data.nil? || resource_data.empty? @resource_exists = true # Map JSON contents to defined properties current_resource.class.rest_property_map.each do |property, match_instruction| property_value = json_to_property(match_instruction, property, resource_data) current_resource.send(property, property_value) unless property_value.nil? end current_resource end
Source
# File lib/chef/resource/_rest_resource.rb, line 346 def path_based_selection? !query_based_selection? end
Source
# File lib/chef/resource/_rest_resource.rb, line 131 def property_map map = {} current_resource.class.state_properties.each do |property| name = property.options[:name] map[name] = current_resource.send(name) end map[id_property] = current_resource.send(id_property) map end
Map properties to their current values
Source
# File lib/chef/resource/_rest_resource.rb, line 161 def property_to_json(property, match_instruction) case match_instruction when String bury(match_instruction, changed_value(property)) when Symbol function = "#{property}_to_json".to_sym raise "#{new_resource.name} missing #{function} method" unless self.class.protected_method_defined?(function) value = new_resource.send(property) changed_value(property).nil? ? {} : send(function, value) else raise TypeError, "Did not expect match type #{match_instruction.class}" end end
Map resource contents into a JSON (Hash) via JMESPath-like syntax or user-supplied function
Source
# File lib/chef/resource/_rest_resource.rb, line 336 def query_based_selection? template_url = current_resource.class.rest_api_document # Will throw exception on presence of RFC 6570 templates URI.parse(template_url) true rescue URI::InvalidURIError => _e false end
Source
# File lib/chef/resource/_rest_resource.rb, line 110 def required_properties current_resource.class.properties.select { |_, v| v.required? }.except(:name).keys end
Source
# File lib/chef/resource/_rest_resource.rb, line 106 def resource_exists? @resource_exists end
Source
# File lib/chef/resource/_rest_resource.rb, line 271 def rest_arity rest_identity_map.keys.count end
Return number of parameters needed to identify a resource (pre- and post-creation)
Source
# File lib/chef/resource/_rest_resource.rb, line 260 def rest_delete response = api_connection.delete(rest_url_document) rest_postprocess(response) rescue RestClient::Exception => e rest_errorhandler(e) end
Source
# File lib/chef/resource/_rest_resource.rb, line 100 def rest_errorhandler(error_obj) error_obj end
Override this for error handling of device-specifics (readable error messages)
Source
# File lib/chef/resource/_rest_resource.rb, line 219 def rest_get response = api_connection.get(rest_url_document) response = rest_postprocess(response) first_only = current_resource.class.rest_api_document_first_element_only response.data = response.data.first if first_only && response.data.is_a?(Array) response rescue RestClient::Exception => e rest_errorhandler(e) end
Source
# File lib/chef/resource/_rest_resource.rb, line 211 def rest_get_all response = api_connection.get(rest_url_collection) rest_postprocess(response) rescue RestClient::Exception => e rest_errorhandler(e) end
Generic REST helpers
Source
# File lib/chef/resource/_rest_resource.rb, line 292 def rest_identity_explicit current_resource.class.rest_identity_map end
Accept direct mapping like { “svm.name” => :name } for specifying the x-ary identity of a resource
Source
# File lib/chef/resource/_rest_resource.rb, line 302 def rest_identity_implicit template_url = current_resource.class.rest_api_document rfc_template = ::Addressable::Template.new(template_url) rfc_template_vars = rfc_template.variables # Shortcut for 0-ary resources return {} if rfc_template_vars.empty? if query_based_selection? uri_query = URI.parse(template_url).query if CGI.parse(uri_query).values.any?(&:empty?) raise "Need explicit identity mapping, as URL does not contain query parameters for all templates" end path_variables = CGI.parse(uri_query).keys elsif path_based_selection? path_variables = rfc_template_vars else # There is also raise "Unknown type of resource selection. Document URL does not seem to be path- or query-based?" end identity_map = {} path_variables.each_with_index do |v, i| next if rfc_template_vars[i].nil? # Not mapped to property, assume metaparameter identity_map[v] = rfc_template_vars[i].to_sym end identity_map end
Parse document URL for RFC 6570 templates and map them to resource properties.
Examples:
Query based: "/api/protocols/san/igroups?name={name}&svm.name={svm}": { "name" => :name, "svm.name" => :svm } Path based: "/api/v1/{address}": { "address" => :address }
Source
# File lib/chef/resource/_rest_resource.rb, line 287 def rest_identity_map rest_identity_explicit || rest_identity_implicit end
Source
# File lib/chef/resource/_rest_resource.rb, line 276 def rest_identity_values data = {} rest_identity_map.each do |rfc_template, property| property_value = new_resource.send(property) data.merge! bury(rfc_template, property_value) end data end
Return mapping of template placeholders to property value of identity parameters
Source
# File lib/chef/resource/_rest_resource.rb, line 252 def rest_patch(data) response = api_connection.patch(rest_url_document, data: data) rest_postprocess(response) rescue RestClient::Exception => e rest_errorhandler(e) end
Source
# File lib/chef/resource/_rest_resource.rb, line 232 def rest_post(data) data.merge! rest_identity_values response = api_connection.post(rest_url_collection, data: data) rest_postprocess(response) rescue RestClient::Exception => e rest_errorhandler(e) end
Source
# File lib/chef/resource/_rest_resource.rb, line 95 def rest_postprocess(response) response end
Override this for postprocessing device-specifics (paging, data conversion)
Source
# File lib/chef/resource/_rest_resource.rb, line 242 def rest_put(data) data.merge! rest_identity_values response = api_connection.put(rest_url_collection, data: data) rest_postprocess(response) rescue RestClient::Exception => e rest_errorhandler(e) end
Source
# File lib/chef/resource/_rest_resource.rb, line 176 def rest_url_collection current_resource.class.rest_api_collection end
Source
# File lib/chef/resource/_rest_resource.rb, line 181 def rest_url_document template = ::Addressable::Template.new(current_resource.class.rest_api_document) template.expand(property_map).to_s end
Resource document URL after RFC 6570 template evaluation via properties substitution
Source
# File lib/chef/resource/cron/_cron_shared.rb, line 95 def weekday_in_crontab(day) weekday = day.to_s.downcase.to_sym WEEKDAYS[weekday] || day end
Convert weekday input value into crontab format that could be written in the crontab @return [Integer, String] A weekday formed as per the user inputs.