Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ For questions or issues with the provider, open up an issue in the provider GitH

- `api_key` (String, Sensitive) The Spectro Cloud API key. Can also be set with the `SPECTROCLOUD_APIKEY` environment variable.
- `host` (String) The Spectro Cloud API host url. Can also be set with the `SPECTROCLOUD_HOST` environment variable. Defaults to https://api.spectrocloud.com
- `ignore_insecure_tls_error` (Boolean) Ignore insecure TLS errors for Spectro Cloud API endpoints. Defaults to false.
- `ignore_insecure_tls_error` (Boolean) Ignore insecure TLS errors for Spectro Cloud API endpoints. ⚠️ WARNING: Setting this to true disables SSL certificate verification and makes connections vulnerable to man-in-the-middle attacks. Only use this in development/testing environments or when connecting to self-signed certificates in trusted networks. Defaults to false.
- `project_name` (String) The Palette project the provider will target. If no value is provided, the `Default` Palette project is used. The default value is `Default`.
- `retry_attempts` (Number) Number of retry attempts. Can also be set with the `SPECTROCLOUD_RETRY_ATTEMPTS` environment variable. Defaults to 10.
- `trace` (Boolean) Enable HTTP request tracing. Can also be set with the `SPECTROCLOUD_TRACE` environment variable. To enable Terraform debug logging, set `TF_LOG=DEBUG`. Visit the Terraform documentation to learn more about Terraform [debugging](https://developer.hashicorp.com/terraform/plugin/log/managing).
2 changes: 1 addition & 1 deletion docs/resources/registry_oci.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Optional:
Optional:

- `certificate` (String) Specifies the TLS certificate used for secure communication. Required for enabling SSL/TLS encryption.
- `insecure_skip_verify` (Boolean) Disables TLS certificate verification when set to true. Use with caution as it may expose connections to security risks.
- `insecure_skip_verify` (Boolean) Disables TLS certificate verification when set to true. ⚠️ WARNING: Setting this to true disables SSL certificate verification and makes connections vulnerable to man-in-the-middle attacks. Only use this when connecting to registries with self-signed certificates in trusted networks.



Expand Down
2 changes: 1 addition & 1 deletion docs/resources/sso.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Optional:

- `default_team_ids` (Set of String) A set of default team IDs assigned to users.
- `identity_provider_ca_certificate` (String) Certificate authority (CA) certificate for the identity provider.
- `insecure_skip_tls_verify` (Boolean) Boolean to skip TLS verification for identity provider communication.
- `insecure_skip_tls_verify` (Boolean) Boolean to skip TLS verification for identity provider communication. ⚠️ WARNING: Setting this to true disables SSL certificate verification and makes connections vulnerable to man-in-the-middle attacks. Only use this when connecting to identity providers with self-signed certificates in trusted networks.
- `user_info_endpoint` (Block List, Max: 1) To allow Palette to query the OIDC userinfo endpoint using the provided Issuer URL. Palette will first attempt to retrieve role and group information from userInfo endpoint. If unavailable, Palette will fall back to using Required Claims as specified above. Use the following fields to specify what Required Claims Palette will include when querying the userinfo endpoint. (see [below for nested schema](#nestedblock--oidc--user_info_endpoint))

Read-Only:
Expand Down
6 changes: 3 additions & 3 deletions spectrocloud/application_create_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func toAppDeploymentTargetClusterLimits(d *schema.ResourceData) *models.V1AppDep
limits := config["limits"].([]interface{})[i].(map[string]interface{})
if limits["cpu"] != nil && limits["memory"] != nil {
return &models.V1AppDeploymentTargetClusterLimits{
CPU: int32(limits["cpu"].(int)),
MemoryMiB: int32(limits["memory"].(int)),
StorageGiB: int32(limits["storage"].(int)),
CPU: SafeInt32(limits["cpu"].(int)),
MemoryMiB: SafeInt32(limits["memory"].(int)),
StorageGiB: SafeInt32(limits["storage"].(int)),
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion spectrocloud/cluster_common_hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"hash/fnv"
"sort"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -467,7 +468,10 @@ func hash(s string) uint32 {
func YamlContentHash(yamlContent string) string {
canonicalContent := yamlContentToCanonicalString(yamlContent)
h := fnv.New64a()
h.Write([]byte(canonicalContent))
if _, err := h.Write([]byte(canonicalContent)); err != nil {
// If hash writing fails, return a fallback hash
return fmt.Sprintf("error_hash_%d", time.Now().UnixNano())
}
return fmt.Sprintf("%x", h.Sum64())
}

Expand Down
15 changes: 15 additions & 0 deletions spectrocloud/constants/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package constants

const (
// Int32MaxValue represents the maximum value for int32 type (2^31 - 1)
Int32MaxValue = 2147483647

// Int32MinValue represents the minimum value for int32 type (-2^31)
Int32MinValue = -2147483648

// UInt32MaxValue represents the maximum value for uint32 type (2^32 - 1)
UInt32MaxValue = 4294967295

// Int64MaxValue represents the maximum value for int64 type (2^63 - 1)
Int64MaxValue = 9223372036854775807
)
16 changes: 14 additions & 2 deletions spectrocloud/kubevirt/schema/k8s/affinity_spec.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package k8s

import (
"math"
"regexp"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand All @@ -11,6 +12,17 @@ import (
"github.com/spectrocloud/terraform-provider-spectrocloud/spectrocloud/kubevirt/utils"
)

// safeInt32 converts int to int32 with bounds checking to prevent overflow
func safeInt32(value int) int32 {
if value > math.MaxInt32 {
return math.MaxInt32
}
if value < math.MinInt32 {
return math.MinInt32
}
return int32(value)
}

func affinityFields() map[string]*schema.Schema {
return map[string]*schema.Schema{
"node_affinity": {
Expand Down Expand Up @@ -437,7 +449,7 @@ func expandPreferredSchedulingTerms(t []interface{}) []v1.PreferredSchedulingTer
for i, n := range t {
in := n.(map[string]interface{})
if v, ok := in["weight"].(int); ok {
obj[i].Weight = int32(v)
obj[i].Weight = safeInt32(v)
}
if v, ok := in["preference"].([]interface{}); ok && len(v) > 0 {
obj[i].Preference = *expandNodeSelectorTerm(v)
Expand Down Expand Up @@ -474,7 +486,7 @@ func expandWeightedPodAffinityTerms(t []interface{}) []v1.WeightedPodAffinityTer
for i, n := range t {
in := n.(map[string]interface{})
if v, ok := in["weight"].(int); ok {
obj[i].Weight = int32(v)
obj[i].Weight = safeInt32(v)
}
if v, ok := in["pod_affinity_term"].([]interface{}); ok && len(v) > 0 {
obj[i].PodAffinityTerm = expandPodAffinityTerms(v)[0]
Expand Down
12 changes: 12 additions & 0 deletions spectrocloud/kubevirt/schema/virtualmachineinstance/domain_spec.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package virtualmachineinstance

import (
"fmt"

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

"github.com/spectrocloud/terraform-provider-spectrocloud/spectrocloud/constants"
"github.com/spectrocloud/terraform-provider-spectrocloud/spectrocloud/kubevirt/utils"
)

Expand Down Expand Up @@ -286,12 +289,21 @@ func expandCPU(cpu map[string]interface{}) (kubevirtapiv1.CPU, error) {
}

if v, ok := cpu["cores"].(int); ok {
if v < 0 || v > constants.UInt32MaxValue {
return result, fmt.Errorf("cores value %d is out of range for uint32", v)
}
result.Cores = uint32(v)
}
if v, ok := cpu["sockets"].(int); ok {
if v < 0 || v > constants.UInt32MaxValue {
return result, fmt.Errorf("sockets value %d is out of range for uint32", v)
}
result.Sockets = uint32(v)
}
if v, ok := cpu["threads"].(int); ok {
if v < 0 || v > constants.UInt32MaxValue {
return result, fmt.Errorf("threads value %d is out of range for uint32", v)
}
result.Threads = uint32(v)
}

Expand Down
4 changes: 3 additions & 1 deletion spectrocloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func New(_ string) func() *schema.Provider {
"ignore_insecure_tls_error": {
Type: schema.TypeBool,
Optional: true,
Description: "Ignore insecure TLS errors for Spectro Cloud API endpoints. Defaults to false.",
Description: "Ignore insecure TLS errors for Spectro Cloud API endpoints. ⚠️ WARNING: Setting this to true disables SSL certificate verification and makes connections vulnerable to man-in-the-middle attacks. Only use this in development/testing environments or when connecting to self-signed certificates in trusted networks. Defaults to false.",
},
},
ResourcesMap: map[string]*schema.Resource{
Expand Down Expand Up @@ -204,7 +204,9 @@ func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}
projectName := d.Get("project_name").(string)

insecure := d.Get("ignore_insecure_tls_error").(bool)

if insecure {
// #nosec G402
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
}

Expand Down
12 changes: 6 additions & 6 deletions spectrocloud/resource_cluster_aks.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,22 +683,22 @@ func toMachinePoolAks(machinePool interface{}) *models.V1AzureMachinePoolConfigE
labels = append(labels, "worker")
}

min := int32(m["count"].(int))
max := int32(m["count"].(int))
min := SafeInt32(m["count"].(int))
max := SafeInt32(m["count"].(int))

if m["min"] != nil {
min = int32(m["min"].(int))
min = SafeInt32(m["min"].(int))
}

if m["max"] != nil {
max = int32(m["max"].(int))
max = SafeInt32(m["max"].(int))
}

mp := &models.V1AzureMachinePoolConfigEntity{
CloudConfig: &models.V1AzureMachinePoolCloudConfigEntity{
InstanceType: m["instance_type"].(string),
OsDisk: &models.V1AzureOSDisk{
DiskSizeGB: int32(m["disk_size_gb"].(int)),
DiskSizeGB: SafeInt32(m["disk_size_gb"].(int)),
ManagedDisk: &models.V1ManagedDisk{
StorageAccountType: m["storage_account_type"].(string),
},
Expand All @@ -715,7 +715,7 @@ func toMachinePoolAks(machinePool interface{}) *models.V1AzureMachinePoolConfigE
IsControlPlane: controlPlane,
Labels: labels,
Name: types.Ptr(m["name"].(string)),
Size: types.Ptr(int32(m["count"].(int))),
Size: types.Ptr(SafeInt32(m["count"].(int))),
UpdateStrategy: &models.V1UpdateStrategy{
Type: getUpdateStrategy(m),
},
Expand Down
14 changes: 7 additions & 7 deletions spectrocloud/resource_cluster_aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -696,23 +696,23 @@ func toMachinePoolAws(machinePool interface{}, vpcId string) (*models.V1AwsMachi
azs = append(azs, az.(string))
}
}
min := int32(m["count"].(int))
max := int32(m["count"].(int))
min := SafeInt32(m["count"].(int))
max := SafeInt32(m["count"].(int))

if m["min"] != nil {
min = int32(m["min"].(int))
min = SafeInt32(m["min"].(int))
}

if m["max"] != nil {
max = int32(m["max"].(int))
max = SafeInt32(m["max"].(int))
}

mp := &models.V1AwsMachinePoolConfigEntity{
CloudConfig: &models.V1AwsMachinePoolCloudConfigEntity{
Azs: azs,
InstanceType: types.Ptr(m["instance_type"].(string)),
CapacityType: &capacityType,
RootDeviceSize: int64(m["disk_size_gb"].(int)),
RootDeviceSize: SafeInt64(m["disk_size_gb"].(int)),
Subnets: azSubnetsConfigs,
},
PoolConfig: &models.V1MachinePoolConfigEntity{
Expand All @@ -721,7 +721,7 @@ func toMachinePoolAws(machinePool interface{}, vpcId string) (*models.V1AwsMachi
IsControlPlane: controlPlane,
Labels: labels,
Name: types.Ptr(m["name"].(string)),
Size: types.Ptr(int32(m["count"].(int))),
Size: types.Ptr(SafeInt32(m["count"].(int))),
UpdateStrategy: &models.V1UpdateStrategy{
Type: getUpdateStrategy(m),
},
Expand All @@ -736,7 +736,7 @@ func toMachinePoolAws(machinePool interface{}, vpcId string) (*models.V1AwsMachi
if m["node_repave_interval"] != nil {
nodeRepaveInterval = m["node_repave_interval"].(int)
}
mp.PoolConfig.NodeRepaveInterval = int32(nodeRepaveInterval)
mp.PoolConfig.NodeRepaveInterval = SafeInt32(nodeRepaveInterval)
} else {
err := ValidationNodeRepaveIntervalForControlPlane(m["node_repave_interval"].(int))
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions spectrocloud/resource_cluster_azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ func toMachinePoolAzure(machinePool interface{}) (*models.V1AzureMachinePoolConf
Azs: azs,
InstanceType: m["instance_type"].(string),
OsDisk: &models.V1AzureOSDisk{
DiskSizeGB: int32(diskSize),
DiskSizeGB: SafeInt32(diskSize),
ManagedDisk: &models.V1ManagedDisk{
StorageAccountType: diskType,
},
Expand All @@ -814,7 +814,7 @@ func toMachinePoolAzure(machinePool interface{}) (*models.V1AzureMachinePoolConf
IsControlPlane: controlPlane,
Labels: labels,
Name: types.Ptr(m["name"].(string)),
Size: types.Ptr(int32(m["count"].(int))),
Size: types.Ptr(SafeInt32(m["count"].(int))),
UpdateStrategy: &models.V1UpdateStrategy{
Type: getUpdateStrategy(m),
},
Expand All @@ -827,7 +827,7 @@ func toMachinePoolAzure(machinePool interface{}) (*models.V1AzureMachinePoolConf
if m["node_repave_interval"] != nil {
nodeRepaveInterval = m["node_repave_interval"].(int)
}
mp.PoolConfig.NodeRepaveInterval = int32(nodeRepaveInterval)
mp.PoolConfig.NodeRepaveInterval = SafeInt32(nodeRepaveInterval)
} else {
err := ValidationNodeRepaveIntervalForControlPlane(m["node_repave_interval"].(int))
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions spectrocloud/resource_cluster_edge_native.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ func toMachinePoolEdgeNative(machinePool interface{}) (*models.V1EdgeNativeMachi
IsControlPlane: controlPlane,
Labels: labels,
Name: types.Ptr(m["name"].(string)),
Size: types.Ptr(int32(len(cloudConfig.EdgeHosts))),
Size: types.Ptr(SafeInt32(len(cloudConfig.EdgeHosts))),
UpdateStrategy: &models.V1UpdateStrategy{
Type: getUpdateStrategy(m),
},
Expand All @@ -703,7 +703,7 @@ func toMachinePoolEdgeNative(machinePool interface{}) (*models.V1EdgeNativeMachi
nodeRepaveInterval = m["node_repave_interval"].(int)
}
if !controlPlane {
mp.PoolConfig.NodeRepaveInterval = int32(nodeRepaveInterval)
mp.PoolConfig.NodeRepaveInterval = SafeInt32(nodeRepaveInterval)
} else {
err := ValidationNodeRepaveIntervalForControlPlane(nodeRepaveInterval)
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions spectrocloud/resource_cluster_edge_vsphere.go
Original file line number Diff line number Diff line change
Expand Up @@ -622,9 +622,9 @@ func toMachinePoolEdgeVsphere(machinePool interface{}) (*models.V1VsphereMachine

ins := m["instance_type"].([]interface{})[0].(map[string]interface{})
instanceType := models.V1VsphereInstanceType{
DiskGiB: types.Ptr(int32(ins["disk_size_gb"].(int))),
MemoryMiB: types.Ptr(int64(ins["memory_mb"].(int))),
NumCPUs: types.Ptr(int32(ins["cpu"].(int))),
DiskGiB: types.Ptr(SafeInt32(ins["disk_size_gb"].(int))),
MemoryMiB: types.Ptr(SafeInt64(ins["memory_mb"].(int))),
NumCPUs: types.Ptr(SafeInt32(ins["cpu"].(int))),
}

mp := &models.V1VsphereMachinePoolConfigEntity{
Expand All @@ -638,7 +638,7 @@ func toMachinePoolEdgeVsphere(machinePool interface{}) (*models.V1VsphereMachine
IsControlPlane: controlPlane,
Labels: labels,
Name: types.Ptr(m["name"].(string)),
Size: types.Ptr(int32(m["count"].(int))),
Size: types.Ptr(SafeInt32(m["count"].(int))),
UpdateStrategy: &models.V1UpdateStrategy{
Type: getUpdateStrategy(m),
},
Expand All @@ -651,7 +651,7 @@ func toMachinePoolEdgeVsphere(machinePool interface{}) (*models.V1VsphereMachine
if m["node_repave_interval"] != nil {
nodeRepaveInterval = m["node_repave_interval"].(int)
}
mp.PoolConfig.NodeRepaveInterval = int32(nodeRepaveInterval)
mp.PoolConfig.NodeRepaveInterval = SafeInt32(nodeRepaveInterval)
} else {
err := ValidationNodeRepaveIntervalForControlPlane(m["node_repave_interval"].(int))
if err != nil {
Expand Down
14 changes: 7 additions & 7 deletions spectrocloud/resource_cluster_eks.go
Original file line number Diff line number Diff line change
Expand Up @@ -896,15 +896,15 @@ func toMachinePoolEks(machinePool interface{}) *models.V1EksMachinePoolConfigEnt
capacityType = m["capacity_type"].(string)
}

min := int32(m["count"].(int))
max := int32(m["count"].(int))
min := SafeInt32(m["count"].(int))
max := SafeInt32(m["count"].(int))

if m["min"] != nil {
min = int32(m["min"].(int))
min = SafeInt32(m["min"].(int))
}

if m["max"] != nil {
max = int32(m["max"].(int))
max = SafeInt32(m["max"].(int))
}
instanceType := ""
if val, ok := m["instance_type"]; ok {
Expand All @@ -914,9 +914,9 @@ func toMachinePoolEks(machinePool interface{}) *models.V1EksMachinePoolConfigEnt
if val, ok := m["ami_type"]; ok {
amiType = val.(string)
}
diskSizeGb := int64(0)
diskSizeGb := SafeInt64(0)
if dVal, ok := m["disk_size_gb"]; ok {
diskSizeGb = int64(dVal.(int))
diskSizeGb = SafeInt64(dVal.(int))
}
mp := &models.V1EksMachinePoolConfigEntity{
CloudConfig: &models.V1EksMachineCloudConfigEntity{
Expand All @@ -933,7 +933,7 @@ func toMachinePoolEks(machinePool interface{}) *models.V1EksMachinePoolConfigEnt
IsControlPlane: controlPlane,
Labels: labels,
Name: types.Ptr(m["name"].(string)),
Size: types.Ptr(int32(m["count"].(int))),
Size: types.Ptr(SafeInt32(m["count"].(int))),
UpdateStrategy: &models.V1UpdateStrategy{
Type: getUpdateStrategy(m),
},
Expand Down
Loading