Confirm before installing dependencies on prepare
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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":
|
||||
|
||||
@@ -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")
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user