Skip to content

Commit

Permalink
add ability to download remote repository in CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
Yusuf Kanchwala committed Oct 2, 2020
1 parent d88a767 commit 0481625
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 5 deletions.
74 changes: 71 additions & 3 deletions pkg/cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,45 @@ package cli

import (
"flag"
"fmt"
"os"
"path/filepath"

"github.com/accurics/terrascan/pkg/downloader"
"github.com/accurics/terrascan/pkg/runtime"
"github.com/accurics/terrascan/pkg/utils"
"github.com/accurics/terrascan/pkg/writer"
"go.uber.org/zap"
)

// Run executes terrascan in CLI mode
func Run(iacType, iacVersion, cloudType, iacFilePath, iacDirPath, configFile,
policyPath, format string, configOnly bool, useColors bool) {
policyPath, format, remoteType, remoteURL string, configOnly, useColors bool) {

// validate remote repository options
toDownload, err := validateRemoteOpts(remoteType, remoteURL)
if err != nil {
os.Exit(5)
}

// download remote repository
var tempDir string
if toDownload {
// temp dir to download the remote repo
tempDir = filepath.Join(os.TempDir(), utils.GenRandomString(6))
defer os.RemoveAll(tempDir)

// download remote repository
iacDirPath, err = downloadRemoteRepo(remoteType, remoteURL, tempDir)
if err != nil {
os.RemoveAll(tempDir)
os.Exit(5)
}
}

// create a new runtime executor for processing IaC
executor, err := runtime.NewExecutor(iacType, iacVersion, cloudType, iacFilePath,
iacDirPath, configFile, policyPath)
executor, err := runtime.NewExecutor(iacType, iacVersion, cloudType,
iacFilePath, iacDirPath, configFile, policyPath)
if err != nil {
return
}
Expand All @@ -50,6 +76,48 @@ func Run(iacType, iacVersion, cloudType, iacFilePath, iacDirPath, configFile,
}

if results.Violations.ViolationStore.Count.TotalCount != 0 && flag.Lookup("test.v") == nil {
os.RemoveAll(tempDir)
os.Exit(3)
}
}

// validateRemoteOpts validate remote repository options
func validateRemoteOpts(remoteType, remoteURL string) (bool, error) {

// 1. remoteType and remoteURL both are empty
if remoteType == "" && remoteURL == "" {
return false, nil
}

// 2. remoteType and remoteURL both are not empty
if remoteType != "" && remoteURL != "" {
zap.S().Debugf("remoteType: %q, remoteURL: %q", remoteType, remoteURL)
return true, nil
}

// 3. remoteType is empty and remoteURL is not
if remoteType != "" || remoteURL != "" {
zap.S().Errorf("remote type and remote url both options should be specified")
return false, fmt.Errorf("incorrect remote options")
}

return false, nil
}

// downloadRemoteRepo downloads the remote repo in the temp directory and
// returns the path of the dir where the remote repository has been downloaded
func downloadRemoteRepo(remoteType, remoteURL, destDir string) (string, error) {

// new downloader
d := downloader.NewDownloader()
url := fmt.Sprintf("%s::%s", remoteType, remoteURL)
path, err := d.Download(url, destDir)
if err != nil {
zap.S().Errorf("failed to download remote repo url: %q, type: %q. error: '%v'",
remoteURL, remoteType, err)
return "", err
}

// successful
return path, nil
}
21 changes: 19 additions & 2 deletions pkg/cli/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,32 @@ import (
var (
// PolicyPath Policy path directory
PolicyPath string

// PolicyType Cloud type (aws, azure, gcp, github)
PolicyType string

// IacType IaC type (terraform)
IacType string

// IacVersion IaC version (for terraform:v12)
IacVersion string

// IacFilePath Path to a single IaC file
IacFilePath string

// IacDirPath Path to a directory containing one or more IaC files
IacDirPath string
//ConfigOnly will output resource config (should only be used for debugging purposes)

// RemoteType indicates the type of remote backend. Supported backends are
// git s3, gcs, http.
RemoteType string

// RemoteURL points to the remote Iac repository on git, s3, gcs, http
RemoteURL string

// ConfigOnly will output resource config (should only be used for debugging purposes)
ConfigOnly bool

// UseColors indicates whether to use color output
UseColors bool
useColors string // used for flag processing
Expand Down Expand Up @@ -85,7 +99,8 @@ Detect compliance and security violations across Infrastructure as Code to mitig

func scan(cmd *cobra.Command, args []string) {
zap.S().Debug("running terrascan in cli mode")
Run(IacType, IacVersion, PolicyType, IacFilePath, IacDirPath, ConfigFile, PolicyPath, OutputType, ConfigOnly, UseColors)
Run(IacType, IacVersion, PolicyType, IacFilePath, IacDirPath, ConfigFile,
PolicyPath, OutputType, RemoteType, RemoteURL, ConfigOnly, UseColors)
}

func init() {
Expand All @@ -95,6 +110,8 @@ func init() {
scanCmd.Flags().StringVarP(&IacFilePath, "iac-file", "f", "", "path to a single IaC file")
scanCmd.Flags().StringVarP(&IacDirPath, "iac-dir", "d", ".", "path to a directory containing one or more IaC files")
scanCmd.Flags().StringVarP(&PolicyPath, "policy-path", "p", "", "policy path directory")
scanCmd.Flags().StringVarP(&RemoteType, "remote-type", "r", "", "type of remote backend (git, s3, gcs, http)")
scanCmd.Flags().StringVarP(&RemoteURL, "remote-url", "u", "", "url pointing to remote IaC repository")
scanCmd.Flags().BoolVarP(&ConfigOnly, "config-only", "", false, "will output resource config (should only be used for debugging purposes)")
// flag passes a string, but we normalize to bool in PreRun
scanCmd.Flags().StringVar(&useColors, "use-colors", "auto", "color output (auto, t, f)")
Expand Down

0 comments on commit 0481625

Please sign in to comment.