Feature: allow system components on nodepools (#591)
* feat: allow system components on nodepools * docs: generated docs for ske * lint: sort imports * revert changes
This commit is contained in:
parent
2bf6a8dce7
commit
3ac1d50253
6 changed files with 155 additions and 59 deletions
|
|
@ -202,6 +202,10 @@ func (r *clusterDataSource) Schema(_ context.Context, _ datasource.SchemaRequest
|
|||
ElementType: types.StringType,
|
||||
Computed: true,
|
||||
},
|
||||
"allow_system_components": schema.BoolAttribute{
|
||||
Description: "Allow system components to run on this node pool.",
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -82,42 +82,44 @@ type Model struct {
|
|||
|
||||
// Struct corresponding to Model.NodePools[i]
|
||||
type nodePool struct {
|
||||
Name types.String `tfsdk:"name"`
|
||||
MachineType types.String `tfsdk:"machine_type"`
|
||||
OSName types.String `tfsdk:"os_name"`
|
||||
OSVersionMin types.String `tfsdk:"os_version_min"`
|
||||
OSVersion types.String `tfsdk:"os_version"`
|
||||
OSVersionUsed types.String `tfsdk:"os_version_used"`
|
||||
Minimum types.Int64 `tfsdk:"minimum"`
|
||||
Maximum types.Int64 `tfsdk:"maximum"`
|
||||
MaxSurge types.Int64 `tfsdk:"max_surge"`
|
||||
MaxUnavailable types.Int64 `tfsdk:"max_unavailable"`
|
||||
VolumeType types.String `tfsdk:"volume_type"`
|
||||
VolumeSize types.Int64 `tfsdk:"volume_size"`
|
||||
Labels types.Map `tfsdk:"labels"`
|
||||
Taints types.List `tfsdk:"taints"`
|
||||
CRI types.String `tfsdk:"cri"`
|
||||
AvailabilityZones types.List `tfsdk:"availability_zones"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
MachineType types.String `tfsdk:"machine_type"`
|
||||
OSName types.String `tfsdk:"os_name"`
|
||||
OSVersionMin types.String `tfsdk:"os_version_min"`
|
||||
OSVersion types.String `tfsdk:"os_version"`
|
||||
OSVersionUsed types.String `tfsdk:"os_version_used"`
|
||||
Minimum types.Int64 `tfsdk:"minimum"`
|
||||
Maximum types.Int64 `tfsdk:"maximum"`
|
||||
MaxSurge types.Int64 `tfsdk:"max_surge"`
|
||||
MaxUnavailable types.Int64 `tfsdk:"max_unavailable"`
|
||||
VolumeType types.String `tfsdk:"volume_type"`
|
||||
VolumeSize types.Int64 `tfsdk:"volume_size"`
|
||||
Labels types.Map `tfsdk:"labels"`
|
||||
Taints types.List `tfsdk:"taints"`
|
||||
CRI types.String `tfsdk:"cri"`
|
||||
AvailabilityZones types.List `tfsdk:"availability_zones"`
|
||||
AllowSystemComponents types.Bool `tfsdk:"allow_system_components"`
|
||||
}
|
||||
|
||||
// Types corresponding to nodePool
|
||||
var nodePoolTypes = map[string]attr.Type{
|
||||
"name": basetypes.StringType{},
|
||||
"machine_type": basetypes.StringType{},
|
||||
"os_name": basetypes.StringType{},
|
||||
"os_version_min": basetypes.StringType{},
|
||||
"os_version": basetypes.StringType{},
|
||||
"os_version_used": basetypes.StringType{},
|
||||
"minimum": basetypes.Int64Type{},
|
||||
"maximum": basetypes.Int64Type{},
|
||||
"max_surge": basetypes.Int64Type{},
|
||||
"max_unavailable": basetypes.Int64Type{},
|
||||
"volume_type": basetypes.StringType{},
|
||||
"volume_size": basetypes.Int64Type{},
|
||||
"labels": basetypes.MapType{ElemType: types.StringType},
|
||||
"taints": basetypes.ListType{ElemType: types.ObjectType{AttrTypes: taintTypes}},
|
||||
"cri": basetypes.StringType{},
|
||||
"availability_zones": basetypes.ListType{ElemType: types.StringType},
|
||||
"name": basetypes.StringType{},
|
||||
"machine_type": basetypes.StringType{},
|
||||
"os_name": basetypes.StringType{},
|
||||
"os_version_min": basetypes.StringType{},
|
||||
"os_version": basetypes.StringType{},
|
||||
"os_version_used": basetypes.StringType{},
|
||||
"minimum": basetypes.Int64Type{},
|
||||
"maximum": basetypes.Int64Type{},
|
||||
"max_surge": basetypes.Int64Type{},
|
||||
"max_unavailable": basetypes.Int64Type{},
|
||||
"volume_type": basetypes.StringType{},
|
||||
"volume_size": basetypes.Int64Type{},
|
||||
"labels": basetypes.MapType{ElemType: types.StringType},
|
||||
"taints": basetypes.ListType{ElemType: types.ObjectType{AttrTypes: taintTypes}},
|
||||
"cri": basetypes.StringType{},
|
||||
"availability_zones": basetypes.ListType{ElemType: types.StringType},
|
||||
"allow_system_components": basetypes.BoolType{},
|
||||
}
|
||||
|
||||
// Struct corresponding to nodePool.Taints[i]
|
||||
|
|
@ -391,6 +393,12 @@ func (r *clusterResource) Schema(_ context.Context, _ resource.SchemaRequest, re
|
|||
Required: true,
|
||||
ElementType: types.StringType,
|
||||
},
|
||||
"allow_system_components": schema.BoolAttribute{
|
||||
Description: "Allow system components to run on this node pool.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Default: booldefault.StaticBool(true),
|
||||
},
|
||||
"minimum": schema.Int64Attribute{
|
||||
Description: "Minimum number of nodes in the pool.",
|
||||
Required: true,
|
||||
|
|
@ -994,16 +1002,32 @@ func toNodepoolsPayload(ctx context.Context, m *Model, availableMachineVersions
|
|||
Type: conversion.StringValueToPointer(nodePool.VolumeType),
|
||||
Size: conversion.Int64ValueToPointer(nodePool.VolumeSize),
|
||||
},
|
||||
Taints: &ts,
|
||||
Cri: &cn,
|
||||
Labels: ls,
|
||||
AvailabilityZones: &zs,
|
||||
Taints: &ts,
|
||||
Cri: &cn,
|
||||
Labels: ls,
|
||||
AvailabilityZones: &zs,
|
||||
AllowSystemComponents: conversion.BoolValueToPointer(nodePool.AllowSystemComponents),
|
||||
}
|
||||
cnps = append(cnps, cnp)
|
||||
}
|
||||
|
||||
if err := verifySystemComponentsInNodePools(cnps); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return cnps, deprecatedVersionsUsed, nil
|
||||
}
|
||||
|
||||
// verifySystemComponentsInNodePools checks if at least one node pool has the allow_system_components attribute set to true.
|
||||
func verifySystemComponentsInNodePools(nodePools []ske.Nodepool) error {
|
||||
for _, nodePool := range nodePools {
|
||||
if nodePool.AllowSystemComponents != nil && *nodePool.AllowSystemComponents {
|
||||
return nil // A node pool allowing system components was found
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("at least one node_pool must allow system components")
|
||||
}
|
||||
|
||||
// latestMatchingMachineVersion determines the latest machine image version for the create/update payload.
|
||||
// It considers the available versions for the specified OS (OSName), the minimum version configured by the user,
|
||||
// and the current version in the cluster. The function's behavior is as follows:
|
||||
|
|
@ -1374,20 +1398,21 @@ func mapNodePools(ctx context.Context, cl *ske.Cluster, m *Model) error {
|
|||
nodePools := []attr.Value{}
|
||||
for i, nodePoolResp := range *cl.Nodepools {
|
||||
nodePool := map[string]attr.Value{
|
||||
"name": types.StringPointerValue(nodePoolResp.Name),
|
||||
"machine_type": types.StringPointerValue(nodePoolResp.Machine.Type),
|
||||
"os_name": types.StringNull(),
|
||||
"os_version_min": modelNodePoolOSVersionMin[*nodePoolResp.Name],
|
||||
"os_version": modelNodePoolOSVersion[*nodePoolResp.Name],
|
||||
"minimum": types.Int64PointerValue(nodePoolResp.Minimum),
|
||||
"maximum": types.Int64PointerValue(nodePoolResp.Maximum),
|
||||
"max_surge": types.Int64PointerValue(nodePoolResp.MaxSurge),
|
||||
"max_unavailable": types.Int64PointerValue(nodePoolResp.MaxUnavailable),
|
||||
"volume_type": types.StringNull(),
|
||||
"volume_size": types.Int64PointerValue(nodePoolResp.Volume.Size),
|
||||
"labels": types.MapNull(types.StringType),
|
||||
"cri": types.StringNull(),
|
||||
"availability_zones": types.ListNull(types.StringType),
|
||||
"name": types.StringPointerValue(nodePoolResp.Name),
|
||||
"machine_type": types.StringPointerValue(nodePoolResp.Machine.Type),
|
||||
"os_name": types.StringNull(),
|
||||
"os_version_min": modelNodePoolOSVersionMin[*nodePoolResp.Name],
|
||||
"os_version": modelNodePoolOSVersion[*nodePoolResp.Name],
|
||||
"minimum": types.Int64PointerValue(nodePoolResp.Minimum),
|
||||
"maximum": types.Int64PointerValue(nodePoolResp.Maximum),
|
||||
"max_surge": types.Int64PointerValue(nodePoolResp.MaxSurge),
|
||||
"max_unavailable": types.Int64PointerValue(nodePoolResp.MaxUnavailable),
|
||||
"volume_type": types.StringNull(),
|
||||
"volume_size": types.Int64PointerValue(nodePoolResp.Volume.Size),
|
||||
"labels": types.MapNull(types.StringType),
|
||||
"cri": types.StringNull(),
|
||||
"availability_zones": types.ListNull(types.StringType),
|
||||
"allow_system_components": types.BoolPointerValue(nodePoolResp.AllowSystemComponents),
|
||||
}
|
||||
|
||||
if nodePoolResp.Machine != nil && nodePoolResp.Machine.Image != nil {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@ import (
|
|||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/utils"
|
||||
"github.com/stackitcloud/stackit-sdk-go/services/ske"
|
||||
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/conversion"
|
||||
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
|
||||
)
|
||||
|
||||
|
|
@ -106,7 +108,8 @@ func TestMapFields(t *testing.T) {
|
|||
Name: utils.Ptr("name"),
|
||||
Nodepools: &[]ske.Nodepool{
|
||||
{
|
||||
AvailabilityZones: &[]string{"z1", "z2"},
|
||||
AllowSystemComponents: utils.Ptr(true),
|
||||
AvailabilityZones: &[]string{"z1", "z2"},
|
||||
Cri: &ske.CRI{
|
||||
Name: utils.Ptr("cri"),
|
||||
},
|
||||
|
|
@ -195,6 +198,7 @@ func TestMapFields(t *testing.T) {
|
|||
types.StringValue("z2"),
|
||||
},
|
||||
),
|
||||
"allow_system_components": types.BoolValue(true),
|
||||
},
|
||||
),
|
||||
},
|
||||
|
|
@ -481,6 +485,7 @@ func TestMapFields(t *testing.T) {
|
|||
types.StringValue("z2"),
|
||||
},
|
||||
),
|
||||
"allow_system_components": types.BoolValue(true),
|
||||
},
|
||||
),
|
||||
},
|
||||
|
|
@ -599,6 +604,7 @@ func TestMapFields(t *testing.T) {
|
|||
types.StringValue("z2"),
|
||||
},
|
||||
),
|
||||
"allow_system_components": types.BoolNull(),
|
||||
},
|
||||
),
|
||||
},
|
||||
|
|
@ -2284,3 +2290,57 @@ func TestToNetworkPayload(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifySystemComponentNodepools(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
nodePools []ske.Nodepool
|
||||
isValid bool
|
||||
}{
|
||||
{
|
||||
description: "all pools allow system components",
|
||||
nodePools: []ske.Nodepool{
|
||||
{
|
||||
AllowSystemComponents: conversion.BoolValueToPointer(basetypes.NewBoolValue(true)),
|
||||
},
|
||||
{
|
||||
AllowSystemComponents: conversion.BoolValueToPointer(basetypes.NewBoolValue(true)),
|
||||
},
|
||||
},
|
||||
isValid: true,
|
||||
},
|
||||
{
|
||||
description: "one pool allows system components",
|
||||
nodePools: []ske.Nodepool{
|
||||
{
|
||||
AllowSystemComponents: conversion.BoolValueToPointer(basetypes.NewBoolValue(true)),
|
||||
},
|
||||
{
|
||||
AllowSystemComponents: conversion.BoolValueToPointer(basetypes.NewBoolValue(false)),
|
||||
},
|
||||
},
|
||||
isValid: true,
|
||||
},
|
||||
{
|
||||
description: "no pool allows system components",
|
||||
nodePools: []ske.Nodepool{
|
||||
{
|
||||
AllowSystemComponents: conversion.BoolValueToPointer(basetypes.NewBoolValue(false)),
|
||||
},
|
||||
{
|
||||
AllowSystemComponents: conversion.BoolValueToPointer(basetypes.NewBoolValue(false)),
|
||||
},
|
||||
},
|
||||
isValid: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.description, func(t *testing.T) {
|
||||
err := verifySystemComponentsInNodePools(tt.nodePools)
|
||||
if (err == nil) != tt.isValid {
|
||||
t.Errorf("expected validity to be %v, but got error: %v", tt.isValid, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,17 +21,17 @@ var clusterResource = map[string]string{
|
|||
"project_id": testutil.ProjectId,
|
||||
"name": fmt.Sprintf("cl-%s", acctest.RandStringFromCharSet(5, acctest.CharSetAlphaNum)),
|
||||
"name_min": fmt.Sprintf("cl-min-%s", acctest.RandStringFromCharSet(3, acctest.CharSetAlphaNum)),
|
||||
"kubernetes_version_min": "1.28",
|
||||
"kubernetes_version_used": "1.28.11",
|
||||
"kubernetes_version_min_new": "1.29",
|
||||
"kubernetes_version_used_new": "1.29.6",
|
||||
"kubernetes_version_min": "1.29",
|
||||
"kubernetes_version_used": "1.29.10",
|
||||
"kubernetes_version_min_new": "1.30",
|
||||
"kubernetes_version_used_new": "1.30.6",
|
||||
"nodepool_name": "np-acc-test",
|
||||
"nodepool_name_min": "np-acc-min-test",
|
||||
"nodepool_machine_type": "b1.2",
|
||||
"nodepool_os_version_min": "3815.2",
|
||||
"nodepool_os_version_used": "3815.2.3",
|
||||
"nodepool_os_version_min_new": "3815.2.3",
|
||||
"nodepool_os_version_used_new": "3815.2.3",
|
||||
"nodepool_os_version_min": "3975.2",
|
||||
"nodepool_os_version_used": "3975.2.0",
|
||||
"nodepool_os_version_min_new": "3975.2.1",
|
||||
"nodepool_os_version_used_new": "3975.2.1",
|
||||
"nodepool_os_name": "flatcar",
|
||||
"nodepool_minimum": "2",
|
||||
"nodepool_maximum": "3",
|
||||
|
|
@ -46,6 +46,7 @@ var clusterResource = map[string]string{
|
|||
"nodepool_taints_effect": "PreferNoSchedule",
|
||||
"nodepool_taints_key": "tkey",
|
||||
"nodepool_taints_value": "tvalue",
|
||||
"nodepool_allow_system_components": "true",
|
||||
"extensions_acl_enabled": "true",
|
||||
"extensions_acl_cidrs": "192.168.0.0/24",
|
||||
"extensions_argus_enabled": "false",
|
||||
|
|
@ -96,6 +97,7 @@ func getConfig(kubernetesVersion, nodePoolMachineOSVersion string, maintenanceEn
|
|||
key = "%s"
|
||||
value = "%s"
|
||||
}]
|
||||
allow_system_components = %s
|
||||
}]
|
||||
extensions = {
|
||||
acl = {
|
||||
|
|
@ -169,6 +171,7 @@ func getConfig(kubernetesVersion, nodePoolMachineOSVersion string, maintenanceEn
|
|||
clusterResource["nodepool_taints_effect"],
|
||||
clusterResource["nodepool_taints_key"],
|
||||
clusterResource["nodepool_taints_value"],
|
||||
clusterResource["nodepool_allow_system_components"],
|
||||
clusterResource["extensions_acl_enabled"],
|
||||
clusterResource["extensions_acl_cidrs"],
|
||||
clusterResource["extensions_argus_enabled"],
|
||||
|
|
@ -233,6 +236,7 @@ func TestAccSKE(t *testing.T) {
|
|||
resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "node_pools.0.taints.0.effect", clusterResource["nodepool_taints_effect"]),
|
||||
resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "node_pools.0.taints.0.key", clusterResource["nodepool_taints_key"]),
|
||||
resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "node_pools.0.taints.0.value", clusterResource["nodepool_taints_value"]),
|
||||
resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "node_pools.0.allow_system_components", clusterResource["nodepool_allow_system_components"]),
|
||||
resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "node_pools.0.cri", clusterResource["nodepool_cri"]),
|
||||
resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "extensions.acl.enabled", clusterResource["extensions_acl_enabled"]),
|
||||
resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "extensions.acl.allowed_cidrs.#", "1"),
|
||||
|
|
@ -343,6 +347,7 @@ func TestAccSKE(t *testing.T) {
|
|||
resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "node_pools.0.taints.0.effect", clusterResource["nodepool_taints_effect"]),
|
||||
resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "node_pools.0.taints.0.key", clusterResource["nodepool_taints_key"]),
|
||||
resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "node_pools.0.taints.0.value", clusterResource["nodepool_taints_value"]),
|
||||
resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "node_pools.0.allow_system_components", clusterResource["nodepool_allow_system_components"]),
|
||||
resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "node_pools.0.cri", clusterResource["nodepool_cri"]),
|
||||
resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "extensions.acl.enabled", clusterResource["extensions_acl_enabled"]),
|
||||
resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "extensions.acl.allowed_cidrs.#", "1"),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue