init: create kubeconfig file with unique user/cluster name (#1133)

* Generate kubeconfig with unique name

* Move create name flag to config

* Add name validation to config

* Move name flag in e2e tests to config generation

* Remove name flag from create

* Update ascii cinema flow

---------

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2023-02-10 13:27:22 +01:00 committed by GitHub
parent fd860ddb91
commit c29107f5be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 359 additions and 436 deletions

View file

@ -53,7 +53,7 @@ func NewCreator(out io.Writer) *Creator {
}
// Create creates the handed amount of instances and all the needed resources.
func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, config *config.Config, name, insType string, controlPlaneCount, workerCount int,
func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, config *config.Config, insType string, controlPlaneCount, workerCount int,
) (clusterid.File, error) {
image, err := c.image.FetchReference(ctx, config)
if err != nil {
@ -67,21 +67,21 @@ func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, c
return clusterid.File{}, err
}
defer cl.RemoveInstaller()
return c.createAWS(ctx, cl, config, name, insType, controlPlaneCount, workerCount, image)
return c.createAWS(ctx, cl, config, insType, controlPlaneCount, workerCount, image)
case cloudprovider.GCP:
cl, err := c.newTerraformClient(ctx)
if err != nil {
return clusterid.File{}, err
}
defer cl.RemoveInstaller()
return c.createGCP(ctx, cl, config, name, insType, controlPlaneCount, workerCount, image)
return c.createGCP(ctx, cl, config, insType, controlPlaneCount, workerCount, image)
case cloudprovider.Azure:
cl, err := c.newTerraformClient(ctx)
if err != nil {
return clusterid.File{}, err
}
defer cl.RemoveInstaller()
return c.createAzure(ctx, cl, config, name, insType, controlPlaneCount, workerCount, image)
return c.createAzure(ctx, cl, config, insType, controlPlaneCount, workerCount, image)
case cloudprovider.QEMU:
if runtime.GOARCH != "amd64" || runtime.GOOS != "linux" {
return clusterid.File{}, fmt.Errorf("creation of a QEMU based Constellation is not supported for %s/%s", runtime.GOOS, runtime.GOARCH)
@ -92,18 +92,18 @@ func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, c
}
defer cl.RemoveInstaller()
lv := c.newLibvirtRunner()
return c.createQEMU(ctx, cl, lv, name, config, controlPlaneCount, workerCount, image)
return c.createQEMU(ctx, cl, lv, config, controlPlaneCount, workerCount, image)
default:
return clusterid.File{}, fmt.Errorf("unsupported cloud provider: %s", provider)
}
}
func (c *Creator) createAWS(ctx context.Context, cl terraformClient, config *config.Config,
name, insType string, controlPlaneCount, workerCount int, image string,
insType string, controlPlaneCount, workerCount int, image string,
) (idFile clusterid.File, retErr error) {
vars := terraform.AWSClusterVariables{
CommonVariables: terraform.CommonVariables{
Name: name,
Name: config.Name,
CountControlPlanes: controlPlaneCount,
CountWorkers: workerCount,
StateDiskSizeGB: config.StateDiskSizeGB,
@ -137,11 +137,11 @@ func (c *Creator) createAWS(ctx context.Context, cl terraformClient, config *con
}
func (c *Creator) createGCP(ctx context.Context, cl terraformClient, config *config.Config,
name, insType string, controlPlaneCount, workerCount int, image string,
insType string, controlPlaneCount, workerCount int, image string,
) (idFile clusterid.File, retErr error) {
vars := terraform.GCPClusterVariables{
CommonVariables: terraform.CommonVariables{
Name: name,
Name: config.Name,
CountControlPlanes: controlPlaneCount,
CountWorkers: workerCount,
StateDiskSizeGB: config.StateDiskSizeGB,
@ -175,11 +175,11 @@ func (c *Creator) createGCP(ctx context.Context, cl terraformClient, config *con
}
func (c *Creator) createAzure(ctx context.Context, cl terraformClient, config *config.Config,
name, insType string, controlPlaneCount, workerCount int, image string,
insType string, controlPlaneCount, workerCount int, image string,
) (idFile clusterid.File, retErr error) {
vars := terraform.AzureClusterVariables{
CommonVariables: terraform.CommonVariables{
Name: name,
Name: config.Name,
CountControlPlanes: controlPlaneCount,
CountWorkers: workerCount,
StateDiskSizeGB: config.StateDiskSizeGB,
@ -241,7 +241,7 @@ func normalizeAzureURIs(vars terraform.AzureClusterVariables) terraform.AzureClu
return vars
}
func (c *Creator) createQEMU(ctx context.Context, cl terraformClient, lv libvirtRunner, name string, config *config.Config,
func (c *Creator) createQEMU(ctx context.Context, cl terraformClient, lv libvirtRunner, config *config.Config,
controlPlaneCount, workerCount int, source string,
) (idFile clusterid.File, retErr error) {
qemuRollbacker := &rollbackerQEMU{client: cl, libvirt: lv, createdWorkspace: false}
@ -260,7 +260,7 @@ func (c *Creator) createQEMU(ctx context.Context, cl terraformClient, lv libvirt
switch {
// if no libvirt URI is specified, start a libvirt container
case libvirtURI == "":
if err := lv.Start(ctx, name, config.Provider.QEMU.LibvirtContainerImage); err != nil {
if err := lv.Start(ctx, config.Name, config.Provider.QEMU.LibvirtContainerImage); err != nil {
return clusterid.File{}, err
}
libvirtURI = libvirt.LibvirtTCPConnectURI
@ -292,7 +292,7 @@ func (c *Creator) createQEMU(ctx context.Context, cl terraformClient, lv libvirt
vars := terraform.QEMUVariables{
CommonVariables: terraform.CommonVariables{
Name: name,
Name: config.Name,
CountControlPlanes: controlPlaneCount,
CountWorkers: workerCount,
StateDiskSizeGB: config.StateDiskSizeGB,

View file

@ -114,7 +114,7 @@ func TestCreator(t *testing.T) {
},
}
idFile, err := creator.Create(context.Background(), tc.provider, tc.config, "name", "type", 2, 3)
idFile, err := creator.Create(context.Background(), tc.provider, tc.config, "type", 2, 3)
if tc.wantErr {
assert.Error(err)

View file

@ -21,7 +21,7 @@ type cloudCreator interface {
ctx context.Context,
provider cloudprovider.Provider,
config *config.Config,
name, insType string,
insType string,
coordCount, nodeCount int,
) (clusterid.File, error)
}

View file

@ -35,7 +35,7 @@ func (c *stubCloudCreator) Create(
ctx context.Context,
provider cloudprovider.Provider,
config *config.Config,
name, insType string,
insType string,
coordCount, nodeCount int,
) (clusterid.File, error) {
c.createCalled = true

View file

@ -41,12 +41,12 @@ func TestConfigGenerateDefaultGCPSpecific(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
wantConf := config.Default()
wantConf.RemoveProviderExcept(cloudprovider.GCP)
fileHandler := file.NewHandler(afero.NewMemMapFs())
cmd := newConfigGenerateCmd()
wantConf := config.Default()
wantConf.RemoveProviderExcept(cloudprovider.GCP)
cg := &configGenerateCmd{log: logger.NewTest(t)}
require.NoError(cg.configGenerate(cmd, fileHandler, cloudprovider.GCP))

View file

@ -30,7 +30,6 @@ func NewCreateCmd() *cobra.Command {
Args: cobra.ExactArgs(0),
RunE: runCreate,
}
cmd.Flags().String("name", "constell", "create the cluster with the specified name")
cmd.Flags().BoolP("yes", "y", false, "create the cluster without further confirmation")
cmd.Flags().IntP("control-plane-nodes", "c", 0, "number of control-plane nodes (required)")
must(cobra.MarkFlagRequired(cmd.Flags(), "control-plane-nodes"))
@ -110,9 +109,6 @@ func (c *createCmd) create(cmd *cobra.Command, creator cloudCreator, fileHandler
case cloudprovider.AWS:
c.log.Debugf("Configuring instance type for AWS")
instanceType = conf.Provider.AWS.InstanceType
if len(flags.name) > 10 {
return fmt.Errorf("cluster name on AWS must not be longer than 10 characters")
}
case cloudprovider.Azure:
c.log.Debugf("Configuring instance type for Azure")
instanceType = conf.Provider.Azure.InstanceType
@ -142,7 +138,7 @@ func (c *createCmd) create(cmd *cobra.Command, creator cloudCreator, fileHandler
}
spinner.Start("Creating", false)
idFile, err := creator.Create(cmd.Context(), provider, conf, flags.name, instanceType, flags.controllerCount, flags.workerCount)
idFile, err := creator.Create(cmd.Context(), provider, conf, instanceType, flags.controllerCount, flags.workerCount)
c.log.Debugf("Successfully created the cloud resources for the cluster")
spinner.Stop()
if err != nil {
@ -177,18 +173,6 @@ func (c *createCmd) parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
return createFlags{}, fmt.Errorf("number of worker nodes must be at least %d", constants.MinWorkerCount)
}
name, err := cmd.Flags().GetString("name")
if err != nil {
return createFlags{}, fmt.Errorf("parsing name argument: %w", err)
}
c.log.Debugf("Name flag is %q", name)
if len(name) > constants.ConstellationNameLength {
return createFlags{}, fmt.Errorf(
"name for Constellation cluster too long, maximum length is %d, got %d: %s",
constants.ConstellationNameLength, len(name), name,
)
}
yes, err := cmd.Flags().GetBool("yes")
if err != nil {
return createFlags{}, fmt.Errorf("%w; Set '-yes' without a value to automatically confirm", err)
@ -210,7 +194,6 @@ func (c *createCmd) parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
return createFlags{
controllerCount: controllerCount,
workerCount: workerCount,
name: name,
configPath: configPath,
force: force,
yes: yes,
@ -221,7 +204,6 @@ func (c *createCmd) parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
type createFlags struct {
controllerCount int
workerCount int
name string
configPath string
force bool
yes bool

View file

@ -10,7 +10,6 @@ import (
"bytes"
"errors"
"strconv"
"strings"
"testing"
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
@ -42,7 +41,6 @@ func TestCreate(t *testing.T) {
controllerCountFlag *int
workerCountFlag *int
configFlag string
nameFlag string
stdin string
wantErr bool
wantAbort bool
@ -81,15 +79,6 @@ func TestCreate(t *testing.T) {
stdin: "foo\nfoo\nfoo\n",
wantErr: true,
},
"flag name to long": {
setupFs: fsWithDefaultConfig,
creator: &stubCloudCreator{},
provider: cloudprovider.GCP,
controllerCountFlag: intPtr(1),
workerCountFlag: intPtr(1),
nameFlag: strings.Repeat("a", constants.ConstellationNameLength+1),
wantErr: true,
},
"flag control-plane-count invalid": {
setupFs: fsWithDefaultConfig,
creator: &stubCloudCreator{},
@ -200,9 +189,6 @@ func TestCreate(t *testing.T) {
if tc.yesFlag {
require.NoError(cmd.Flags().Set("yes", "true"))
}
if tc.nameFlag != "" {
require.NoError(cmd.Flags().Set("name", tc.nameFlag))
}
if tc.configFlag != "" {
require.NoError(cmd.Flags().Set("config", tc.configFlag))
}

View file

@ -226,6 +226,7 @@ func TestIAMCreateAWS(t *testing.T) {
cmd.Flags().String("config", constants.ConfigFilename, "") // register persistent flag manually
cmd.Flags().Bool("generate-config", false, "") // register persistent flag manually
cmd.Flags().Bool("yes", false, "") // register persistent flag manually
cmd.Flags().String("name", "constell", "") // register persistent flag manually
if tc.zoneFlag != "" {
require.NoError(cmd.Flags().Set("zone", tc.zoneFlag))
@ -446,7 +447,8 @@ func TestIAMCreateAzure(t *testing.T) {
cmd.Flags().String("config", constants.ConfigFilename, "") // register persistent flag manually
cmd.Flags().Bool("generate-config", false, "") // register persistent flag manually
cmd.Flags().Bool("yes", false, "") // register persistent flag
cmd.Flags().Bool("yes", false, "") // register persistent flag manually
cmd.Flags().String("name", "constell", "") // register persistent flag manually
if tc.regionFlag != "" {
require.NoError(cmd.Flags().Set("region", tc.regionFlag))
@ -694,7 +696,8 @@ func TestIAMCreateGCP(t *testing.T) {
cmd.Flags().String("config", constants.ConfigFilename, "") // register persistent flag manually
cmd.Flags().Bool("generate-config", false, "") // register persistent flag manually
cmd.Flags().Bool("yes", false, "") // register persistent flag
cmd.Flags().Bool("yes", false, "") // register persistent flag manually
cmd.Flags().String("name", "constell", "") // register persistent flag manually
if tc.zoneFlag != "" {
require.NoError(cmd.Flags().Set("zone", tc.zoneFlag))

View file

@ -137,11 +137,14 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator *cloud
helmLoader := helm.NewLoader(provider, k8sVersion)
i.log.Debugf("Created new Helm loader")
helmDeployments, err := helmLoader.Load(conf, flags.conformance, masterSecret.Key, masterSecret.Salt)
i.log.Debugf("Loaded Helm heployments")
i.log.Debugf("Loaded Helm deployments")
if err != nil {
return fmt.Errorf("loading Helm charts: %w", err)
}
clusterName := conf.Name + "-" + idFile.UID
i.log.Debugf("Setting cluster name to %s", clusterName)
spinner.Start("Initializing cluster ", false)
req := &initproto.InitRequest{
MasterSecret: masterSecret.Key,
@ -158,6 +161,7 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator *cloud
EnforceIdkeydigest: conf.EnforcesIDKeyDigest(),
ConformanceMode: flags.conformance,
InitSecret: idFile.InitSecret,
ClusterName: clusterName,
}
i.log.Debugf("Sending initialization request")
resp, err := i.initCall(cmd.Context(), newDialer(validator), idFile.IP, req)

View file

@ -479,6 +479,7 @@ func defaultConfigWithExpectedMeasurements(t *testing.T, conf *config.Config, cs
t.Helper()
conf.Image = constants.VersionInfo
conf.Name = "kubernetes"
switch csp {
case cloudprovider.Azure:

View file

@ -213,6 +213,7 @@ func (m *miniUpCmd) prepareConfig(cmd *cobra.Command, fileHandler file.Handler)
}
config := config.Default()
config.Name = constants.MiniConstellationUID
config.RemoveProviderExcept(cloudprovider.QEMU)
config.StateDiskSizeGB = 8
m.log.Debugf("Prepared configuration")
@ -223,7 +224,7 @@ func (m *miniUpCmd) prepareConfig(cmd *cobra.Command, fileHandler file.Handler)
// createMiniCluster creates a new cluster using the given config.
func (m *miniUpCmd) createMiniCluster(ctx context.Context, fileHandler file.Handler, creator cloudCreator, config *config.Config) error {
m.log.Debugf("Creating mini cluster")
idFile, err := creator.Create(ctx, cloudprovider.QEMU, config, "mini", "", 1, 1)
idFile, err := creator.Create(ctx, cloudprovider.QEMU, config, "", 1, 1)
if err != nil {
return err
}