class Inspec::Resources::NginxConf
Attributes
Public Class Methods
# File lib/inspec/resources/nginx_conf.rb, line 32 def initialize(conf_path = nil) @conf_path = conf_path || "/etc/nginx/nginx.conf" @contents = {} return skip_resource "The `nginx_conf` resource is currently not supported on Windows." if inspec.os.windows? read_content(@conf_path) end
Public Instance Methods
# File lib/inspec/resources/nginx_conf.rb, line 47 def http NginxConfHttp.new(params["http"], self) end
# File lib/inspec/resources/nginx_conf.rb, line 57 def method_missing(name) return super if name.to_s.match?(/^to_/) v = params[name.to_s] return v.flatten unless v.nil? nil end
# File lib/inspec/resources/nginx_conf.rb, line 40 def params @params ||= parse_nginx(@conf_path) rescue StandardError => e skip_resource e.message @params = {} end
# File lib/inspec/resources/nginx_conf.rb, line 66 def respond_to_missing?(name, include_all = false) return super if name.to_s.match?(/^to_/) true end
# File lib/inspec/resources/nginx_conf.rb, line 53 def to_s "nginx_conf #{@conf_path}" end
Private Instance Methods
Deep merge fields from NginxConfig.parse
. A regular merge would overwrite values so a deep merge is needed. @param data [Hash] data structure from NginxConfig.parse
@param conf [Hash] data structure to be deep merged into data @return [Hash] data structure with conf and data deep merged
# File lib/inspec/resources/nginx_conf.rb, line 132 def merge_config!(data, conf) # Catch edge-cases return if data.nil? || conf.nil? # Step through all conf items and create combined return value data.merge!(conf) do |_, v1, v2| if v1.is_a?(Array) && v2.is_a?(Array) # If both the data field and the conf field are arrays, then combine them v1 + v2 elsif v1.is_a?(Hash) && v2.is_a?(Hash) # If both the data field and the conf field are maps, then deep merge them merge_config!(v1, v2) else # All other cases, just use the new value (regular merge behavior) v2 end end end
# File lib/inspec/resources/nginx_conf.rb, line 80 def parse_nginx(path) return nil if inspec.os.windows? content = read_content(path) # Don't attempt to parse file if it contains only comments or is empty # https://regexper.com/#%2F%5E%5Cs*%23%7C%5E%24%2F return {} if content.lines.reject { |l| l =~ /^\s*#|^$/ }.empty? data = NginxConfig.parse(content) resolve_references(data, File.dirname(path)) rescue StandardError => _ raise "Cannot parse NginX config in #{path}." end
# File lib/inspec/resources/nginx_conf.rb, line 74 def read_content(path) return @contents[path] if @contents.key?(path) @contents[path] = read_file_content(path, allow_empty: true) end
Cycle through the complete parsed data structure and try to find any calls to `include`. In NginX, this is used to embed data from other files into the current data structure.
The method steps through the object structure that is passed in to find any calls to 'include' and returns the object structure with the included data merged in.
@param data [Hash] data structure from NginxConfig.parse
@param rel_path [String] the relative path from which this config is read @return [Hash] data structure with references included
# File lib/inspec/resources/nginx_conf.rb, line 106 def resolve_references(data, rel_path) # Walk through all array entries to find more references return data.map { |x| resolve_references(x, rel_path) } if data.is_a?(Array) # Return any data that we cannot step into to find more `include` calls return data unless data.is_a?(Hash) # Any call to `include` gets its data read, parsed, and merged back # into the current data structure if data.key?("include") data.delete("include").flatten .map { |x| File.expand_path(x, rel_path) } .map { |x| find_files(x) }.flatten .map { |path| parse_nginx(path) } .each { |conf| merge_config!(data, conf) } end # Walk through the remaining hash fields to find more references Hash[data.map { |k, v| [k, resolve_references(v, rel_path)] }] end