-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor our polled workers to use a common macro (#709)
- Loading branch information
1 parent
864b865
commit 173ea78
Showing
28 changed files
with
261 additions
and
196 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
defmodule Core.Services.Scan do | ||
require Logger | ||
alias Core.Services.{Repositories, Versions} | ||
alias Core.Schema.{DockerImage, Version, Chart, Terraform} | ||
alias Core.Docker.TrivySource | ||
|
||
def scan_image(%DockerImage{} = image) do | ||
%{docker_repository: %{repository: repo} = dkr} = img = Core.Repo.preload(image, [docker_repository: :repository]) | ||
%{publisher: %{owner: owner}} = Core.Repo.preload(repo, [publisher: :owner]) | ||
|
||
registry_name = img_name(img) | ||
{:ok, registry_token} = Repositories.docker_token([:pull], "#{repo.name}/#{dkr.name}", owner) | ||
env = [{"TRIVY_REGISTRY_TOKEN", registry_token} | Core.conf(:docker_env)] | ||
|
||
image = "#{registry_name}:#{image.tag}" | ||
Logger.info "Scanning image #{image}" | ||
case System.cmd("trivy", ["--quiet", "image", "--format", "json", image, "--timeout", "10m0s"], env: env) do | ||
{output, 0} -> | ||
case Jason.decode(output) do | ||
{:ok, [%{"Vulnerabilities" => vulns} | _]} -> insert_vulns(vulns, img) | ||
{:ok, %{"Results" => [_ | _] = res, "SchemaVersion" => 2}} -> | ||
Enum.flat_map(res, &Map.get(&1, "Vulnerabilities", [])) | ||
|> insert_vulns(img) | ||
|> log() | ||
res -> | ||
Logger.info "irregular trivy output #{inspect(res)}" | ||
insert_vulns([], img) | ||
|> log() | ||
end | ||
{output, _} -> | ||
Logger.info "Trivy failed with: #{output}" | ||
handle_trivy_error(output, img) | ||
end | ||
end | ||
|
||
def terrascan(%Version{} = version) do | ||
{type, url} = terrascan_details(version) | ||
{output, _} = System.cmd("terrascan", [ | ||
"scan", | ||
"--iac-type", type, | ||
"--remote-type", "http", | ||
"--remote-url", url, | ||
"--output", "json", | ||
"--use-colors", "f" | ||
]) | ||
Versions.record_scan(output, version) | ||
end | ||
|
||
defp handle_trivy_error(output, %DockerImage{} = img) do | ||
case String.contains?(output, "timeout") do | ||
true -> Ecto.Changeset.change(img, %{scan_completed_at: Timex.now()}) |> Core.Repo.update() | ||
_ -> :error | ||
end | ||
end | ||
|
||
defp terrascan_details(%Version{ | ||
version: v, | ||
chart: %Chart{name: chart, repository: %{name: name}} | ||
}) do | ||
{"helm", "http://chartmuseum:8080/cm/#{name}/charts/#{chart}-#{v}.tgz"} | ||
end | ||
defp terrascan_details(%Version{terraform: %Terraform{}} = v), | ||
do: {"terraform", Core.Storage.url({v.package, v}, :original)} | ||
|
||
defp img_name(%DockerImage{docker_repository: %{repository: repo} = dkr}), | ||
do: "#{Core.conf(:registry)}/#{repo.name}/#{dkr.name}" | ||
|
||
defp insert_vulns(nil, img), do: insert_vulns([], img) | ||
defp insert_vulns(vulns, img) when is_list(vulns) do | ||
Logger.info "found #{length(vulns)} vulnerabilities for #{img_name(img)}" | ||
vulns | ||
|> Enum.map(&TrivySource.to_vulnerability/1) | ||
|> Repositories.add_vulnerabilities(img) | ||
end | ||
|
||
defp log({:ok, %DockerImage{id: id, vulnerabilities: vulns}}) when is_list(vulns) do | ||
Logger.info "Found #{length(vulns)} vulns for image #{id}" | ||
end | ||
defp log(_), do: :ok | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
defmodule Core.Services.ScanTest do | ||
use Core.SchemaCase, async: true | ||
use Mimic | ||
|
||
alias Core.Services.Scan | ||
|
||
describe "#scan_image/1" do | ||
test "it can execute a trivy command" do | ||
image = insert(:docker_image) | ||
image_name = "dkr.plural.sh/#{image.docker_repository.repository.name}/#{image.docker_repository.name}:#{image.tag}" | ||
vuln = Application.get_env(:core, :vulnerability) | ||
expect(System, :cmd, fn | ||
"trivy", ["--quiet", "image", "--format", "json", ^image_name, "--timeout", "10m0s"], [env: [{"TRIVY_REGISTRY_TOKEN", _}]] -> | ||
{~s([{"Vulnerabilities": [#{vuln}]}]), 0} | ||
end) | ||
|
||
{:ok, scanned} = Scan.scan_image(image) | ||
|
||
assert scanned.id == image.id | ||
assert scanned.grade == :c | ||
assert scanned.scan_completed_at | ||
|
||
[vuln] = scanned.vulnerabilities | ||
assert vuln.image_id == scanned.id | ||
end | ||
end | ||
|
||
describe "terrascan/2" do | ||
test "it can scan a terraform version" do | ||
result = terrascan_res() | ||
version = insert(:version, | ||
terraform: insert(:terraform, package: %{file_name: "file.tgz", updated_at: nil}), | ||
chart: nil, | ||
chart_id: nil | ||
) | ||
url = Core.Storage.url({version.package, version}, :original) | ||
expect(System, :cmd, fn | ||
"terrascan", [ | ||
"scan", | ||
"--iac-type", "terraform", | ||
"--remote-type", "http", | ||
"--remote-url", ^url, | ||
"--output", "json", | ||
"--use-colors", "f" | ||
] -> | ||
{result, 0} | ||
end) | ||
|
||
{:ok, scanned} = Scan.terrascan(version) | ||
|
||
assert scanned.grade == :d | ||
end | ||
|
||
test "it can scan a chart version" do | ||
result = terrascan_res() | ||
version = insert(:version, chart: insert(:chart)) | ||
url = "http://chartmuseum:8080/cm/#{version.chart.repository.name}/charts/#{version.chart.name}-#{version.version}.tgz" | ||
expect(System, :cmd, fn | ||
"terrascan", [ | ||
"scan", | ||
"--iac-type", "helm", | ||
"--remote-type", "http", | ||
"--remote-url", ^url, | ||
"--output", "json", | ||
"--use-colors", "f" | ||
] -> | ||
{result, 0} | ||
end) | ||
|
||
{:ok, scanned} = Scan.terrascan(version) | ||
|
||
assert scanned.grade == :d | ||
end | ||
end | ||
|
||
defp terrascan_res(), do: priv_file(:core, "scan.json") |> File.read!() | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.