github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/pkg/inspector/cmd/local.go (about) 1 package cmd 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "strings" 8 9 "github.com/apprenda/kismatic/pkg/inspector/check" 10 "github.com/apprenda/kismatic/pkg/inspector/rule" 11 "github.com/spf13/cobra" 12 ) 13 14 type localOpts struct { 15 outputType string 16 nodeRoles string 17 rulesFile string 18 packageInstallationDisabled bool 19 dockerInstallationDisabled bool 20 disconnectedInstallation bool 21 useUpgradeDefaults bool 22 additionalVariables map[string]string 23 } 24 25 var localExample = `# Run with a custom rules file 26 kismatic-inspector local --node-roles master -f inspector-rules.yaml 27 ` 28 29 // NewCmdLocal returns the "local" command 30 func NewCmdLocal(out io.Writer) *cobra.Command { 31 opts := localOpts{} 32 var additionalVars []string 33 cmd := &cobra.Command{ 34 Use: "local", 35 Short: "Run the inspector checks against the local host", 36 Example: localExample, 37 RunE: func(cmd *cobra.Command, args []string) error { 38 opts.additionalVariables = make(map[string]string) 39 for _, v := range additionalVars { 40 kv := strings.Split(v, "=") 41 if len(kv) != 2 { 42 return fmt.Errorf("invalid key-value %q", v) 43 } 44 opts.additionalVariables[kv[0]] = kv[1] 45 } 46 return runLocal(out, opts) 47 }, 48 } 49 cmd.Flags().StringVarP(&opts.outputType, "output", "o", "table", "set the result output type. Options are 'json', 'table'") 50 cmd.Flags().StringVar(&opts.nodeRoles, "node-roles", "", "comma-separated list of the node's roles. Valid roles are 'etcd', 'master', 'worker'") 51 cmd.Flags().StringVarP(&opts.rulesFile, "file", "f", "", "the path to an inspector rules file. If blank, the inspector uses the default rules") 52 cmd.Flags().BoolVar(&opts.packageInstallationDisabled, "pkg-installation-disabled", false, "when true, the inspector will ensure that the necessary packages are installed on the node") 53 cmd.Flags().BoolVar(&opts.dockerInstallationDisabled, "docker-installation-disabled", false, "when true, the inspector will check for docker packages to be installed") 54 cmd.Flags().BoolVar(&opts.disconnectedInstallation, "disconnected-installation", false, "when true will check for the required packages needed during a disconnected install") 55 cmd.Flags().BoolVarP(&opts.useUpgradeDefaults, "upgrade", "u", false, "use defaults for upgrade, rather than install") 56 cmd.Flags().StringSliceVar(&additionalVars, "additional-vars", []string{}, "provide a key=value list to template ruleset") 57 return cmd 58 } 59 60 func runLocal(out io.Writer, opts localOpts) error { 61 if opts.nodeRoles == "" { 62 return fmt.Errorf("node role is required") 63 } 64 roles, err := getNodeRoles(opts.nodeRoles) 65 if err != nil { 66 return err 67 } 68 if err = validateOutputType(opts.outputType); err != nil { 69 return err 70 } 71 // Gather rules 72 rules, err := getRulesFromFileOrDefault(out, opts.rulesFile, opts.useUpgradeDefaults, opts.additionalVariables) 73 if err != nil { 74 return err 75 } 76 // Set up engine dependencies 77 distro, err := check.DetectDistro() 78 if err != nil { 79 return fmt.Errorf("error running checks locally: %v", err) 80 } 81 pkgMgr, err := check.NewPackageManager(distro) 82 if err != nil { 83 return err 84 } 85 86 // Create rule engine 87 e := rule.Engine{ 88 RuleCheckMapper: rule.DefaultCheckMapper{ 89 PackageManager: pkgMgr, 90 PackageInstallationDisabled: opts.packageInstallationDisabled, 91 DockerInstallationDisabled: opts.dockerInstallationDisabled, 92 DisconnectedInstallation: opts.disconnectedInstallation, 93 }, 94 } 95 labels := append(roles, string(distro)) 96 results, err := e.ExecuteRules(rules, labels) 97 if err != nil { 98 return fmt.Errorf("error running local rules: %v", err) 99 } 100 if err := printResults(out, results, opts.outputType); err != nil { 101 return fmt.Errorf("error printing results: %v", err) 102 } 103 for _, r := range results { 104 if !r.Success { 105 return errors.New("inspector rules failed") 106 } 107 } 108 return nil 109 }