Skip to content

Commit 96a3cf9

Browse files
authored
Release v0.24.5 (week 39) (#684)
* goreleaser bug * review fix for sec G115 issue * G115 go sec fix * go sec fix * PLT-1911: Added graceful_creation_timeout feature for all clusters (#686) * PLT-1911: Addded graceful_creation_timeout feature for all clusters * added support for state and health in data source * fixed unit test * fixed timeout condition * PLT-1969: Fix * PLT-1964: Added TypeSet support for machine_pool in custom cloud (#688) * Added TypeSet support for machine_pool in custom cloud * added docs * hash fix * PLT-1964: Fixed upgrade issues * fix update repave * PLT-1964: Eks cluster machine_pool TypeSet update (#689) * PLT-1964-eks: Updated typeset for eks machine_pool * PLT-1964: Updated machine_pool to typeset update schema * fixed unit test * Reverted PLT-1911
1 parent 839e77b commit 96a3cf9

18 files changed

+946
-141
lines changed

docs/data-sources/cluster.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,7 @@ resource "local_file" "admin_kube_config" {
5050
### Read-Only
5151

5252
- `admin_kube_config` (String) The admin kubeconfig file for accessing the cluster. This is computed automatically.
53+
- `health` (String) The current health status of the cluster. This is computed automatically.
5354
- `id` (String) The ID of this resource.
5455
- `kube_config` (String) The kubeconfig file for accessing the cluster as a non-admin user. This is computed automatically.
56+
- `state` (String) The current state of the cluster. This is computed automatically.

docs/resources/cluster_custom_cloud.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Refer to the [Import section](/docs#import) to learn more.
147147
- `cloud` (String) The cloud provider name.
148148
- `cloud_account_id` (String) The cloud account id to use for this cluster.
149149
- `cloud_config` (Block List, Min: 1, Max: 1) The Cloud environment configuration settings such as network parameters and encryption parameters that apply to this cluster. (see [below for nested schema](#nestedblock--cloud_config))
150-
- `machine_pool` (Block List, Min: 1) The machine pool configuration for the cluster. (see [below for nested schema](#nestedblock--machine_pool))
150+
- `machine_pool` (Block Set, Min: 1) The machine pool configuration for the cluster. (see [below for nested schema](#nestedblock--machine_pool))
151151
- `name` (String) The name of the cluster.
152152

153153
### Optional

docs/resources/cluster_eks.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ Refer to the [Import section](/docs#import) to learn more.
116116

117117
- `cloud_account_id` (String) The AWS cloud account id to use for this cluster.
118118
- `cloud_config` (Block List, Min: 1, Max: 1) The AWS environment configuration settings such as network parameters and encryption parameters that apply to this cluster. (see [below for nested schema](#nestedblock--cloud_config))
119-
- `machine_pool` (Block List, Min: 1) The machine pool configuration for the cluster. (see [below for nested schema](#nestedblock--machine_pool))
119+
- `machine_pool` (Block Set, Min: 1) The machine pool configuration for the cluster. (see [below for nested schema](#nestedblock--machine_pool))
120120
- `name` (String) The name of the cluster.
121121

122122
### Optional

spectrocloud/cluster_common_hash.go

Lines changed: 118 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,28 @@ func CommonHash(nodePool map[string]interface{}) *bytes.Buffer {
2222
buf.WriteString(HashStringMapList(nodePool["taints"]))
2323
}
2424
if val, ok := nodePool["control_plane"]; ok {
25-
buf.WriteString(fmt.Sprintf("%t-", val.(bool)))
25+
var boolVal bool
26+
switch v := val.(type) {
27+
case bool:
28+
boolVal = v
29+
case *bool:
30+
if v != nil {
31+
boolVal = *v
32+
}
33+
}
34+
buf.WriteString(fmt.Sprintf("%t-", boolVal))
2635
}
2736
if val, ok := nodePool["control_plane_as_worker"]; ok {
28-
buf.WriteString(fmt.Sprintf("%t-", val.(bool)))
37+
var boolVal bool
38+
switch v := val.(type) {
39+
case bool:
40+
boolVal = v
41+
case *bool:
42+
if v != nil {
43+
boolVal = *v
44+
}
45+
}
46+
buf.WriteString(fmt.Sprintf("%t-", boolVal))
2947
}
3048
if val, ok := nodePool["name"]; ok {
3149
buf.WriteString(fmt.Sprintf("%s-", val.(string)))
@@ -66,7 +84,16 @@ func resourceMachinePoolAzureHash(v interface{}) int {
6684
buf.WriteString(fmt.Sprintf("%s-", val.(string)))
6785
}
6886
if val, ok := m["is_system_node_pool"]; ok {
69-
buf.WriteString(fmt.Sprintf("%t-", val.(bool)))
87+
var boolVal bool
88+
switch v := val.(type) {
89+
case bool:
90+
boolVal = v
91+
case *bool:
92+
if v != nil {
93+
boolVal = *v
94+
}
95+
}
96+
buf.WriteString(fmt.Sprintf("%t-", boolVal))
7097
}
7198
if val, ok := m["os_type"]; ok && val != "" {
7299
buf.WriteString(fmt.Sprintf("%s-", val.(string)))
@@ -86,7 +113,16 @@ func resourceMachinePoolAksHash(v interface{}) int {
86113
buf.WriteString(fmt.Sprintf("%d-", val.(int)))
87114
}
88115
if val, ok := m["is_system_node_pool"]; ok {
89-
buf.WriteString(fmt.Sprintf("%t-", val.(bool)))
116+
var boolVal bool
117+
switch v := val.(type) {
118+
case bool:
119+
boolVal = v
120+
case *bool:
121+
if v != nil {
122+
boolVal = *v
123+
}
124+
}
125+
buf.WriteString(fmt.Sprintf("%t-", boolVal))
90126
}
91127
if val, ok := m["storage_account_type"]; ok {
92128
buf.WriteString(fmt.Sprintf("%s-", val.(string)))
@@ -150,31 +186,73 @@ func resourceMachinePoolAwsHash(v interface{}) int {
150186
}
151187

152188
func resourceMachinePoolEksHash(v interface{}) int {
153-
m := v.(map[string]interface{})
154-
buf := CommonHash(m)
189+
nodePool := v.(map[string]interface{})
190+
var buf bytes.Buffer
155191

156-
buf.WriteString(fmt.Sprintf("%d-", m["disk_size_gb"].(int)))
157-
if m["min"] != nil {
158-
buf.WriteString(fmt.Sprintf("%d-", m["min"].(int)))
192+
if val, ok := nodePool["count"]; ok {
193+
buf.WriteString(fmt.Sprintf("%d-", val.(int)))
159194
}
160-
if m["max"] != nil {
161-
buf.WriteString(fmt.Sprintf("%d-", m["max"].(int)))
195+
if val, ok := nodePool["disk_size_gb"]; ok {
196+
buf.WriteString(fmt.Sprintf("%d-", val.(int)))
197+
}
198+
if val, ok := nodePool["instance_type"]; ok {
199+
buf.WriteString(fmt.Sprintf("%s-", val.(string)))
200+
}
201+
if val, ok := nodePool["name"]; ok {
202+
buf.WriteString(fmt.Sprintf("%s-", val.(string)))
203+
}
204+
205+
if _, ok := nodePool["additional_labels"]; ok {
206+
buf.WriteString(HashStringMap(nodePool["additional_labels"]))
207+
}
208+
if val, ok := nodePool["ami_type"]; ok {
209+
buf.WriteString(fmt.Sprintf("%s-", val.(string)))
162210
}
163-
buf.WriteString(fmt.Sprintf("%s-", m["instance_type"].(string)))
164-
buf.WriteString(fmt.Sprintf("%s-", m["capacity_type"].(string)))
165-
buf.WriteString(fmt.Sprintf("%s-", m["max_price"].(string)))
166211

167-
keys := make([]string, 0, len(m["az_subnets"].(map[string]interface{})))
168-
for k := range m["az_subnets"].(map[string]interface{}) {
212+
keys := make([]string, 0, len(nodePool["az_subnets"].(map[string]interface{})))
213+
for k := range nodePool["az_subnets"].(map[string]interface{}) {
169214
keys = append(keys, k)
170215
}
171216
sort.Strings(keys)
172217
for _, k := range keys {
173-
buf.WriteString(fmt.Sprintf("%s-%s", k, m["az_subnets"].(map[string]interface{})[k].(string)))
218+
buf.WriteString(fmt.Sprintf("%s-%s", k, nodePool["az_subnets"].(map[string]interface{})[k].(string)))
174219
}
175220

176-
if m["eks_launch_template"] != nil {
177-
buf.WriteString(eksLaunchTemplate(m["eks_launch_template"]))
221+
if nodePool["azs"] != nil {
222+
azsList := nodePool["azs"].([]interface{})
223+
azsListStr := make([]string, len(azsList))
224+
for i, v := range azsList {
225+
azsListStr[i] = v.(string)
226+
}
227+
sort.Strings(azsListStr)
228+
azsStr := strings.Join(azsListStr, "-")
229+
buf.WriteString(fmt.Sprintf("%s-", azsStr))
230+
}
231+
232+
if val, ok := nodePool["capacity_type"]; ok {
233+
buf.WriteString(fmt.Sprintf("%s-", val.(string)))
234+
}
235+
236+
if nodePool["min"] != nil {
237+
buf.WriteString(fmt.Sprintf("%d-", nodePool["min"].(int)))
238+
}
239+
if nodePool["max"] != nil {
240+
buf.WriteString(fmt.Sprintf("%d-", nodePool["max"].(int)))
241+
}
242+
if nodePool["max_price"] != nil {
243+
buf.WriteString(fmt.Sprintf("%s-", nodePool["max_price"].(string)))
244+
}
245+
if nodePool["node"] != nil {
246+
buf.WriteString(HashStringMapList(nodePool["node"]))
247+
}
248+
if _, ok := nodePool["taints"]; ok {
249+
buf.WriteString(HashStringMapList(nodePool["taints"]))
250+
}
251+
if nodePool["eks_launch_template"] != nil {
252+
buf.WriteString(eksLaunchTemplate(nodePool["eks_launch_template"]))
253+
}
254+
if val, ok := nodePool["update_strategy"]; ok {
255+
buf.WriteString(fmt.Sprintf("%s-", val.(string)))
178256
}
179257

180258
return int(hash(buf.String()))
@@ -246,23 +324,33 @@ func resourceMachinePoolVsphereHash(v interface{}) int {
246324
func resourceMachinePoolCustomCloudHash(v interface{}) int {
247325
m := v.(map[string]interface{})
248326
var buf bytes.Buffer
249-
if _, ok := m["name"]; ok {
250-
buf.WriteString(HashStringMap(m["name"]))
251-
}
252-
if _, ok := m["count"]; ok {
253-
buf.WriteString(HashStringMap(m["count"]))
254-
}
255-
if _, ok := m["additional_labels"]; ok {
256-
buf.WriteString(HashStringMap(m["additional_labels"]))
257-
}
327+
258328
if _, ok := m["taints"]; ok {
259329
buf.WriteString(HashStringMapList(m["taints"]))
260330
}
261331
if val, ok := m["control_plane"]; ok {
262-
buf.WriteString(fmt.Sprintf("%t-", val.(bool)))
332+
var boolVal bool
333+
switch v := val.(type) {
334+
case bool:
335+
boolVal = v
336+
case *bool:
337+
if v != nil {
338+
boolVal = *v
339+
}
340+
}
341+
buf.WriteString(fmt.Sprintf("%t-", boolVal))
263342
}
264343
if val, ok := m["control_plane_as_worker"]; ok {
265-
buf.WriteString(fmt.Sprintf("%t-", val.(bool)))
344+
var boolVal bool
345+
switch v := val.(type) {
346+
case bool:
347+
boolVal = v
348+
case *bool:
349+
if v != nil {
350+
boolVal = *v
351+
}
352+
}
353+
buf.WriteString(fmt.Sprintf("%t-", boolVal))
266354
}
267355
buf.WriteString(fmt.Sprintf("%s-", m["node_pool_config"].(string)))
268356

spectrocloud/cluster_common_hash_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func TestResourceMachinePoolEksHash(t *testing.T) {
216216
},
217217
},
218218
},
219-
expected: 456946481,
219+
expected: 706444520,
220220
},
221221
}
222222

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package common
2+
3+
// SafeUint32 converts int to uint32 with bounds checking to prevent overflow
4+
func SafeUint32(value int) uint32 {
5+
if value < 0 {
6+
return 0
7+
}
8+
// On 32-bit systems, int max is smaller than uint32 max, so no overflow possible
9+
// On 64-bit systems, we need to check against uint32 max
10+
if ^uint(0)>>32 == 0 {
11+
// 32-bit system: int and uint32 have same size, no overflow possible
12+
if value >= 0 {
13+
return uint32(value)
14+
}
15+
return 0
16+
}
17+
// 64-bit system: check against uint32 max
18+
if uint64(value) > 0xFFFFFFFF {
19+
return 0xFFFFFFFF
20+
}
21+
if value >= 0 {
22+
return uint32(value)
23+
}
24+
return 0
25+
}

spectrocloud/data_source_cluster.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ func dataSourceCluster() *schema.Resource {
4343
Default: false,
4444
Description: "If set to true, the cluster will treated as a virtual cluster. Defaults to `false`.",
4545
},
46+
"state": {
47+
Type: schema.TypeString,
48+
Computed: true,
49+
Description: "The current state of the cluster. This is computed automatically.",
50+
},
51+
"health": {
52+
Type: schema.TypeString,
53+
Computed: true,
54+
Description: "The current health status of the cluster. This is computed automatically.",
55+
},
4656
},
4757
}
4858
}
@@ -73,6 +83,21 @@ func dataSourceClusterRead(_ context.Context, d *schema.ResourceData, m interfac
7383
if err := d.Set("name", cluster.Metadata.Name); err != nil {
7484
return diag.FromErr(err)
7585
}
86+
87+
// Set cluster state
88+
if cluster.Status != nil && cluster.Status.State != "" {
89+
if err := d.Set("state", cluster.Status.State); err != nil {
90+
return diag.FromErr(err)
91+
}
92+
}
93+
94+
// Set cluster health
95+
clusterSummary, summaryErr := c.GetClusterOverview(cluster.Metadata.UID)
96+
if summaryErr == nil && clusterSummary.Status.Health != nil && clusterSummary.Status.Health.State != "" {
97+
if err := d.Set("health", clusterSummary.Status.Health.State); err != nil {
98+
return diag.FromErr(err)
99+
}
100+
}
76101
}
77102
}
78103
return diags

spectrocloud/data_source_cluster_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package spectrocloud
22

33
import (
44
"context"
5+
"testing"
6+
57
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
68
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
79
"github.com/stretchr/testify/assert"
8-
"testing"
910
)
1011

1112
func TestDataSourceClusterRead(t *testing.T) {
@@ -23,6 +24,8 @@ func TestDataSourceClusterRead(t *testing.T) {
2324
"virtual": {Type: schema.TypeBool, Optional: true},
2425
"kube_config": {Type: schema.TypeString, Computed: true},
2526
"admin_kube_config": {Type: schema.TypeString, Computed: true},
27+
"state": {Type: schema.TypeString, Computed: true},
28+
"health": {Type: schema.TypeString, Computed: true},
2629
}, map[string]interface{}{
2730
"name": "test-cluster",
2831
"context": "some-context",
@@ -39,6 +42,8 @@ func TestDataSourceClusterRead(t *testing.T) {
3942
"virtual": {Type: schema.TypeBool, Optional: true},
4043
"kube_config": {Type: schema.TypeString, Computed: true},
4144
"admin_kube_config": {Type: schema.TypeString, Computed: true},
45+
"state": {Type: schema.TypeString, Computed: true},
46+
"health": {Type: schema.TypeString, Computed: true},
4247
}, map[string]interface{}{
4348
"name": "test-cluster",
4449
"context": "some-context",

spectrocloud/kubevirt/schema/virtualmachineinstance/domain_spec.go

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ package virtualmachineinstance
22

33
import (
44
"fmt"
5+
"math"
56

67
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
78
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
89
"k8s.io/apimachinery/pkg/api/resource"
910
kubevirtapiv1 "kubevirt.io/api/core/v1"
1011

11-
"github.com/spectrocloud/terraform-provider-spectrocloud/spectrocloud/constants"
12+
"github.com/spectrocloud/terraform-provider-spectrocloud/spectrocloud/common"
1213
"github.com/spectrocloud/terraform-provider-spectrocloud/spectrocloud/kubevirt/utils"
1314
)
1415

@@ -289,22 +290,31 @@ func expandCPU(cpu map[string]interface{}) (kubevirtapiv1.CPU, error) {
289290
}
290291

291292
if v, ok := cpu["cores"].(int); ok {
292-
if v < 0 || v > constants.UInt32MaxValue {
293+
if v < 0 {
294+
return result, fmt.Errorf("cores value %d cannot be negative", v)
295+
}
296+
if v > math.MaxInt { // Cap to max representable int on this architecture
293297
return result, fmt.Errorf("cores value %d is out of range for uint32", v)
294298
}
295-
result.Cores = uint32(v)
299+
result.Cores = common.SafeUint32(v)
296300
}
297301
if v, ok := cpu["sockets"].(int); ok {
298-
if v < 0 || v > constants.UInt32MaxValue {
302+
if v < 0 {
303+
return result, fmt.Errorf("sockets value %d cannot be negative", v)
304+
}
305+
if v > math.MaxInt { // Cap to max representable int on this architecture
299306
return result, fmt.Errorf("sockets value %d is out of range for uint32", v)
300307
}
301-
result.Sockets = uint32(v)
308+
result.Sockets = common.SafeUint32(v)
302309
}
303310
if v, ok := cpu["threads"].(int); ok {
304-
if v < 0 || v > constants.UInt32MaxValue {
311+
if v < 0 {
312+
return result, fmt.Errorf("threads value %d cannot be negative", v)
313+
}
314+
if v > math.MaxInt { // Cap to max representable int on this architecture
305315
return result, fmt.Errorf("threads value %d is out of range for uint32", v)
306316
}
307-
result.Threads = uint32(v)
317+
result.Threads = common.SafeUint32(v)
308318
}
309319

310320
return result, nil

0 commit comments

Comments
 (0)