From 6338c53c2e69bb87c76686de1fdbca5f2fa34766 Mon Sep 17 00:00:00 2001 From: Bader Boland Date: Fri, 24 Jan 2020 11:29:51 -0500 Subject: [PATCH] Moved the rest of the commands. --- cmd/polaris/audit.go | 152 +++++++++++++++++++++++++++++++++++++++ cmd/polaris/dashboard.go | 2 +- cmd/polaris/root.go | 2 + main.go | 141 +----------------------------------- 4 files changed, 156 insertions(+), 141 deletions(-) create mode 100644 cmd/polaris/audit.go diff --git a/cmd/polaris/audit.go b/cmd/polaris/audit.go new file mode 100644 index 00000000..4758b889 --- /dev/null +++ b/cmd/polaris/audit.go @@ -0,0 +1,152 @@ +// Copyright 2020 FairwindsOps Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "os" + + "github.com/spf13/cobra" + "github.com/sirupsen/logrus" + "github.com/fairwindsops/polaris/pkg/validator" + conf "github.com/fairwindsops/polaris/pkg/config" + "github.com/fairwindsops/polaris/pkg/kube" + "sigs.k8s.io/yaml" +) + +var setExitCode bool +var minScore int +var auditOutputURL string +var auditOutputFile string +var auditOutputFormat string +var displayName string + + +func init() { + rootCmd.AddCommand(auditCmd) + auditCmd.PersistentFlags().StringVar(&auditPath, "audit-path", "", "If specified, audits one or more YAML files instead of a cluster.") + auditCmd.PersistentFlags().BoolVar(&setExitCode, "set-exit-code-on-error", false, "Set an exit code of 3 when the audit contains error-level issues.") + auditCmd.PersistentFlags().IntVar(&minScore, "set-exit-code-below-score", 0, "Set an exit code of 4 when the score is below this threshold (1-100).") + auditCmd.PersistentFlags().StringVar(&auditOutputURL, "output-url", "", "Destination URL to send audit results.") + auditCmd.PersistentFlags().StringVar(&auditOutputFile, "output-file", "", "Destination file for audit results.") + auditCmd.PersistentFlags().StringVar(&auditOutputFormat, "output-format", "json", "Output format for results - json, yaml, or score.") + auditCmd.PersistentFlags().StringVar(&displayName, "display-name", "", "An optional identifier for the audit.") +} + +var auditCmd = &cobra.Command{ + Use: "audit", + Short: "Runs a one-time audit.", + Long: `Runs a one-time audit.`, + Run: func(cmd *cobra.Command, args []string) { + if displayName != "" { + c.DisplayName = displayName + } + + auditData := runAndReportAudit(c, auditPath, auditOutputFile, auditOutputURL, auditOutputFormat) + + summary := auditData.GetSummary() + score := summary.GetScore() + if setExitCode && summary.Errors > 0 { + logrus.Infof("%d errors found in audit", summary.Errors) + os.Exit(3) + } else if minScore != 0 && score < uint(minScore) { + logrus.Infof("Audit score of %d is less than the provided minimum of %d", score, minScore) + os.Exit(4) + } + }, +} + + +func runAndReportAudit(c conf.Configuration, auditPath string, outputFile string, outputURL string, outputFormat string) validator.AuditData { + // Create a kubernetes client resource provider + k, err := kube.CreateResourceProvider(auditPath) + if err != nil { + logrus.Errorf("Error fetching Kubernetes resources %v", err) + os.Exit(1) + } + auditData, err := validator.RunAudit(c, k) + + if err != nil { + logrus.Errorf("Error while running audit on resources: %v", err) + os.Exit(1) + } + + var outputBytes []byte + if outputFormat == "score" { + outputBytes = []byte(fmt.Sprintf("%d\n", auditData.GetSummary().GetScore())) + } else if outputFormat == "yaml" { + jsonBytes, err := json.Marshal(auditData) + if err == nil { + outputBytes, err = yaml.JSONToYAML(jsonBytes) + } + } else { + outputBytes, err = json.MarshalIndent(auditData, "", " ") + } + if err != nil { + logrus.Errorf("Error marshalling audit: %v", err) + os.Exit(1) + } + if outputURL == "" && outputFile == "" { + os.Stdout.Write(outputBytes) + } else { + if outputURL != "" { + req, err := http.NewRequest("POST", outputURL, bytes.NewBuffer(outputBytes)) + + if err != nil { + logrus.Errorf("Error building request for output: %v", err) + os.Exit(1) + } + + if outputFormat == "json" { + req.Header.Set("Content-Type", "application/json") + } else if outputFormat == "yaml" { + req.Header.Set("Content-Type", "application/x-yaml") + } else { + req.Header.Set("Content-Type", "text/plain") + } + client := &http.Client{} + resp, err := client.Do(req) + + if err != nil { + logrus.Errorf("Error making request for output: %v", err) + os.Exit(1) + } + + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + + if err != nil { + logrus.Errorf("Error reading response: %v", err) + os.Exit(1) + } + + logrus.Infof("Received response: %v", body) + } + + if outputFile != "" { + err := ioutil.WriteFile(outputFile, []byte(outputBytes), 0644) + if err != nil { + logrus.Errorf("Error writing output to file: %v", err) + os.Exit(1) + } + } + } + return auditData +} diff --git a/cmd/polaris/dashboard.go b/cmd/polaris/dashboard.go index 7b22e693..4e6e3271 100644 --- a/cmd/polaris/dashboard.go +++ b/cmd/polaris/dashboard.go @@ -27,7 +27,7 @@ import ( var serverPort int var basePath string var loadAuditFile string -var auditPath string + func init() { rootCmd.AddCommand(dashboardCmd) diff --git a/cmd/polaris/root.go b/cmd/polaris/root.go index b5e6a1f0..a10d9da4 100644 --- a/cmd/polaris/root.go +++ b/cmd/polaris/root.go @@ -22,11 +22,13 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/pflag" + ) var configPath string var disallowExemptions bool var logLevel string +var auditPath string var ( version string diff --git a/main.go b/main.go index 6880309f..c48db92b 100644 --- a/main.go +++ b/main.go @@ -15,22 +15,7 @@ package main import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "io/ioutil" - "net/http" - "os" - - conf "github.com/fairwindsops/polaris/pkg/config" - "github.com/fairwindsops/polaris/pkg/kube" - "github.com/fairwindsops/polaris/pkg/validator" "github.com/fairwindsops/polaris/cmd/polaris" - "github.com/sirupsen/logrus" - _ "k8s.io/client-go/plugin/pkg/client/auth" // Required for other auth providers like GKE. - "sigs.k8s.io/yaml" - ) const ( @@ -41,130 +26,6 @@ const ( ) func main() { - // Load CLI Flags - // TODO: Split up global flags vs dashboard/webhook/audit specific flags - audit := flag.Bool("audit", false, "Runs a one-time audit.") - auditPath := flag.String("audit-path", "", "If specified, audits one or more YAML files instead of a cluster") - setExitCode := flag.Bool("set-exit-code-on-error", false, "When running with --audit, set an exit code of 3 when the audit contains error-level issues.") - minScore := flag.Int("set-exit-code-below-score", 0, "When running with --audit, set an exit code of 4 when the score is below this threshold (1-100)") - auditOutputURL := flag.String("output-url", "", "Destination URL to send audit results") - auditOutputFile := flag.String("output-file", "", "Destination file for audit results") - auditOutputFormat := flag.String("output-format", "json", "Output format for results - json, yaml, or score") - displayName := flag.String("display-name", "", "An optional identifier for the audit") - - - - - //configPath := flag.String("config", "", "Location of Polaris configuration file") - //disallowExemptions := flag.Bool("disallow-exemptions", false, "Location of Polaris configuration file") - //logLevel := flag.String("log-level", logrus.InfoLevel.String(), "Logrus log level") - - flag.Parse() - - c := conf.Configuration{} - - if *displayName != "" { - c.DisplayName = *displayName - } - - if *audit { - auditData := runAndReportAudit(c, *auditPath, *auditOutputFile, *auditOutputURL, *auditOutputFormat) - - summary := auditData.GetSummary() - score := summary.GetScore() - if *setExitCode && summary.Errors > 0 { - logrus.Infof("%d errors found in audit", summary.Errors) - os.Exit(3) - } else if *minScore != 0 && score < uint(*minScore) { - logrus.Infof("Audit score of %d is less than the provided minimum of %d", score, *minScore) - os.Exit(4) - } - } else { - cmd.Execute(Version, commit) - } + cmd.Execute(Version, commit) } -func startDashboardServer(c conf.Configuration, auditPath string, loadAuditFile string, port int, basePath string) { -} - -func startWebhookServer(c conf.Configuration, disableWebhookConfigInstaller bool, port int) { - -} - -func runAndReportAudit(c conf.Configuration, auditPath string, outputFile string, outputURL string, outputFormat string) validator.AuditData { - // Create a kubernetes client resource provider - k, err := kube.CreateResourceProvider(auditPath) - if err != nil { - logrus.Errorf("Error fetching Kubernetes resources %v", err) - os.Exit(1) - } - auditData, err := validator.RunAudit(c, k) - - if err != nil { - logrus.Errorf("Error while running audit on resources: %v", err) - os.Exit(1) - } - - var outputBytes []byte - if outputFormat == "score" { - outputBytes = []byte(fmt.Sprintf("%d\n", auditData.GetSummary().GetScore())) - } else if outputFormat == "yaml" { - jsonBytes, err := json.Marshal(auditData) - if err == nil { - outputBytes, err = yaml.JSONToYAML(jsonBytes) - } - } else { - outputBytes, err = json.MarshalIndent(auditData, "", " ") - } - if err != nil { - logrus.Errorf("Error marshalling audit: %v", err) - os.Exit(1) - } - if outputURL == "" && outputFile == "" { - os.Stdout.Write(outputBytes) - } else { - if outputURL != "" { - req, err := http.NewRequest("POST", outputURL, bytes.NewBuffer(outputBytes)) - - if err != nil { - logrus.Errorf("Error building request for output: %v", err) - os.Exit(1) - } - - if outputFormat == "json" { - req.Header.Set("Content-Type", "application/json") - } else if outputFormat == "yaml" { - req.Header.Set("Content-Type", "application/x-yaml") - } else { - req.Header.Set("Content-Type", "text/plain") - } - client := &http.Client{} - resp, err := client.Do(req) - - if err != nil { - logrus.Errorf("Error making request for output: %v", err) - os.Exit(1) - } - - defer resp.Body.Close() - - body, err := ioutil.ReadAll(resp.Body) - - if err != nil { - logrus.Errorf("Error reading response: %v", err) - os.Exit(1) - } - - logrus.Infof("Received response: %v", body) - } - - if outputFile != "" { - err := ioutil.WriteFile(outputFile, []byte(outputBytes), 0644) - if err != nil { - logrus.Errorf("Error writing output to file: %v", err) - os.Exit(1) - } - } - } - return auditData -}