mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-11-09 07:17:10 -05:00
terraform-provider: require kubernetes and microservice version (#2791)
This commit is contained in:
parent
26a9639bcf
commit
f41ce43919
8 changed files with 157 additions and 133 deletions
|
|
@ -94,6 +94,7 @@ go_test(
|
|||
"//internal/config",
|
||||
"//internal/constants",
|
||||
"//internal/semver",
|
||||
"//internal/versions",
|
||||
"//terraform-provider-constellation/internal/data",
|
||||
"@com_github_hashicorp_terraform_plugin_framework//attr",
|
||||
"@com_github_hashicorp_terraform_plugin_framework//providerserver",
|
||||
|
|
|
|||
|
|
@ -160,14 +160,14 @@ func (r *ClusterResource) Schema(_ context.Context, _ resource.SchemaRequest, re
|
|||
},
|
||||
"image": newImageAttributeSchema(attributeInput),
|
||||
"kubernetes_version": schema.StringAttribute{
|
||||
MarkdownDescription: fmt.Sprintf("The Kubernetes version to use for the cluster. When not set, version %s is used. The supported versions are %s.", versions.Default, versions.SupportedK8sVersions()),
|
||||
Description: fmt.Sprintf("The Kubernetes version to use for the cluster. When not set, version %s is used. The supported versions are %s.", versions.Default, versions.SupportedK8sVersions()),
|
||||
Optional: true,
|
||||
MarkdownDescription: fmt.Sprintf("The Kubernetes version to use for the cluster. The supported versions are %s.", versions.SupportedK8sVersions()),
|
||||
Description: fmt.Sprintf("The Kubernetes version to use for the cluster. The supported versions are %s.", versions.SupportedK8sVersions()),
|
||||
Required: true,
|
||||
},
|
||||
"constellation_microservice_version": schema.StringAttribute{
|
||||
MarkdownDescription: "The version of Constellation's microservices used within the cluster. When not set, the provider version is used.",
|
||||
Description: "The version of Constellation's microservices used within the cluster. When not set, the provider version is used.",
|
||||
Optional: true,
|
||||
MarkdownDescription: "The version of Constellation's microservices used within the cluster.",
|
||||
Description: "The version of Constellation's microservices used within the cluster.",
|
||||
Required: true,
|
||||
},
|
||||
"out_of_cluster_endpoint": schema.StringAttribute{
|
||||
MarkdownDescription: "The endpoint of the cluster. Typically, this is the public IP of a loadbalancer.",
|
||||
|
|
@ -470,13 +470,13 @@ func (r *ClusterResource) ModifyPlan(ctx context.Context, req resource.ModifyPla
|
|||
}
|
||||
|
||||
// Warn the user about possibly destructive changes in case microservice changes are to be applied.
|
||||
currVer, diags := r.getMicroserviceVersion(ctx, ¤tState)
|
||||
currVer, diags := r.getMicroserviceVersion(¤tState)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
plannedVer, diags := r.getMicroserviceVersion(ctx, &plannedState)
|
||||
plannedVer, diags := r.getMicroserviceVersion(&plannedState)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
|
|
@ -718,14 +718,14 @@ func (r *ClusterResource) apply(ctx context.Context, data *ClusterResourceModel,
|
|||
}
|
||||
|
||||
// parse Constellation microservice version
|
||||
microserviceVersion, convertDiags := r.getMicroserviceVersion(ctx, data)
|
||||
microserviceVersion, convertDiags := r.getMicroserviceVersion(data)
|
||||
diags.Append(convertDiags...)
|
||||
if diags.HasError() {
|
||||
return diags
|
||||
}
|
||||
|
||||
// parse Kubernetes version
|
||||
k8sVersion, getDiags := r.getK8sVersion(ctx, data)
|
||||
k8sVersion, getDiags := r.getK8sVersion(data)
|
||||
diags.Append(getDiags...)
|
||||
if diags.HasError() {
|
||||
return diags
|
||||
|
|
@ -1163,44 +1163,30 @@ func (r *ClusterResource) convertSecrets(data ClusterResourceModel) (secretInput
|
|||
|
||||
// getK8sVersion returns the Kubernetes version from the Terraform state if set, and the default
|
||||
// version otherwise.
|
||||
func (r *ClusterResource) getK8sVersion(ctx context.Context, data *ClusterResourceModel) (versions.ValidK8sVersion, diag.Diagnostics) {
|
||||
func (r *ClusterResource) getK8sVersion(data *ClusterResourceModel) (versions.ValidK8sVersion, diag.Diagnostics) {
|
||||
diags := diag.Diagnostics{}
|
||||
var k8sVersion versions.ValidK8sVersion
|
||||
var err error
|
||||
if data.KubernetesVersion.ValueString() != "" {
|
||||
k8sVersion, err = versions.NewValidK8sVersion(data.KubernetesVersion.ValueString(), true)
|
||||
if err != nil {
|
||||
diags.AddAttributeError(
|
||||
path.Root("kubernetes_vesion"),
|
||||
"Invalid Kubernetes version",
|
||||
fmt.Sprintf("Parsing Kubernetes version: %s", err))
|
||||
return "", diags
|
||||
}
|
||||
} else {
|
||||
tflog.Info(ctx, fmt.Sprintf("No Kubernetes version specified. Using default version %s.", versions.Default))
|
||||
k8sVersion = versions.Default
|
||||
k8sVersion, err := versions.NewValidK8sVersion(data.KubernetesVersion.ValueString(), true)
|
||||
if err != nil {
|
||||
diags.AddAttributeError(
|
||||
path.Root("kubernetes_version"),
|
||||
"Invalid Kubernetes version",
|
||||
fmt.Sprintf("Parsing Kubernetes version: %s", err))
|
||||
return "", diags
|
||||
}
|
||||
return k8sVersion, diags
|
||||
}
|
||||
|
||||
// getK8sVersion returns the Microservice version from the Terraform state if set, and the default
|
||||
// version otherwise.
|
||||
func (r *ClusterResource) getMicroserviceVersion(ctx context.Context, data *ClusterResourceModel) (semver.Semver, diag.Diagnostics) {
|
||||
func (r *ClusterResource) getMicroserviceVersion(data *ClusterResourceModel) (semver.Semver, diag.Diagnostics) {
|
||||
diags := diag.Diagnostics{}
|
||||
var ver semver.Semver
|
||||
var err error
|
||||
if data.MicroserviceVersion.ValueString() != "" {
|
||||
ver, err = semver.New(data.MicroserviceVersion.ValueString())
|
||||
if err != nil {
|
||||
diags.AddAttributeError(
|
||||
path.Root("constellation_microservice_version"),
|
||||
"Invalid microservice version",
|
||||
fmt.Sprintf("Parsing microservice version: %s", err))
|
||||
return semver.Semver{}, diags
|
||||
}
|
||||
} else {
|
||||
tflog.Info(ctx, fmt.Sprintf("No Microservice version specified. Using default version %s.", r.providerData.Version))
|
||||
ver = r.providerData.Version
|
||||
ver, err := semver.New(data.MicroserviceVersion.ValueString())
|
||||
if err != nil {
|
||||
diags.AddAttributeError(
|
||||
path.Root("constellation_microservice_version"),
|
||||
"Invalid microservice version",
|
||||
fmt.Sprintf("Parsing microservice version: %s", err))
|
||||
return semver.Semver{}, diags
|
||||
}
|
||||
if err := config.ValidateMicroserviceVersion(r.providerData.Version, ver); err != nil {
|
||||
diags.AddAttributeError(
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ package provider
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/semver"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versions"
|
||||
"github.com/edgelesssys/constellation/v2/terraform-provider-constellation/internal/data"
|
||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
|
|
@ -21,10 +23,12 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var providerVersion = semver.NewFromInt(2, 15, 0, "")
|
||||
|
||||
func TestMicroserviceConstraint(t *testing.T) {
|
||||
sut := &ClusterResource{
|
||||
providerData: data.ProviderData{
|
||||
Version: semver.NewFromInt(2, 15, 0, ""),
|
||||
Version: providerVersion,
|
||||
},
|
||||
}
|
||||
testCases := []struct {
|
||||
|
|
@ -50,7 +54,7 @@ func TestMicroserviceConstraint(t *testing.T) {
|
|||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
_, diags := sut.getMicroserviceVersion(context.Background(), &ClusterResourceModel{
|
||||
_, diags := sut.getMicroserviceVersion(&ClusterResourceModel{
|
||||
MicroserviceVersion: basetypes.NewStringValue(tc.version),
|
||||
})
|
||||
require.Equal(t, tc.expectedErrorCount, diags.ErrorsCount())
|
||||
|
|
@ -208,7 +212,7 @@ func TestAccClusterResource(t *testing.T) {
|
|||
PreCheck: bazelPreCheck,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fullClusterTestingConfig(t, "aws") + `
|
||||
Config: fullClusterTestingConfig(t, "aws") + fmt.Sprintf(`
|
||||
resource "constellation_cluster" "test" {
|
||||
csp = "aws"
|
||||
name = "constell"
|
||||
|
|
@ -225,8 +229,10 @@ func TestAccClusterResource(t *testing.T) {
|
|||
ip_cidr_node = "0.0.0.0/24"
|
||||
ip_cidr_service = "0.0.0.0/24"
|
||||
}
|
||||
kubernetes_version = "%s"
|
||||
constellation_microservice_version = "%s"
|
||||
}
|
||||
`,
|
||||
`, versions.Default, providerVersion.String()),
|
||||
ExpectError: regexp.MustCompile(".*Master secret must be a hex-encoded 32-byte.*"),
|
||||
},
|
||||
},
|
||||
|
|
@ -236,7 +242,7 @@ func TestAccClusterResource(t *testing.T) {
|
|||
PreCheck: bazelPreCheck,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fullClusterTestingConfig(t, "aws") + `
|
||||
Config: fullClusterTestingConfig(t, "aws") + fmt.Sprintf(`
|
||||
resource "constellation_cluster" "test" {
|
||||
csp = "aws"
|
||||
name = "constell"
|
||||
|
|
@ -253,8 +259,10 @@ func TestAccClusterResource(t *testing.T) {
|
|||
ip_cidr_node = "0.0.0.0/24"
|
||||
ip_cidr_service = "0.0.0.0/24"
|
||||
}
|
||||
kubernetes_version = "%s"
|
||||
constellation_microservice_version = "%s"
|
||||
}
|
||||
`,
|
||||
`, versions.Default, providerVersion.String()),
|
||||
ExpectError: regexp.MustCompile(".*Master secret salt must be a hex-encoded 32-byte.*"),
|
||||
},
|
||||
},
|
||||
|
|
@ -264,7 +272,7 @@ func TestAccClusterResource(t *testing.T) {
|
|||
PreCheck: bazelPreCheck,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fullClusterTestingConfig(t, "aws") + `
|
||||
Config: fullClusterTestingConfig(t, "aws") + fmt.Sprintf(`
|
||||
resource "constellation_cluster" "test" {
|
||||
csp = "aws"
|
||||
name = "constell"
|
||||
|
|
@ -281,8 +289,10 @@ func TestAccClusterResource(t *testing.T) {
|
|||
ip_cidr_node = "0.0.0.0/24"
|
||||
ip_cidr_service = "0.0.0.0/24"
|
||||
}
|
||||
kubernetes_version = "%s"
|
||||
constellation_microservice_version = "%s"
|
||||
}
|
||||
`,
|
||||
`, versions.Default, providerVersion.String()),
|
||||
ExpectError: regexp.MustCompile(".*Measurement salt must be a hex-encoded 32-byte.*"),
|
||||
},
|
||||
},
|
||||
|
|
@ -292,7 +302,7 @@ func TestAccClusterResource(t *testing.T) {
|
|||
PreCheck: bazelPreCheck,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fullClusterTestingConfig(t, "aws") + `
|
||||
Config: fullClusterTestingConfig(t, "aws") + fmt.Sprintf(`
|
||||
resource "constellation_cluster" "test" {
|
||||
csp = "aws"
|
||||
name = "constell"
|
||||
|
|
@ -309,8 +319,10 @@ func TestAccClusterResource(t *testing.T) {
|
|||
ip_cidr_node = "0.0.0x.0/xxx"
|
||||
ip_cidr_service = "0.0.0.0/24"
|
||||
}
|
||||
kubernetes_version = "%s"
|
||||
constellation_microservice_version = "%s"
|
||||
}
|
||||
`,
|
||||
`, versions.Default, providerVersion.String()),
|
||||
ExpectError: regexp.MustCompile(".*Node IP CIDR must be a valid CIDR.*"),
|
||||
},
|
||||
},
|
||||
|
|
@ -320,7 +332,7 @@ func TestAccClusterResource(t *testing.T) {
|
|||
PreCheck: bazelPreCheck,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fullClusterTestingConfig(t, "aws") + `
|
||||
Config: fullClusterTestingConfig(t, "aws") + fmt.Sprintf(`
|
||||
resource "constellation_cluster" "test" {
|
||||
csp = "aws"
|
||||
name = "constell"
|
||||
|
|
@ -337,8 +349,10 @@ func TestAccClusterResource(t *testing.T) {
|
|||
ip_cidr_node = "0.0.0.0/24"
|
||||
ip_cidr_service = "0.0.0x.0/xxx"
|
||||
}
|
||||
kubernetes_version = "%s"
|
||||
constellation_microservice_version = "%s"
|
||||
}
|
||||
`,
|
||||
`, versions.Default, providerVersion.String()),
|
||||
ExpectError: regexp.MustCompile(".*Service IP CIDR must be a valid CIDR.*"),
|
||||
},
|
||||
},
|
||||
|
|
@ -348,7 +362,7 @@ func TestAccClusterResource(t *testing.T) {
|
|||
PreCheck: bazelPreCheck,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fullClusterTestingConfig(t, "azure") + `
|
||||
Config: fullClusterTestingConfig(t, "azure") + fmt.Sprintf(`
|
||||
resource "constellation_cluster" "test" {
|
||||
csp = "azure"
|
||||
name = "constell"
|
||||
|
|
@ -365,8 +379,10 @@ func TestAccClusterResource(t *testing.T) {
|
|||
ip_cidr_node = "0.0.0.0/24"
|
||||
ip_cidr_service = "0.0.0.0/24"
|
||||
}
|
||||
kubernetes_version = "%s"
|
||||
constellation_microservice_version = "%s"
|
||||
}
|
||||
`,
|
||||
`, versions.Default, providerVersion.String()),
|
||||
ExpectError: regexp.MustCompile(".*When csp is set to 'azure', the 'azure' configuration must be set.*"),
|
||||
},
|
||||
},
|
||||
|
|
@ -376,7 +392,7 @@ func TestAccClusterResource(t *testing.T) {
|
|||
PreCheck: bazelPreCheck,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fullClusterTestingConfig(t, "gcp") + `
|
||||
Config: fullClusterTestingConfig(t, "gcp") + fmt.Sprintf(`
|
||||
resource "constellation_cluster" "test" {
|
||||
csp = "gcp"
|
||||
name = "constell"
|
||||
|
|
@ -394,8 +410,10 @@ func TestAccClusterResource(t *testing.T) {
|
|||
ip_cidr_service = "0.0.0.0/24"
|
||||
ip_cidr_pod = "0.0.0.0/24"
|
||||
}
|
||||
kubernetes_version = "%s"
|
||||
constellation_microservice_version = "%s"
|
||||
}
|
||||
`,
|
||||
`, versions.Default, providerVersion.String()),
|
||||
ExpectError: regexp.MustCompile(".*When csp is set to 'gcp', the 'gcp' configuration must be set.*"),
|
||||
},
|
||||
},
|
||||
|
|
@ -405,29 +423,31 @@ func TestAccClusterResource(t *testing.T) {
|
|||
PreCheck: bazelPreCheck,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: fullClusterTestingConfig(t, "gcp") + `
|
||||
Config: fullClusterTestingConfig(t, "gcp") + fmt.Sprintf(`
|
||||
resource "constellation_cluster" "test" {
|
||||
csp = "gcp"
|
||||
name = "constell"
|
||||
uid = "test"
|
||||
image = data.constellation_image.bar.image
|
||||
attestation = data.constellation_attestation.foo.attestation
|
||||
init_secret = "deadbeef"
|
||||
master_secret = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||
master_secret_salt = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||
measurement_salt = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||
out_of_cluster_endpoint = "192.0.2.1"
|
||||
in_cluster_endpoint = "192.0.2.1"
|
||||
network_config = {
|
||||
ip_cidr_node = "0.0.0.0/24"
|
||||
ip_cidr_service = "0.0.0.0/24"
|
||||
}
|
||||
gcp = {
|
||||
project_id = "test"
|
||||
service_account_key = "eyJ0ZXN0IjogInRlc3QifQ=="
|
||||
}
|
||||
csp = "gcp"
|
||||
name = "constell"
|
||||
uid = "test"
|
||||
image = data.constellation_image.bar.image
|
||||
attestation = data.constellation_attestation.foo.attestation
|
||||
init_secret = "deadbeef"
|
||||
master_secret = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||
master_secret_salt = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||
measurement_salt = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||
out_of_cluster_endpoint = "192.0.2.1"
|
||||
in_cluster_endpoint = "192.0.2.1"
|
||||
network_config = {
|
||||
ip_cidr_node = "0.0.0.0/24"
|
||||
ip_cidr_service = "0.0.0.0/24"
|
||||
}
|
||||
gcp = {
|
||||
project_id = "test"
|
||||
service_account_key = "eyJ0ZXN0IjogInRlc3QifQ=="
|
||||
}
|
||||
kubernetes_version = "%s"
|
||||
constellation_microservice_version = "%s"
|
||||
}
|
||||
`,
|
||||
`, versions.Default, providerVersion.String()),
|
||||
ExpectError: regexp.MustCompile(".*When csp is set to 'gcp', 'ip_cidr_pod' must be set.*"),
|
||||
},
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue