Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confirm before installing dependencies on prepare #219

Merged
merged 1 commit into from
Oct 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions commands/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,9 @@ func (p *PrepareCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{
return subcommands.ExitFailure
}

logger.Info("Installing...")
if errs := scan.Prepare(); 0 < len(errs) {
for _, e := range errs {
logger.Errorf("Failed: %s", e)
logger.Errorf("Failed to prepare: %s", e)
}
return subcommands.ExitFailure
}
Expand Down
7 changes: 6 additions & 1 deletion scan/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ import (
type base struct {
ServerInfo config.ServerInfo
Distro config.Distro
Platform models.Platform

Platform models.Platform
lackDependencies []string
osPackages

log *logrus.Entry
Expand Down Expand Up @@ -77,6 +78,10 @@ func (l base) getPlatform() models.Platform {
return l.Platform
}

func (l base) getLackDependencies() []string {
return l.lackDependencies
}

func (l base) allContainers() (containers []config.Container, err error) {
switch l.ServerInfo.Container.Type {
case "", "docker":
Expand Down
31 changes: 27 additions & 4 deletions scan/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,31 @@ func (o *debian) checkIfSudoNoPasswd() error {
return nil
}

func (o *debian) checkDependencies() error {
switch o.Distro.Family {
case "ubuntu":
return nil

case "debian":
// Debian needs aptitude to get changelogs.
// Because unable to get changelogs via apt-get changelog on Debian.
name := "aptitude"
cmd := name + " -h"
if r := o.ssh(cmd, noSudo); !r.isSuccess() {
o.lackDependencies = []string{name}
}
return nil

default:
return fmt.Errorf("Not implemented yet: %s", o.Distro)
}
}

func (o *debian) install() error {
if len(o.lackDependencies) == 0 {
return nil
}

// apt-get update
o.log.Infof("apt-get update...")
cmd := util.PrependProxyEnv("apt-get update")
Expand All @@ -134,15 +158,14 @@ func (o *debian) install() error {
return fmt.Errorf(msg)
}

if o.Distro.Family == "debian" {
// install aptitude
cmd = util.PrependProxyEnv("apt-get install --force-yes -y aptitude")
for _, name := range o.lackDependencies {
cmd = util.PrependProxyEnv("apt-get install " + name)
if r := o.ssh(cmd, sudo); !r.isSuccess() {
msg := fmt.Sprintf("Failed to SSH: %s", r)
o.log.Errorf(msg)
return fmt.Errorf(msg)
}
o.log.Infof("Installed: aptitude")
o.log.Infof("Installed: " + name)
}
return nil
}
Expand Down
4 changes: 4 additions & 0 deletions scan/freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ func (o *bsd) checkIfSudoNoPasswd() error {
return nil
}

func (o *bsd) checkDependencies() error {
return nil
}

func (o *bsd) install() error {
return nil
}
Expand Down
37 changes: 19 additions & 18 deletions scan/redhat.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,45 +112,46 @@ func (o *redhat) checkIfSudoNoPasswd() error {
// CentOS 6 ... yum-plugin-changelog
// CentOS 7 ... yum-plugin-changelog
// RHEL, Amazon ... no additinal packages needed
func (o *redhat) install() error {
func (o *redhat) checkDependencies() error {
switch o.Distro.Family {
case "rhel", "amazon":
o.log.Infof("Nothing to do")
// o.log.Infof("Nothing to do")
return nil
}
// CentOS
return o.installYumChangelog()
}

func (o *redhat) installYumChangelog() error {
if o.Distro.Family == "centos" {
case "centos":
var majorVersion int
if 0 < len(o.Distro.Release) {
majorVersion, _ = strconv.Atoi(strings.Split(o.Distro.Release, ".")[0])
} else {
return fmt.Errorf(
"Not implemented yet: %s", o.Distro)
return fmt.Errorf("Not implemented yet: %s", o.Distro)
}

var packName = ""
var name = ""
if majorVersion < 6 {
packName = "yum-changelog"
name = "yum-changelog"
} else {
packName = "yum-plugin-changelog"
name = "yum-plugin-changelog"
}

cmd := "rpm -q " + packName
cmd := "rpm -q " + name
if r := o.ssh(cmd, noSudo); r.isSuccess() {
o.log.Infof("Ignored: %s already installed", packName)
return nil
}
o.lackDependencies = []string{name}
return nil

o.log.Infof("Installing %s...", packName)
cmd = util.PrependProxyEnv("yum install -y " + packName)
default:
return fmt.Errorf("Not implemented yet: %s", o.Distro)
}
}

func (o *redhat) install() error {
for _, name := range o.lackDependencies {
cmd := util.PrependProxyEnv("yum install -y " + name)
if r := o.ssh(cmd, sudo); !r.isSuccess() {
return fmt.Errorf("Failed to SSH: %s", r)
}
o.log.Infof("Installed: %s", packName)
o.log.Infof("Installed: %s", name)
}
return nil
}
Expand Down
65 changes: 62 additions & 3 deletions scan/serverapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package scan

import (
"bufio"
"fmt"
"os"
"strings"
"time"

"github.com/Sirupsen/logrus"
Expand All @@ -40,7 +43,10 @@ type osTypeInterface interface {

setDistro(string, string)
getDistro() config.Distro
// getFamily() string

// checkDependencies checks if dependencies are installed on the target server.
checkDependencies() error
getLackDependencies() []string

checkIfSudoNoPasswd() error
detectPlatform() error
Expand All @@ -60,7 +66,7 @@ type osTypeInterface interface {
setErrs([]error)
}

// osPackages included by linux struct
// osPackages is included by base struct
type osPackages struct {
// installed packages
Packages models.PackageInfoList
Expand Down Expand Up @@ -425,12 +431,65 @@ func detectPlatforms() []error {

// Prepare installs requred packages to scan vulnerabilities.
func Prepare() []error {
return parallelSSHExec(func(o osTypeInterface) error {
errs := parallelSSHExec(func(o osTypeInterface) error {
if err := o.checkDependencies(); err != nil {
return err
}
return nil
})
if len(errs) != 0 {
return errs
}

var targets []osTypeInterface
for _, s := range servers {
deps := s.getLackDependencies()
if len(deps) != 0 {
targets = append(targets, s)
}
}
if len(targets) == 0 {
Log.Info("No need to install dependencies")
return nil
}

Log.Info("Below servers are needed to install dependencies")
for _, s := range targets {
for _, d := range s.getLackDependencies() {
Log.Infof(" - %s on %s", d, s.getServerInfo().GetServerName())
}
}
Log.Info("Is this ok to install dependencies on the servers? [y/N]")

reader := bufio.NewReader(os.Stdin)
for {
text, err := reader.ReadString('\n')
if err != nil {
return []error{err}
}
switch strings.TrimSpace(text) {
case "", "N", "n":
return nil
case "y", "Y":
goto yes
default:
Log.Info("Please enter y or N")
}
}

yes:
servers = targets
errs = parallelSSHExec(func(o osTypeInterface) error {
if err := o.install(); err != nil {
return err
}
return nil
})
if len(errs) != 0 {
return errs
}
Log.Info("All dependencies were installed correctly")
return nil
}

// Scan scan
Expand Down