class InspecTools::CSVTool

Methods for converting from CSV to various formats

Public Class Methods

new(csv, mapping, name, verbose = false) click to toggle source
# File lib/inspec_tools/csv.rb, line 12
def initialize(csv, mapping, name, verbose = false)
  @name = name
  @csv = csv
  @mapping = Utils::MappingValidator.validate(mapping)
  @verbose = verbose
  @csv.shift if @mapping['skip_csv_header']
end

Public Instance Methods

to_inspec(control_name_prefix: nil) click to toggle source
# File lib/inspec_tools/csv.rb, line 20
def to_inspec(control_name_prefix: nil)
  @controls = []
  @profile = {}
  @cci_xml = Utils::CciXml.get_cci_list('U_CCI_List.xml')
  insert_metadata
  parse_controls(control_name_prefix)
  @profile['controls'] = @controls
  @profile['sha256'] = Digest::SHA256.hexdigest(@profile.to_s)
  @profile
end

Private Instance Methods

generate_control_id(prefix, id) click to toggle source
# File lib/inspec_tools/csv.rb, line 94
def generate_control_id(prefix, id)
  return id if prefix.nil?

  "#{prefix}-#{id}"
end
get_cci_number(cell) click to toggle source
# File lib/inspec_tools/csv.rb, line 57
def get_cci_number(cell)
  # Return nil if a mapping to the CCI was not provided or if there is not content in the CSV cell.
  return nil if cell.nil? || @mapping['control.tags']['cci'].nil?

  # If the content has been exported from STIG Viewer, the cell will have extra information
  cell.split("\n").first
end
get_nist_reference(cci_number) click to toggle source
# File lib/inspec_tools/csv.rb, line 50
def get_nist_reference(cci_number)
  item_node = @cci_xml.xpath("//cci_list/cci_items/cci_item[@id='#{cci_number}']")[0] unless @cci_xml.nil?
  return nil if item_node.nil?

  [] << item_node.xpath('./references/reference[not(@version <= preceding-sibling::reference/@version) and not(@version <=following-sibling::reference/@version)]/@index').text
end
insert_metadata() click to toggle source
# File lib/inspec_tools/csv.rb, line 33
def insert_metadata
  @profile['name'] = @name
  @profile['title'] = 'InSpec Profile'
  @profile['maintainer'] = 'The Authors'
  @profile['copyright'] = 'The Authors'
  @profile['copyright_email'] = 'you@example.com'
  @profile['license'] = 'Apache-2.0'
  @profile['summary'] = 'An InSpec Compliance Profile'
  @profile['version'] = '0.1.0'
  @profile['supports'] = []
  @profile['attributes'] = []
  @profile['generator'] = {
    name: 'inspec_tools',
    version: VERSION
  }
end
parse_controls(prefix) click to toggle source
# File lib/inspec_tools/csv.rb, line 65
def parse_controls(prefix)
  @csv.each do |row|
    control = {}
    control['id']     = generate_control_id(prefix, row[@mapping['control.id']]) unless @mapping['control.id'].nil? || row[@mapping['control.id']].nil?
    control['title']  = row[@mapping['control.title']] unless @mapping['control.title'].nil? || row[@mapping['control.title']].nil?
    control['desc']   = row[@mapping['control.desc']] unless @mapping['control.desc'].nil? || row[@mapping['control.desc']].nil?
    control['tags'] = {}
    cci_number = get_cci_number(row[@mapping['control.tags']['cci']])
    nist = get_nist_reference(cci_number) unless cci_number.nil?
    control['tags']['nist'] = nist unless nist.nil? || nist.include?(nil)
    @mapping['control.tags'].each do |tag|
      if tag.first == 'cci'
        if cci_number.is_a? Array
          control['tags'][tag.first] = cci_number
        else
          control['tags'][tag.first] = [cci_number]
        end
        next
      end
      control['tags'][tag.first] = row[tag.last] unless row[tag.last].nil?
    end
    unless @mapping['control.tags']['severity'].nil? || row[@mapping['control.tags']['severity']].nil?
      control['impact'] = Utils::InspecUtil.get_impact(row[@mapping['control.tags']['severity']])
      control['tags']['severity'] = Utils::InspecUtil.get_impact_string(control['impact'])
    end
    @controls << control
  end
end