mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-11 00:44:20 -05:00
cli: remove TF ApplyOutput dependency in CLI (#2323)
This commit is contained in:
parent
322c4aad10
commit
4680882708
@ -33,7 +33,7 @@ type tfCommonClient interface {
|
|||||||
|
|
||||||
type tfResourceClient interface {
|
type tfResourceClient interface {
|
||||||
tfCommonClient
|
tfCommonClient
|
||||||
ApplyCluster(ctx context.Context, provider cloudprovider.Provider, logLevel terraform.LogLevel) (terraform.ApplyOutput, error)
|
ApplyCluster(ctx context.Context, provider cloudprovider.Provider, logLevel terraform.LogLevel) (state.Infrastructure, error)
|
||||||
ShowInfrastructure(ctx context.Context, provider cloudprovider.Provider) (state.Infrastructure, error)
|
ShowInfrastructure(ctx context.Context, provider cloudprovider.Provider) (state.Infrastructure, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ type tfIAMUpgradeClient interface {
|
|||||||
|
|
||||||
type tfClusterUpgradeClient interface {
|
type tfClusterUpgradeClient interface {
|
||||||
tfUpgradePlanner
|
tfUpgradePlanner
|
||||||
ApplyCluster(ctx context.Context, provider cloudprovider.Provider, logLevel terraform.LogLevel) (terraform.ApplyOutput, error)
|
ApplyCluster(ctx context.Context, provider cloudprovider.Provider, logLevel terraform.LogLevel) (state.Infrastructure, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type libvirtRunner interface {
|
type libvirtRunner interface {
|
||||||
|
@ -45,12 +45,12 @@ type stubTerraformClient struct {
|
|||||||
showErr error
|
showErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *stubTerraformClient) ApplyCluster(_ context.Context, _ cloudprovider.Provider, _ terraform.LogLevel) (terraform.ApplyOutput, error) {
|
func (c *stubTerraformClient) ApplyCluster(_ context.Context, _ cloudprovider.Provider, _ terraform.LogLevel) (state.Infrastructure, error) {
|
||||||
return terraform.ApplyOutput{
|
return state.Infrastructure{
|
||||||
IP: c.ip,
|
ClusterEndpoint: c.ip,
|
||||||
Secret: c.initSecret,
|
InitSecret: c.initSecret,
|
||||||
UID: c.uid,
|
UID: c.uid,
|
||||||
Azure: &terraform.AzureApplyOutput{
|
Azure: &state.Azure{
|
||||||
AttestationURL: c.attestationURL,
|
AttestationURL: c.attestationURL,
|
||||||
},
|
},
|
||||||
}, c.createClusterErr
|
}, c.createClusterErr
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/state"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
@ -70,16 +71,16 @@ func (u *ClusterUpgrader) RestoreClusterWorkspace() error {
|
|||||||
|
|
||||||
// ApplyClusterUpgrade applies the Terraform migrations planned by PlanClusterUpgrade.
|
// ApplyClusterUpgrade applies the Terraform migrations planned by PlanClusterUpgrade.
|
||||||
// On success, the workspace of the Upgrader replaces the existing Terraform workspace.
|
// On success, the workspace of the Upgrader replaces the existing Terraform workspace.
|
||||||
func (u *ClusterUpgrader) ApplyClusterUpgrade(ctx context.Context, csp cloudprovider.Provider) (terraform.ApplyOutput, error) {
|
func (u *ClusterUpgrader) ApplyClusterUpgrade(ctx context.Context, csp cloudprovider.Provider) (state.Infrastructure, error) {
|
||||||
tfOutput, err := u.tf.ApplyCluster(ctx, csp, u.logLevel)
|
infraState, err := u.tf.ApplyCluster(ctx, csp, u.logLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tfOutput, fmt.Errorf("terraform apply: %w", err)
|
return infraState, fmt.Errorf("terraform apply: %w", err)
|
||||||
}
|
}
|
||||||
if tfOutput.Azure != nil {
|
if infraState.Azure != nil {
|
||||||
if err := u.policyPatcher.Patch(ctx, tfOutput.Azure.AttestationURL); err != nil {
|
if err := u.policyPatcher.Patch(ctx, infraState.Azure.AttestationURL); err != nil {
|
||||||
return tfOutput, fmt.Errorf("patching policies: %w", err)
|
return infraState, fmt.Errorf("patching policies: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tfOutput, nil
|
return infraState, nil
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/edgelesssys/constellation/v2/cli/internal/state"
|
||||||
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
@ -194,8 +195,8 @@ func (t *tfClusterUpgradeStub) ShowPlan(_ context.Context, _ terraform.LogLevel,
|
|||||||
return t.showErr
|
return t.showErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tfClusterUpgradeStub) ApplyCluster(_ context.Context, _ cloudprovider.Provider, _ terraform.LogLevel) (terraform.ApplyOutput, error) {
|
func (t *tfClusterUpgradeStub) ApplyCluster(_ context.Context, _ cloudprovider.Provider, _ terraform.LogLevel) (state.Infrastructure, error) {
|
||||||
return terraform.ApplyOutput{}, t.applyErr
|
return state.Infrastructure{}, t.applyErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tfClusterUpgradeStub) PrepareUpgradeWorkspace(_, _ string, _ terraform.Variables) error {
|
func (t *tfClusterUpgradeStub) PrepareUpgradeWorkspace(_, _ string, _ terraform.Variables) error {
|
||||||
|
@ -80,20 +80,20 @@ func (c *Creator) Create(ctx context.Context, opts CreateOptions) (state.Infrast
|
|||||||
}
|
}
|
||||||
defer cl.RemoveInstaller()
|
defer cl.RemoveInstaller()
|
||||||
|
|
||||||
var tfOutput terraform.ApplyOutput
|
var infraState state.Infrastructure
|
||||||
switch opts.Provider {
|
switch opts.Provider {
|
||||||
case cloudprovider.AWS:
|
case cloudprovider.AWS:
|
||||||
|
|
||||||
tfOutput, err = c.createAWS(ctx, cl, opts)
|
infraState, err = c.createAWS(ctx, cl, opts)
|
||||||
case cloudprovider.GCP:
|
case cloudprovider.GCP:
|
||||||
|
|
||||||
tfOutput, err = c.createGCP(ctx, cl, opts)
|
infraState, err = c.createGCP(ctx, cl, opts)
|
||||||
case cloudprovider.Azure:
|
case cloudprovider.Azure:
|
||||||
|
|
||||||
tfOutput, err = c.createAzure(ctx, cl, opts)
|
infraState, err = c.createAzure(ctx, cl, opts)
|
||||||
case cloudprovider.OpenStack:
|
case cloudprovider.OpenStack:
|
||||||
|
|
||||||
tfOutput, err = c.createOpenStack(ctx, cl, opts)
|
infraState, err = c.createOpenStack(ctx, cl, opts)
|
||||||
case cloudprovider.QEMU:
|
case cloudprovider.QEMU:
|
||||||
if runtime.GOARCH != "amd64" || runtime.GOOS != "linux" {
|
if runtime.GOARCH != "amd64" || runtime.GOOS != "linux" {
|
||||||
return state.Infrastructure{}, fmt.Errorf("creation of a QEMU based Constellation is not supported for %s/%s", runtime.GOOS, runtime.GOARCH)
|
return state.Infrastructure{}, fmt.Errorf("creation of a QEMU based Constellation is not supported for %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
@ -104,7 +104,7 @@ func (c *Creator) Create(ctx context.Context, opts CreateOptions) (state.Infrast
|
|||||||
CreateOptions: opts,
|
CreateOptions: opts,
|
||||||
}
|
}
|
||||||
|
|
||||||
tfOutput, err = c.createQEMU(ctx, cl, lv, qemuOpts)
|
infraState, err = c.createQEMU(ctx, cl, lv, qemuOpts)
|
||||||
default:
|
default:
|
||||||
return state.Infrastructure{}, fmt.Errorf("unsupported cloud provider: %s", opts.Provider)
|
return state.Infrastructure{}, fmt.Errorf("unsupported cloud provider: %s", opts.Provider)
|
||||||
}
|
}
|
||||||
@ -112,46 +112,46 @@ func (c *Creator) Create(ctx context.Context, opts CreateOptions) (state.Infrast
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return state.Infrastructure{}, fmt.Errorf("creating cluster: %w", err)
|
return state.Infrastructure{}, fmt.Errorf("creating cluster: %w", err)
|
||||||
}
|
}
|
||||||
return terraform.ConvertToInfrastructure(tfOutput), nil
|
return infraState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Creator) createAWS(ctx context.Context, cl tfResourceClient, opts CreateOptions) (tfOutput terraform.ApplyOutput, retErr error) {
|
func (c *Creator) createAWS(ctx context.Context, cl tfResourceClient, opts CreateOptions) (tfOutput state.Infrastructure, retErr error) {
|
||||||
vars := awsTerraformVars(opts.Config, opts.image)
|
vars := awsTerraformVars(opts.Config, opts.image)
|
||||||
|
|
||||||
tfOutput, err := runTerraformCreate(ctx, cl, cloudprovider.AWS, vars, c.out, opts.TFLogLevel)
|
tfOutput, err := runTerraformCreate(ctx, cl, cloudprovider.AWS, vars, c.out, opts.TFLogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return terraform.ApplyOutput{}, err
|
return state.Infrastructure{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return tfOutput, nil
|
return tfOutput, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Creator) createGCP(ctx context.Context, cl tfResourceClient, opts CreateOptions) (tfOutput terraform.ApplyOutput, retErr error) {
|
func (c *Creator) createGCP(ctx context.Context, cl tfResourceClient, opts CreateOptions) (tfOutput state.Infrastructure, retErr error) {
|
||||||
vars := gcpTerraformVars(opts.Config, opts.image)
|
vars := gcpTerraformVars(opts.Config, opts.image)
|
||||||
|
|
||||||
tfOutput, err := runTerraformCreate(ctx, cl, cloudprovider.GCP, vars, c.out, opts.TFLogLevel)
|
tfOutput, err := runTerraformCreate(ctx, cl, cloudprovider.GCP, vars, c.out, opts.TFLogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return terraform.ApplyOutput{}, err
|
return state.Infrastructure{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return tfOutput, nil
|
return tfOutput, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Creator) createAzure(ctx context.Context, cl tfResourceClient, opts CreateOptions) (tfOutput terraform.ApplyOutput, retErr error) {
|
func (c *Creator) createAzure(ctx context.Context, cl tfResourceClient, opts CreateOptions) (tfOutput state.Infrastructure, retErr error) {
|
||||||
vars := azureTerraformVars(opts.Config, opts.image)
|
vars := azureTerraformVars(opts.Config, opts.image)
|
||||||
|
|
||||||
tfOutput, err := runTerraformCreate(ctx, cl, cloudprovider.Azure, vars, c.out, opts.TFLogLevel)
|
tfOutput, err := runTerraformCreate(ctx, cl, cloudprovider.Azure, vars, c.out, opts.TFLogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return terraform.ApplyOutput{}, err
|
return state.Infrastructure{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if vars.GetCreateMAA() {
|
if vars.GetCreateMAA() {
|
||||||
// Patch the attestation policy to allow the cluster to boot while having secure boot disabled.
|
// Patch the attestation policy to allow the cluster to boot while having secure boot disabled.
|
||||||
if tfOutput.Azure == nil {
|
if tfOutput.Azure == nil {
|
||||||
return terraform.ApplyOutput{}, errors.New("no Terraform Azure output found")
|
return state.Infrastructure{}, errors.New("no Terraform Azure output found")
|
||||||
}
|
}
|
||||||
if err := c.policyPatcher.Patch(ctx, tfOutput.Azure.AttestationURL); err != nil {
|
if err := c.policyPatcher.Patch(ctx, tfOutput.Azure.AttestationURL); err != nil {
|
||||||
return terraform.ApplyOutput{}, err
|
return state.Infrastructure{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,12 +189,12 @@ func normalizeAzureURIs(vars *terraform.AzureClusterVariables) *terraform.AzureC
|
|||||||
return vars
|
return vars
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Creator) createOpenStack(ctx context.Context, cl tfResourceClient, opts CreateOptions) (tfOutput terraform.ApplyOutput, retErr error) {
|
func (c *Creator) createOpenStack(ctx context.Context, cl tfResourceClient, opts CreateOptions) (infraState state.Infrastructure, retErr error) {
|
||||||
if os.Getenv("CONSTELLATION_OPENSTACK_DEV") != "1" {
|
if os.Getenv("CONSTELLATION_OPENSTACK_DEV") != "1" {
|
||||||
return terraform.ApplyOutput{}, errors.New("Constellation must be fine-tuned to your OpenStack deployment. Please create an issue or contact Edgeless Systems at https://edgeless.systems/contact/")
|
return state.Infrastructure{}, errors.New("Constellation must be fine-tuned to your OpenStack deployment. Please create an issue or contact Edgeless Systems at https://edgeless.systems/contact/")
|
||||||
}
|
}
|
||||||
if _, hasOSAuthURL := os.LookupEnv("OS_AUTH_URL"); !hasOSAuthURL && opts.Config.Provider.OpenStack.Cloud == "" {
|
if _, hasOSAuthURL := os.LookupEnv("OS_AUTH_URL"); !hasOSAuthURL && opts.Config.Provider.OpenStack.Cloud == "" {
|
||||||
return terraform.ApplyOutput{}, errors.New(
|
return state.Infrastructure{}, errors.New(
|
||||||
"neither environment variable OS_AUTH_URL nor cloud name for \"clouds.yaml\" is set. OpenStack authentication requires a set of " +
|
"neither environment variable OS_AUTH_URL nor cloud name for \"clouds.yaml\" is set. OpenStack authentication requires a set of " +
|
||||||
"OS_* environment variables that are typically sourced into the current shell with an openrc file " +
|
"OS_* environment variables that are typically sourced into the current shell with an openrc file " +
|
||||||
"or a cloud name for \"clouds.yaml\". " +
|
"or a cloud name for \"clouds.yaml\". " +
|
||||||
@ -204,23 +204,23 @@ func (c *Creator) createOpenStack(ctx context.Context, cl tfResourceClient, opts
|
|||||||
|
|
||||||
vars := openStackTerraformVars(opts.Config, opts.image)
|
vars := openStackTerraformVars(opts.Config, opts.image)
|
||||||
|
|
||||||
tfOutput, err := runTerraformCreate(ctx, cl, cloudprovider.OpenStack, vars, c.out, opts.TFLogLevel)
|
infraState, err := runTerraformCreate(ctx, cl, cloudprovider.OpenStack, vars, c.out, opts.TFLogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return terraform.ApplyOutput{}, err
|
return state.Infrastructure{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return tfOutput, nil
|
return infraState, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTerraformCreate(ctx context.Context, cl tfResourceClient, provider cloudprovider.Provider, vars terraform.Variables, outWriter io.Writer, loglevel terraform.LogLevel) (output terraform.ApplyOutput, retErr error) {
|
func runTerraformCreate(ctx context.Context, cl tfResourceClient, provider cloudprovider.Provider, vars terraform.Variables, outWriter io.Writer, loglevel terraform.LogLevel) (output state.Infrastructure, retErr error) {
|
||||||
if err := cl.PrepareWorkspace(path.Join("terraform", strings.ToLower(provider.String())), vars); err != nil {
|
if err := cl.PrepareWorkspace(path.Join("terraform", strings.ToLower(provider.String())), vars); err != nil {
|
||||||
return terraform.ApplyOutput{}, err
|
return state.Infrastructure{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer rollbackOnError(outWriter, &retErr, &rollbackerTerraform{client: cl}, loglevel)
|
defer rollbackOnError(outWriter, &retErr, &rollbackerTerraform{client: cl}, loglevel)
|
||||||
tfOutput, err := cl.ApplyCluster(ctx, provider, loglevel)
|
tfOutput, err := cl.ApplyCluster(ctx, provider, loglevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return terraform.ApplyOutput{}, err
|
return state.Infrastructure{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return tfOutput, nil
|
return tfOutput, nil
|
||||||
@ -231,7 +231,7 @@ type qemuCreateOptions struct {
|
|||||||
CreateOptions
|
CreateOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Creator) createQEMU(ctx context.Context, cl tfResourceClient, lv libvirtRunner, opts qemuCreateOptions) (tfOutput terraform.ApplyOutput, retErr error) {
|
func (c *Creator) createQEMU(ctx context.Context, cl tfResourceClient, lv libvirtRunner, opts qemuCreateOptions) (tfOutput state.Infrastructure, retErr error) {
|
||||||
qemuRollbacker := &rollbackerQEMU{client: cl, libvirt: lv, createdWorkspace: false}
|
qemuRollbacker := &rollbackerQEMU{client: cl, libvirt: lv, createdWorkspace: false}
|
||||||
defer rollbackOnError(c.out, &retErr, qemuRollbacker, opts.TFLogLevel)
|
defer rollbackOnError(c.out, &retErr, qemuRollbacker, opts.TFLogLevel)
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ func (c *Creator) createQEMU(ctx context.Context, cl tfResourceClient, lv libvir
|
|||||||
downloader := c.newRawDownloader()
|
downloader := c.newRawDownloader()
|
||||||
imagePath, err := downloader.Download(ctx, c.out, false, opts.source, opts.Config.Image)
|
imagePath, err := downloader.Download(ctx, c.out, false, opts.source, opts.Config.Image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return terraform.ApplyOutput{}, fmt.Errorf("download raw image: %w", err)
|
return state.Infrastructure{}, fmt.Errorf("download raw image: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
libvirtURI := opts.Config.Provider.QEMU.LibvirtURI
|
libvirtURI := opts.Config.Provider.QEMU.LibvirtURI
|
||||||
@ -249,7 +249,7 @@ func (c *Creator) createQEMU(ctx context.Context, cl tfResourceClient, lv libvir
|
|||||||
// if no libvirt URI is specified, start a libvirt container
|
// if no libvirt URI is specified, start a libvirt container
|
||||||
case libvirtURI == "":
|
case libvirtURI == "":
|
||||||
if err := lv.Start(ctx, opts.Config.Name, opts.Config.Provider.QEMU.LibvirtContainerImage); err != nil {
|
if err := lv.Start(ctx, opts.Config.Name, opts.Config.Provider.QEMU.LibvirtContainerImage); err != nil {
|
||||||
return terraform.ApplyOutput{}, fmt.Errorf("start libvirt container: %w", err)
|
return state.Infrastructure{}, fmt.Errorf("start libvirt container: %w", err)
|
||||||
}
|
}
|
||||||
libvirtURI = libvirt.LibvirtTCPConnectURI
|
libvirtURI = libvirt.LibvirtTCPConnectURI
|
||||||
|
|
||||||
@ -265,11 +265,11 @@ func (c *Creator) createQEMU(ctx context.Context, cl tfResourceClient, lv libvir
|
|||||||
case strings.HasPrefix(libvirtURI, "qemu+unix://"):
|
case strings.HasPrefix(libvirtURI, "qemu+unix://"):
|
||||||
unixURI, err := url.Parse(strings.TrimPrefix(libvirtURI, "qemu+unix://"))
|
unixURI, err := url.Parse(strings.TrimPrefix(libvirtURI, "qemu+unix://"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return terraform.ApplyOutput{}, err
|
return state.Infrastructure{}, err
|
||||||
}
|
}
|
||||||
libvirtSocketPath = unixURI.Query().Get("socket")
|
libvirtSocketPath = unixURI.Query().Get("socket")
|
||||||
if libvirtSocketPath == "" {
|
if libvirtSocketPath == "" {
|
||||||
return terraform.ApplyOutput{}, fmt.Errorf("socket path not specified in qemu+unix URI: %s", libvirtURI)
|
return state.Infrastructure{}, fmt.Errorf("socket path not specified in qemu+unix URI: %s", libvirtURI)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ func (c *Creator) createQEMU(ctx context.Context, cl tfResourceClient, lv libvir
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := cl.PrepareWorkspace(path.Join("terraform", strings.ToLower(cloudprovider.QEMU.String())), vars); err != nil {
|
if err := cl.PrepareWorkspace(path.Join("terraform", strings.ToLower(cloudprovider.QEMU.String())), vars); err != nil {
|
||||||
return terraform.ApplyOutput{}, fmt.Errorf("prepare workspace: %w", err)
|
return state.Infrastructure{}, fmt.Errorf("prepare workspace: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow rollback of QEMU Terraform workspace from this point on
|
// Allow rollback of QEMU Terraform workspace from this point on
|
||||||
@ -293,7 +293,7 @@ func (c *Creator) createQEMU(ctx context.Context, cl tfResourceClient, lv libvir
|
|||||||
|
|
||||||
tfOutput, err = cl.ApplyCluster(ctx, opts.Provider, opts.TFLogLevel)
|
tfOutput, err = cl.ApplyCluster(ctx, opts.Provider, opts.TFLogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return terraform.ApplyOutput{}, fmt.Errorf("create cluster: %w", err)
|
return state.Infrastructure{}, fmt.Errorf("create cluster: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return tfOutput, nil
|
return tfOutput, nil
|
||||||
|
@ -318,15 +318,14 @@ func (u *upgradeApplyCmd) migrateTerraform(cmd *cobra.Command, conf *config.Conf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
u.log.Debugf("Applying Terraform migrations")
|
u.log.Debugf("Applying Terraform migrations")
|
||||||
tfOutput, err := u.clusterUpgrader.ApplyClusterUpgrade(cmd.Context(), conf.GetProvider())
|
infraState, err := u.clusterUpgrader.ApplyClusterUpgrade(cmd.Context(), conf.GetProvider())
|
||||||
res = terraform.ConvertToInfrastructure(tfOutput)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, fmt.Errorf("applying terraform migrations: %w", err)
|
return infraState, fmt.Errorf("applying terraform migrations: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply possible updates to cluster ID file
|
// Apply possible updates to cluster ID file
|
||||||
if err := updateClusterIDFile(tfOutput, u.fileHandler); err != nil {
|
if err := updateClusterIDFile(infraState, u.fileHandler); err != nil {
|
||||||
return res, fmt.Errorf("merging cluster ID files: %w", err)
|
return infraState, fmt.Errorf("merging cluster ID files: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Printf("Terraform migrations applied successfully and output written to: %s\n"+
|
cmd.Printf("Terraform migrations applied successfully and output written to: %s\n"+
|
||||||
@ -588,15 +587,15 @@ func parseUpgradeApplyFlags(cmd *cobra.Command) (upgradeApplyFlags, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateClusterIDFile(tfOutput terraform.ApplyOutput, fileHandler file.Handler) error {
|
func updateClusterIDFile(infraState state.Infrastructure, fileHandler file.Handler) error {
|
||||||
newIDFile := clusterid.File{
|
newIDFile := clusterid.File{
|
||||||
InitSecret: []byte(tfOutput.Secret),
|
InitSecret: []byte(infraState.InitSecret),
|
||||||
IP: tfOutput.IP,
|
IP: infraState.ClusterEndpoint,
|
||||||
APIServerCertSANs: tfOutput.APIServerCertSANs,
|
APIServerCertSANs: infraState.APIServerCertSANs,
|
||||||
UID: tfOutput.UID,
|
UID: infraState.UID,
|
||||||
}
|
}
|
||||||
if tfOutput.Azure != nil {
|
if infraState.Azure != nil {
|
||||||
newIDFile.AttestationURL = tfOutput.Azure.AttestationURL
|
newIDFile.AttestationURL = infraState.Azure.AttestationURL
|
||||||
}
|
}
|
||||||
|
|
||||||
idFile := &clusterid.File{}
|
idFile := &clusterid.File{}
|
||||||
@ -650,6 +649,6 @@ type kubernetesUpgrader interface {
|
|||||||
|
|
||||||
type clusterUpgrader interface {
|
type clusterUpgrader interface {
|
||||||
PlanClusterUpgrade(ctx context.Context, outWriter io.Writer, vars terraform.Variables, csp cloudprovider.Provider) (bool, error)
|
PlanClusterUpgrade(ctx context.Context, outWriter io.Writer, vars terraform.Variables, csp cloudprovider.Provider) (bool, error)
|
||||||
ApplyClusterUpgrade(ctx context.Context, csp cloudprovider.Provider) (terraform.ApplyOutput, error)
|
ApplyClusterUpgrade(ctx context.Context, csp cloudprovider.Provider) (state.Infrastructure, error)
|
||||||
RestoreClusterWorkspace() error
|
RestoreClusterWorkspace() error
|
||||||
}
|
}
|
||||||
|
@ -277,8 +277,8 @@ func (u stubTerraformUpgrader) PlanClusterUpgrade(_ context.Context, _ io.Writer
|
|||||||
return u.terraformDiff, u.planTerraformErr
|
return u.terraformDiff, u.planTerraformErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubTerraformUpgrader) ApplyClusterUpgrade(_ context.Context, _ cloudprovider.Provider) (terraform.ApplyOutput, error) {
|
func (u stubTerraformUpgrader) ApplyClusterUpgrade(_ context.Context, _ cloudprovider.Provider) (state.Infrastructure, error) {
|
||||||
return terraform.ApplyOutput{}, u.applyTerraformErr
|
return state.Infrastructure{}, u.applyTerraformErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u stubTerraformUpgrader) RestoreClusterWorkspace() error {
|
func (u stubTerraformUpgrader) RestoreClusterWorkspace() error {
|
||||||
@ -294,9 +294,9 @@ func (m *mockTerraformUpgrader) PlanClusterUpgrade(ctx context.Context, w io.Wri
|
|||||||
return args.Bool(0), args.Error(1)
|
return args.Bool(0), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockTerraformUpgrader) ApplyClusterUpgrade(ctx context.Context, provider cloudprovider.Provider) (terraform.ApplyOutput, error) {
|
func (m *mockTerraformUpgrader) ApplyClusterUpgrade(ctx context.Context, provider cloudprovider.Provider) (state.Infrastructure, error) {
|
||||||
args := m.Called(ctx, provider)
|
args := m.Called(ctx, provider)
|
||||||
return args.Get(0).(terraform.ApplyOutput), args.Error(1)
|
return args.Get(0).(state.Infrastructure), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockTerraformUpgrader) RestoreClusterWorkspace() error {
|
func (m *mockTerraformUpgrader) RestoreClusterWorkspace() error {
|
||||||
|
@ -173,96 +173,58 @@ func (c *Client) ShowIAM(ctx context.Context, provider cloudprovider.Provider) (
|
|||||||
|
|
||||||
// ShowInfrastructure reads the state of Constellation cluster resources from Terraform.
|
// ShowInfrastructure reads the state of Constellation cluster resources from Terraform.
|
||||||
func (c *Client) ShowInfrastructure(ctx context.Context, provider cloudprovider.Provider) (state.Infrastructure, error) {
|
func (c *Client) ShowInfrastructure(ctx context.Context, provider cloudprovider.Provider) (state.Infrastructure, error) {
|
||||||
tfOutput, err := c.ShowCluster(ctx, provider)
|
|
||||||
if err != nil {
|
|
||||||
return state.Infrastructure{}, err
|
|
||||||
}
|
|
||||||
return ConvertToInfrastructure(tfOutput), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConvertToInfrastructure converts the Terraform output of a cluster creation or apply operation to a state.Infrastructure.
|
|
||||||
func ConvertToInfrastructure(applyOutput ApplyOutput) state.Infrastructure {
|
|
||||||
var infra state.Infrastructure
|
|
||||||
infra.UID = applyOutput.UID
|
|
||||||
infra.ClusterEndpoint = applyOutput.IP
|
|
||||||
infra.InitSecret = applyOutput.Secret
|
|
||||||
infra.APIServerCertSANs = applyOutput.APIServerCertSANs
|
|
||||||
|
|
||||||
if applyOutput.Azure != nil {
|
|
||||||
infra.Azure = &state.Azure{
|
|
||||||
ResourceGroup: applyOutput.Azure.ResourceGroup,
|
|
||||||
SubscriptionID: applyOutput.Azure.SubscriptionID,
|
|
||||||
UserAssignedIdentity: applyOutput.Azure.UserAssignedIdentity,
|
|
||||||
NetworkSecurityGroupName: applyOutput.Azure.NetworkSecurityGroupName,
|
|
||||||
LoadBalancerName: applyOutput.Azure.LoadBalancerName,
|
|
||||||
AttestationURL: applyOutput.Azure.AttestationURL,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if applyOutput.GCP != nil {
|
|
||||||
infra.GCP = &state.GCP{
|
|
||||||
ProjectID: applyOutput.GCP.ProjectID,
|
|
||||||
IPCidrNode: applyOutput.GCP.IPCidrNode,
|
|
||||||
IPCidrPod: applyOutput.GCP.IPCidrPod,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return infra
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShowCluster reads the state of Constellation cluster resources from Terraform.
|
|
||||||
func (c *Client) ShowCluster(ctx context.Context, provider cloudprovider.Provider) (ApplyOutput, error) {
|
|
||||||
tfState, err := c.tf.Show(ctx)
|
tfState, err := c.tf.Show(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ApplyOutput{}, fmt.Errorf("terraform show: %w", err)
|
return state.Infrastructure{}, fmt.Errorf("terraform show: %w", err)
|
||||||
}
|
}
|
||||||
if tfState.Values == nil {
|
if tfState.Values == nil {
|
||||||
return ApplyOutput{}, errors.New("terraform show: no values returned")
|
return state.Infrastructure{}, errors.New("terraform show: no values returned")
|
||||||
}
|
}
|
||||||
|
|
||||||
ipOutput, ok := tfState.Values.Outputs["ip"]
|
ipOutput, ok := tfState.Values.Outputs["ip"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no IP output found")
|
return state.Infrastructure{}, errors.New("no IP output found")
|
||||||
}
|
}
|
||||||
ip, ok := ipOutput.Value.(string)
|
ip, ok := ipOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in IP output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in IP output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerCertSANsOutput, ok := tfState.Values.Outputs["api_server_cert_sans"]
|
apiServerCertSANsOutput, ok := tfState.Values.Outputs["api_server_cert_sans"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no api_server_cert_sans output found")
|
return state.Infrastructure{}, errors.New("no api_server_cert_sans output found")
|
||||||
}
|
}
|
||||||
apiServerCertSANsUntyped, ok := apiServerCertSANsOutput.Value.([]any)
|
apiServerCertSANsUntyped, ok := apiServerCertSANsOutput.Value.([]any)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, fmt.Errorf("invalid type in api_server_cert_sans output: %s is not a list of elements", apiServerCertSANsOutput.Type.FriendlyName())
|
return state.Infrastructure{}, fmt.Errorf("invalid type in api_server_cert_sans output: %s is not a list of elements", apiServerCertSANsOutput.Type.FriendlyName())
|
||||||
}
|
}
|
||||||
apiServerCertSANs, err := toStringSlice(apiServerCertSANsUntyped)
|
apiServerCertSANs, err := toStringSlice(apiServerCertSANsUntyped)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ApplyOutput{}, fmt.Errorf("convert api_server_cert_sans output: %w", err)
|
return state.Infrastructure{}, fmt.Errorf("convert api_server_cert_sans output: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
secretOutput, ok := tfState.Values.Outputs["initSecret"]
|
secretOutput, ok := tfState.Values.Outputs["initSecret"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no initSecret output found")
|
return state.Infrastructure{}, errors.New("no initSecret output found")
|
||||||
}
|
}
|
||||||
secret, ok := secretOutput.Value.(string)
|
secret, ok := secretOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in initSecret output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in initSecret output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
uidOutput, ok := tfState.Values.Outputs["uid"]
|
uidOutput, ok := tfState.Values.Outputs["uid"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no uid output found")
|
return state.Infrastructure{}, errors.New("no uid output found")
|
||||||
}
|
}
|
||||||
uid, ok := uidOutput.Value.(string)
|
uid, ok := uidOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in uid output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in uid output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
res := ApplyOutput{
|
res := state.Infrastructure{
|
||||||
IP: ip,
|
ClusterEndpoint: ip,
|
||||||
APIServerCertSANs: apiServerCertSANs,
|
APIServerCertSANs: apiServerCertSANs,
|
||||||
Secret: secret,
|
InitSecret: secret,
|
||||||
UID: uid,
|
UID: uid,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,32 +232,32 @@ func (c *Client) ShowCluster(ctx context.Context, provider cloudprovider.Provide
|
|||||||
case cloudprovider.GCP:
|
case cloudprovider.GCP:
|
||||||
gcpProjectOutput, ok := tfState.Values.Outputs["project"]
|
gcpProjectOutput, ok := tfState.Values.Outputs["project"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no project output found")
|
return state.Infrastructure{}, errors.New("no project output found")
|
||||||
}
|
}
|
||||||
gcpProject, ok := gcpProjectOutput.Value.(string)
|
gcpProject, ok := gcpProjectOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in project output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in project output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
cidrNodesOutput, ok := tfState.Values.Outputs["ip_cidr_nodes"]
|
cidrNodesOutput, ok := tfState.Values.Outputs["ip_cidr_nodes"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no ip_cidr_nodes output found")
|
return state.Infrastructure{}, errors.New("no ip_cidr_nodes output found")
|
||||||
}
|
}
|
||||||
cidrNodes, ok := cidrNodesOutput.Value.(string)
|
cidrNodes, ok := cidrNodesOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in ip_cidr_nodes output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in ip_cidr_nodes output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
cidrPodsOutput, ok := tfState.Values.Outputs["ip_cidr_pods"]
|
cidrPodsOutput, ok := tfState.Values.Outputs["ip_cidr_pods"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no ip_cidr_pods output found")
|
return state.Infrastructure{}, errors.New("no ip_cidr_pods output found")
|
||||||
}
|
}
|
||||||
cidrPods, ok := cidrPodsOutput.Value.(string)
|
cidrPods, ok := cidrPodsOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in ip_cidr_pods output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in ip_cidr_pods output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
res.GCP = &GCPApplyOutput{
|
res.GCP = &state.GCP{
|
||||||
ProjectID: gcpProject,
|
ProjectID: gcpProject,
|
||||||
IPCidrNode: cidrNodes,
|
IPCidrNode: cidrNodes,
|
||||||
IPCidrPod: cidrPods,
|
IPCidrPod: cidrPods,
|
||||||
@ -303,57 +265,57 @@ func (c *Client) ShowCluster(ctx context.Context, provider cloudprovider.Provide
|
|||||||
case cloudprovider.Azure:
|
case cloudprovider.Azure:
|
||||||
attestationURLOutput, ok := tfState.Values.Outputs["attestationURL"]
|
attestationURLOutput, ok := tfState.Values.Outputs["attestationURL"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no attestationURL output found")
|
return state.Infrastructure{}, errors.New("no attestationURL output found")
|
||||||
}
|
}
|
||||||
attestationURL, ok := attestationURLOutput.Value.(string)
|
attestationURL, ok := attestationURLOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in attestationURL output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in attestationURL output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
azureUAMIOutput, ok := tfState.Values.Outputs["user_assigned_identity_client_id"]
|
azureUAMIOutput, ok := tfState.Values.Outputs["user_assigned_identity_client_id"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no user_assigned_identity_client_id output found")
|
return state.Infrastructure{}, errors.New("no user_assigned_identity_client_id output found")
|
||||||
}
|
}
|
||||||
azureUAMI, ok := azureUAMIOutput.Value.(string)
|
azureUAMI, ok := azureUAMIOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in user_assigned_identity_client_id output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in user_assigned_identity_client_id output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
rgOutput, ok := tfState.Values.Outputs["resource_group"]
|
rgOutput, ok := tfState.Values.Outputs["resource_group"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no resource_group output found")
|
return state.Infrastructure{}, errors.New("no resource_group output found")
|
||||||
}
|
}
|
||||||
rg, ok := rgOutput.Value.(string)
|
rg, ok := rgOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in resource_group output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in resource_group output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
subscriptionOutput, ok := tfState.Values.Outputs["subscription_id"]
|
subscriptionOutput, ok := tfState.Values.Outputs["subscription_id"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no subscription_id output found")
|
return state.Infrastructure{}, errors.New("no subscription_id output found")
|
||||||
}
|
}
|
||||||
subscriptionID, ok := subscriptionOutput.Value.(string)
|
subscriptionID, ok := subscriptionOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in subscription_id output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in subscription_id output: not a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
networkSGNameOutput, ok := tfState.Values.Outputs["network_security_group_name"]
|
networkSGNameOutput, ok := tfState.Values.Outputs["network_security_group_name"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no network_security_group_name output found")
|
return state.Infrastructure{}, errors.New("no network_security_group_name output found")
|
||||||
}
|
}
|
||||||
networkSGName, ok := networkSGNameOutput.Value.(string)
|
networkSGName, ok := networkSGNameOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in network_security_group_name output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in network_security_group_name output: not a string")
|
||||||
}
|
}
|
||||||
loadBalancerNameOutput, ok := tfState.Values.Outputs["loadbalancer_name"]
|
loadBalancerNameOutput, ok := tfState.Values.Outputs["loadbalancer_name"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("no loadbalancer_name output found")
|
return state.Infrastructure{}, errors.New("no loadbalancer_name output found")
|
||||||
}
|
}
|
||||||
loadBalancerName, ok := loadBalancerNameOutput.Value.(string)
|
loadBalancerName, ok := loadBalancerNameOutput.Value.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ApplyOutput{}, errors.New("invalid type in loadbalancer_name output: not a string")
|
return state.Infrastructure{}, errors.New("invalid type in loadbalancer_name output: not a string")
|
||||||
}
|
}
|
||||||
res.Azure = &AzureApplyOutput{
|
res.Azure = &state.Azure{
|
||||||
ResourceGroup: rg,
|
ResourceGroup: rg,
|
||||||
SubscriptionID: subscriptionID,
|
SubscriptionID: subscriptionID,
|
||||||
UserAssignedIdentity: azureUAMI,
|
UserAssignedIdentity: azureUAMI,
|
||||||
@ -386,11 +348,11 @@ func (c *Client) PrepareUpgradeWorkspace(path, backupDir string, vars Variables)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ApplyCluster applies the Terraform configuration of the workspace to create or upgrade a Constellation cluster.
|
// ApplyCluster applies the Terraform configuration of the workspace to create or upgrade a Constellation cluster.
|
||||||
func (c *Client) ApplyCluster(ctx context.Context, provider cloudprovider.Provider, logLevel LogLevel) (ApplyOutput, error) {
|
func (c *Client) ApplyCluster(ctx context.Context, provider cloudprovider.Provider, logLevel LogLevel) (state.Infrastructure, error) {
|
||||||
if err := c.apply(ctx, logLevel); err != nil {
|
if err := c.apply(ctx, logLevel); err != nil {
|
||||||
return ApplyOutput{}, err
|
return state.Infrastructure{}, err
|
||||||
}
|
}
|
||||||
return c.ShowCluster(ctx, provider)
|
return c.ShowInfrastructure(ctx, provider)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyIAM applies the Terraform configuration of the workspace to create or upgrade an IAM configuration.
|
// ApplyIAM applies the Terraform configuration of the workspace to create or upgrade an IAM configuration.
|
||||||
@ -547,35 +509,6 @@ type StateMigration struct {
|
|||||||
Hook func(ctx context.Context, tfClient TFMigrator) error
|
Hook func(ctx context.Context, tfClient TFMigrator) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyOutput contains the Terraform output values of a cluster creation
|
|
||||||
// or apply operation.
|
|
||||||
type ApplyOutput struct {
|
|
||||||
IP string
|
|
||||||
APIServerCertSANs []string
|
|
||||||
Secret string
|
|
||||||
UID string
|
|
||||||
GCP *GCPApplyOutput
|
|
||||||
Azure *AzureApplyOutput
|
|
||||||
}
|
|
||||||
|
|
||||||
// AzureApplyOutput contains the Terraform output values of a terraform apply operation on Microsoft Azure.
|
|
||||||
type AzureApplyOutput struct {
|
|
||||||
ResourceGroup string
|
|
||||||
SubscriptionID string
|
|
||||||
NetworkSecurityGroupName string
|
|
||||||
LoadBalancerName string
|
|
||||||
UserAssignedIdentity string
|
|
||||||
// AttestationURL is the URL of the attestation provider.
|
|
||||||
AttestationURL string
|
|
||||||
}
|
|
||||||
|
|
||||||
// GCPApplyOutput contains the Terraform output values of a terraform apply operation on GCP.
|
|
||||||
type GCPApplyOutput struct {
|
|
||||||
ProjectID string
|
|
||||||
IPCidrNode string
|
|
||||||
IPCidrPod string
|
|
||||||
}
|
|
||||||
|
|
||||||
// IAMOutput contains the output information of the Terraform IAM operations.
|
// IAMOutput contains the output information of the Terraform IAM operations.
|
||||||
type IAMOutput struct {
|
type IAMOutput struct {
|
||||||
GCP GCPIAMOutput
|
GCP GCPIAMOutput
|
||||||
|
@ -449,18 +449,18 @@ func TestCreateCluster(t *testing.T) {
|
|||||||
|
|
||||||
path := path.Join(tc.pathBase, strings.ToLower(tc.provider.String()))
|
path := path.Join(tc.pathBase, strings.ToLower(tc.provider.String()))
|
||||||
require.NoError(c.PrepareWorkspace(path, tc.vars))
|
require.NoError(c.PrepareWorkspace(path, tc.vars))
|
||||||
tfOutput, err := c.ApplyCluster(context.Background(), tc.provider, LogLevelDebug)
|
infraState, err := c.ApplyCluster(context.Background(), tc.provider, LogLevelDebug)
|
||||||
|
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal("192.0.2.100", tfOutput.IP)
|
assert.Equal("192.0.2.100", infraState.ClusterEndpoint)
|
||||||
assert.Equal("initSecret", tfOutput.Secret)
|
assert.Equal("initSecret", infraState.InitSecret)
|
||||||
assert.Equal("12345abc", tfOutput.UID)
|
assert.Equal("12345abc", infraState.UID)
|
||||||
if tc.provider == cloudprovider.Azure {
|
if tc.provider == cloudprovider.Azure {
|
||||||
assert.Equal(tc.expectedAttestationURL, tfOutput.Azure.AttestationURL)
|
assert.Equal(tc.expectedAttestationURL, infraState.Azure.AttestationURL)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user