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