class Terradoc
——————————————————————————– # ——————————————————————————– # ——————————————————————————– #
Constants
- VERSION
Public Class Methods
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 13 def initialize(options = {}) @command = 'hcl2json' raise StandardError.new("Failed to locate #{@command} please install (pip install #{@command})") unless which @command @console_only = false @console_only = options[:console] unless options[:console].nil? @base_path = '.' @base_path = options[:path] unless options[:path].nil? @base_path.chomp!('/') raise StandardError.new("Path #{@base_path} does not exist - Aborting") unless Dir.exist? @base_path @output_file = 'README.md' @output_file = options[:output] unless options[:output].nil? @files = [] @pattern = "#{@base_path}/*.tf" @config = { 'data-sources' => { 'start' => '<!--Terradoc-data-sources-start-->', 'end' => '<!--Terradoc-data-sources-end-->', 'raw-results' => [], 'sorted-results' => [], 'data-table' => [] }, 'modules' => { 'start' => '<!--Terradoc-modules-start-->', 'end' => '<!--Terradoc-modules-end-->', 'raw-results' => [], 'sorted-results' => [], 'data-table' => [] }, 'outputs' => { 'start' => '<!--Terradoc-outputs-start-->', 'end' => '<!--Terradoc-outputs-end-->', 'raw-results' => [], 'sorted-results' => [], 'data-table' => [] }, 'providers' => { 'start' => '<!--Terradoc-providers-start-->', 'end' => '<!--Terradoc-providers-end-->', 'raw-results' => [], 'sorted-results' => [], 'data-table' => [] }, 'resources' => { 'start' => '<!--Terradoc-resources-start-->', 'end' => '<!--Terradoc-resources-end-->', 'raw-results' => [], 'sorted-results' => [], 'data-table' => [] }, 'variables' => { 'start' => '<!--Terradoc-variables-start-->', 'end' => '<!--Terradoc-variables-end-->', 'raw-results' => [], 'sorted-results' => [], 'data-table' => [] } } terradoc_main end
Public Instance Methods
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 204 def cleanup_array(array) array = array.uniq { |k| k[:name] } if array.count.positive? array = array.sort_by { |k| k[:name] } if array.count.positive? return array end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 223 def generate_data_tables if @config['data-sources']['sorted-results'].size.positive? @config['data-sources']['data-table'] << '| Name |' @config['data-sources']['data-table'] << '| ---- |' @config['data-sources']['sorted-results'].each do |item| @config['data-sources']['data-table'] << "| #{item[:name]} |" end else @config['data-sources']['data-table'] << '> No data sources found' end if @config['modules']['sorted-results'].size.positive? @config['modules']['data-table'] << '| Name |' @config['modules']['data-table'] << '| ---- |' @config['modules']['sorted-results'] .each do |item| @config['modules']['data-table'] << "| #{item[:name]} |" end else @config['modules']['data-table'] << '> No modules found' end if @config['outputs']['sorted-results'].size.positive? @config['outputs']['data-table'] << '| Name | Description |' @config['outputs']['data-table'] << '| ---- | ----------- |' @config['outputs']['sorted-results'].each do |item| @config['outputs']['data-table'] << "| #{item[:name]} | #{item[:description]} |" end else @config['outputs']['data-table'] << '> No outputs found' end if @config['providers']['sorted-results'].size.positive? @config['providers']['data-table'] << '| Name |' @config['providers']['data-table'] << '| ---- |' @config['providers']['sorted-results'].each do |item| @config['providers']['data-table'] << "| #{item[:name]} |" end else @config['providers']['data-table'] << '> No providers found' end if @config['resources']['sorted-results'].size.positive? @config['resources']['data-table'] << '| Name |' @config['resources']['data-table'] << '| ---- |' @config['resources']['sorted-results'].each do |item| @config['resources']['data-table'] << "| #{item[:name]} |" end else @config['resources']['data-table'] << '> No resources found' end if @config['variables']['sorted-results'].size.positive? @config['variables']['data-table'] << '| Name | Description | Type | Default | Required? |' @config['variables']['data-table'] << '| ---- | ----------- |:----:|:-------:|:---------:|' @config['variables']['sorted-results'].each do |item| @config['variables']['data-table'] << "| #{item[:name]} | #{item[:description]} | #{item[:type]} | #{item[:default]} | #{item[:required]} |" end else @config['variables']['data-table'] << '> No variables found' end end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 130 def generate_file_list Dir.glob(@pattern).each do |file| @files << file end end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 300 def generate_output(lines, start_tag, end_tag, data_table) processed = [] skip_lines = false lines.each do |line| if line.casecmp?(end_tag) && skip_lines processed << line skip_lines = false next end next if skip_lines processed << line next unless line.casecmp?(start_tag) skip_lines = true data_table.each do |row| processed << row end end return processed end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 287 def load_file(filename) lines = [] begin lines = File.readlines(filename).each(&:chomp!) rescue SystemCallError raise StandardError.new("Failed to open file #{filename} for reading") end return lines end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 138 def process_files @files.each do |file| Open3.popen3("hcl2json #{file}") do |_stdin, stdout, _stderr, _wait_thr| stdout_str = stdout.read json = JSON.parse(stdout_str, max_nesting: 256) process_raw_results(json) end end end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 152 def process_raw_results(json) unless json['data'].nil? json['data'].each do |key, _value| name = key.gsub('_', '\_') @config['data-sources']['raw-results'] << { :name => name } end end unless json['module'].nil? json['module'].each do |key, value| name = key.gsub('_', '\_') @config['modules']['raw-results'] << { :name => name, :source => value['source'], :version => value['version'] } end end unless json['output'].nil? json['output'].each do |key, value| name = key.gsub('_', '\_') @config['outputs']['raw-results'] << { :name => name, :description => value['description'] } end end unless json['provider'].nil? json['provider'].each do |key, _value| name = key.gsub('_', '\_') @config['providers']['raw-results'] << { :name => name } end end unless json['resource'].nil? json['resource'].each do |key, _value| name = key.gsub('_', '\_') @config['resources']['raw-results'] << { :name => name } end end unless json['variable'].nil? json['variable'].each do |key, value| name = key.gsub('_', '\_') default = value['default'].to_s.gsub('_', '\_') required = if default.empty? 'Yes' else 'No' end @config['variables']['raw-results'] << { :name => name, :description => value['description'], :type => value['type'], :default => default, :required => required } end end end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 212 def sort_details @config['data-sources']['sorted-results'] = cleanup_array(@config['data-sources']['raw-results']) @config['modules']['sorted-results'] = cleanup_array(@config['modules']['raw-results']) @config['outputs']['sorted-results'] = cleanup_array(@config['outputs']['raw-results']) @config['providers']['sorted-results'] = cleanup_array(@config['providers']['raw-results']) @config['resources']['sorted-results'] = cleanup_array(@config['resources']['raw-results']) @config['variables']['sorted-results'] = cleanup_array(@config['variables']['raw-results']) end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 95 def terradoc_main unless @console_only spinners = TTY::Spinner::Multi.new("[:spinner] Terradoc is processing your files (Path: #{@base_path}, Output File: #{@output_file})") sp1 = spinners.register '[:spinner] Locating files' sp2 = spinners.register '[:spinner] Processing files' sp3 = spinners.register '[:spinner] Sorting the results' sp4 = spinners.register '[:spinner] Generating data tables' sp5 = spinners.register '[:spinner] Writing output' sp1.auto_spin sp2.auto_spin sp3.auto_spin sp4.auto_spin sp5.auto_spin end generate_file_list sp1.success unless @console_only process_files sp2.success unless @console_only sort_details sp3.success unless @console_only generate_data_tables sp4.success unless @console_only write_output sp5.success unless @console_only end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 82 def which(cmd) exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| exts.each do |ext| exe = File.join(path, "#{cmd}#{ext}") return exe if File.executable?(exe) && !File.directory?(exe) end end return nil end
——————————————————————————– # ——————————————————————————– #
# File lib/terradoc.rb, line 328 def write_output permissions = 0o0644 lines = load_file(@output_file) lines = generate_output(lines, @config['data-sources']['start'], @config['data-sources']['end'], @config['data-sources']['data-table']) lines = generate_output(lines, @config['modules']['start'], @config['modules']['end'], @config['modules']['data-table']) lines = generate_output(lines, @config['outputs']['start'], @config['outputs']['end'], @config['outputs']['data-table']) lines = generate_output(lines, @config['providers']['start'], @config['providers']['end'], @config['providers']['data-table']) lines = generate_output(lines, @config['resources']['start'], @config['resources']['end'], @config['resources']['data-table']) lines = generate_output(lines, @config['variables']['start'], @config['variables']['end'], @config['variables']['data-table']) if @console_only puts lines else begin File.open(@output_file, 'w') do |f| lines.each do |line| f.puts line end f.chmod(permissions) end rescue SystemCallError raise StandardError.new("Failed to open file #{filename} for writing") end end end