github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/pkg/inspector/cmd/client.go (about) 1 package cmd 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "strings" 8 9 "github.com/apprenda/kismatic/pkg/inspector" 10 "github.com/spf13/cobra" 11 ) 12 13 type clientOpts struct { 14 outputType string 15 nodeRoles string 16 rulesFile string 17 targetNode string 18 useUpgradeDefaults bool 19 additionalVariables map[string]string 20 } 21 22 var clientExample = `# Run the inspector against an etcd node 23 kismatic-inspector client 10.0.1.24:9090 --node-roles etcd 24 25 # Run the inspector against a remote node, and ask for JSON output 26 kismatic-inspector client 10.0.1.24:9090 --node-roles etcd -o json 27 28 # Run the inspector against a remote node using a custom rules file 29 kismatic-inspector client 10.0.1.24:9090 -f inspector-rules.yaml --node-roles etcd` 30 31 // NewCmdClient returns the "client" command 32 func NewCmdClient(out io.Writer) *cobra.Command { 33 opts := clientOpts{} 34 var additionalVars []string 35 cmd := &cobra.Command{ 36 Use: "client HOST:PORT", 37 Short: "Run the inspector against a remote inspector server.", 38 Example: clientExample, 39 RunE: func(cmd *cobra.Command, args []string) error { 40 if len(args) != 1 { 41 return cmd.Usage() 42 } 43 // Set the target node as the first argument 44 opts.targetNode = args[0] 45 opts.additionalVariables = make(map[string]string) 46 for _, v := range additionalVars { 47 kv := strings.Split(v, "=") 48 if len(kv) != 2 { 49 return fmt.Errorf("invalid key=value %q", v) 50 } 51 opts.additionalVariables[kv[0]] = kv[1] 52 } 53 return runClient(out, opts) 54 }, 55 } 56 cmd.Flags().StringVarP(&opts.outputType, "output", "o", "table", "set the result output type. Options are 'json', 'table'") 57 cmd.Flags().StringVar(&opts.nodeRoles, "node-roles", "", "comma-separated list of the node's roles. Valid roles are 'etcd', 'master', 'worker'") 58 cmd.Flags().StringVarP(&opts.rulesFile, "file", "f", "", "the path to an inspector rules file. If blank, the inspector uses the default rules") 59 cmd.Flags().BoolVarP(&opts.useUpgradeDefaults, "upgrade", "u", false, "use defaults for upgrade, rather than install") 60 cmd.Flags().StringSliceVar(&additionalVars, "additional-vars", []string{}, "key=value pairs separated by ',' to template ruleset") 61 return cmd 62 } 63 64 func runClient(out io.Writer, opts clientOpts) error { 65 if err := validateOutputType(opts.outputType); err != nil { 66 return err 67 } 68 if opts.nodeRoles == "" { 69 return fmt.Errorf("--node-roles is required") 70 } 71 roles, err := getNodeRoles(opts.nodeRoles) 72 if err != nil { 73 return err 74 } 75 c, err := inspector.NewClient(opts.targetNode, roles) 76 if err != nil { 77 return fmt.Errorf("error creating inspector client: %v", err) 78 } 79 rules, err := getRulesFromFileOrDefault(out, opts.rulesFile, opts.useUpgradeDefaults, opts.additionalVariables) 80 if err != nil { 81 return err 82 } 83 84 results, err := c.ExecuteRules(rules) 85 if err != nil { 86 return fmt.Errorf("error running inspector against remote node: %v", err) 87 } 88 if err := printResults(out, results, opts.outputType); err != nil { 89 return err 90 } 91 for _, r := range results { 92 if !r.Success { 93 return errors.New("inspector rules failed") 94 } 95 } 96 return nil 97 }