cmd

package
v1.0.54 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2023 License: Apache-2.0 Imports: 62 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AddCanary = &cobra.Command{
	Use:   "canary <system.yaml>",
	Short: "Add a new canary spec",
	Run: func(cmd *cobra.Command, configFiles []string) {
		if err := configSync.SyncCanary(dataFile, configFiles...); err != nil {
			logger.Fatalf("Could not sync canaries: %v", err)
		}
	},
}
View Source
var AddTopology = &cobra.Command{
	Use:   "topology <system.yaml>",
	Short: "Add a new topology spec",
	Run: func(cmd *cobra.Command, configFiles []string) {
		opts := getTopologyRunOptions(0)
		if err := configSync.SyncTopology(opts, dataFile, configFiles...); err != nil {
			logger.Fatalf("Could not sync topology: %v", err)
		}
	},
}
View Source
var Docs = &cobra.Command{
	Use:    "docs",
	Short:  "Generate docs ",
	Hidden: true,
	Args:   cobra.MinimumNArgs(0),
	Run: func(cmd *cobra.Command, args []string) {
		printAPIDocs(args)
	},
}
View Source
var GoOffline = &cobra.Command{
	Use:  "go-offline",
	Long: "Download all dependencies.",
	Run: func(cmd *cobra.Command, args []string) {
		if err := db.GoOffline(); err != nil {
			logger.Fatalf("Failed to go offline: %+v", err)
		}

		databaseDir := "temp-database-dir"
		if err := os.Mkdir(databaseDir, 0755); err != nil {
			logger.Fatalf("Failed to create database directory[%s]: %+v", err)
		}
		defer os.RemoveAll(databaseDir)

		db.ConnectionString = "embedded://" + databaseDir
		if err := db.Init(); err != nil {
			logger.Fatalf("Failed to run in embedded mode: %+v", err)
		}
		if err := db.PostgresServer.Stop(); err != nil {
			logger.Fatalf("Failed to stop embedded postgres: %+v", err)
		}

		os.Exit(0)
	},
}
View Source
var Operator = &cobra.Command{
	Use:   "operator",
	Short: "Start the kubernetes operator",
	Run:   run,
}
View Source
var QueryTopology = &cobra.Command{
	Use:   "query",
	Short: "Query the topology",
	Args:  cobra.MinimumNArgs(0),
	Run: func(cmd *cobra.Command, args []string) {
		if !db.IsConfigured() {
			logger.Fatalf("Must specify --db or DB_URL env")
		}

		if err := db.Init(); err != nil {
			logger.Fatalf("error connecting with postgres %v", err)
		}

		results, err := topology.Query(queryParams)
		if err != nil {
			logger.Fatalf("Failed to query topology: %v", err)
		}
		data, _ := json.MarshalIndent(results, "", "  ")
		fmt.Println(string(data))
	},
}
View Source
var Root = &cobra.Command{
	Use: "canary-checker",
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
		logger.UseZap(cmd.Flags())
		for _, script := range sharedLibrary {
			if err := gomplate.LoadSharedLibrary(script); err != nil {
				logger.Errorf("Failed to load shared library %s: %v", script, err)
			}
		}
		db.ConnectionString = readFromEnv(db.ConnectionString)
		if db.ConnectionString == "DB_URL" {
			db.ConnectionString = ""
		}
	},
}
View Source
var Run = &cobra.Command{
	Use:   "run <canary.yaml>",
	Short: "Execute checks and return",
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
		logger.ParseFlags(cmd.Flags())
		db.ConnectionString = readFromEnv(db.ConnectionString)
		if err := db.Init(); err != nil {
			logger.Fatalf("error connecting with postgres %v", err)
		}
	},
	Run: func(cmd *cobra.Command, configFiles []string) {
		timer := timer.NewTimer()
		if len(configFiles) == 0 {
			log.Fatalln("Must specify at least one canary")
		}
		kommonsClient, k8s, err := pkg.NewKommonsClient()
		if err != nil {
			logger.Warnf("Failed to get kubernetes client: %v", err)
		}
		var results = []*pkg.CheckResult{}

		wg := sync.WaitGroup{}
		queue := make(chan []*pkg.CheckResult, 1)

		for _, configfile := range configFiles {
			configs, err := pkg.ParseConfig(configfile, dataFile)
			if err != nil {
				logger.Errorf("Could not parse %s: %v", configfile, err)
				continue
			}
			logger.Infof("Checking %s, %d checks found", configfile, len(configs))
			for _, config := range configs {
				if runNamespace != "" {
					config.Namespace = runNamespace
				}
				if config.Name == "" {
					config.Name = CleanupFilename(configfile)
				}
				wg.Add(1)
				_config := config
				go func() {
					defer wg.Done()

					res, err := checks.RunChecks(context.New(kommonsClient, k8s, db.Gorm, db.Pool, _config))
					if err != nil {
						logger.Errorf("error running checks: %v", err)
						return
					}

					queue <- res
				}()
			}
		}
		failed := 0
		passed := 0

		go func() {
			wg.Wait()
			close(queue)
		}()

		for item := range queue {
			for _, result := range item {
				if !result.Pass {
					failed++
				} else {
					passed++
				}
				fmt.Printf("%s \t%s\t\n", time.Now().Format(time.RFC3339), result.String())
				results = append(results, result)
			}
		}

		if junit {
			report := output.GetJunitReport(results)
			if err := output.HandleOutput(report, outputFile); err != nil {
				logger.Fatalf("error writing output file: %v", err)
			}
		}
		if csv {
			report, err := output.GetCSVReport(results)
			if err != nil {
				logger.Fatalf("error generating CSV file: %v", err)
			}
			if err := output.HandleOutput(report, outputFile); err != nil {
				logger.Fatalf("error writing output file: %v", err)
			}
		}

		logger.Infof("%d passed, %d failed in %s", passed, failed, timer)

		if failed > 0 {
			os.Exit(1)
		}
	},
}
View Source
var RunTopology = &cobra.Command{
	Use:   "run <system.yaml>",
	Short: "Execute topology and return",
	Run: func(cmd *cobra.Command, configFiles []string) {
		timer := timer.NewTimer()
		if len(configFiles) == 0 {
			log.Fatalln("Must specify at least one topology definition")
		}

		opts := getTopologyRunOptions(10)

		var results = []*pkg.Component{}

		wg := sync.WaitGroup{}

		for _, configfile := range configFiles {
			configs, err := pkg.ParseSystems(configfile, dataFile)
			if err != nil {
				logger.Errorf("Could not parse %s: %v", configfile, err)
				continue
			}
			logger.Infof("Checking %s, %d systems found", configfile, len(configs))
			for _, config := range configs {
				wg.Add(1)
				_config := config
				if _config.GetPersistedID() == "" {
					_config.Status = v1.TopologyStatus{
						PersistedID: &StaticTemplatedID,
					}
				}
				go func() {
					components := topology.Run(opts, _config)
					results = append(results, components...)
					wg.Done()
				}()
			}
		}
		wg.Wait()

		logger.Infof("Checked %d systems in %v", len(results), timer)

		if db.IsConnected() {
			if err := db.PersistComponents(results); err != nil {
				logger.Errorf("error persisting results: %v", err)
			}
		}

		if topologyOutput != "" {
			data, _ := json.Marshal(results)
			logger.Infof("Writing results to %s", topologyOutput)
			if err := os.WriteFile(topologyOutput, data, 0644); err != nil {
				log.Fatalln(err)
			}
		}

	},
}
View Source
var Serve = &cobra.Command{
	Use:   "serve config.yaml",
	Short: "Start a server to execute checks",
	Run: func(cmd *cobra.Command, configFiles []string) {
		setup()
		canaryJobs.StartScanCanaryConfigs(dataFile, configFiles)
		if executor {
			jobs.Start()
		}
		serve()
	},
}
View Source
var StaticTemplatedID string = "cf38821d-434f-4496-9bbd-c0c633bb2699"

StaticTemplatedID for topologies created by CLI, to ensure that components are updated rather than duplicated

View Source
var Sync = &cobra.Command{
	Use: "sync",
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
		if err := db.Init(); err != nil {
			logger.Fatalf("error connecting with postgres %v", err)
		}
	},
}
View Source
var Topology = &cobra.Command{
	Use: "topology",
	PersistentPreRun: func(cmd *cobra.Command, args []string) {
		db.ConnectionString = readFromEnv(db.ConnectionString)
		if db.IsConfigured() {
			if err := db.Init(); err != nil {
				logger.Debugf("error connecting with postgres %v", err)
			}
		}
	},
}

Functions

func CleanupFilename added in v0.33.0

func CleanupFilename(fileName string) string

func ParseDocumentationFrom

func ParseDocumentationFrom(srcs []string) map[string]*Struct

ParseDocumentationFrom gets all types' documentation and returns them as an array. Each type is again represented as an array (we have to use arrays as we need to be sure for the order of the fields). This function returns fields and struct definitions that have no documentation as {name, ""}.

func ServerFlags added in v0.38.4

func ServerFlags(flags *pflag.FlagSet)

Types

type Struct

type Struct struct {
	Name, Doc  string
	StructType *ast.StructType
	DocType    *doc.Type
	Fields     StructFields
}

func (Struct) Print added in v0.38.32

func (strukt Struct) Print(structs map[string]*Struct) string

type StructField

type StructField struct {
	Name, Doc, Type, ID string
	Mandatory           bool
	Markdown            string
}

func NewStructField

func NewStructField(field *ast.Field) StructField

func (StructField) MarkdownRow added in v0.38.32

func (f StructField) MarkdownRow(structs map[string]*Struct) string

type StructFields added in v0.38.32

type StructFields []StructField

func (StructFields) GetAllFields added in v0.38.32

func (s StructFields) GetAllFields(structs map[string]*Struct) StructFields

func (StructFields) Len added in v0.38.32

func (s StructFields) Len() int

func (StructFields) Less added in v0.38.32

func (s StructFields) Less(i, j int) bool

func (StructFields) Swap added in v0.38.32

func (s StructFields) Swap(i, j int)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL