mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-08-03 12:36:09 -04:00
Move instanceType from CLI to config
This commit is contained in:
parent
91d2c8ae73
commit
0aefe2c0ba
10 changed files with 269 additions and 217 deletions
|
@ -1,78 +0,0 @@
|
|||
package azure
|
||||
|
||||
// CVMInstanceTypes are valid Azure CVM instance types.
|
||||
var CVMInstanceTypes = []string{
|
||||
// CVMs (3rd Generation EPYC 7763v processors)
|
||||
// DCasv5-series
|
||||
"Standard_DC4as_v5",
|
||||
"Standard_DC8as_v5",
|
||||
"Standard_DC16as_v5",
|
||||
"Standard_DC32as_v5",
|
||||
"Standard_DC48as_v5",
|
||||
"Standard_DC64as_v5",
|
||||
"Standard_DC96as_v5",
|
||||
// DCadsv5-series
|
||||
"Standard_DC4ads_v5",
|
||||
"Standard_DC8ads_v5",
|
||||
"Standard_DC16ads_v5",
|
||||
"Standard_DC32ads_v5",
|
||||
"Standard_DC48ads_v5",
|
||||
"Standard_DC64ads_v5",
|
||||
"Standard_DC96ads_v5",
|
||||
// ECasv5-series
|
||||
"Standard_EC4as_v5",
|
||||
"Standard_EC8as_v5",
|
||||
"Standard_EC16as_v5",
|
||||
"Standard_EC20as_v5",
|
||||
"Standard_EC32as_v5",
|
||||
"Standard_EC48as_v5",
|
||||
"Standard_EC64as_v5",
|
||||
"Standard_EC96as_v5",
|
||||
// ECadsv5-series
|
||||
"Standard_EC4ads_v5",
|
||||
"Standard_EC8ads_v5",
|
||||
"Standard_EC16ads_v5",
|
||||
"Standard_EC20ads_v5",
|
||||
"Standard_EC32ads_v5",
|
||||
"Standard_EC48ads_v5",
|
||||
"Standard_EC64ads_v5",
|
||||
"Standard_EC96ads_v5",
|
||||
}
|
||||
|
||||
// TrustedLaunchInstanceTypes are valid Azure Trusted Launch instance types.
|
||||
var TrustedLaunchInstanceTypes = []string{
|
||||
// Trusted Launch (2nd Generation AMD EPYC 7452 or 3rd Generation EPYC 7763v processors)
|
||||
// Dav4-series
|
||||
"Standard_D4a_v4",
|
||||
"Standard_D8a_v4",
|
||||
"Standard_D16a_v4",
|
||||
"Standard_D32a_v4",
|
||||
"Standard_D48a_v4",
|
||||
"Standard_D64a_v4",
|
||||
"Standard_D96a_v4",
|
||||
// Dasv4-series
|
||||
"Standard_D4as_v4",
|
||||
"Standard_D8as_v4",
|
||||
"Standard_D16as_v4",
|
||||
"Standard_D32as_v4",
|
||||
"Standard_D48as_v4",
|
||||
"Standard_D64as_v4",
|
||||
"Standard_D96as_v4",
|
||||
// Eav4-series
|
||||
"Standard_E4a_v4",
|
||||
"Standard_E8a_v4",
|
||||
"Standard_E16a_v4",
|
||||
"Standard_E32a_v4",
|
||||
"Standard_E48a_v4",
|
||||
"Standard_E64a_v4",
|
||||
"Standard_E96a_v4",
|
||||
// Easv4-series
|
||||
"Standard_E4as_v4",
|
||||
"Standard_E8as_v4",
|
||||
"Standard_E16as_v4",
|
||||
"Standard_E20as_v4",
|
||||
"Standard_E32as_v4",
|
||||
"Standard_E48as_v4",
|
||||
"Standard_E64as_v4",
|
||||
"Standard_E96as_v4",
|
||||
}
|
|
@ -5,9 +5,7 @@ import (
|
|||
"fmt"
|
||||
"io/fs"
|
||||
|
||||
"github.com/edgelesssys/constellation/cli/internal/azure"
|
||||
"github.com/edgelesssys/constellation/cli/internal/cloudcmd"
|
||||
"github.com/edgelesssys/constellation/cli/internal/gcp"
|
||||
"github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/internal/constants"
|
||||
"github.com/edgelesssys/constellation/internal/file"
|
||||
|
@ -36,20 +34,6 @@ func NewCreateCmd() *cobra.Command {
|
|||
must(cobra.MarkFlagRequired(cmd.Flags(), "control-plane-nodes"))
|
||||
cmd.Flags().IntP("worker-nodes", "w", 0, "number of worker nodes (required)")
|
||||
must(cobra.MarkFlagRequired(cmd.Flags(), "worker-nodes"))
|
||||
cmd.Flags().StringP("instance-type", "t", "", "instance type of cluster nodes")
|
||||
must(cmd.RegisterFlagCompletionFunc("instance-type", instanceTypeCompletion))
|
||||
|
||||
cmd.SetHelpTemplate(cmd.HelpTemplate() + fmt.Sprintf(`
|
||||
Azure Confidential VM instance types:
|
||||
%v
|
||||
|
||||
Azure Trusted Launch instance types:
|
||||
%v
|
||||
|
||||
GCP instance types:
|
||||
%v
|
||||
`, formatInstanceTypes(azure.CVMInstanceTypes), formatInstanceTypes(azure.TrustedLaunchInstanceTypes), formatInstanceTypes(gcp.InstanceTypes)))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -63,7 +47,7 @@ func runCreate(cmd *cobra.Command, args []string) error {
|
|||
|
||||
func create(cmd *cobra.Command, creator cloudCreator, fileHandler file.Handler, provider cloudprovider.Provider,
|
||||
) (retErr error) {
|
||||
flags, err := parseCreateFlags(cmd, provider)
|
||||
flags, err := parseCreateFlags(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -85,11 +69,19 @@ func create(cmd *cobra.Command, creator cloudCreator, fileHandler file.Handler,
|
|||
cmd.Println("Disabling Confidential VMs is insecure. Use only for evaluation purposes.")
|
||||
}
|
||||
|
||||
var instanceType string
|
||||
switch provider {
|
||||
case cloudprovider.Azure:
|
||||
instanceType = config.Provider.Azure.InstanceType
|
||||
case cloudprovider.GCP:
|
||||
instanceType = config.Provider.GCP.InstanceType
|
||||
}
|
||||
|
||||
if !flags.yes {
|
||||
// Ask user to confirm action.
|
||||
cmd.Printf("The following Constellation cluster will be created:\n")
|
||||
cmd.Printf("%d control-planes nodes of type %s will be created.\n", flags.controllerCount, flags.insType)
|
||||
cmd.Printf("%d worker nodes of type %s will be created.\n", flags.workerCount, flags.insType)
|
||||
cmd.Printf("%d control-planes nodes of type %s will be created.\n", flags.controllerCount, instanceType)
|
||||
cmd.Printf("%d worker nodes of type %s will be created.\n", flags.workerCount, instanceType)
|
||||
ok, err := askToConfirm(cmd, "Do you want to create this cluster?")
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -100,7 +92,7 @@ func create(cmd *cobra.Command, creator cloudCreator, fileHandler file.Handler,
|
|||
}
|
||||
}
|
||||
|
||||
state, err := creator.Create(cmd.Context(), provider, config, flags.name, flags.insType, flags.controllerCount, flags.workerCount)
|
||||
state, err := creator.Create(cmd.Context(), provider, config, flags.name, instanceType, flags.controllerCount, flags.workerCount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -118,7 +110,7 @@ func create(cmd *cobra.Command, creator cloudCreator, fileHandler file.Handler,
|
|||
}
|
||||
|
||||
// parseCreateFlags parses the flags of the create command.
|
||||
func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (createFlags, error) {
|
||||
func parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
|
||||
controllerCount, err := cmd.Flags().GetInt("control-plane-nodes")
|
||||
if err != nil {
|
||||
return createFlags{}, fmt.Errorf("parsing number of control-plane nodes: %w", err)
|
||||
|
@ -135,17 +127,6 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
|
|||
return createFlags{}, fmt.Errorf("number of worker nodes must be at least %d", constants.MinWorkerCount)
|
||||
}
|
||||
|
||||
insType, err := cmd.Flags().GetString("instance-type")
|
||||
if err != nil {
|
||||
return createFlags{}, fmt.Errorf("parsing instance type argument: %w", err)
|
||||
}
|
||||
if insType == "" {
|
||||
insType = defaultInstanceType(provider)
|
||||
}
|
||||
if err := validInstanceTypeForProvider(cmd, insType, provider); err != nil {
|
||||
return createFlags{}, err
|
||||
}
|
||||
|
||||
name, err := cmd.Flags().GetString("name")
|
||||
if err != nil {
|
||||
return createFlags{}, fmt.Errorf("parsing name argument: %w", err)
|
||||
|
@ -170,7 +151,6 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
|
|||
return createFlags{
|
||||
controllerCount: controllerCount,
|
||||
workerCount: workerCount,
|
||||
insType: insType,
|
||||
name: name,
|
||||
configPath: configPath,
|
||||
yes: yes,
|
||||
|
@ -181,24 +161,11 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
|
|||
type createFlags struct {
|
||||
controllerCount int
|
||||
workerCount int
|
||||
insType string
|
||||
name string
|
||||
configPath string
|
||||
yes bool
|
||||
}
|
||||
|
||||
// defaultInstanceType returns the default instance type for the given provider.
|
||||
func defaultInstanceType(provider cloudprovider.Provider) string {
|
||||
switch provider {
|
||||
case cloudprovider.GCP:
|
||||
return gcp.InstanceTypes[0]
|
||||
case cloudprovider.Azure:
|
||||
return azure.CVMInstanceTypes[0]
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// checkDirClean checks if files of a previous Constellation are left in the current working dir.
|
||||
func checkDirClean(fileHandler file.Handler) error {
|
||||
if _, err := fileHandler.Stat(constants.StateFilename); !errors.Is(err, fs.ErrNotExist) {
|
||||
|
@ -242,20 +209,3 @@ func must(err error) {
|
|||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func instanceTypeCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
if len(args) != 1 {
|
||||
return []string{}, cobra.ShellCompDirectiveError
|
||||
}
|
||||
switch args[0] {
|
||||
case "gcp":
|
||||
return gcp.InstanceTypes, cobra.ShellCompDirectiveNoFileComp
|
||||
case "azure":
|
||||
var azureInstanceTypes []string
|
||||
azureInstanceTypes = append(azureInstanceTypes, azure.CVMInstanceTypes...)
|
||||
azureInstanceTypes = append(azureInstanceTypes, azure.TrustedLaunchInstanceTypes...)
|
||||
return azureInstanceTypes, cobra.ShellCompDirectiveNoFileComp
|
||||
default:
|
||||
return []string{}, cobra.ShellCompDirectiveError
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/cli/internal/azure"
|
||||
"github.com/edgelesssys/constellation/cli/internal/gcp"
|
||||
"github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/internal/constants"
|
||||
"github.com/edgelesssys/constellation/internal/file"
|
||||
|
@ -56,7 +54,6 @@ func TestCreate(t *testing.T) {
|
|||
yesFlag bool
|
||||
controllerCountFlag *int
|
||||
workerCountFlag *int
|
||||
insTypeFlag string
|
||||
configFlag string
|
||||
nameFlag string
|
||||
stdin string
|
||||
|
@ -136,15 +133,6 @@ func TestCreate(t *testing.T) {
|
|||
controllerCountFlag: intPtr(3),
|
||||
wantErr: true,
|
||||
},
|
||||
"flag invalid instance-type": {
|
||||
setupFs: func(require *require.Assertions) afero.Fs { return afero.NewMemMapFs() },
|
||||
creator: &stubCloudCreator{},
|
||||
provider: cloudprovider.GCP,
|
||||
controllerCountFlag: intPtr(1),
|
||||
workerCountFlag: intPtr(1),
|
||||
insTypeFlag: "invalid",
|
||||
wantErr: true,
|
||||
},
|
||||
"old state in directory": {
|
||||
setupFs: func(require *require.Assertions) afero.Fs {
|
||||
fs := afero.NewMemMapFs()
|
||||
|
@ -245,9 +233,6 @@ func TestCreate(t *testing.T) {
|
|||
if tc.workerCountFlag != nil {
|
||||
require.NoError(cmd.Flags().Set("worker-nodes", strconv.Itoa(*tc.workerCountFlag)))
|
||||
}
|
||||
if tc.insTypeFlag != "" {
|
||||
require.NoError(cmd.Flags().Set("instance-type", tc.insTypeFlag))
|
||||
}
|
||||
|
||||
fileHandler := file.NewHandler(tc.setupFs(require))
|
||||
|
||||
|
@ -353,47 +338,6 @@ func TestCreateCompletion(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestInstanceTypeCompletion(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
args []string
|
||||
wantResult []string
|
||||
wantShellCD cobra.ShellCompDirective
|
||||
}{
|
||||
"azure": {
|
||||
args: []string{"azure"},
|
||||
wantResult: append(append([]string{}, azure.CVMInstanceTypes...), azure.TrustedLaunchInstanceTypes...),
|
||||
wantShellCD: cobra.ShellCompDirectiveNoFileComp,
|
||||
},
|
||||
"gcp": {
|
||||
args: []string{"gcp"},
|
||||
wantResult: gcp.InstanceTypes,
|
||||
wantShellCD: cobra.ShellCompDirectiveNoFileComp,
|
||||
},
|
||||
"empty args": {
|
||||
args: []string{},
|
||||
wantResult: []string{},
|
||||
wantShellCD: cobra.ShellCompDirectiveError,
|
||||
},
|
||||
"unknown provider": {
|
||||
args: []string{"foo"},
|
||||
wantResult: []string{},
|
||||
wantShellCD: cobra.ShellCompDirectiveError,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
cmd := &cobra.Command{}
|
||||
result, shellCD := instanceTypeCompletion(cmd, tc.args, "")
|
||||
|
||||
assert.Equal(tc.wantResult, result)
|
||||
assert.Equal(tc.wantShellCD, shellCD)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func intPtr(i int) *int {
|
||||
return &i
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
package cmd
|
||||
|
||||
import "strings"
|
||||
|
||||
func formatInstanceTypes(types []string) string {
|
||||
return " " + strings.Join(types, "\n ")
|
||||
}
|
|
@ -4,8 +4,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/edgelesssys/constellation/cli/internal/azure"
|
||||
"github.com/edgelesssys/constellation/cli/internal/gcp"
|
||||
"github.com/edgelesssys/constellation/internal/cloud/cloudprovider"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -28,34 +26,3 @@ func isCloudProvider(arg int) cobra.PositionalArgs {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func validInstanceTypeForProvider(cmd *cobra.Command, insType string, provider cloudprovider.Provider) error {
|
||||
switch provider {
|
||||
case cloudprovider.GCP:
|
||||
for _, instanceType := range gcp.InstanceTypes {
|
||||
if insType == instanceType {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
cmd.SetUsageTemplate("GCP instance types:\n" + formatInstanceTypes(gcp.InstanceTypes))
|
||||
cmd.SilenceUsage = false
|
||||
return fmt.Errorf("%s isn't a valid GCP instance type", insType)
|
||||
case cloudprovider.Azure:
|
||||
for _, instanceType := range azure.CVMInstanceTypes {
|
||||
if insType == instanceType {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
for _, instanceType := range azure.TrustedLaunchInstanceTypes {
|
||||
if insType == instanceType {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
cmd.SetUsageTemplate("Azure CVM instance types:\n" + formatInstanceTypes(azure.CVMInstanceTypes) +
|
||||
"\n\nAzure Trusted Launch instance types:\n" + formatInstanceTypes(azure.TrustedLaunchInstanceTypes))
|
||||
cmd.SilenceUsage = false
|
||||
return fmt.Errorf("%s isn't a valid Azure instance type", insType)
|
||||
default:
|
||||
return fmt.Errorf("%s isn't a valid cloud platform", provider)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
package gcp
|
||||
|
||||
// InstanceTypes are valid GCP instance types.
|
||||
var InstanceTypes = []string{
|
||||
"n2d-standard-4",
|
||||
"n2d-standard-8",
|
||||
"n2d-standard-16",
|
||||
"n2d-standard-32",
|
||||
"n2d-standard-48",
|
||||
"n2d-standard-64",
|
||||
"n2d-standard-80",
|
||||
"n2d-standard-96",
|
||||
"n2d-standard-128",
|
||||
"n2d-standard-424",
|
||||
"n2d-highmem-4",
|
||||
"n2d-highmem-8",
|
||||
"n2d-highmem-16",
|
||||
"n2d-highmem-32",
|
||||
"n2d-highmem-48",
|
||||
"n2d-highmem-64",
|
||||
"n2d-highmem-80",
|
||||
"n2d-highmem-96",
|
||||
"n2d-highcpu-4",
|
||||
"n2d-highcpu-8",
|
||||
"n2d-highcpu-16",
|
||||
"n2d-highcpu-32",
|
||||
"n2d-highcpu-48",
|
||||
"n2d-highcpu-64",
|
||||
"n2d-highcpu-80",
|
||||
"n2d-highcpu-96",
|
||||
"n2d-highcpu-128",
|
||||
"n2d-highcpu-224",
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue