github.com/manicqin/nomad@v0.9.5/command/sentinel_apply.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/hashicorp/nomad/api"
    10  	"github.com/posener/complete"
    11  )
    12  
    13  type SentinelApplyCommand struct {
    14  	Meta
    15  }
    16  
    17  func (c *SentinelApplyCommand) Help() string {
    18  	helpText := `
    19  Usage: nomad sentinel apply [options] <name> <file>
    20  
    21    Apply is used to write a new Sentinel policy or update an existing one.
    22    The name of the policy and file must be specified. The file will be read
    23    from stdin by specifying "-".
    24  
    25  General Options:
    26  
    27    ` + generalOptionsUsage() + `
    28  
    29  Apply Options:
    30  
    31    -description
    32      Sets a human readable description for the policy.
    33  
    34    -scope (default: submit-job)
    35      Sets the scope of the policy and when it should be enforced.
    36  
    37    -level (default: advisory)
    38      Sets the enforcement level of the policy. Must be one of advisory,
    39      soft-mandatory, hard-mandatory.
    40  
    41  `
    42  	return strings.TrimSpace(helpText)
    43  }
    44  
    45  func (c *SentinelApplyCommand) AutocompleteFlags() complete.Flags {
    46  	return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
    47  		complete.Flags{
    48  			"-description": complete.PredictAnything,
    49  			"-scope":       complete.PredictAnything,
    50  			"-level":       complete.PredictAnything,
    51  		})
    52  }
    53  
    54  func (c *SentinelApplyCommand) AutocompleteArgs() complete.Predictor {
    55  	return complete.PredictNothing
    56  }
    57  
    58  func (c *SentinelApplyCommand) Synopsis() string {
    59  	return "Create a new or update existing Sentinel policies"
    60  }
    61  
    62  func (c *SentinelApplyCommand) Name() string { return "sentinel apply" }
    63  
    64  func (c *SentinelApplyCommand) Run(args []string) int {
    65  	var description, scope, enfLevel string
    66  	var err error
    67  	flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
    68  	flags.Usage = func() { c.Ui.Output(c.Help()) }
    69  	flags.StringVar(&description, "description", "", "")
    70  	flags.StringVar(&scope, "scope", "submit-job", "")
    71  	flags.StringVar(&enfLevel, "level", "advisory", "")
    72  	if err := flags.Parse(args); err != nil {
    73  		return 1
    74  	}
    75  
    76  	// Check that we got exactly two arguments
    77  	args = flags.Args()
    78  	if l := len(args); l != 2 {
    79  		c.Ui.Error("This command takes exactly two arguments: <name> <file>")
    80  		c.Ui.Error(commandErrorText(c))
    81  		return 1
    82  	}
    83  
    84  	// Get the name and file
    85  	policyName := args[0]
    86  
    87  	// Read the file contents
    88  	file := args[1]
    89  	var rawPolicy []byte
    90  	if file == "-" {
    91  		rawPolicy, err = ioutil.ReadAll(os.Stdin)
    92  		if err != nil {
    93  			c.Ui.Error(fmt.Sprintf("Failed to read stdin: %v", err))
    94  			return 1
    95  		}
    96  	} else {
    97  		rawPolicy, err = ioutil.ReadFile(file)
    98  		if err != nil {
    99  			c.Ui.Error(fmt.Sprintf("Failed to read file: %v", err))
   100  			return 1
   101  		}
   102  	}
   103  
   104  	// Construct the policy
   105  	sp := &api.SentinelPolicy{
   106  		Name:             policyName,
   107  		Description:      description,
   108  		Scope:            scope,
   109  		EnforcementLevel: enfLevel,
   110  		Policy:           string(rawPolicy),
   111  	}
   112  
   113  	// Get the HTTP client
   114  	client, err := c.Meta.Client()
   115  	if err != nil {
   116  		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
   117  		return 1
   118  	}
   119  
   120  	// Get the list of policies
   121  	_, err = client.SentinelPolicies().Upsert(sp, nil)
   122  	if err != nil {
   123  		c.Ui.Error(fmt.Sprintf("Error writing Sentinel policy: %s", err))
   124  		return 1
   125  	}
   126  
   127  	c.Ui.Output(fmt.Sprintf("Successfully wrote %q Sentinel policy!",
   128  		policyName))
   129  	return 0
   130  }