diff --git a/go.mod b/go.mod index 7f012d80..48aa9489 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/stackitcloud/stackit-sdk-go/services/serverbackup v0.5.0 github.com/stackitcloud/stackit-sdk-go/services/serverupdate v0.3.0 github.com/stackitcloud/stackit-sdk-go/services/serviceenablement v0.4.0 - github.com/stackitcloud/stackit-sdk-go/services/ske v0.21.0 + github.com/stackitcloud/stackit-sdk-go/services/ske v0.21.1 github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v0.9.0 github.com/teambition/rrule-go v1.8.2 golang.org/x/mod v0.22.0 diff --git a/go.sum b/go.sum index 11e9adee..87bf65e7 100644 --- a/go.sum +++ b/go.sum @@ -187,8 +187,8 @@ github.com/stackitcloud/stackit-sdk-go/services/serverupdate v0.3.0 h1:x39lier26 github.com/stackitcloud/stackit-sdk-go/services/serverupdate v0.3.0/go.mod h1:m/lZ3XH3wdKkkFb6vHxi0MhhMdRL2uAuCATeYChh+s0= github.com/stackitcloud/stackit-sdk-go/services/serviceenablement v0.4.0 h1:K5fVTcJxjOVwJBa3kiWRsYNAq+I3jAYdU1U+f6no5lE= github.com/stackitcloud/stackit-sdk-go/services/serviceenablement v0.4.0/go.mod h1:zyg0hpiNdZLRbelkJb2KDf9OHQKLqqcTpePQ1qHL5dE= -github.com/stackitcloud/stackit-sdk-go/services/ske v0.21.0 h1:Pew85wQJe2e9K8ZRzxeFSimI29aqUZwOT/Ty0N1K+c0= -github.com/stackitcloud/stackit-sdk-go/services/ske v0.21.0/go.mod h1:iZyh3DMi2fUZxAIseykjKfDo2wf2FIDwpF43I22b8uk= +github.com/stackitcloud/stackit-sdk-go/services/ske v0.21.1 h1:oO+wCobC4OfH+vpfJQEnCUQuKVILRj5mQojBbzWgzDA= +github.com/stackitcloud/stackit-sdk-go/services/ske v0.21.1/go.mod h1:iZyh3DMi2fUZxAIseykjKfDo2wf2FIDwpF43I22b8uk= github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v0.9.0 h1:OYWT7B63isBPyVuPxd3yobvky7/nhcXQxaBgPki5nR4= github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex v0.9.0/go.mod h1:vrl+OVJkjjupkvfkqY2T3HAB6x2x0S6zDhdFB5BWEnU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/stackit/internal/services/logme/instance/resource.go b/stackit/internal/services/logme/instance/resource.go index 0f3b2a45..3e4119c8 100644 --- a/stackit/internal/services/logme/instance/resource.go +++ b/stackit/internal/services/logme/instance/resource.go @@ -76,7 +76,7 @@ type parametersModel struct { OpensearchTlsCiphers types.List `tfsdk:"opensearch_tls_ciphers"` OpensearchTlsProtocols types.List `tfsdk:"opensearch_tls_protocols"` Syslog types.List `tfsdk:"syslog"` - SyslogUseUdp types.String `tfsdk:"syslog_use_udp"` + SyslogUseUdp types.String `tfsdk:"syslog_use_udp"` // Deprecated } // Types corresponding to parametersModel @@ -103,7 +103,7 @@ var parametersTypes = map[string]attr.Type{ "opensearch_tls_ciphers": basetypes.ListType{ElemType: types.StringType}, "opensearch_tls_protocols": basetypes.ListType{ElemType: types.StringType}, "syslog": basetypes.ListType{ElemType: types.StringType}, - "syslog_use_udp": basetypes.StringType{}, + "syslog_use_udp": basetypes.StringType{}, // Deprecated } // NewInstanceResource is a helper function to simplify the provider implementation. @@ -365,9 +365,10 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r Computed: true, }, "syslog_use_udp": schema.StringAttribute{ - Description: parametersDescriptions["syslog_use_udp"], - Optional: true, - Computed: true, + Description: parametersDescriptions["syslog_use_udp"], + Optional: true, + Computed: true, + DeprecationMessage: "The `syslog_use_udp` field has been deprecated because it is not required. Will be removed after July 22th 2025.", }, }, Optional: true, @@ -859,7 +860,6 @@ func toInstanceParams(parameters *parametersModel) (*logme.InstanceParameters, e payloadParams.MetricsFrequency = conversion.Int64ValueToPointer(parameters.MetricsFrequency) payloadParams.MetricsPrefix = conversion.StringValueToPointer(parameters.MetricsPrefix) payloadParams.MonitoringInstanceId = conversion.StringValueToPointer(parameters.MonitoringInstanceId) - payloadParams.SyslogUseUdp = conversion.StringValueToPointer(parameters.SyslogUseUdp) var err error payloadParams.OpensearchTlsCiphers, err = conversion.StringListToPointer(parameters.OpensearchTlsCiphers) diff --git a/stackit/internal/services/logme/instance/resource_test.go b/stackit/internal/services/logme/instance/resource_test.go index 2d7535c0..7f66aa77 100644 --- a/stackit/internal/services/logme/instance/resource_test.go +++ b/stackit/internal/services/logme/instance/resource_test.go @@ -96,7 +96,6 @@ var fixtureInstanceParameters = logme.InstanceParameters{ OpensearchTlsCiphers: &[]string{"ciphers", "ciphers2"}, OpensearchTlsProtocols: &[]string{"protocols", "protocols2"}, Syslog: &[]string{"syslog", "syslog2"}, - SyslogUseUdp: utils.Ptr("udp"), } func TestMapFields(t *testing.T) { diff --git a/stackit/internal/services/ske/cluster/resource.go b/stackit/internal/services/ske/cluster/resource.go index 772a6e4c..b1f8b687 100644 --- a/stackit/internal/services/ske/cluster/resource.go +++ b/stackit/internal/services/ske/cluster/resource.go @@ -1236,20 +1236,24 @@ func toMaintenancePayload(ctx context.Context, m *Model) (*ske.Maintenance, erro return nil, fmt.Errorf("converting maintenance object: %v", diags.Errors()) } - var timeWindowStart *string + var timeWindowStart *time.Time if !(maintenance.Start.IsNull() || maintenance.Start.IsUnknown()) { // API expects RFC3339 datetime - timeWindowStart = sdkUtils.Ptr( - fmt.Sprintf("0000-01-01T%s", maintenance.Start.ValueString()), - ) + tempTime, err := time.Parse(time.RFC3339, maintenance.Start.ValueString()) + if err != nil { + return nil, fmt.Errorf("converting maintenance object: %w", err) + } + timeWindowStart = sdkUtils.Ptr(tempTime) } - var timeWindowEnd *string + var timeWindowEnd *time.Time if !(maintenance.End.IsNull() || maintenance.End.IsUnknown()) { // API expects RFC3339 datetime - timeWindowEnd = sdkUtils.Ptr( - fmt.Sprintf("0000-01-01T%s", maintenance.End.ValueString()), - ) + tempTime, err := time.Parse(time.RFC3339, maintenance.End.ValueString()) + if err != nil { + return nil, fmt.Errorf("converting maintenance object: %w", err) + } + timeWindowEnd = sdkUtils.Ptr(tempTime) } return &ske.Maintenance{ @@ -1583,14 +1587,8 @@ func mapNetwork(cl *ske.Cluster, m *Model) error { } func getMaintenanceTimes(ctx context.Context, cl *ske.Cluster, m *Model) (startTime, endTime string, err error) { - startTimeAPI, err := time.Parse(time.RFC3339, *cl.Maintenance.TimeWindow.Start) - if err != nil { - return "", "", fmt.Errorf("parsing start time '%s' from API response as RFC3339 datetime: %w", *cl.Maintenance.TimeWindow.Start, err) - } - endTimeAPI, err := time.Parse(time.RFC3339, *cl.Maintenance.TimeWindow.End) - if err != nil { - return "", "", fmt.Errorf("parsing end time '%s' from API response as RFC3339 datetime: %w", *cl.Maintenance.TimeWindow.End, err) - } + startTimeAPI := *cl.Maintenance.TimeWindow.Start + endTimeAPI := *cl.Maintenance.TimeWindow.End if m.Maintenance.IsNull() || m.Maintenance.IsUnknown() { return startTimeAPI.Format("15:04:05Z07:00"), endTimeAPI.Format("15:04:05Z07:00"), nil diff --git a/stackit/internal/services/ske/cluster/resource_test.go b/stackit/internal/services/ske/cluster/resource_test.go index c2cd4481..5386ca60 100644 --- a/stackit/internal/services/ske/cluster/resource_test.go +++ b/stackit/internal/services/ske/cluster/resource_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/hashicorp/terraform-plugin-framework/attr" @@ -97,8 +98,8 @@ func TestMapFields(t *testing.T) { MachineImageVersion: utils.Ptr(true), }, TimeWindow: &ske.TimeWindow{ - Start: utils.Ptr("0000-01-02T03:04:05+06:00"), - End: utils.Ptr("0010-11-12T13:14:15Z"), + Start: utils.Ptr(time.Date(0, 1, 2, 3, 4, 5, 6, time.FixedZone("UTC+6:00", 6*60*60))), + End: utils.Ptr(time.Date(10, 11, 12, 13, 14, 15, 0, time.UTC)), }, }, Network: &ske.Network{ @@ -517,8 +518,8 @@ func TestMapFields(t *testing.T) { MachineImageVersion: utils.Ptr(true), }, TimeWindow: &ske.TimeWindow{ - Start: utils.Ptr("0000-01-02T03:04:05+06:00"), - End: utils.Ptr("0010-11-12T13:14:15Z"), + Start: utils.Ptr(time.Date(0, 1, 2, 3, 4, 5, 6, time.FixedZone("UTC+6:00", 6*60*60))), + End: utils.Ptr(time.Date(10, 11, 12, 13, 14, 15, 0, time.UTC)), }, }, Network: &ske.Network{ @@ -1643,9 +1644,9 @@ func TestLatestMatchingMachineVersion(t *testing.T) { func TestGetMaintenanceTimes(t *testing.T) { tests := []struct { description string - startAPI string + startAPI time.Time startTF *string - endAPI string + endAPI time.Time endTF *string isValid bool startExpected string @@ -1653,37 +1654,25 @@ func TestGetMaintenanceTimes(t *testing.T) { }{ { description: "base", - startAPI: "0001-02-03T04:05:06+07:08", - endAPI: "0011-12-13T14:15:16+17:18", + startAPI: time.Date(1, 2, 3, 4, 5, 6, 7, time.FixedZone("UTC+7:08", 7*60*60+8*60)), + endAPI: time.Date(11, 12, 13, 14, 15, 16, 17, time.FixedZone("UTC+17:18", 17*60*60+18*60)), isValid: true, startExpected: "04:05:06+07:08", endExpected: "14:15:16+17:18", }, { description: "base_utc", - startAPI: "0001-02-03T04:05:06Z", - endAPI: "0011-12-13T14:15:16Z", + startAPI: time.Date(1, 2, 3, 4, 5, 6, 0, time.UTC), + endAPI: time.Date(11, 12, 13, 14, 15, 16, 0, time.UTC), isValid: true, startExpected: "04:05:06Z", endExpected: "14:15:16Z", }, - { - description: "api_wrong_format_1", - startAPI: "T04:05:06+07:08", - endAPI: "0011-12-13T14:15:16+17:18", - isValid: false, - }, - { - description: "api_wrong_format_2", - startAPI: "0001-02-03T04:05:06+07:08", - endAPI: "14:15:16+17:18", - isValid: false, - }, { description: "tf_state_filled_in_1", - startAPI: "0001-02-03T04:05:06+07:08", + startAPI: time.Date(1, 2, 3, 4, 5, 6, 7, time.FixedZone("UTC+7:08", 7*60*60+8*60)), startTF: utils.Ptr("04:05:06+07:08"), - endAPI: "0011-12-13T14:15:16+17:18", + endAPI: time.Date(11, 12, 13, 14, 15, 16, 17, time.FixedZone("UTC+17:18", 17*60*60+18*60)), endTF: utils.Ptr("14:15:16+17:18"), isValid: true, startExpected: "04:05:06+07:08", @@ -1691,9 +1680,9 @@ func TestGetMaintenanceTimes(t *testing.T) { }, { description: "tf_state_filled_in_2", - startAPI: "0001-02-03T04:05:06Z", + startAPI: time.Date(1, 2, 3, 4, 5, 6, 0, time.UTC), startTF: utils.Ptr("04:05:06+00:00"), - endAPI: "0011-12-13T14:15:16Z", + endAPI: time.Date(11, 12, 13, 14, 15, 16, 0, time.UTC), endTF: utils.Ptr("14:15:16+00:00"), isValid: true, startExpected: "04:05:06+00:00", @@ -1701,9 +1690,9 @@ func TestGetMaintenanceTimes(t *testing.T) { }, { description: "tf_state_filled_in_3", - startAPI: "0001-02-03T04:05:06+00:00", + startAPI: time.Date(1, 2, 3, 4, 5, 6, 0, time.UTC), startTF: utils.Ptr("04:05:06Z"), - endAPI: "0011-12-13T14:15:16+00:00", + endAPI: time.Date(11, 12, 13, 14, 15, 16, 0, time.UTC), endTF: utils.Ptr("14:15:16Z"), isValid: true, startExpected: "04:05:06Z", @@ -1711,9 +1700,9 @@ func TestGetMaintenanceTimes(t *testing.T) { }, { description: "api_takes_precedence_if_different_1", - startAPI: "0001-02-03T04:05:06+07:08", + startAPI: time.Date(1, 2, 3, 4, 5, 6, 7, time.FixedZone("UTC+7:08", 7*60*60+8*60)), startTF: utils.Ptr("00:00:00+07:08"), - endAPI: "0011-12-13T14:15:16+17:18", + endAPI: time.Date(11, 12, 13, 14, 15, 16, 17, time.FixedZone("UTC+17:18", 17*60*60+18*60)), endTF: utils.Ptr("14:15:16+17:18"), isValid: true, startExpected: "04:05:06+07:08", @@ -1721,9 +1710,9 @@ func TestGetMaintenanceTimes(t *testing.T) { }, { description: "api_takes_precedence_if_different_2", - startAPI: "0001-02-03T04:05:06+07:08", + startAPI: time.Date(1, 2, 3, 4, 5, 6, 7, time.FixedZone("UTC+7:08", 7*60*60+8*60)), startTF: utils.Ptr("04:05:06+07:08"), - endAPI: "0011-12-13T14:15:16+17:18", + endAPI: time.Date(11, 12, 13, 14, 15, 16, 17, time.FixedZone("UTC+17:18", 17*60*60+18*60)), endTF: utils.Ptr("00:00:00+17:18"), isValid: true, startExpected: "04:05:06+07:08", @@ -1731,9 +1720,9 @@ func TestGetMaintenanceTimes(t *testing.T) { }, { description: "api_takes_precedence_if_different_3", - startAPI: "0001-02-03T04:05:06+07:08", + startAPI: time.Date(1, 2, 3, 4, 5, 6, 7, time.FixedZone("UTC+7:08", 7*60*60+8*60)), startTF: utils.Ptr("04:05:06Z"), - endAPI: "0011-12-13T14:15:16+17:18", + endAPI: time.Date(11, 12, 13, 14, 15, 16, 17, time.FixedZone("UTC+17:18", 17*60*60+18*60)), endTF: utils.Ptr("14:15:16+17:18"), isValid: true, startExpected: "04:05:06+07:08", @@ -1741,9 +1730,9 @@ func TestGetMaintenanceTimes(t *testing.T) { }, { description: "api_takes_precedence_if_different_3", - startAPI: "0001-02-03T04:05:06+07:08", + startAPI: time.Date(1, 2, 3, 4, 5, 6, 7, time.FixedZone("UTC+7:08", 7*60*60+8*60)), startTF: utils.Ptr("04:05:06+07:08"), - endAPI: "0011-12-13T14:15:16+17:18", + endAPI: time.Date(11, 12, 13, 14, 15, 16, 17, time.FixedZone("UTC+17:18", 17*60*60+18*60)), endTF: utils.Ptr("14:15:16Z"), isValid: true, startExpected: "04:05:06+07:08", diff --git a/stackit/internal/services/ske/kubeconfig/resource.go b/stackit/internal/services/ske/kubeconfig/resource.go index 9772493b..8342091e 100644 --- a/stackit/internal/services/ske/kubeconfig/resource.go +++ b/stackit/internal/services/ske/kubeconfig/resource.go @@ -370,7 +370,7 @@ func mapFields(kubeconfigResp *ske.Kubeconfig, model *Model, creationTime time.T } model.Kubeconfig = types.StringPointerValue(kubeconfigResp.Kubeconfig) - model.ExpiresAt = types.StringPointerValue(kubeconfigResp.ExpirationTimestamp) + model.ExpiresAt = types.StringValue(kubeconfigResp.ExpirationTimestamp.Format(time.RFC3339)) // set creation time model.CreationTime = types.StringValue(creationTime.Format(time.RFC3339)) return nil @@ -413,12 +413,7 @@ func checkCredentialsRotation(cluster *ske.Cluster, model *Model) (bool, error) return false, fmt.Errorf("converting creationTime field to timestamp: %w", err) } if cluster.Status.CredentialsRotation.LastCompletionTime != nil { - lastCompletionTime, err := time.Parse(time.RFC3339, *cluster.Status.CredentialsRotation.LastCompletionTime) - if err != nil { - return false, fmt.Errorf("converting LastCompletionTime to timestamp: %w", err) - } - - if creationTime.Before(lastCompletionTime) { + if creationTime.Before(*cluster.Status.CredentialsRotation.LastCompletionTime) { return true, nil } } @@ -432,12 +427,7 @@ func checkClusterRecreation(cluster *ske.Cluster, model *Model) (bool, error) { return false, fmt.Errorf("converting creationTime field to timestamp: %w", err) } if cluster.Status.CreationTime != nil { - clusterCreationTime, err := time.Parse(time.RFC3339, *cluster.Status.CreationTime) - if err != nil { - return false, fmt.Errorf("converting clusterCreationTime to timestamp: %w", err) - } - - if creationTime.Before(clusterCreationTime) { + if creationTime.Before(*cluster.Status.CreationTime) { return true, nil } } diff --git a/stackit/internal/services/ske/kubeconfig/resource_test.go b/stackit/internal/services/ske/kubeconfig/resource_test.go index c78aa201..8354ceee 100644 --- a/stackit/internal/services/ske/kubeconfig/resource_test.go +++ b/stackit/internal/services/ske/kubeconfig/resource_test.go @@ -21,7 +21,7 @@ func TestMapFields(t *testing.T) { { "simple_values", &ske.Kubeconfig{ - ExpirationTimestamp: utils.Ptr("2024-02-07T16:42:12Z"), + ExpirationTimestamp: utils.Ptr(time.Date(2024, 2, 7, 16, 42, 12, 0, time.UTC)), Kubeconfig: utils.Ptr("kubeconfig"), }, Model{ @@ -50,7 +50,7 @@ func TestMapFields(t *testing.T) { { "no_kubeconfig_field", &ske.Kubeconfig{ - ExpirationTimestamp: utils.Ptr("2024-02-07T16:42:12Z"), + ExpirationTimestamp: utils.Ptr(time.Date(2024, 2, 7, 16, 42, 12, 0, time.UTC)), }, Model{}, false, @@ -62,7 +62,7 @@ func TestMapFields(t *testing.T) { ProjectId: tt.expected.ProjectId, ClusterName: tt.expected.ClusterName, } - creationTime, _ := time.Parse("2006-01-02T15:04:05Z07:00", tt.expected.CreationTime.ValueString()) + creationTime, _ := time.Parse(time.RFC3339, tt.expected.CreationTime.ValueString()) err := mapFields(tt.input, state, creationTime) if !tt.isValid && err == nil { t.Fatalf("Should have failed") @@ -205,7 +205,7 @@ func TestCheckCredentialsRotation(t *testing.T) { inputCluster: &ske.Cluster{ Status: &ske.ClusterStatus{ CredentialsRotation: &ske.CredentialsRotationState{ - LastCompletionTime: utils.Ptr(time.Now().Add(-1 * time.Hour).Format(time.RFC3339)), // one hour ago + LastCompletionTime: utils.Ptr(time.Now().Add(-1 * time.Hour)), // one hour ago }, }, }, @@ -220,7 +220,7 @@ func TestCheckCredentialsRotation(t *testing.T) { inputCluster: &ske.Cluster{ Status: &ske.ClusterStatus{ CredentialsRotation: &ske.CredentialsRotationState{ - LastCompletionTime: utils.Ptr(time.Now().Add(1 * time.Hour).Format(time.RFC3339)), + LastCompletionTime: utils.Ptr(time.Now().Add(1 * time.Hour)), }, }, }, @@ -245,21 +245,6 @@ func TestCheckCredentialsRotation(t *testing.T) { expected: false, expectedError: false, }, - { - description: "invalid last completion time", - inputCluster: &ske.Cluster{ - Status: &ske.ClusterStatus{ - CredentialsRotation: &ske.CredentialsRotationState{ - LastCompletionTime: utils.Ptr("invalid time"), - }, - }, - }, - inputModel: &Model{ - CreationTime: types.StringValue(time.Now().Format(time.RFC3339)), - }, - expected: false, - expectedError: true, - }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { @@ -287,7 +272,7 @@ func TestCheckClusterRecreation(t *testing.T) { description: "cluster creation time after kubeconfig creation time", inputCluster: &ske.Cluster{ Status: &ske.ClusterStatus{ - CreationTime: utils.Ptr(time.Now().Add(-1 * time.Hour).Format(time.RFC3339)), + CreationTime: utils.Ptr(time.Now().Add(-1 * time.Hour)), }, }, inputModel: &Model{ @@ -300,7 +285,7 @@ func TestCheckClusterRecreation(t *testing.T) { description: "cluster creation time before kubeconfig creation time", inputCluster: &ske.Cluster{ Status: &ske.ClusterStatus{ - CreationTime: utils.Ptr(time.Now().Add(1 * time.Hour).Format(time.RFC3339)), + CreationTime: utils.Ptr(time.Now().Add(1 * time.Hour)), }, }, inputModel: &Model{ @@ -322,19 +307,6 @@ func TestCheckClusterRecreation(t *testing.T) { expected: false, expectedError: false, }, - { - description: "invalid cluster creation time", - inputCluster: &ske.Cluster{ - Status: &ske.ClusterStatus{ - CreationTime: utils.Ptr("invalid time"), - }, - }, - inputModel: &Model{ - CreationTime: types.StringValue(time.Now().Format(time.RFC3339)), - }, - expected: false, - expectedError: true, - }, } for _, tt := range tests { t.Run(tt.description, func(t *testing.T) {