github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/acl_policy_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 ACLPolicyApplyCommand struct {
    14  	Meta
    15  }
    16  
    17  func (c *ACLPolicyApplyCommand) Help() string {
    18  	helpText := `
    19  Usage: nomad acl policy apply [options] <name> <path>
    20  
    21    Apply is used to create or update an ACL policy. The policy is
    22    sourced from <path> or from stdin if path is "-".
    23  
    24    This command requires a management ACL token.
    25  
    26  General Options:
    27  
    28    ` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace) + `
    29  
    30  Apply Options:
    31  
    32    -description
    33      Specifies a human readable description for the policy.
    34  
    35    -job
    36      Attaches the policy to the specified job. Requires that -namespace is
    37      also set.
    38  
    39    -namespace
    40      Attaches the policy to the specified namespace. Requires that -job is
    41      also set.
    42  
    43    -group
    44      Attaches the policy to the specified task group. Requires that -namespace
    45      and -job are also set.
    46  
    47    -task
    48      Attaches the policy to the specified task. Requires that -namespace, -job
    49      and -group are also set.
    50  `
    51  	return strings.TrimSpace(helpText)
    52  }
    53  
    54  func (c *ACLPolicyApplyCommand) AutocompleteFlags() complete.Flags {
    55  	return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
    56  		complete.Flags{})
    57  }
    58  
    59  func (c *ACLPolicyApplyCommand) AutocompleteArgs() complete.Predictor {
    60  	return complete.PredictNothing
    61  }
    62  
    63  func (c *ACLPolicyApplyCommand) Synopsis() string {
    64  	return "Create or update an ACL policy"
    65  }
    66  
    67  func (c *ACLPolicyApplyCommand) Name() string { return "acl policy apply" }
    68  
    69  func (c *ACLPolicyApplyCommand) Run(args []string) int {
    70  	var description string
    71  	var jobID, group, task string // namespace is included in default flagset
    72  
    73  	flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
    74  	flags.Usage = func() { c.Ui.Output(c.Help()) }
    75  	flags.StringVar(&description, "description", "", "")
    76  
    77  	flags.StringVar(&jobID, "job", "", "attach policy to job")
    78  	flags.StringVar(&group, "group", "", "attach policy to group")
    79  	flags.StringVar(&task, "task", "", "attach policy to task")
    80  
    81  	if err := flags.Parse(args); err != nil {
    82  		return 1
    83  	}
    84  
    85  	// Check that we got two arguments
    86  	args = flags.Args()
    87  	if l := len(args); l != 2 {
    88  		c.Ui.Error("This command takes two arguments: <name> and <path>")
    89  		c.Ui.Error(commandErrorText(c))
    90  		return 1
    91  	}
    92  
    93  	// Get the policy name
    94  	policyName := args[0]
    95  
    96  	// Read the file contents
    97  	file := args[1]
    98  	var rawPolicy []byte
    99  	var err error
   100  	if file == "-" {
   101  		rawPolicy, err = ioutil.ReadAll(os.Stdin)
   102  		if err != nil {
   103  			c.Ui.Error(fmt.Sprintf("Failed to read stdin: %v", err))
   104  			return 1
   105  		}
   106  	} else {
   107  		rawPolicy, err = ioutil.ReadFile(file)
   108  		if err != nil {
   109  			c.Ui.Error(fmt.Sprintf("Failed to read file: %v", err))
   110  			return 1
   111  		}
   112  	}
   113  
   114  	f := flags.Lookup("namespace")
   115  	namespace := f.Value.String()
   116  
   117  	if jobID != "" && namespace == "" {
   118  		c.Ui.Error("-namespace is required if -job is set")
   119  		return 1
   120  	}
   121  	if group != "" && jobID == "" {
   122  		c.Ui.Error("-job is required if -group is set")
   123  		return 1
   124  	}
   125  	if task != "" && group == "" {
   126  		c.Ui.Error("-group is required if -task is set")
   127  		return 1
   128  	}
   129  
   130  	// Construct the policy
   131  	ap := &api.ACLPolicy{
   132  		Name:        policyName,
   133  		Description: description,
   134  		Rules:       string(rawPolicy),
   135  	}
   136  	if namespace != "" {
   137  		ap.JobACL = &api.JobACL{
   138  			Namespace: namespace,
   139  			JobID:     jobID,
   140  			Group:     group,
   141  			Task:      task,
   142  		}
   143  	}
   144  
   145  	// Get the HTTP client
   146  	client, err := c.Meta.Client()
   147  	if err != nil {
   148  		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
   149  		return 1
   150  	}
   151  
   152  	// Upsert the policy
   153  	_, err = client.ACLPolicies().Upsert(ap, nil)
   154  	if err != nil {
   155  		c.Ui.Error(fmt.Sprintf("Error writing ACL policy: %s", err))
   156  		return 1
   157  	}
   158  
   159  	c.Ui.Output(fmt.Sprintf("Successfully wrote %q ACL policy!",
   160  		policyName))
   161  	return 0
   162  }