github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/command/volume_register.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/hashicorp/hcl"
    10  	"github.com/hashicorp/hcl/hcl/ast"
    11  	"github.com/posener/complete"
    12  )
    13  
    14  type VolumeRegisterCommand struct {
    15  	Meta
    16  }
    17  
    18  func (c *VolumeRegisterCommand) Help() string {
    19  	helpText := `
    20  Usage: nomad volume register [options] <input>
    21  
    22    Creates or updates a volume in Nomad. The volume must exist on the remote
    23    storage provider before it can be used by a task.
    24  
    25    If the supplied path is "-" the volume file is read from stdin. Otherwise, it
    26    is read from the file at the supplied path.
    27  
    28  General Options:
    29  
    30    ` + generalOptionsUsage()
    31  
    32  	return strings.TrimSpace(helpText)
    33  }
    34  
    35  func (c *VolumeRegisterCommand) AutocompleteFlags() complete.Flags {
    36  	return c.Meta.AutocompleteFlags(FlagSetClient)
    37  }
    38  
    39  func (c *VolumeRegisterCommand) AutocompleteArgs() complete.Predictor {
    40  	return complete.PredictFiles("*")
    41  }
    42  
    43  func (c *VolumeRegisterCommand) Synopsis() string {
    44  	return "Create or update a volume"
    45  }
    46  
    47  func (c *VolumeRegisterCommand) Name() string { return "volume register" }
    48  
    49  func (c *VolumeRegisterCommand) Run(args []string) int {
    50  	flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
    51  	flags.Usage = func() { c.Ui.Output(c.Help()) }
    52  
    53  	if err := flags.Parse(args); err != nil {
    54  		c.Ui.Error(fmt.Sprintf("Error parsing arguments %s", err))
    55  		return 1
    56  	}
    57  
    58  	// Check that we get exactly one argument
    59  	args = flags.Args()
    60  	if l := len(args); l != 1 {
    61  		c.Ui.Error("This command takes one argument: <input>")
    62  		c.Ui.Error(commandErrorText(c))
    63  		return 1
    64  	}
    65  
    66  	// Read the file contents
    67  	file := args[0]
    68  	var rawVolume []byte
    69  	var err error
    70  	if file == "-" {
    71  		rawVolume, err = ioutil.ReadAll(os.Stdin)
    72  		if err != nil {
    73  			c.Ui.Error(fmt.Sprintf("Failed to read stdin: %v", err))
    74  			return 1
    75  		}
    76  	} else {
    77  		rawVolume, err = ioutil.ReadFile(file)
    78  		if err != nil {
    79  			c.Ui.Error(fmt.Sprintf("Failed to read file: %v", err))
    80  			return 1
    81  		}
    82  	}
    83  
    84  	ast, volType, err := parseVolumeType(string(rawVolume))
    85  	if err != nil {
    86  		c.Ui.Error(fmt.Sprintf("Error parsing the volume type: %s", err))
    87  		return 1
    88  	}
    89  	volType = strings.ToLower(volType)
    90  
    91  	// Get the HTTP client
    92  	client, err := c.Meta.Client()
    93  	if err != nil {
    94  		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
    95  		return 1
    96  	}
    97  
    98  	switch volType {
    99  	case "csi":
   100  		code := c.csiRegister(client, ast)
   101  		if code != 0 {
   102  			return code
   103  		}
   104  	default:
   105  		c.Ui.Error(fmt.Sprintf("Error unknown volume type: %s", volType))
   106  		return 1
   107  	}
   108  
   109  	return 0
   110  }
   111  
   112  // parseVolume is used to parse the quota specification from HCL
   113  func parseVolumeType(input string) (*ast.File, string, error) {
   114  	// Parse the AST first
   115  	ast, err := hcl.Parse(input)
   116  	if err != nil {
   117  		return nil, "", fmt.Errorf("parse error: %v", err)
   118  	}
   119  
   120  	// Decode the type, so we can dispatch on it
   121  	dispatch := &struct {
   122  		T string `hcl:"type"`
   123  	}{}
   124  	err = hcl.DecodeObject(dispatch, ast)
   125  	if err != nil {
   126  		return nil, "", fmt.Errorf("dispatch error: %v", err)
   127  	}
   128  
   129  	return ast, dispatch.T, nil
   130  }