2023-04-10 15:36:59 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2017-10-13 21:36:02 +00:00
|
|
|
package command
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/posener/complete"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// DefaultHclQuotaInitName is the default name we use when initializing the
|
|
|
|
// example quota file in HCL format
|
|
|
|
DefaultHclQuotaInitName = "spec.hcl"
|
|
|
|
|
|
|
|
// DefaultHclQuotaInitName is the default name we use when initializing the
|
|
|
|
// example quota file in JSON format
|
|
|
|
DefaultJsonQuotaInitName = "spec.json"
|
|
|
|
)
|
|
|
|
|
|
|
|
// QuotaInitCommand generates a new quota spec that you can customize to your
|
|
|
|
// liking, like vagrant init
|
|
|
|
type QuotaInitCommand struct {
|
|
|
|
Meta
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *QuotaInitCommand) Help() string {
|
|
|
|
helpText := `
|
2021-04-18 18:14:05 +00:00
|
|
|
Usage: nomad quota init <filename>
|
2017-10-13 21:36:02 +00:00
|
|
|
|
|
|
|
Creates an example quota specification file that can be used as a starting
|
2021-04-18 18:14:05 +00:00
|
|
|
point to customize further. If no filename is given, the default of "spec.hcl"
|
|
|
|
or "spec.json" will be used.
|
2017-10-13 21:36:02 +00:00
|
|
|
|
|
|
|
Init Options:
|
|
|
|
|
|
|
|
-json
|
2018-04-18 16:02:11 +00:00
|
|
|
Create an example JSON quota specification.
|
2017-10-13 21:36:02 +00:00
|
|
|
`
|
|
|
|
return strings.TrimSpace(helpText)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *QuotaInitCommand) Synopsis() string {
|
|
|
|
return "Create an example quota specification file"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *QuotaInitCommand) AutocompleteFlags() complete.Flags {
|
|
|
|
return complete.Flags{
|
|
|
|
"-json": complete.PredictNothing,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *QuotaInitCommand) AutocompleteArgs() complete.Predictor {
|
|
|
|
return complete.PredictNothing
|
|
|
|
}
|
|
|
|
|
2018-04-18 16:02:11 +00:00
|
|
|
func (c *QuotaInitCommand) Name() string { return "quota init" }
|
|
|
|
|
2017-10-13 21:36:02 +00:00
|
|
|
func (c *QuotaInitCommand) Run(args []string) int {
|
|
|
|
var jsonOutput bool
|
2018-04-18 16:02:11 +00:00
|
|
|
flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
|
2017-10-13 21:36:02 +00:00
|
|
|
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
|
|
|
flags.BoolVar(&jsonOutput, "json", false, "")
|
|
|
|
|
|
|
|
if err := flags.Parse(args); err != nil {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that we get no arguments
|
|
|
|
args = flags.Args()
|
2021-04-18 18:14:05 +00:00
|
|
|
if l := len(args); l > 1 {
|
|
|
|
c.Ui.Error("This command takes no arguments or one: <filename>")
|
2018-04-18 16:02:11 +00:00
|
|
|
c.Ui.Error(commandErrorText(c))
|
2017-10-13 21:36:02 +00:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
fileName := DefaultHclQuotaInitName
|
|
|
|
fileContent := defaultHclQuotaSpec
|
|
|
|
if jsonOutput {
|
|
|
|
fileName = DefaultJsonQuotaInitName
|
|
|
|
fileContent = defaultJsonQuotaSpec
|
|
|
|
}
|
2021-04-18 18:14:05 +00:00
|
|
|
if len(args) == 1 {
|
|
|
|
fileName = args[0]
|
|
|
|
}
|
2017-10-13 21:36:02 +00:00
|
|
|
|
|
|
|
// Check if the file already exists
|
|
|
|
_, err := os.Stat(fileName)
|
|
|
|
if err != nil && !os.IsNotExist(err) {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Failed to stat %q: %v", fileName, err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
if !os.IsNotExist(err) {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Quota specification %q already exists", fileName))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write out the example
|
2023-03-08 15:20:04 +00:00
|
|
|
err = os.WriteFile(fileName, []byte(fileContent), 0660)
|
2017-10-13 21:36:02 +00:00
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Failed to write %q: %v", fileName, err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// Success
|
|
|
|
c.Ui.Output(fmt.Sprintf("Example quota specification written to %s", fileName))
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
var defaultHclQuotaSpec = strings.TrimSpace(`
|
2021-04-30 13:48:03 +00:00
|
|
|
name = "default-quota"
|
2017-10-13 21:36:02 +00:00
|
|
|
description = "Limit the shared default namespace"
|
|
|
|
|
|
|
|
# Create a limit for the global region. Additional limits may
|
|
|
|
# be specified in-order to limit other regions.
|
|
|
|
limit {
|
2021-04-30 13:48:03 +00:00
|
|
|
region = "global"
|
|
|
|
region_limit {
|
|
|
|
cpu = 2500
|
|
|
|
memory = 1000
|
|
|
|
memory_max = 1000
|
|
|
|
}
|
2022-08-26 18:03:56 +00:00
|
|
|
variables_limit = 1000
|
2017-10-13 21:36:02 +00:00
|
|
|
}
|
|
|
|
`)
|
|
|
|
|
|
|
|
var defaultJsonQuotaSpec = strings.TrimSpace(`
|
|
|
|
{
|
|
|
|
"Name": "default-quota",
|
|
|
|
"Description": "Limit the shared default namespace",
|
|
|
|
"Limits": [
|
|
|
|
{
|
|
|
|
"Region": "global",
|
|
|
|
"RegionLimit": {
|
|
|
|
"CPU": 2500,
|
2021-04-30 13:48:03 +00:00
|
|
|
"MemoryMB": 1000,
|
|
|
|
"MemoryMaxMB": 1000
|
2022-08-02 13:32:09 +00:00
|
|
|
},
|
2022-08-26 18:03:56 +00:00
|
|
|
"VariablesLimit": 1000
|
2017-10-13 21:36:02 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
`)
|