Skip to content

Instantly share code, notes, and snippets.

@RoseSecurity
Created September 11, 2024 16:51
Show Gist options
  • Save RoseSecurity/999557b0a593fae196efd4dad432e195 to your computer and use it in GitHub Desktop.
Save RoseSecurity/999557b0a593fae196efd4dad432e195 to your computer and use it in GitHub Desktop.
A Neovim plugin for installing and running Trivy against Infrastructure as Code
local function get_trivy_dir()
return vim.fn.stdpath('data') .. '/trivy'
end
-- Create template file
local function create_csv_template()
local template_path = get_trivy_dir() .. '/csv.tpl'
local template_content = [[
{{ range . }}
{{ $target := .Target }}
{{- if and (eq (len .Vulnerabilities) 0) (eq (len .Misconfigurations) 0) }}{{- else }}
{{- range .Vulnerabilities }}{{ $target }},1,[{{ .Severity }}] {{ .VulnerabilityID }} - {{ .Title }}
{{ end }}
{{- range .Misconfigurations }}{{ $target }},{{ if not .CauseMetadata }}1{{ else if .CauseMetadata.StartLine }}{{ .CauseMetadata.StartLine }}{{ else }}1{{ end }},[{{ .Severity }}] {{ .ID }} - {{ .Title}}
{{ end }}
{{ end -}}{{- end }}
]]
local file = io.open(template_path, 'w')
if file then
file:write(template_content)
file:close()
vim.notify('Created CSV template file at ' .. template_path, vim.log.levels.INFO)
return true
else
vim.notify('Failed to create CSV template file at ' .. template_path, vim.log.levels.ERROR)
return false
end
end
local function ensure_template_exists()
local template_path = get_trivy_dir() .. '/csv.tpl'
if vim.fn.filereadable(template_path) == 0 then
return create_csv_template()
end
return true
end
local function Trivy()
if not ensure_template_exists() then
return
end
local errorformat = vim.o.errorformat -- Capture the current error format
local trivy_dir = get_trivy_dir()
local template = '"@' .. trivy_dir .. '/csv.tpl"'
local command = trivy_dir .. '/trivy fs -q --scanners vuln,misconfig --exit-code 0 -f template --template ' .. template .. ' . | sort -u | sed -r "/^\\s*$/d"'
-- Set the error format for use with Trivy
vim.o.errorformat = '%f,%l,%m'
-- Get the latest Trivy comments and open the quick fix window with them
local output = vim.fn.systemlist(command)
if vim.v.shell_error ~= 0 then
vim.notify('Trivy command failed: ' .. table.concat(output, '\n'), vim.log.levels.ERROR)
return
end
vim.fn.setqflist({}, 'r', {title = ':Trivy', lines = output})
vim.cmd('copen')
-- Restore the errorformat value
vim.o.errorformat = errorformat
end
local function TrivyInstall()
vim.notify('Downloading the latest version of Trivy')
local trivy_dir = get_trivy_dir()
local install_command = string.format('curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b "%s"', trivy_dir)
local install_result = vim.fn.system(install_command)
if vim.v.shell_error ~= 0 then
vim.notify('Failed to install Trivy: ' .. install_result, vim.log.levels.ERROR)
else
vim.notify('Trivy downloaded successfully', vim.log.levels.INFO)
-- Add Trivy to PATH
vim.env.PATH = vim.env.PATH .. ':' .. trivy_dir
-- Create the template file
ensure_template_exists()
end
end
-- Create user commands
vim.api.nvim_create_user_command('Trivy', Trivy, {})
vim.api.nvim_create_user_command('TrivyInstall', TrivyInstall, {})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment