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  }