From 6ecd70220be558edfd62737b8fc06bb4c5e03732 Mon Sep 17 00:00:00 2001 From: jiazio Date: Fri, 6 Jan 2017 22:11:13 +0900 Subject: [PATCH] Add LXD support --- config/tomlloader.go | 2 ++ scan/base.go | 48 ++++++++++++++++++++++++++++++++++++++++++++ scan/base_test.go | 38 +++++++++++++++++++++++++++++++++++ scan/serverapi.go | 1 + scan/sshutil.go | 2 ++ 5 files changed, 91 insertions(+) diff --git a/config/tomlloader.go b/config/tomlloader.go index abb7a9ed..d9834939 100644 --- a/config/tomlloader.go +++ b/config/tomlloader.go @@ -129,6 +129,8 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error { s.Containers = d.Containers } + s.Container.Type = v.Container.Type + s.IgnoreCves = v.IgnoreCves for _, cve := range d.IgnoreCves { found := false diff --git a/scan/base.go b/scan/base.go index 04485ea4..e68d0ec6 100644 --- a/scan/base.go +++ b/scan/base.go @@ -90,6 +90,12 @@ func (l base) allContainers() (containers []config.Container, err error) { return containers, err } return l.parseDockerPs(stdout) + case "lxd": + stdout, err := l.lxdPs("-c n") + if err != nil { + return containers, err + } + return l.parseLxdPs(stdout) default: return containers, fmt.Errorf( "Not supported yet: %s", l.ServerInfo.Container.Type) @@ -104,6 +110,12 @@ func (l *base) runningContainers() (containers []config.Container, err error) { return containers, err } return l.parseDockerPs(stdout) + case "lxd": + stdout, err := l.lxdPs("volatile.last_state.power=RUNNING -c n") + if err != nil { + return containers, err + } + return l.parseLxdPs(stdout) default: return containers, fmt.Errorf( "Not supported yet: %s", l.ServerInfo.Container.Type) @@ -118,6 +130,12 @@ func (l *base) exitedContainers() (containers []config.Container, err error) { return containers, err } return l.parseDockerPs(stdout) + case "lxd": + stdout, err := l.lxdPs("volatile.last_state.power=STOPPED -c n") + if err != nil { + return containers, err + } + return l.parseLxdPs(stdout) default: return containers, fmt.Errorf( "Not supported yet: %s", l.ServerInfo.Container.Type) @@ -133,6 +151,15 @@ func (l *base) dockerPs(option string) (string, error) { return r.Stdout, nil } +func (l *base) lxdPs(option string) (string, error) { + cmd := fmt.Sprintf("lxc list %s", option) + r := l.ssh(cmd, noSudo) + if !r.isSuccess() { + return "", fmt.Errorf("failed to SSH: %s", r) + } + return r.Stdout, nil +} + func (l *base) parseDockerPs(stdout string) (containers []config.Container, err error) { lines := strings.Split(stdout, "\n") for _, line := range lines { @@ -151,6 +178,27 @@ func (l *base) parseDockerPs(stdout string) (containers []config.Container, err return } +func (l *base) parseLxdPs(stdout string) (containers []config.Container, err error) { + lines := strings.Split(stdout, "\n") + for i, line := range lines[3:] { + if i % 2 == 1 { + continue + } + fields := strings.Fields(strings.Replace(line, "|", " ", -1)) + if len(fields) == 0 { + break + } + if len(fields) != 1 { + return containers, fmt.Errorf("Unknown format: %s", line) + } + containers = append(containers, config.Container{ + ContainerID: fields[0], + Name: fields[0], + }) + } + return +} + func (l *base) detectPlatform() error { ok, instanceID, err := l.detectRunningOnAws() if err != nil { diff --git a/scan/base_test.go b/scan/base_test.go index 86d58342..b3de4305 100644 --- a/scan/base_test.go +++ b/scan/base_test.go @@ -57,6 +57,44 @@ f570ae647edc agitated_lovelace`, } } +func TestParseLxdPs(t *testing.T) { + + var test = struct { + in string + expected []config.Container + }{ + `+-------+ +| NAME | ++-------+ +| test1 | ++-------+ +| test2 | ++-------+` , + []config.Container{ + { + ContainerID: "test1", + Name: "test1", + }, + { + ContainerID: "test2", + Name: "test2", + }, + }, + } + + r := newRedhat(config.ServerInfo{}) + actual, err := r.parseLxdPs(test.in) + if err != nil { + t.Errorf("Error occurred. in: %s, err: %s", test.in, err) + return + } + for i, e := range test.expected { + if !reflect.DeepEqual(e, actual[i]) { + t.Errorf("expected %v, actual %v", e, actual[i]) + } + } +} + func TestIsAwsInstanceID(t *testing.T) { var tests = []struct { in string diff --git a/scan/serverapi.go b/scan/serverapi.go index eb8dbf32..eb6ac75d 100644 --- a/scan/serverapi.go +++ b/scan/serverapi.go @@ -330,6 +330,7 @@ func detectContainerOSesOnServer(containerHost osTypeInterface) (oses []osTypeIn copied.SetContainer(config.Container{ ContainerID: containerInfo.ContainerID, Name: containerInfo.Name, + Type: containerHostInfo.Container.Type, }) os := detectOS(copied) oses = append(oses, os) diff --git a/scan/sshutil.go b/scan/sshutil.go index fe245e15..bf029259 100644 --- a/scan/sshutil.go +++ b/scan/sshutil.go @@ -307,6 +307,8 @@ func decolateCmd(c conf.ServerInfo, cmd string, sudo bool) string { switch c.Container.Type { case "", "docker": cmd = fmt.Sprintf(`docker exec %s /bin/bash -c "%s"`, c.Container.ContainerID, cmd) + case "lxd": + cmd = fmt.Sprintf(`lxc exec %s -- /bin/bash -c "%s"`, c.Container.Name, cmd) } } // cmd = fmt.Sprintf("set -x; %s", cmd)