From 2e113ee64d8f5d7747986cf5a0645a09363edf6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:01:44 -0400 Subject: [PATCH 01/19] build(deps): bump github.com/aws/aws-sdk-go-v2/service/s3 (#1593) Bumps [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) from 1.62.0 to 1.63.1. - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.62.0...service/s3/v1.63.1) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/service/s3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 20 ++++++++++---------- go.sum | 40 ++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index 1a858fc88..a93dfaa11 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,11 @@ go 1.22.0 toolchain go1.22.5 require ( - github.com/aws/aws-sdk-go-v2 v1.30.5 + github.com/aws/aws-sdk-go-v2 v1.31.0 github.com/aws/aws-sdk-go-v2/config v1.27.23 github.com/aws/aws-sdk-go-v2/credentials v1.17.23 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 - github.com/aws/aws-sdk-go-v2/service/s3 v1.62.0 + github.com/aws/aws-sdk-go-v2/service/s3 v1.63.1 github.com/aws/smithy-go v1.21.0 github.com/go-resty/resty/v2 v2.14.0 github.com/google/go-cmp v0.6.0 @@ -38,16 +38,16 @@ require ( github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.5 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.19 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.18 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.20 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.18 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect diff --git a/go.sum b/go.sum index 2f6d9a1df..3aa029884 100644 --- a/go.sum +++ b/go.sum @@ -9,10 +9,10 @@ github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/aws/aws-sdk-go-v2 v1.30.5 h1:mWSRTwQAb0aLE17dSzztCVJWI9+cRMgqebndjwDyK0g= -github.com/aws/aws-sdk-go-v2 v1.30.5/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 h1:70PVAiL15/aBMh5LThwgXdSQorVr91L127ttckI9QQU= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4/go.mod h1:/MQxMqci8tlqDH+pjmoLu1i0tbWCUP1hhyMRuFxpQCw= +github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= +github.com/aws/aws-sdk-go-v2 v1.31.0/go.mod h1:ztolYtaEUtdpf9Wftr31CJfLVjOnD/CVRkKOOYgF8hA= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.5 h1:xDAuZTn4IMm8o1LnBZvmrL8JA1io4o3YWNXgohbf20g= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.5/go.mod h1:wYSv6iDS621sEFLfKvpPE2ugjTuGlAG7iROg0hLOkfc= github.com/aws/aws-sdk-go-v2/config v1.27.23 h1:Cr/gJEa9NAS7CDAjbnB7tHYb3aLZI2gVggfmSAasDac= github.com/aws/aws-sdk-go-v2/config v1.27.23/go.mod h1:WMMYHqLCFu5LH05mFOF5tsq1PGEMfKbu083VKqLCd0o= github.com/aws/aws-sdk-go-v2/credentials v1.17.23 h1:G1CfmLVoO2TdQ8z9dW+JBc/r8+MqyPQhXCafNZcXVZo= @@ -21,24 +21,24 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 h1:6eKRM6fgeXG4krRO9XKz755vuRhT5UyB9M1W6vjA3JU= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4/go.mod h1:h0TjcRi+nTob6fksqubKOe+Hra8uqfgmN+vuw4xRwWE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17 h1:pI7Bzt0BJtYA0N/JEC6B8fJ4RBrEMi1LBrkMdFYNSnQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.17/go.mod h1:Dh5zzJYMtxfIjYW+/evjQ8uj2OyR/ve2KROHGHlSFqE= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17 h1:Mqr/V5gvrhA2gvgnF42Zh5iMiQNcOYthFYwCyrnuWlc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.17/go.mod h1:aLJpZlCmjE+V+KtN1q1uyZkfnUWpQGpbsn89XPKyzfU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 h1:kYQ3H1u0ANr9KEKlGs/jTLrBFPo8P8NaH/w7A01NeeM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18/go.mod h1:r506HmK5JDUh9+Mw4CfGJGSSoqIiLCndAuqXuhbv67Y= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 h1:Z7IdFUONvTcvS7YuhtVxN99v2cCoHRXOS4mTr0B/pUc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18/go.mod h1:DkKMmksZVVyat+Y+r1dEOgJEfUeA7UngIHWeKsi0yNc= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17 h1:Roo69qTpfu8OlJ2Tb7pAYVuF0CpuUMB0IYWwYP/4DZM= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.17/go.mod h1:NcWPxQzGM1USQggaTVwz6VpqMZPX1CvDJLDh6jnOCa4= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.19 h1:FLMkfEiRjhgeDTCjjLoc3URo/TBkgeQbocA78lfkzSI= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.19/go.mod h1:Vx+GucNSsdhaxs3aZIKfSUjKVGsxN25nX2SRcdhuw08= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19 h1:rfprUlsdzgl7ZL2KlXiUAoJnI/VxfHCvDFr2QDFj6u4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.19/go.mod h1:SCWkEdRq8/7EK60NcvvQ6NXKuTcchAD4ROAsC37VEZE= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.17 h1:u+EfGmksnJc/x5tq3A+OD7LrMbSSR/5TrKLvkdy/fhY= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.17/go.mod h1:VaMx6302JHax2vHJWgRo+5n9zvbacs3bLU/23DNQrTY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.62.0 h1:rd/aA3iDq1q7YsL5sc4dEwChutH7OZF9Ihfst6pXQzI= -github.com/aws/aws-sdk-go-v2/service/s3 v1.62.0/go.mod h1:5FmD/Dqq57gP+XwaUnd5WFPipAuzrf0HmupX27Gvjvc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.18 h1:OWYvKL53l1rbsUmW7bQyJVsYU/Ii3bbAAQIIFNbM0Tk= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.18/go.mod h1:CUx0G1v3wG6l01tUB+j7Y8kclA8NSqK4ef0YG79a4cg= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.20 h1:rTWjG6AvWekO2B1LHeM3ktU7MqyX9rzWQ7hgzneZW7E= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.20/go.mod h1:RGW2DDpVc8hu6Y6yG8G5CHVmVOAn1oV8rNKOHRJyswg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.18 h1:eb+tFOIl9ZsUe2259/BKPeniKuz4/02zZFH/i4Nf8Rg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.18/go.mod h1:GVCC2IJNJTmdlyEsSmofEy7EfJncP7DNnXDzRjJ5Keg= +github.com/aws/aws-sdk-go-v2/service/s3 v1.63.1 h1:TR96r56VwELV0qguNFCuz+/bEpRfnR3ZsS9/IG05C7Q= +github.com/aws/aws-sdk-go-v2/service/s3 v1.63.1/go.mod h1:NLTqRLe3pUNu3nTEHI6XlHLKYmc8fbHUdMxAB6+s41Q= github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc= github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 h1:lCEv9f8f+zJ8kcFeAjRZsekLd/x5SAm96Cva+VbUdo8= From 3108a2ec67ecbae1c4f4302340d91d1b221b9bfb Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Wed, 25 Sep 2024 17:48:54 -0400 Subject: [PATCH 02/19] Add taints and labels support for embedded LKE pools (#1579) --- linode/helper/compare.go | 21 ++++- linode/helper/conversion.go | 20 ++++ linode/helper/expand.go | 16 +++- linode/instance/resource_test.go | 1 - linode/lke/cluster.go | 73 ++++++++++++++- linode/lke/cluster_test.go | 3 +- linode/lke/framework_datasource_test.go | 34 ++----- ...rce_test.go => framework_resource_test.go} | 93 +++++++++++++++++++ linode/lke/resource.go | 5 +- linode/lke/schema_resource.go | 48 ++++++++++ linode/lke/tmpl/data_taints_labels.gotf | 5 +- linode/lke/tmpl/taints_labels.gotf | 31 +++++++ linode/lke/tmpl/template.go | 20 +++- 13 files changed, 329 insertions(+), 41 deletions(-) rename linode/lke/{resource_test.go => framework_resource_test.go} (86%) create mode 100644 linode/lke/tmpl/taints_labels.gotf diff --git a/linode/helper/compare.go b/linode/helper/compare.go index 172a45c79..292de1636 100644 --- a/linode/helper/compare.go +++ b/linode/helper/compare.go @@ -1,7 +1,10 @@ package helper import ( + "fmt" + "reflect" "slices" + "sort" "strings" "time" ) @@ -72,7 +75,7 @@ func ValidateSubset(superset, subset []any) bool { // Check if two slices are equivalent without considering ordering, // assuming no duplicated items are in the sets. func CompareSets(a, b []any) bool { - return ValidateSubset(a, b) && ValidateSubset(b, a) + return CompareSlices(true, true, a, b) } // Check if two string slices are equivalent without considering ordering, @@ -95,3 +98,19 @@ func CompareScopes(s1, s2 string) bool { s2List := strings.Split(s2, " ") return StringListElementsEqual(s1List, s2List) } + +func CompareSlices(ignoreNil, unordered bool, a, b []any) bool { + if ignoreNil && len(a) == 0 && len(b) == 0 { + return true + } + + if unordered { + less := func(i, j int) bool { + return fmt.Sprintf("%v", a[i]) < fmt.Sprintf("%v", a[j]) + } + sort.Slice(a, less) + sort.Slice(b, less) + } + + return reflect.DeepEqual(a, b) +} diff --git a/linode/helper/conversion.go b/linode/helper/conversion.go index 9a65607ac..0e90dff3c 100644 --- a/linode/helper/conversion.go +++ b/linode/helper/conversion.go @@ -29,6 +29,26 @@ func AnySliceToTyped[T any](obj []any) []T { return result } +func StringTypedMapToAny[T any](m map[string]T) map[string]any { + result := make(map[string]any, len(m)) + + for k, v := range m { + result[k] = v + } + + return result +} + +func StringAnyMapToTyped[T any](m map[string]any) map[string]T { + result := make(map[string]T, len(m)) + + for k, v := range m { + result[k] = v.(T) + } + + return result +} + func StringAliasSliceToStringSlice[T ~string](obj []T) ([]string, error) { var result []string diff --git a/linode/helper/expand.go b/linode/helper/expand.go index b2d9ffe4d..bd0d40bf3 100644 --- a/linode/helper/expand.go +++ b/linode/helper/expand.go @@ -22,7 +22,21 @@ func ExpandStringSet(set *schema.Set) []string { return ExpandStringList(set.List()) } -func ExpandIntList(list []interface{}) []int { +func ExpandObjectList(list []any) []map[string]any { + slice := make([]map[string]any, 0, len(list)) + for _, s := range list { + if val, ok := s.(map[string]any); ok { + slice = append(slice, val) + } + } + return slice +} + +func ExpandObjectSet(set *schema.Set) []map[string]any { + return ExpandObjectList(set.List()) +} + +func ExpandIntList(list []any) []int { slice := make([]int, 0, len(list)) for _, n := range list { if val, ok := n.(int); ok { diff --git a/linode/instance/resource_test.go b/linode/instance/resource_test.go index b3f9c702b..1fff21aae 100644 --- a/linode/instance/resource_test.go +++ b/linode/instance/resource_test.go @@ -504,7 +504,6 @@ func TestAccResourceInstance_disk(t *testing.T) { checkComputeInstanceDisk(&instance, "disk", 3000), ), }, - { ResourceName: resName, ImportState: true, diff --git a/linode/lke/cluster.go b/linode/lke/cluster.go index 7af29b364..633d5bb4b 100644 --- a/linode/lke/cluster.go +++ b/linode/lke/cluster.go @@ -18,6 +18,8 @@ type NodePoolSpec struct { Tags []string Type string Count int + Taints []map[string]any + Labels map[string]string AutoScalerEnabled bool AutoScalerMin int AutoScalerMax int @@ -30,7 +32,7 @@ type NodePoolUpdates struct { } func ReconcileLKENodePoolSpecs( - oldSpecs []NodePoolSpec, newSpecs []NodePoolSpec, + ctx context.Context, oldSpecs []NodePoolSpec, newSpecs []NodePoolSpec, ) (NodePoolUpdates, error) { result := NodePoolUpdates{ ToCreate: make([]linodego.LKENodePoolCreateOptions, 0), @@ -40,9 +42,14 @@ func ReconcileLKENodePoolSpecs( createPool := func(spec NodePoolSpec) error { createOpts := linodego.LKENodePoolCreateOptions{ - Count: spec.Count, - Type: spec.Type, - Tags: spec.Tags, + Count: spec.Count, + Type: spec.Type, + Tags: spec.Tags, + Labels: linodego.LKENodePoolLabels(spec.Labels), + } + + if spec.Taints != nil { + createOpts.Taints = expandNodePoolTaints(spec.Taints) } if createOpts.Count == 0 { @@ -115,6 +122,16 @@ func ReconcileLKENodePoolSpecs( Tags: &newSpecs[i].Tags, } + if !helper.CompareSets(helper.TypedSliceToAny(newSpec.Taints), helper.TypedSliceToAny(oldSpec.Taints)) { + taints := expandNodePoolTaints(newSpec.Taints) + updateOpts.Taints = &taints + } + + if !reflect.DeepEqual(newSpec.Labels, oldSpec.Labels) && !(len(newSpec.Labels) == 0 && len(oldSpec.Labels) == 0) { + labels := linodego.LKENodePoolLabels(newSpecs[i].Labels) + updateOpts.Labels = &labels + } + // Only include the autoscaler if the autoscaler has updated // This isn't stricly necessary but it makes unit testing easier if newSpec.AutoScalerEnabled != oldSpec.AutoScalerEnabled || @@ -265,7 +282,8 @@ func recycleLKECluster(ctx context.Context, meta *helper.ProviderMeta, id int, p // This cannot currently be handled efficiently by a DiffSuppressFunc // See: https://github.com/hashicorp/terraform-plugin-sdk/issues/477 -func matchPoolsWithSchema(pools []linodego.LKENodePool, declaredPools []interface{}) ([]linodego.LKENodePool, error) { +func matchPoolsWithSchema(ctx context.Context, pools []linodego.LKENodePool, declaredPools []interface{}) ([]linodego.LKENodePool, error) { + tflog.Info(ctx, "Enter matchPoolsWithSchema helper function") result := make([]linodego.LKENodePool, len(declaredPools)) // Contains all unpaired pools returned by the API @@ -342,6 +360,21 @@ func matchPoolsWithSchema(pools []linodego.LKENodePool, declaredPools []interfac continue } + declaredTaints := expandNodePoolTaints(helper.ExpandObjectSet(declaredPool["taint"].(*schema.Set))) + + if !helper.CompareSets(helper.TypedSliceToAny(declaredTaints), helper.TypedSliceToAny(apiPool.Taints)) { + continue + } + + declaredLabels := helper.StringAnyMapToTyped[string](declaredPool["labels"].(map[string]any)) + + // - Length comparison is for handling the case of nil vs empty slice + // - Converting `apiPool.Labels` back to original (non-alias) type to make `reflect.DeepEqual` to really compare them + if !reflect.DeepEqual(declaredLabels, map[string]string(apiPool.Labels)) && + !(len(declaredLabels) == 0 && len(apiPool.Labels) == 0) { + continue + } + // Pair the API pool with the declared pool result[i] = apiPool delete(apiPools, apiPool.ID) @@ -395,6 +428,8 @@ func expandLinodeLKENodePoolSpecs(pool []interface{}, preserveNoTarget bool) (po ID: specMap["id"].(int), Type: specMap["type"].(string), Tags: helper.ExpandStringSet(specMap["tags"].(*schema.Set)), + Taints: helper.ExpandObjectSet(specMap["taint"].(*schema.Set)), + Labels: helper.StringAnyMapToTyped[string](specMap["labels"].(map[string]any)), Count: specMap["count"].(int), AutoScalerEnabled: autoscaler.Enabled, AutoScalerMin: autoscaler.Min, @@ -434,6 +469,8 @@ func flattenLKENodePools(pools []linodego.LKENodePool) []map[string]interface{} "type": pool.Type, "tags": pool.Tags, "disk_encryption": pool.DiskEncryption, + "taint": flattenNodePoolTaints(pool.Taints), + "labels": pool.Labels, "nodes": nodes, "autoscaler": autoscaler, } @@ -441,6 +478,20 @@ func flattenLKENodePools(pools []linodego.LKENodePool) []map[string]interface{} return flattened } +func flattenNodePoolTaints(taints []linodego.LKENodePoolTaint) []map[string]string { + result := make([]map[string]string, len(taints)) + + for i, t := range taints { + result[i] = map[string]string{ + "effect": string(t.Effect), + "key": t.Key, + "value": t.Value, + } + } + + return result +} + func flattenLKEClusterControlPlane(controlPlane linodego.LKEClusterControlPlane, aclResp *linodego.LKEClusterControlPlaneACLResponse) map[string]interface{} { flattened := make(map[string]interface{}) if aclResp != nil { @@ -549,3 +600,15 @@ func poolHasAnyOfTags(pool linodego.LKENodePool, tagSet map[string]bool) *string } return nil } + +func expandNodePoolTaints(poolTaints []map[string]any) []linodego.LKENodePoolTaint { + taints := make([]linodego.LKENodePoolTaint, len(poolTaints)) + for i, taint := range poolTaints { + taints[i] = linodego.LKENodePoolTaint{ + Key: taint["key"].(string), + Value: taint["value"].(string), + Effect: linodego.LKENodePoolTaintEffect(taint["effect"].(string)), + } + } + return taints +} diff --git a/linode/lke/cluster_test.go b/linode/lke/cluster_test.go index 4e1d93200..6f6cbf1fd 100644 --- a/linode/lke/cluster_test.go +++ b/linode/lke/cluster_test.go @@ -3,6 +3,7 @@ package lke_test import ( + "context" "reflect" "testing" @@ -145,7 +146,7 @@ func TestReconcileLKENodePoolSpecs(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - updates, err := lke.ReconcileLKENodePoolSpecs(tc.oldSpecs, tc.newSpecs) + updates, err := lke.ReconcileLKENodePoolSpecs(context.Background(), tc.oldSpecs, tc.newSpecs) if err != nil { t.Fatal(err) } diff --git a/linode/lke/framework_datasource_test.go b/linode/lke/framework_datasource_test.go index f3618db15..962ffbaa9 100644 --- a/linode/lke/framework_datasource_test.go +++ b/linode/lke/framework_datasource_test.go @@ -9,7 +9,6 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/linode/terraform-provider-linode/v2/linode/acceptance" "github.com/linode/terraform-provider-linode/v2/linode/lke/tmpl" - nodepooltmpl "github.com/linode/terraform-provider-linode/v2/linode/lkenodepool/tmpl" ) const dataSourceClusterName = "data.linode_lke_cluster.test" @@ -19,7 +18,6 @@ func TestAccDataSourceLKECluster_taints_labels(t *testing.T) { acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { clusterName := acctest.RandomWithPrefix("tf_test") - poolTag := acctest.RandomWithPrefix("tf_test_") resource.Test(tRetry, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, @@ -27,33 +25,19 @@ func TestAccDataSourceLKECluster_taints_labels(t *testing.T) { Steps: []resource.TestStep{ { Config: tmpl.DataTaintsLabels( - t, &nodepooltmpl.TemplateData{ - K8sVersion: k8sVersionLatest, - Region: testRegion, - PoolNodeType: "g6-standard-1", - NodeCount: 1, - ClusterLabel: clusterName, - Taints: []nodepooltmpl.TaintData{ - { - Effect: "PreferNoSchedule", - Key: "foo", - Value: "bar", - }, + t, clusterName, k8sVersionLatest, testRegion, []tmpl.TaintData{ + { + Effect: "PreferNoSchedule", + Key: "foo", + Value: "bar", }, - PoolTag: poolTag, - Labels: map[string]string{"foo": "bar"}, }, + map[string]string{"foo": "bar"}, ), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceClusterName, "pools.1.nodes.#", "1"), - acceptance.AnyOfTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceClusterName, "pools.0.taints.#", "1"), - resource.TestCheckResourceAttr(dataSourceClusterName, "pools.1.taints.#", "1"), - ), - acceptance.AnyOfTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceClusterName, "pools.0.labels.foo", "bar"), - resource.TestCheckResourceAttr(dataSourceClusterName, "pools.1.labels.foo", "bar"), - ), + resource.TestCheckResourceAttr(dataSourceClusterName, "pools.0.nodes.#", "1"), + resource.TestCheckResourceAttr(dataSourceClusterName, "pools.0.taints.#", "1"), + resource.TestCheckResourceAttr(dataSourceClusterName, "pools.0.labels.foo", "bar"), ), }, }, diff --git a/linode/lke/resource_test.go b/linode/lke/framework_resource_test.go similarity index 86% rename from linode/lke/resource_test.go rename to linode/lke/framework_resource_test.go index 5c75a6cd5..4dbcc2852 100644 --- a/linode/lke/resource_test.go +++ b/linode/lke/framework_resource_test.go @@ -589,3 +589,96 @@ func TestAccResourceLKECluster_implicitCount(t *testing.T) { }, }) } + +func TestAccResourceLKEClusterNodePoolTaintsLabels(t *testing.T) { + t.Parallel() + + acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + clusterName := acctest.RandomWithPrefix("tf_test") + resource.Test(tRetry, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + CheckDestroy: acceptance.CheckLKEClusterDestroy, + Steps: []resource.TestStep{ + { + // create a cluster with taints and labels + Config: tmpl.DataTaintsLabels( + t, clusterName, k8sVersionLatest, testRegion, []tmpl.TaintData{ + { + Effect: "PreferNoSchedule", + Key: "foo", + Value: "bar", + }, + }, + map[string]string{"foo": "bar"}, + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.nodes.#", "1"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.#", "1"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.0.effect", "PreferNoSchedule"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.0.key", "foo"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.0.value", "bar"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.labels.foo", "bar"), + ), + }, + { + // update taints and labels values + Config: tmpl.DataTaintsLabels( + t, clusterName, k8sVersionLatest, testRegion, []tmpl.TaintData{ + { + Effect: "PreferNoSchedule", + Key: "baz", + Value: "qux", + }, + }, + map[string]string{"baz": "qux"}, + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.nodes.#", "1"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.#", "1"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.0.effect", "PreferNoSchedule"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.0.key", "baz"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.0.value", "qux"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.labels.baz", "qux"), + ), + }, + { + // remove taints and labels + Config: tmpl.DataTaintsLabels(t, clusterName, k8sVersionLatest, testRegion, nil, nil), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.nodes.#", "1"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.#", "0"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.labels.#", "0"), + ), + }, + { + // add taints and labels back + Config: tmpl.DataTaintsLabels( + t, clusterName, k8sVersionLatest, testRegion, []tmpl.TaintData{ + { + Effect: "PreferNoSchedule", + Key: "foo", + Value: "bar", + }, + }, + map[string]string{"foo": "bar"}, + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.nodes.#", "1"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.#", "1"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.0.effect", "PreferNoSchedule"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.0.key", "foo"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.taint.0.value", "bar"), + resource.TestCheckResourceAttr(resourceClusterName, "pool.0.labels.foo", "bar"), + ), + }, + { + ResourceName: resourceClusterName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"pool.0.nodes.0.status"}, + }, + }, + }) + }) +} diff --git a/linode/lke/resource.go b/linode/lke/resource.go index 0b7111602..3c3e4372e 100644 --- a/linode/lke/resource.go +++ b/linode/lke/resource.go @@ -123,7 +123,7 @@ func readResource(ctx context.Context, d *schema.ResourceData, meta interface{}) d.Set("dashboard_url", dashboard.URL) d.Set("api_endpoints", flattenLKEClusterAPIEndpoints(endpoints)) - matchedPools, err := matchPoolsWithSchema(pools, declaredPools) + matchedPools, err := matchPoolsWithSchema(ctx, pools, declaredPools) if err != nil { return diag.Errorf("failed to match api pools with schema: %s", err) } @@ -178,6 +178,8 @@ func createResource(ctx context.Context, d *schema.ResourceData, meta interface{ createOpts.NodePools = append(createOpts.NodePools, linodego.LKENodePoolCreateOptions{ Type: poolSpec["type"].(string), Tags: helper.ExpandStringSet(poolSpec["tags"].(*schema.Set)), + Taints: expandNodePoolTaints(helper.ExpandObjectSet(poolSpec["taint"].(*schema.Set))), + Labels: helper.StringAnyMapToTyped[string](poolSpec["labels"].(map[string]any)), Count: count, Autoscaler: autoscaler, }) @@ -281,6 +283,7 @@ func updateResource(ctx context.Context, d *schema.ResourceData, meta interface{ oldPools, newPools := d.GetChange("pool") updates, err := ReconcileLKENodePoolSpecs( + ctx, expandLinodeLKENodePoolSpecs(oldPools.([]any), false), expandLinodeLKENodePoolSpecs(newPools.([]any), true), ) diff --git a/linode/lke/schema_resource.go b/linode/lke/schema_resource.go index 9a6641bd9..ae297e961 100644 --- a/linode/lke/schema_resource.go +++ b/linode/lke/schema_resource.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/linode/linodego" "github.com/linode/terraform-provider-linode/v2/linode/helper" ) @@ -83,6 +84,53 @@ var resourceSchema = map[string]*schema.Schema{ Description: "A Linode Type for all of the nodes in the Node Pool.", Required: true, }, + "labels": { + Type: schema.TypeMap, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Key-value pairs added as labels to nodes in the node pool. " + + "Labels help classify your nodes and to easily select subsets of objects.", + Optional: true, + }, + "taint": { + Type: schema.TypeSet, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "effect": { + Type: schema.TypeString, + Description: "The Kubernetes taint effect.", + Required: true, + ValidateDiagFunc: validation.ToDiagFunc( + validation.StringInSlice([]string{ + string(linodego.LKENodePoolTaintEffectNoExecute), + string(linodego.LKENodePoolTaintEffectNoSchedule), + string(linodego.LKENodePoolTaintEffectPreferNoSchedule), + }, false), + ), + }, + "key": { + Description: "The Kubernetes taint key.", + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validation.ToDiagFunc( + validation.StringIsNotEmpty, + ), + }, + "value": { + Description: "The Kubernetes taint value.", + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validation.ToDiagFunc( + validation.StringIsNotEmpty, + ), + }, + }, + }, + Description: "Kubernetes taints to add to node pool nodes. Taints help control how " + + "pods are scheduled onto nodes, specifically allowing them to repel certain pods.", + Optional: true, + }, "tags": { Type: schema.TypeSet, Description: "A set of tags applied to this node pool.", diff --git a/linode/lke/tmpl/data_taints_labels.gotf b/linode/lke/tmpl/data_taints_labels.gotf index 1f27fa31f..297b040a6 100644 --- a/linode/lke/tmpl/data_taints_labels.gotf +++ b/linode/lke/tmpl/data_taints_labels.gotf @@ -1,10 +1,9 @@ {{ define "lke_cluster_data_taints_labels" }} -{{ template "nodepool_template" . }} +{{ template "lke_cluster_taints_labels" . }} data "linode_lke_cluster" "test" { - depends_on = [ linode_lke_node_pool.foobar ] - id = linode_lke_cluster.nodepool_test_cluster.id + id = linode_lke_cluster.test.id } {{ end }} diff --git a/linode/lke/tmpl/taints_labels.gotf b/linode/lke/tmpl/taints_labels.gotf new file mode 100644 index 000000000..43b522522 --- /dev/null +++ b/linode/lke/tmpl/taints_labels.gotf @@ -0,0 +1,31 @@ +{{ define "lke_cluster_taints_labels" }} + +resource "linode_lke_cluster" "test" { + label = "{{ .Label }}" + region = "{{ .Region }}" + k8s_version = "{{ .K8sVersion }}" + tags = ["test"] + + pool { + type = "g6-standard-1" + count = 1 + tags = ["test"] + +{{ range $taint := .Taints }} + taint { + effect = "{{ $taint.Effect }}" + key = "{{ $taint.Key }}" + value = "{{ $taint.Value }}" + } +{{ end }} + +{{ range $key, $val := .Labels }} + labels = { + "{{ $key }}" = "{{ $val }}" + } +{{ end }} + } +} + +{{ end }} + diff --git a/linode/lke/tmpl/template.go b/linode/lke/tmpl/template.go index 295b7b4ad..ee508f6f3 100644 --- a/linode/lke/tmpl/template.go +++ b/linode/lke/tmpl/template.go @@ -4,9 +4,14 @@ import ( "testing" "github.com/linode/terraform-provider-linode/v2/linode/acceptance" - nodepooltmpl "github.com/linode/terraform-provider-linode/v2/linode/lkenodepool/tmpl" ) +type TaintData struct { + Effect string + Key string + Value string +} + type TemplateData struct { Label string K8sVersion string @@ -15,6 +20,8 @@ type TemplateData struct { ACLEnabled bool IPv4 string IPv6 string + Taints []TaintData + Labels map[string]string } func Basic(t *testing.T, name, version, region string) string { @@ -110,6 +117,13 @@ func DataControlPlane(t *testing.T, name, version, region, ipv4, ipv6 string, ha }) } -func DataTaintsLabels(t *testing.T, data *nodepooltmpl.TemplateData) string { - return acceptance.ExecuteTemplate(t, "lke_cluster_data_taints_labels", *data) +func DataTaintsLabels(t *testing.T, name, version, region string, taints []TaintData, labels map[string]string) string { + return acceptance.ExecuteTemplate(t, + "lke_cluster_data_taints_labels", TemplateData{ + Label: name, + K8sVersion: version, + Region: region, + Labels: labels, + Taints: taints, + }) } From 7d781d597e9c80b35325245426d11d3164afb2fe Mon Sep 17 00:00:00 2001 From: Youjung Kim <126618609+ykim-1@users.noreply.github.com> Date: Thu, 26 Sep 2024 09:30:15 -0700 Subject: [PATCH 03/19] test: Refactor smoke tests and add improve nightly workflow (#1566) * refactor smoke tests and update Makefile and nightly_smoke_tests.yml * clean up output on smoke tests and add slack notifications in nightly_smoke_tests.yml * gha test 1 * gha test 2 * Fix makefile smoke-test command * add option to input sha value in workflow file * set env for nightly_smoke_tests.yml * add conditions to cron in nightly_smoke_tests.yml * fix syntax for slack message * setting pipefail status before piping output * set to bash terminal instead of sh * set to bash terminal instead of sh * Change slack notification * resolve gha issues * set slack webhook env * Change slack message * Change slack message * Fix slack payload * Fix slack payload # 2 * Fix slack payload # 3 * Fix slack payload # 3 * revert slack gha package * add submodule checks before running integration and smoke tests * addressing pr comment to remove global smoke test map variable for simplicity * fix syntax in slack message * Change slack notification * Add repo name in payload * Add repo name in slack payload * bump slackgha version and add slack notification to integration workflow * fix typo in workflow * add condition to send test results and notification only on main repository --- .github/workflows/integration_tests.yml | 70 +++++++++++++++++- .github/workflows/nightly_smoke_tests.yml | 84 ++++++++++++++++++++-- Makefile | 24 ++++++- linode/childaccount/datasource_test.go | 13 ++++ linode/databasepostgresql/resource_test.go | 13 ++++ linode/domain/datasource_test.go | 13 ++++ linode/domain/resource_test.go | 13 ++++ linode/firewall/framework_resource_test.go | 13 ++++ linode/firewalldevice/resource_test.go | 13 ++++ linode/instance/resource_test.go | 13 ++++ linode/instancedisk/resource_test.go | 13 ++++ linode/lke/framework_resource_test.go | 13 ++++ linode/nb/resource_test.go | 13 ++++ linode/objbucket/resource_test.go | 14 ++++ linode/regions/datasource_test.go | 13 ++++ linode/stackscript/resource_test.go | 13 ++++ linode/stackscripts/datasource_test.go | 13 ++++ linode/volume/resource_test.go | 13 ++++ linode/vpcsubnets/datasource_test.go | 13 ++++ 19 files changed, 377 insertions(+), 10 deletions(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index 2260b408b..c7777eb90 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -81,7 +81,7 @@ jobs: process-upload-report: runs-on: ubuntu-latest needs: [integration_tests] - if: always() # Run even if previous job fails + if: always() && github.repository == 'linode/terraform-provider-linode' # Run even if integration tests fail and only on main repository steps: - name: Checkout code @@ -145,4 +145,70 @@ jobs: run: | cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh env: - LINODE_TOKEN: ${{ secrets.LINODE_TOKEN_USER_4 }} \ No newline at end of file + LINODE_TOKEN: ${{ secrets.LINODE_TOKEN_USER_4 }} + + notify-slack: + runs-on: ubuntu-latest + needs: [integration_tests] + if: always() && github.repository == 'linode/terraform-provider-linode' # Run even if integration tests fail and only on main repository + + steps: + - name: Notify Slack + uses: slackapi/slack-github-action@v1.27.0 + with: + channel-id: ${{ secrets.SLACK_CHANNEL_ID }} + payload: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* :white_check_mark:" + } + }, + { + "type": "divider" + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Build Result:*\n${{ steps.integration_tests.outcome == 'success' && ':large_green_circle: Build Passed' || ':red_circle: Build Failed' }}" + }, + { + "type": "mrkdwn", + "text": "*Branch:*\n`${{ github.ref_name }}`" + } + ] + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Commit Hash:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>" + }, + { + "type": "mrkdwn", + "text": "*Run URL:*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run Details>" + } + ] + }, + { + "type": "divider" + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Triggered by: :bust_in_silhouette: `${{ github.actor }}`" + } + ] + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/nightly_smoke_tests.yml b/.github/workflows/nightly_smoke_tests.yml index 076f3e2d0..21f12d1cc 100644 --- a/.github/workflows/nightly_smoke_tests.yml +++ b/.github/workflows/nightly_smoke_tests.yml @@ -4,25 +4,99 @@ on: schedule: - cron: "0 0 * * *" workflow_dispatch: + inputs: + sha: + description: 'Commit SHA to test' + required: false + default: '' + type: string jobs: smoke_tests: + if: github.repository == 'linode/terraform-provider-linode' || github.event_name == 'workflow_dispatch' runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: - ref: dev + fetch-depth: 0 + submodules: 'recursive' + ref: ${{ github.event.inputs.sha || github.ref }} - - name: Set up go + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 'stable' + go-version: '1.x' - - run: go version + - name: Install Dependencies + run: | + make deps - name: Run smoke tests - run: make smoke-test + id: smoke_tests + run: | + make smoke-test env: LINODE_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} + + - name: Notify Slack + if: always() + uses: slackapi/slack-github-action@v1.27.0 + with: + channel-id: ${{ secrets.SLACK_CHANNEL_ID }} + payload: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":rocket: *${{ github.workflow }} Completed in: ${{ github.repository }}* :white_check_mark:" + } + }, + { + "type": "divider" + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Build Result:*\n${{ steps.smoke_tests.outcome == 'success' && ':large_green_circle: Build Passed' || ':red_circle: Build Failed' }}" + }, + { + "type": "mrkdwn", + "text": "*Branch:*\n`${{ github.ref_name }}`" + } + ] + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Commit Hash:*\n<${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}|${{ github.sha }}>" + }, + { + "type": "mrkdwn", + "text": "*Run URL:*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run Details>" + } + ] + }, + { + "type": "divider" + }, + { + "type": "context", + "elements": [ + { + "type": "mrkdwn", + "text": "Triggered by: :bust_in_silhouette: `${{ github.actor }}`" + } + ] + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/Makefile b/Makefile index 7e3c93403..9e325c27f 100644 --- a/Makefile +++ b/Makefile @@ -78,16 +78,34 @@ include-env: $(IP_ENV_FILE) generate-ip-env-fw-e2e: $(IP_ENV_FILE) +SUBMODULE_DIR := e2e_scripts + $(IP_ENV_FILE): # Generate env file for E2E cloud firewall - . ./e2e_scripts/cloud_security_scripts/cloud_e2e_firewall/terraform-provider-linode/generate_ip_env_fw_e2e.sh || touch $(IP_ENV_FILE) + @if [ ! -d $(SUBMODULE_DIR) ]; then \ + echo "Submodule directory $(SUBMODULE_DIR) does not exist. Updating submodules..."; \ + git submodule update --init --recursive; \ + else \ + echo "Submodule directory $(SUBMODULE_DIR) already exists. Skipping update."; \ + fi + . ./e2e_scripts/cloud_security_scripts/cloud_e2e_firewall/terraform-provider-linode/generate_ip_env_fw_e2e.sh .PHONY: smoke-test -smoke-test: fmt-check +smoke-test: fmt-check generate-ip-env-fw-e2e include-env TF_ACC=1 \ LINODE_API_VERSION="v4beta" \ RUN_LONG_TESTS=$(RUN_LONG_TESTS) \ - go test -v -run smoke ./linode/... -count $(COUNT) -timeout $(TIMEOUT) -parallel=$(PARALLEL) -ldflags="-X=github.com/linode/terraform-provider-linode/v2/version.ProviderVersion=acc" + TF_VAR_ipv4_addr=${PUBLIC_IPV4} \ + TF_VAR_ipv6_addr=${PUBLIC_IPV6} \ + bash -c 'set -o pipefail && go test -v ./linode/... -run TestSmokeTests -tags=integration \ + -count $(COUNT) \ + -timeout $(TIMEOUT) \ + -parallel=$(PARALLEL) \ + -ldflags="-X=github.com/linode/terraform-provider-linode/v2/version.ProviderVersion=acc" \ + | sed -e "/testing: warning: no tests to run/,+1d" -e "/\[no test files\]/d" -e "/\[no tests to run\]/d"; \ + exit_status=$$?; \ + exit $$exit_status' + .PHONY: docs-check docs-check: diff --git a/linode/childaccount/datasource_test.go b/linode/childaccount/datasource_test.go index b800ff486..3f0dac7c9 100644 --- a/linode/childaccount/datasource_test.go +++ b/linode/childaccount/datasource_test.go @@ -10,6 +10,19 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/childaccount/tmpl" ) +func TestSmokeTests_childaccount(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccDataSourceChildAccount_basic_smoke", TestAccDataSourceChildAccount_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccDataSourceChildAccount_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/databasepostgresql/resource_test.go b/linode/databasepostgresql/resource_test.go index afa66a1ec..518acd7d4 100644 --- a/linode/databasepostgresql/resource_test.go +++ b/linode/databasepostgresql/resource_test.go @@ -75,6 +75,19 @@ func sweep(prefix string) error { return nil } +func TestSmokeTests_databasepostgresql(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceDatabasePostgres_basic_smoke", TestAccResourceDatabasePostgres_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceDatabasePostgres_basic_smoke(t *testing.T) { acceptance.LongRunningTest(t) diff --git a/linode/domain/datasource_test.go b/linode/domain/datasource_test.go index 8a7f81f0f..2b54315d6 100644 --- a/linode/domain/datasource_test.go +++ b/linode/domain/datasource_test.go @@ -12,6 +12,19 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/domain/tmpl" ) +func TestSmokeTests_domain_datasource(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccDataSourceDomain_basic_smoke", TestAccDataSourceDomain_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccDataSourceDomain_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/domain/resource_test.go b/linode/domain/resource_test.go index b39a74d02..059939c67 100644 --- a/linode/domain/resource_test.go +++ b/linode/domain/resource_test.go @@ -48,6 +48,19 @@ func sweep(prefix string) error { return nil } +func TestSmokeTests_domain_resource(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceDomain_basic_smoke", TestAccResourceDomain_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceDomain_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/firewall/framework_resource_test.go b/linode/firewall/framework_resource_test.go index 26f126205..6db229064 100644 --- a/linode/firewall/framework_resource_test.go +++ b/linode/firewall/framework_resource_test.go @@ -57,6 +57,19 @@ func sweep(prefix string) error { return nil } +func TestSmokeTests_firewall(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccLinodeFirewall_basic", TestAccLinodeFirewall_basic}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccLinodeFirewall_basic(t *testing.T) { t.Parallel() diff --git a/linode/firewalldevice/resource_test.go b/linode/firewalldevice/resource_test.go index e595db960..0ac2dacea 100644 --- a/linode/firewalldevice/resource_test.go +++ b/linode/firewalldevice/resource_test.go @@ -29,6 +29,19 @@ func init() { testRegion = region } +func TestSmokeTests_firewalldevice(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceFirewallDevice_basic_smoke", TestAccResourceFirewallDevice_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceFirewallDevice_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/instance/resource_test.go b/linode/instance/resource_test.go index 1fff21aae..db0d77e16 100644 --- a/linode/instance/resource_test.go +++ b/linode/instance/resource_test.go @@ -64,6 +64,19 @@ func sweep(prefix string) error { return nil } +func TestSmokeTests_instance(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceInstance_basic_smoke", TestAccResourceInstance_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceInstance_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/instancedisk/resource_test.go b/linode/instancedisk/resource_test.go index 3755e8bd4..7d79b5688 100644 --- a/linode/instancedisk/resource_test.go +++ b/linode/instancedisk/resource_test.go @@ -29,6 +29,19 @@ func init() { testRegion = region } +func TestSmokeTests_instancedisk(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceInstanceDisk_basic_smoke", TestAccResourceInstanceDisk_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceInstanceDisk_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/lke/framework_resource_test.go b/linode/lke/framework_resource_test.go index 4dbcc2852..72218b1b5 100644 --- a/linode/lke/framework_resource_test.go +++ b/linode/lke/framework_resource_test.go @@ -164,6 +164,19 @@ func waitForAllNodesReady(t *testing.T, cluster *linodego.LKECluster, pollInterv } } +func TestSmokeTests_lke(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceLKECluster_basic_smoke", TestAccResourceLKECluster_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceLKECluster_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/nb/resource_test.go b/linode/nb/resource_test.go index ed8443c2f..1c2554e71 100644 --- a/linode/nb/resource_test.go +++ b/linode/nb/resource_test.go @@ -62,6 +62,19 @@ func sweep(prefix string) error { return nil } +func TestSmokeTests_nb(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceNodeBalancer_basic_smoke", TestAccResourceNodeBalancer_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceNodeBalancer_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/objbucket/resource_test.go b/linode/objbucket/resource_test.go index 9277bf8f3..95c22d4f3 100644 --- a/linode/objbucket/resource_test.go +++ b/linode/objbucket/resource_test.go @@ -171,6 +171,20 @@ func sweep(prefix string) error { return nil } +func TestSmokeTests_objbucket(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceBucket_basic_legacy_smoke", TestAccResourceBucket_basic_legacy_smoke}, + {"TestAccResourceBucket_basic_smoke", TestAccResourceBucket_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceBucket_basic_legacy_smoke(t *testing.T) { t.Parallel() diff --git a/linode/regions/datasource_test.go b/linode/regions/datasource_test.go index 36faa22a3..789809879 100644 --- a/linode/regions/datasource_test.go +++ b/linode/regions/datasource_test.go @@ -13,6 +13,19 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/regions/tmpl" ) +func TestSmokeTests_firewall(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccDataSourceRegions_basic_smoke", TestAccDataSourceRegions_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccDataSourceRegions_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/stackscript/resource_test.go b/linode/stackscript/resource_test.go index b22e4a3ea..09e077741 100644 --- a/linode/stackscript/resource_test.go +++ b/linode/stackscript/resource_test.go @@ -48,6 +48,19 @@ func sweep(prefix string) error { return nil } +func TestSmokeTests_stackscript(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceStackscript_basic_smoke", TestAccResourceStackscript_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceStackscript_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/stackscripts/datasource_test.go b/linode/stackscripts/datasource_test.go index f5e894787..ba10ca9a4 100644 --- a/linode/stackscripts/datasource_test.go +++ b/linode/stackscripts/datasource_test.go @@ -17,6 +17,19 @@ var basicStackScript = `#!/bin/bash echo "Hello, $NAME!" ` +func TestSmokeTests_stackscripts(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccDataSourceStackscripts_basic_smoke", TestAccDataSourceStackscripts_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccDataSourceStackscripts_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/volume/resource_test.go b/linode/volume/resource_test.go index c117f4f6b..4cf2e4094 100644 --- a/linode/volume/resource_test.go +++ b/linode/volume/resource_test.go @@ -56,6 +56,19 @@ func sweep(prefix string) error { return nil } +func TestSmokeTests_volume(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccResourceVolume_basic_smoke", TestAccResourceVolume_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccResourceVolume_basic_smoke(t *testing.T) { t.Parallel() diff --git a/linode/vpcsubnets/datasource_test.go b/linode/vpcsubnets/datasource_test.go index 8d1b6f249..91c01e632 100644 --- a/linode/vpcsubnets/datasource_test.go +++ b/linode/vpcsubnets/datasource_test.go @@ -13,6 +13,19 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/vpcsubnets/tmpl" ) +func TestSmokeTests_vpcsubnets(t *testing.T) { + tests := []struct { + name string + test func(*testing.T) + }{ + {"TestAccDataSourceVPCSubnets_basic_smoke", TestAccDataSourceVPCSubnets_basic_smoke}, + } + + for _, tt := range tests { + t.Run(tt.name, tt.test) + } +} + func TestAccDataSourceVPCSubnets_basic_smoke(t *testing.T) { t.Parallel() From 23d4bfeccc9007b27eb3fa54232d54201f2bd53a Mon Sep 17 00:00:00 2001 From: Youjung Kim <126618609+ykim-1@users.noreply.github.com> Date: Thu, 3 Oct 2024 11:58:59 -0700 Subject: [PATCH 04/19] Fix slack payload (#1600) --- .github/workflows/integration_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index c7777eb90..fe9b89003 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -175,7 +175,7 @@ jobs: "fields": [ { "type": "mrkdwn", - "text": "*Build Result:*\n${{ steps.integration_tests.outcome == 'success' && ':large_green_circle: Build Passed' || ':red_circle: Build Failed' }}" + "text": "*Build Result:*\n${{ needs.integration_tests.result == 'success' && ':large_green_circle: Build Passed' || ':red_circle: Build Failed' }}" }, { "type": "mrkdwn", From 253b3f76024e41e4a0e2f9aedc1910147bcb2150 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 09:34:13 -0400 Subject: [PATCH 05/19] build(deps): bump github.com/aws/smithy-go from 1.21.0 to 1.22.0 (#1604) Bumps [github.com/aws/smithy-go](https://github.com/aws/smithy-go) from 1.21.0 to 1.22.0. - [Release notes](https://github.com/aws/smithy-go/releases) - [Changelog](https://github.com/aws/smithy-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws/smithy-go/compare/v1.21.0...v1.22.0) --- updated-dependencies: - dependency-name: github.com/aws/smithy-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a93dfaa11..98d02a0f3 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/aws/aws-sdk-go-v2/credentials v1.17.23 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 github.com/aws/aws-sdk-go-v2/service/s3 v1.63.1 - github.com/aws/smithy-go v1.21.0 + github.com/aws/smithy-go v1.22.0 github.com/go-resty/resty/v2 v2.14.0 github.com/google/go-cmp v0.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637 diff --git a/go.sum b/go.sum index 3aa029884..fa42a2a41 100644 --- a/go.sum +++ b/go.sum @@ -45,8 +45,8 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 h1:lCEv9f8f+zJ8kcFeAjRZsekL github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4= github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 h1:+woJ607dllHJQtsnJLi52ycuqHMwlW+Wqm2Ppsfp4nQ= github.com/aws/aws-sdk-go-v2/service/sts v1.30.1/go.mod h1:jiNR3JqT15Dm+QWq2SRgh0x0bCNSRP2L25+CqPNpJlQ= -github.com/aws/smithy-go v1.21.0 h1:H7L8dtDRk0P1Qm6y0ji7MCYMQObJ5R9CRpyPhRUkLYA= -github.com/aws/smithy-go v1.21.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= +github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= From 196fc57cc2cca91724e943f47e61e82b5bae4032 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 12:47:19 -0700 Subject: [PATCH 06/19] build(deps): bump golang.org/x/crypto from 0.27.0 to 0.28.0 (#1610) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.27.0 to 0.28.0. - [Commits](https://github.com/golang/crypto/compare/v0.27.0...v0.28.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 98d02a0f3..8e0a2a707 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/linode/linodego v1.41.0 github.com/linode/linodego/k8s v1.25.2 github.com/stretchr/testify v1.9.0 - golang.org/x/crypto v0.27.0 + golang.org/x/crypto v0.28.0 golang.org/x/net v0.29.0 golang.org/x/sync v0.8.0 ) @@ -102,9 +102,9 @@ require ( github.com/zclconf/go-cty v1.15.0 // indirect golang.org/x/mod v0.19.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/appengine v1.6.8 // indirect diff --git a/go.sum b/go.sum index fa42a2a41..42645697a 100644 --- a/go.sum +++ b/go.sum @@ -273,8 +273,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -331,8 +331,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -342,8 +342,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -355,8 +355,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= From 1772dd01683b9f3ed0d3a0f85792dd8ee2322875 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:02:56 -0400 Subject: [PATCH 07/19] build(deps): bump github.com/aws/aws-sdk-go-v2/service/s3 (#1608) Bumps [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) from 1.63.1 to 1.65.0. - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.63.1...service/s3/v1.65.0) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/service/s3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 20 ++++++++++---------- go.sum | 40 ++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index 8e0a2a707..2f08f04ba 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,11 @@ go 1.22.0 toolchain go1.22.5 require ( - github.com/aws/aws-sdk-go-v2 v1.31.0 + github.com/aws/aws-sdk-go-v2 v1.32.0 github.com/aws/aws-sdk-go-v2/config v1.27.23 github.com/aws/aws-sdk-go-v2/credentials v1.17.23 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 - github.com/aws/aws-sdk-go-v2/service/s3 v1.63.1 + github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0 github.com/aws/smithy-go v1.22.0 github.com/go-resty/resty/v2 v2.14.0 github.com/google/go-cmp v0.6.0 @@ -38,16 +38,16 @@ require ( github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.5 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.18 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.20 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.19 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.0 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect diff --git a/go.sum b/go.sum index 42645697a..a00652015 100644 --- a/go.sum +++ b/go.sum @@ -9,10 +9,10 @@ github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= -github.com/aws/aws-sdk-go-v2 v1.31.0/go.mod h1:ztolYtaEUtdpf9Wftr31CJfLVjOnD/CVRkKOOYgF8hA= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.5 h1:xDAuZTn4IMm8o1LnBZvmrL8JA1io4o3YWNXgohbf20g= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.5/go.mod h1:wYSv6iDS621sEFLfKvpPE2ugjTuGlAG7iROg0hLOkfc= +github.com/aws/aws-sdk-go-v2 v1.32.0 h1:GuHp7GvMN74PXD5C97KT5D87UhIy4bQPkflQKbfkndg= +github.com/aws/aws-sdk-go-v2 v1.32.0/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= github.com/aws/aws-sdk-go-v2/config v1.27.23 h1:Cr/gJEa9NAS7CDAjbnB7tHYb3aLZI2gVggfmSAasDac= github.com/aws/aws-sdk-go-v2/config v1.27.23/go.mod h1:WMMYHqLCFu5LH05mFOF5tsq1PGEMfKbu083VKqLCd0o= github.com/aws/aws-sdk-go-v2/credentials v1.17.23 h1:G1CfmLVoO2TdQ8z9dW+JBc/r8+MqyPQhXCafNZcXVZo= @@ -21,24 +21,24 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 h1:6eKRM6fgeXG4krRO9XKz755vuRhT5UyB9M1W6vjA3JU= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4/go.mod h1:h0TjcRi+nTob6fksqubKOe+Hra8uqfgmN+vuw4xRwWE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 h1:kYQ3H1u0ANr9KEKlGs/jTLrBFPo8P8NaH/w7A01NeeM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18/go.mod h1:r506HmK5JDUh9+Mw4CfGJGSSoqIiLCndAuqXuhbv67Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 h1:Z7IdFUONvTcvS7YuhtVxN99v2cCoHRXOS4mTr0B/pUc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18/go.mod h1:DkKMmksZVVyat+Y+r1dEOgJEfUeA7UngIHWeKsi0yNc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19 h1:Q/k5wCeJkSWs+62kDfOillkNIJ5NqmE3iOfm48g/W8c= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19/go.mod h1:Wns1C66VvtA2Bv/cUBuKZKQKdjo7EVMhp90aAa+8oTI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19 h1:AYLE0lUfKvN6icFTR/p+NmD1amYKTbqHQ1Nm+jwE6BM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19/go.mod h1:1giLakj64GjuH1NBzF/DXqly5DWHtMTaOzRZ53nFX0I= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.18 h1:OWYvKL53l1rbsUmW7bQyJVsYU/Ii3bbAAQIIFNbM0Tk= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.18/go.mod h1:CUx0G1v3wG6l01tUB+j7Y8kclA8NSqK4ef0YG79a4cg= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.20 h1:rTWjG6AvWekO2B1LHeM3ktU7MqyX9rzWQ7hgzneZW7E= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.20/go.mod h1:RGW2DDpVc8hu6Y6yG8G5CHVmVOAn1oV8rNKOHRJyswg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.18 h1:eb+tFOIl9ZsUe2259/BKPeniKuz4/02zZFH/i4Nf8Rg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.18/go.mod h1:GVCC2IJNJTmdlyEsSmofEy7EfJncP7DNnXDzRjJ5Keg= -github.com/aws/aws-sdk-go-v2/service/s3 v1.63.1 h1:TR96r56VwELV0qguNFCuz+/bEpRfnR3ZsS9/IG05C7Q= -github.com/aws/aws-sdk-go-v2/service/s3 v1.63.1/go.mod h1:NLTqRLe3pUNu3nTEHI6XlHLKYmc8fbHUdMxAB6+s41Q= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.19 h1:FKdiFzTxlTRO71p0C7VrLbkkdW8qfMKF5+ej6bTmkT0= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.19/go.mod h1:abO3pCj7WLQPTllnSeYImqFfkGrmJV0JovWo/gqT5N0= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.0 h1:FQNWhRuSq8QwW74GtU0MrveNhZbqvHsA4dkA9w8fTDQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.0/go.mod h1:j/zZ3zmWfGCK91K73YsfHP53BSTLSjL/y6YN39XbBLM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0 h1:AdbiDUgQZmM28rDIZbiSwFxz8+3B94aOXxzs6oH+EA0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0/go.mod h1:uV476Bd80tiDTX4X2redMtagQUg65aU/gzPojSJ4kSI= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.0 h1:1NKXS8XfhMM0bg5wVYa/eOH8AM2f6JijugbKEyQFTIg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.0/go.mod h1:ph931DUfVfgrhZR7py9olSvHCiRpvaGxNvlWBcXxFds= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0 h1:2dSm7frMrw2tdJ0QvyccQNJyPGaP24dyDgZ6h1QJMGU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0/go.mod h1:4XSVpw66upN8wND3JZA29eXl2NOZvfFVq7DIP6xvfuQ= github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc= github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 h1:lCEv9f8f+zJ8kcFeAjRZsekLd/x5SAm96Cva+VbUdo8= From 158e8e96302a0a95ba6f3cbfebdf4996e8eed7a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:03:16 -0400 Subject: [PATCH 08/19] build(deps): bump golang.org/x/net from 0.29.0 to 0.30.0 (#1607) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.29.0 to 0.30.0. - [Commits](https://github.com/golang/net/compare/v0.29.0...v0.30.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2f08f04ba..9a23c4b9f 100644 --- a/go.mod +++ b/go.mod @@ -30,7 +30,7 @@ require ( github.com/linode/linodego/k8s v1.25.2 github.com/stretchr/testify v1.9.0 golang.org/x/crypto v0.28.0 - golang.org/x/net v0.29.0 + golang.org/x/net v0.30.0 golang.org/x/sync v0.8.0 ) diff --git a/go.sum b/go.sum index a00652015..a1f50f3e6 100644 --- a/go.sum +++ b/go.sum @@ -296,8 +296,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From 1603370606324c2f8b2754a30250ddf6eced9bf5 Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Mon, 7 Oct 2024 16:46:28 -0400 Subject: [PATCH 09/19] Add support for LKE, Volume, NodeBalancer, and network transfer pricing endpoints (#1591) * Added LKE Types datasource * Added Node Balancer Types datasource * Added Volume Types datasource * Added Network Transfer Prices datasource * Abstracted base pricing types * Addressed PR comments * Fixed filters for new endpoints --- linode/framework_provider.go | 11 +- linode/helper/base_pricing_types.go | 50 ++++++++ .../framework_datasource_schema.go | 24 +--- linode/instancetype/framework_models.go | 10 +- linode/lketypes/datasource_test.go | 35 +++++ linode/lketypes/framework_datasource.go | 73 +++++++++++ .../lketypes/framework_datasource_schema.go | 34 +++++ linode/lketypes/framework_models.go | 121 ++++++++++++++++++ linode/lketypes/tmpl/data_basic.gotf | 10 ++ linode/lketypes/tmpl/template.go | 12 ++ linode/nbtypes/datasource_test.go | 38 ++++++ linode/nbtypes/framework_datasource.go | 73 +++++++++++ linode/nbtypes/framework_datasource_schema.go | 34 +++++ linode/nbtypes/framework_models.go | 121 ++++++++++++++++++ linode/nbtypes/tmpl/data_basic.gotf | 10 ++ linode/nbtypes/tmpl/template.go | 12 ++ .../networktransferprices/datasource_test.go | 38 ++++++ .../framework_datasource.go | 73 +++++++++++ .../framework_datasource_schema.go | 34 +++++ .../networktransferprices/framework_models.go | 121 ++++++++++++++++++ .../tmpl/data_basic.gotf | 10 ++ linode/networktransferprices/tmpl/template.go | 12 ++ linode/volumetypes/datasource_test.go | 38 ++++++ linode/volumetypes/framework_datasource.go | 73 +++++++++++ .../framework_datasource_schema.go | 34 +++++ linode/volumetypes/framework_models.go | 121 ++++++++++++++++++ linode/volumetypes/tmpl/data_basic.gotf | 10 ++ linode/volumetypes/tmpl/template.go | 12 ++ 28 files changed, 1219 insertions(+), 25 deletions(-) create mode 100644 linode/helper/base_pricing_types.go create mode 100644 linode/lketypes/datasource_test.go create mode 100644 linode/lketypes/framework_datasource.go create mode 100644 linode/lketypes/framework_datasource_schema.go create mode 100644 linode/lketypes/framework_models.go create mode 100644 linode/lketypes/tmpl/data_basic.gotf create mode 100644 linode/lketypes/tmpl/template.go create mode 100644 linode/nbtypes/datasource_test.go create mode 100644 linode/nbtypes/framework_datasource.go create mode 100644 linode/nbtypes/framework_datasource_schema.go create mode 100644 linode/nbtypes/framework_models.go create mode 100644 linode/nbtypes/tmpl/data_basic.gotf create mode 100644 linode/nbtypes/tmpl/template.go create mode 100644 linode/networktransferprices/datasource_test.go create mode 100644 linode/networktransferprices/framework_datasource.go create mode 100644 linode/networktransferprices/framework_datasource_schema.go create mode 100644 linode/networktransferprices/framework_models.go create mode 100644 linode/networktransferprices/tmpl/data_basic.gotf create mode 100644 linode/networktransferprices/tmpl/template.go create mode 100644 linode/volumetypes/datasource_test.go create mode 100644 linode/volumetypes/framework_datasource.go create mode 100644 linode/volumetypes/framework_datasource_schema.go create mode 100644 linode/volumetypes/framework_models.go create mode 100644 linode/volumetypes/tmpl/data_basic.gotf create mode 100644 linode/volumetypes/tmpl/template.go diff --git a/linode/framework_provider.go b/linode/framework_provider.go index 22cab83ff..7dc261184 100644 --- a/linode/framework_provider.go +++ b/linode/framework_provider.go @@ -3,8 +3,6 @@ package linode import ( "context" - "github.com/linode/terraform-provider-linode/v2/linode/vpcips" - "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/provider" "github.com/hashicorp/terraform-plugin-framework/provider/schema" @@ -46,13 +44,16 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/lke" "github.com/linode/terraform-provider-linode/v2/linode/lkeclusters" "github.com/linode/terraform-provider-linode/v2/linode/lkenodepool" + "github.com/linode/terraform-provider-linode/v2/linode/lketypes" "github.com/linode/terraform-provider-linode/v2/linode/lkeversions" "github.com/linode/terraform-provider-linode/v2/linode/nb" "github.com/linode/terraform-provider-linode/v2/linode/nbconfig" "github.com/linode/terraform-provider-linode/v2/linode/nbconfigs" "github.com/linode/terraform-provider-linode/v2/linode/nbnode" "github.com/linode/terraform-provider-linode/v2/linode/nbs" + "github.com/linode/terraform-provider-linode/v2/linode/nbtypes" "github.com/linode/terraform-provider-linode/v2/linode/networkingip" + "github.com/linode/terraform-provider-linode/v2/linode/networktransferprices" "github.com/linode/terraform-provider-linode/v2/linode/objbucket" "github.com/linode/terraform-provider-linode/v2/linode/objcluster" "github.com/linode/terraform-provider-linode/v2/linode/objkey" @@ -73,7 +74,9 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/vlan" "github.com/linode/terraform-provider-linode/v2/linode/volume" "github.com/linode/terraform-provider-linode/v2/linode/volumes" + "github.com/linode/terraform-provider-linode/v2/linode/volumetypes" "github.com/linode/terraform-provider-linode/v2/linode/vpc" + "github.com/linode/terraform-provider-linode/v2/linode/vpcips" "github.com/linode/terraform-provider-linode/v2/linode/vpcs" "github.com/linode/terraform-provider-linode/v2/linode/vpcsubnet" "github.com/linode/terraform-provider-linode/v2/linode/vpcsubnets" @@ -237,6 +240,7 @@ func (p *FrameworkProvider) DataSources(ctx context.Context) []func() datasource profile.NewDataSource, nb.NewDataSource, networkingip.NewDataSource, + networktransferprices.NewDataSource, lkeversions.NewDataSource, regions.NewDataSource, ipv6range.NewDataSource, @@ -253,6 +257,7 @@ func (p *FrameworkProvider) DataSources(ctx context.Context) []func() datasource domain.NewDataSource, user.NewDataSource, nbconfig.NewDataSource, + nbtypes.NewDataSource, instancetype.NewDataSource, instancetypes.NewDataSource, image.NewDataSource, @@ -276,12 +281,14 @@ func (p *FrameworkProvider) DataSources(ctx context.Context) []func() datasource vpcsubnets.NewDataSource, vpcs.NewDataSource, volumes.NewDataSource, + volumetypes.NewDataSource, accountavailability.NewDataSource, nbconfigs.NewDataSource, ipv6ranges.NewDataSource, domains.NewDataSource, lke.NewDataSource, lkeclusters.NewDataSource, + lketypes.NewDataSource, placementgroup.NewDataSource, placementgroups.NewDataSource, childaccount.NewDataSource, diff --git a/linode/helper/base_pricing_types.go b/linode/helper/base_pricing_types.go new file mode 100644 index 000000000..f3e96878c --- /dev/null +++ b/linode/helper/base_pricing_types.go @@ -0,0 +1,50 @@ +package helper + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var PriceObjectType = types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "hourly": types.Float64Type, + "monthly": types.Float64Type, + }, +} + +var RegionPriceObjectType = types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "id": types.StringType, + "hourly": types.Float64Type, + "monthly": types.Float64Type, + }, +} + +func GetPricingTypeAttributes(typeName string) map[string]schema.Attribute { + return map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "The unique ID assigned to this " + typeName + ".", + Required: true, + }, + "label": schema.StringAttribute{ + Description: "The " + typeName + "'s label.", + Computed: true, + Optional: true, + }, + "price": schema.ListAttribute{ + Description: "Cost in US dollars, broken down into hourly and monthly charges.", + Computed: true, + ElementType: PriceObjectType, + }, + "region_prices": schema.ListAttribute{ + Description: "A list of region-specific prices for this " + typeName + ".", + Computed: true, + ElementType: RegionPriceObjectType, + }, + "transfer": schema.Int64Attribute{ + Description: "The monthly outbound transfer amount, in MB.", + Computed: true, + }, + } +} diff --git a/linode/instancetype/framework_datasource_schema.go b/linode/instancetype/framework_datasource_schema.go index 8af4219bf..351808cff 100644 --- a/linode/instancetype/framework_datasource_schema.go +++ b/linode/instancetype/framework_datasource_schema.go @@ -4,27 +4,13 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/linode/terraform-provider-linode/v2/linode/helper" ) -var priceObjectType = types.ObjectType{ - AttrTypes: map[string]attr.Type{ - "hourly": types.Float64Type, - "monthly": types.Float64Type, - }, -} - -var regionPriceObjectType = types.ObjectType{ - AttrTypes: map[string]attr.Type{ - "id": types.StringType, - "hourly": types.Float64Type, - "monthly": types.Float64Type, - }, -} - var backupsObjectType = types.ObjectType{ AttrTypes: map[string]attr.Type{ - "price": types.ListType{ElemType: priceObjectType}, - "region_prices": types.ListType{ElemType: regionPriceObjectType}, + "price": types.ListType{ElemType: helper.PriceObjectType}, + "region_prices": types.ListType{ElemType: helper.RegionPriceObjectType}, }, } @@ -56,7 +42,7 @@ var Attributes = map[string]schema.Attribute{ "price": schema.ListAttribute{ Description: "Cost in US dollars, broken down into hourly and monthly charges.", Computed: true, - ElementType: priceObjectType, + ElementType: helper.PriceObjectType, }, "addons": schema.ListAttribute{ Description: "Information about the optional Backup service offered for Linodes.", @@ -66,7 +52,7 @@ var Attributes = map[string]schema.Attribute{ "region_prices": schema.ListAttribute{ Description: "A list of region-specific prices for this plan.", Computed: true, - ElementType: regionPriceObjectType, + ElementType: helper.RegionPriceObjectType, }, "network_out": schema.Int64Attribute{ Description: "The Mbits outbound bandwidth allocation.", diff --git a/linode/instancetype/framework_models.go b/linode/instancetype/framework_models.go index 83ded6d18..810e0c3e4 100644 --- a/linode/instancetype/framework_models.go +++ b/linode/instancetype/framework_models.go @@ -3,6 +3,8 @@ package instancetype import ( "context" + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" @@ -134,7 +136,7 @@ func FlattenPrice(ctx context.Context, price linodego.LinodePrice) ( result["hourly"] = types.Float64Value(float64(price.Hourly)) result["monthly"] = types.Float64Value(float64(price.Monthly)) - obj, diag := types.ObjectValue(priceObjectType.AttrTypes, result) + obj, diag := types.ObjectValue(helper.PriceObjectType.AttrTypes, result) if diag.HasError() { return nil, diag } @@ -142,7 +144,7 @@ func FlattenPrice(ctx context.Context, price linodego.LinodePrice) ( objList := []attr.Value{obj} resultList, diag := types.ListValue( - priceObjectType, + helper.PriceObjectType, objList, ) if diag.HasError() { @@ -158,7 +160,7 @@ func FlattenRegionPrices(prices []linodego.LinodeRegionPrice) ( result := make([]attr.Value, len(prices)) for i, price := range prices { - obj, d := types.ObjectValue(regionPriceObjectType.AttrTypes, map[string]attr.Value{ + obj, d := types.ObjectValue(helper.RegionPriceObjectType.AttrTypes, map[string]attr.Value{ "id": types.StringValue(price.ID), "hourly": types.Float64Value(float64(price.Hourly)), "monthly": types.Float64Value(float64(price.Monthly)), @@ -171,7 +173,7 @@ func FlattenRegionPrices(prices []linodego.LinodeRegionPrice) ( } priceList, d := basetypes.NewListValue( - regionPriceObjectType, + helper.RegionPriceObjectType, result, ) return &priceList, d diff --git a/linode/lketypes/datasource_test.go b/linode/lketypes/datasource_test.go new file mode 100644 index 000000000..a7dc0a276 --- /dev/null +++ b/linode/lketypes/datasource_test.go @@ -0,0 +1,35 @@ +//go:build integration || lketypes + +package lketypes_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" + "github.com/linode/terraform-provider-linode/v2/linode/lketypes/tmpl" +) + +func TestAccDataSourceLKETypes_basic(t *testing.T) { + t.Parallel() + + dataSourceName := "data.linode_lke_types.foobar" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: tmpl.DataBasic(t), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "types.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "types.0.id", "lke-sa"), + resource.TestCheckResourceAttr(dataSourceName, "types.0.label", "LKE Standard Availability"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.transfer"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.price.0.hourly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.price.0.monthly"), + ), + }, + }, + }) +} diff --git a/linode/lketypes/framework_datasource.go b/linode/lketypes/framework_datasource.go new file mode 100644 index 000000000..f35b16a77 --- /dev/null +++ b/linode/lketypes/framework_datasource.go @@ -0,0 +1,73 @@ +package lketypes + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" +) + +func NewDataSource() datasource.DataSource { + return &DataSource{ + BaseDataSource: helper.NewBaseDataSource( + helper.BaseDataSourceConfig{ + Name: "linode_lke_types", + Schema: &frameworkDataSourceSchema, + }, + ), + } +} + +type DataSource struct { + helper.BaseDataSource +} + +func (r *DataSource) Read( + ctx context.Context, + req datasource.ReadRequest, + resp *datasource.ReadResponse, +) { + tflog.Debug(ctx, "Read data.linode_lke_types") + + var data LKETypeFilterModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + id, d := filterConfig.GenerateID(data.Filters) + if d != nil { + resp.Diagnostics.Append(d) + return + } + data.ID = id + + result, d := filterConfig.GetAndFilter( + ctx, r.Meta.Client, data.Filters, listLKETypes, data.Order, data.OrderBy) + if d != nil { + resp.Diagnostics.Append(d) + return + } + + data.parseLKETypes(helper.AnySliceToTyped[linodego.LKEType](result)) + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func listLKETypes(ctx context.Context, client *linodego.Client, filter string) ([]any, error) { + tflog.Debug(ctx, "Listing LKE types", map[string]any{ + "filter_header": filter, + }) + + types, err := client.ListLKETypes(ctx, &linodego.ListOptions{ + Filter: filter, + }) + if err != nil { + return nil, err + } + + return helper.TypedSliceToAny(types), nil +} diff --git a/linode/lketypes/framework_datasource_schema.go b/linode/lketypes/framework_datasource_schema.go new file mode 100644 index 000000000..7c3af3117 --- /dev/null +++ b/linode/lketypes/framework_datasource_schema.go @@ -0,0 +1,34 @@ +package lketypes + +import ( + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" +) + +var lkeTypeSchema = schema.NestedBlockObject{ + Attributes: helper.GetPricingTypeAttributes("LKE Type"), +} + +var filterConfig = frameworkfilter.Config{ + "label": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeString}, + "transfer": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeInt}, +} + +var frameworkDataSourceSchema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "The data source's unique ID.", + Computed: true, + }, + "order_by": filterConfig.OrderBySchema(), + "order": filterConfig.OrderSchema(), + }, + Blocks: map[string]schema.Block{ + "filter": filterConfig.Schema(), + "types": schema.ListNestedBlock{ + Description: "The returned list of LKE types.", + NestedObject: lkeTypeSchema, + }, + }, +} diff --git a/linode/lketypes/framework_models.go b/linode/lketypes/framework_models.go new file mode 100644 index 000000000..b357dfbfd --- /dev/null +++ b/linode/lketypes/framework_models.go @@ -0,0 +1,121 @@ +package lketypes + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" +) + +type DataSourceModel struct { + ID types.String `tfsdk:"id"` + Label types.String `tfsdk:"label"` + Price types.List `tfsdk:"price"` + RegionPrices types.List `tfsdk:"region_prices"` + Transfer types.Int64 `tfsdk:"transfer"` +} + +func (data *DataSourceModel) parseLKEType(lkeType *linodego.LKEType, +) diag.Diagnostics { + data.ID = types.StringValue(lkeType.ID) + + price, diags := flattenPrice(lkeType.Price) + if diags.HasError() { + return diags + } + data.Price = *price + + data.Label = types.StringValue(lkeType.Label) + + regionPrices, d := flattenRegionPrices(lkeType.RegionPrices) + if d.HasError() { + return d + } + data.RegionPrices = *regionPrices + + data.Transfer = types.Int64Value(int64(lkeType.Transfer)) + + return nil +} + +func flattenPrice(price linodego.LKETypePrice) ( + *basetypes.ListValue, diag.Diagnostics, +) { + result := make(map[string]attr.Value) + + result["hourly"] = types.Float64Value(float64(price.Hourly)) + result["monthly"] = types.Float64Value(float64(price.Monthly)) + + obj, diag := types.ObjectValue(helper.PriceObjectType.AttrTypes, result) + if diag.HasError() { + return nil, diag + } + + objList := []attr.Value{obj} + + resultList, diag := types.ListValue( + helper.PriceObjectType, + objList, + ) + if diag.HasError() { + return nil, diag + } + + return &resultList, nil +} + +func flattenRegionPrices(prices []linodego.LKETypeRegionPrice) ( + *basetypes.ListValue, diag.Diagnostics, +) { + result := make([]attr.Value, len(prices)) + + for i, price := range prices { + obj, d := types.ObjectValue(helper.RegionPriceObjectType.AttrTypes, map[string]attr.Value{ + "id": types.StringValue(price.ID), + "hourly": types.Float64Value(float64(price.Hourly)), + "monthly": types.Float64Value(float64(price.Monthly)), + }) + if d.HasError() { + return nil, d + } + + result[i] = obj + } + + priceList, d := basetypes.NewListValue( + helper.RegionPriceObjectType, + result, + ) + return &priceList, d +} + +type LKETypeFilterModel struct { + ID types.String `tfsdk:"id"` + Order types.String `tfsdk:"order"` + OrderBy types.String `tfsdk:"order_by"` + Filters frameworkfilter.FiltersModelType `tfsdk:"filter"` + Types []DataSourceModel `tfsdk:"types"` +} + +func (model *LKETypeFilterModel) parseLKETypes(lkeTypes []linodego.LKEType, +) diag.Diagnostics { + result := make([]DataSourceModel, len(lkeTypes)) + + for i := range lkeTypes { + var m DataSourceModel + + diags := m.parseLKEType(&lkeTypes[i]) + if diags.HasError() { + return diags + } + + result[i] = m + } + + model.Types = result + + return nil +} diff --git a/linode/lketypes/tmpl/data_basic.gotf b/linode/lketypes/tmpl/data_basic.gotf new file mode 100644 index 000000000..5b260627c --- /dev/null +++ b/linode/lketypes/tmpl/data_basic.gotf @@ -0,0 +1,10 @@ +{{ define "lke_types_data_basic" }} + +data "linode_lke_types" "foobar" { + filter { + name = "label" + values = ["LKE Standard Availability"] + } +} + +{{ end }} \ No newline at end of file diff --git a/linode/lketypes/tmpl/template.go b/linode/lketypes/tmpl/template.go new file mode 100644 index 000000000..687ebbe6b --- /dev/null +++ b/linode/lketypes/tmpl/template.go @@ -0,0 +1,12 @@ +package tmpl + +import ( + "testing" + + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" +) + +func DataBasic(t *testing.T) string { + return acceptance.ExecuteTemplate(t, + "lke_types_data_basic", nil) +} diff --git a/linode/nbtypes/datasource_test.go b/linode/nbtypes/datasource_test.go new file mode 100644 index 000000000..d97eb41dc --- /dev/null +++ b/linode/nbtypes/datasource_test.go @@ -0,0 +1,38 @@ +//go:build integration || nbtypes + +package nbtypes_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" + "github.com/linode/terraform-provider-linode/v2/linode/nbtypes/tmpl" +) + +func TestAccDataSourceNodeBalancerTypes_basic(t *testing.T) { + t.Parallel() + + dataSourceName := "data.linode_nb_types.foobar" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: tmpl.DataBasic(t), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "types.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "types.0.id", "nodebalancer"), + resource.TestCheckResourceAttr(dataSourceName, "types.0.label", "NodeBalancer"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.transfer"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.price.0.hourly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.price.0.monthly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.region_prices.0.id"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.region_prices.0.hourly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.region_prices.0.monthly"), + ), + }, + }, + }) +} diff --git a/linode/nbtypes/framework_datasource.go b/linode/nbtypes/framework_datasource.go new file mode 100644 index 000000000..bcaf07679 --- /dev/null +++ b/linode/nbtypes/framework_datasource.go @@ -0,0 +1,73 @@ +package nbtypes + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" +) + +func NewDataSource() datasource.DataSource { + return &DataSource{ + BaseDataSource: helper.NewBaseDataSource( + helper.BaseDataSourceConfig{ + Name: "linode_nb_types", + Schema: &frameworkDataSourceSchema, + }, + ), + } +} + +type DataSource struct { + helper.BaseDataSource +} + +func (r *DataSource) Read( + ctx context.Context, + req datasource.ReadRequest, + resp *datasource.ReadResponse, +) { + tflog.Debug(ctx, "Read data.linode_nb_types") + + var data NodeBalancerTypeFilterModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + id, d := filterConfig.GenerateID(data.Filters) + if d != nil { + resp.Diagnostics.Append(d) + return + } + data.ID = id + + result, d := filterConfig.GetAndFilter( + ctx, r.Meta.Client, data.Filters, listNodeBalancerTypes, data.Order, data.OrderBy) + if d != nil { + resp.Diagnostics.Append(d) + return + } + + data.parseNodeBalancerTypes(helper.AnySliceToTyped[linodego.NodeBalancerType](result)) + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func listNodeBalancerTypes(ctx context.Context, client *linodego.Client, filter string) ([]any, error) { + tflog.Debug(ctx, "Listing Node Balancer types", map[string]any{ + "filter_header": filter, + }) + + types, err := client.ListNodeBalancerTypes(ctx, &linodego.ListOptions{ + Filter: filter, + }) + if err != nil { + return nil, err + } + + return helper.TypedSliceToAny(types), nil +} diff --git a/linode/nbtypes/framework_datasource_schema.go b/linode/nbtypes/framework_datasource_schema.go new file mode 100644 index 000000000..89bc9c327 --- /dev/null +++ b/linode/nbtypes/framework_datasource_schema.go @@ -0,0 +1,34 @@ +package nbtypes + +import ( + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" +) + +var nodebalancerTypeSchema = schema.NestedBlockObject{ + Attributes: helper.GetPricingTypeAttributes("Node Balancer Type"), +} + +var filterConfig = frameworkfilter.Config{ + "label": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeString}, + "transfer": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeInt}, +} + +var frameworkDataSourceSchema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "The data source's unique ID.", + Computed: true, + }, + "order_by": filterConfig.OrderBySchema(), + "order": filterConfig.OrderSchema(), + }, + Blocks: map[string]schema.Block{ + "filter": filterConfig.Schema(), + "types": schema.ListNestedBlock{ + Description: "The returned list of Node Balancer types.", + NestedObject: nodebalancerTypeSchema, + }, + }, +} diff --git a/linode/nbtypes/framework_models.go b/linode/nbtypes/framework_models.go new file mode 100644 index 000000000..6b0010213 --- /dev/null +++ b/linode/nbtypes/framework_models.go @@ -0,0 +1,121 @@ +package nbtypes + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" +) + +type DataSourceModel struct { + ID types.String `tfsdk:"id"` + Label types.String `tfsdk:"label"` + Price types.List `tfsdk:"price"` + RegionPrices types.List `tfsdk:"region_prices"` + Transfer types.Int64 `tfsdk:"transfer"` +} + +func (data *DataSourceModel) parseNodeBalancerType(nbType *linodego.NodeBalancerType, +) diag.Diagnostics { + data.ID = types.StringValue(nbType.ID) + + price, diags := flattenPrice(nbType.Price) + if diags.HasError() { + return diags + } + data.Price = *price + + data.Label = types.StringValue(nbType.Label) + + regionPrices, d := flattenRegionPrices(nbType.RegionPrices) + if d.HasError() { + return d + } + data.RegionPrices = *regionPrices + + data.Transfer = types.Int64Value(int64(nbType.Transfer)) + + return nil +} + +func flattenPrice(price linodego.NodeBalancerTypePrice) ( + *basetypes.ListValue, diag.Diagnostics, +) { + result := make(map[string]attr.Value) + + result["hourly"] = types.Float64Value(float64(price.Hourly)) + result["monthly"] = types.Float64Value(float64(price.Monthly)) + + obj, diag := types.ObjectValue(helper.PriceObjectType.AttrTypes, result) + if diag.HasError() { + return nil, diag + } + + objList := []attr.Value{obj} + + resultList, diag := types.ListValue( + helper.PriceObjectType, + objList, + ) + if diag.HasError() { + return nil, diag + } + + return &resultList, nil +} + +func flattenRegionPrices(prices []linodego.NodeBalancerTypeRegionPrice) ( + *basetypes.ListValue, diag.Diagnostics, +) { + result := make([]attr.Value, len(prices)) + + for i, price := range prices { + obj, d := types.ObjectValue(helper.RegionPriceObjectType.AttrTypes, map[string]attr.Value{ + "id": types.StringValue(price.ID), + "hourly": types.Float64Value(float64(price.Hourly)), + "monthly": types.Float64Value(float64(price.Monthly)), + }) + if d.HasError() { + return nil, d + } + + result[i] = obj + } + + priceList, d := basetypes.NewListValue( + helper.RegionPriceObjectType, + result, + ) + return &priceList, d +} + +type NodeBalancerTypeFilterModel struct { + ID types.String `tfsdk:"id"` + Order types.String `tfsdk:"order"` + OrderBy types.String `tfsdk:"order_by"` + Filters frameworkfilter.FiltersModelType `tfsdk:"filter"` + Types []DataSourceModel `tfsdk:"types"` +} + +func (model *NodeBalancerTypeFilterModel) parseNodeBalancerTypes(nbTypes []linodego.NodeBalancerType, +) diag.Diagnostics { + result := make([]DataSourceModel, len(nbTypes)) + + for i := range nbTypes { + var m DataSourceModel + + diags := m.parseNodeBalancerType(&nbTypes[i]) + if diags.HasError() { + return diags + } + + result[i] = m + } + + model.Types = result + + return nil +} diff --git a/linode/nbtypes/tmpl/data_basic.gotf b/linode/nbtypes/tmpl/data_basic.gotf new file mode 100644 index 000000000..fb8fffe12 --- /dev/null +++ b/linode/nbtypes/tmpl/data_basic.gotf @@ -0,0 +1,10 @@ +{{ define "nb_types_data_basic" }} + +data "linode_nb_types" "foobar" { + filter { + name = "label" + values = ["NodeBalancer"] + } +} + +{{ end }} \ No newline at end of file diff --git a/linode/nbtypes/tmpl/template.go b/linode/nbtypes/tmpl/template.go new file mode 100644 index 000000000..b57ade428 --- /dev/null +++ b/linode/nbtypes/tmpl/template.go @@ -0,0 +1,12 @@ +package tmpl + +import ( + "testing" + + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" +) + +func DataBasic(t *testing.T) string { + return acceptance.ExecuteTemplate(t, + "nb_types_data_basic", nil) +} diff --git a/linode/networktransferprices/datasource_test.go b/linode/networktransferprices/datasource_test.go new file mode 100644 index 000000000..018966654 --- /dev/null +++ b/linode/networktransferprices/datasource_test.go @@ -0,0 +1,38 @@ +//go:build integration || networktransferprices + +package networktransferprices_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" + "github.com/linode/terraform-provider-linode/v2/linode/networktransferprices/tmpl" +) + +func TestAccDataSourceNetworkTransferPrices_basic(t *testing.T) { + t.Parallel() + + dataSourceName := "data.linode_network_transfer_prices.foobar" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: tmpl.DataBasic(t), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "types.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "types.0.id", "network_transfer"), + resource.TestCheckResourceAttr(dataSourceName, "types.0.label", "Network Transfer"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.transfer"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.price.0.hourly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.price.0.monthly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.region_prices.0.id"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.region_prices.0.hourly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.region_prices.0.monthly"), + ), + }, + }, + }) +} diff --git a/linode/networktransferprices/framework_datasource.go b/linode/networktransferprices/framework_datasource.go new file mode 100644 index 000000000..7700e1fcb --- /dev/null +++ b/linode/networktransferprices/framework_datasource.go @@ -0,0 +1,73 @@ +package networktransferprices + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" +) + +func NewDataSource() datasource.DataSource { + return &DataSource{ + BaseDataSource: helper.NewBaseDataSource( + helper.BaseDataSourceConfig{ + Name: "linode_network_transfer_prices", + Schema: &frameworkDataSourceSchema, + }, + ), + } +} + +type DataSource struct { + helper.BaseDataSource +} + +func (r *DataSource) Read( + ctx context.Context, + req datasource.ReadRequest, + resp *datasource.ReadResponse, +) { + tflog.Debug(ctx, "Read data.linode_network_transfer_prices") + + var data NetworkTransferPriceFilterModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + id, d := filterConfig.GenerateID(data.Filters) + if d != nil { + resp.Diagnostics.Append(d) + return + } + data.ID = id + + result, d := filterConfig.GetAndFilter( + ctx, r.Meta.Client, data.Filters, listNetworkTransferPrices, data.Order, data.OrderBy) + if d != nil { + resp.Diagnostics.Append(d) + return + } + + data.parseNetworkTransferPrices(helper.AnySliceToTyped[linodego.NetworkTransferPrice](result)) + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func listNetworkTransferPrices(ctx context.Context, client *linodego.Client, filter string) ([]any, error) { + tflog.Debug(ctx, "Listing Network Transfer Prices", map[string]any{ + "filter_header": filter, + }) + + types, err := client.ListNetworkTransferPrices(ctx, &linodego.ListOptions{ + Filter: filter, + }) + if err != nil { + return nil, err + } + + return helper.TypedSliceToAny(types), nil +} diff --git a/linode/networktransferprices/framework_datasource_schema.go b/linode/networktransferprices/framework_datasource_schema.go new file mode 100644 index 000000000..3db54b351 --- /dev/null +++ b/linode/networktransferprices/framework_datasource_schema.go @@ -0,0 +1,34 @@ +package networktransferprices + +import ( + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" +) + +var networkTransferPriceSchema = schema.NestedBlockObject{ + Attributes: helper.GetPricingTypeAttributes("Network Transfer Price"), +} + +var filterConfig = frameworkfilter.Config{ + "label": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeString}, + "transfer": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeInt}, +} + +var frameworkDataSourceSchema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "The data source's unique ID.", + Computed: true, + }, + "order_by": filterConfig.OrderBySchema(), + "order": filterConfig.OrderSchema(), + }, + Blocks: map[string]schema.Block{ + "filter": filterConfig.Schema(), + "types": schema.ListNestedBlock{ + Description: "The returned list of Network Transfer Prices.", + NestedObject: networkTransferPriceSchema, + }, + }, +} diff --git a/linode/networktransferprices/framework_models.go b/linode/networktransferprices/framework_models.go new file mode 100644 index 000000000..3efb1901a --- /dev/null +++ b/linode/networktransferprices/framework_models.go @@ -0,0 +1,121 @@ +package networktransferprices + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" +) + +type DataSourceModel struct { + ID types.String `tfsdk:"id"` + Label types.String `tfsdk:"label"` + Price types.List `tfsdk:"price"` + RegionPrices types.List `tfsdk:"region_prices"` + Transfer types.Int64 `tfsdk:"transfer"` +} + +func (data *DataSourceModel) parseNetworkTransferPrice(networkTransferPrice *linodego.NetworkTransferPrice, +) diag.Diagnostics { + data.ID = types.StringValue(networkTransferPrice.ID) + + price, diags := flattenPrice(networkTransferPrice.Price) + if diags.HasError() { + return diags + } + data.Price = *price + + data.Label = types.StringValue(networkTransferPrice.Label) + + regionPrices, d := flattenRegionPrices(networkTransferPrice.RegionPrices) + if d.HasError() { + return d + } + data.RegionPrices = *regionPrices + + data.Transfer = types.Int64Value(int64(networkTransferPrice.Transfer)) + + return nil +} + +func flattenPrice(price linodego.NetworkTransferTypePrice) ( + *basetypes.ListValue, diag.Diagnostics, +) { + result := make(map[string]attr.Value) + + result["hourly"] = types.Float64Value(float64(price.Hourly)) + result["monthly"] = types.Float64Value(float64(price.Monthly)) + + obj, diag := types.ObjectValue(helper.PriceObjectType.AttrTypes, result) + if diag.HasError() { + return nil, diag + } + + objList := []attr.Value{obj} + + resultList, diag := types.ListValue( + helper.PriceObjectType, + objList, + ) + if diag.HasError() { + return nil, diag + } + + return &resultList, nil +} + +func flattenRegionPrices(prices []linodego.NetworkTransferTypeRegionPrice) ( + *basetypes.ListValue, diag.Diagnostics, +) { + result := make([]attr.Value, len(prices)) + + for i, price := range prices { + obj, d := types.ObjectValue(helper.RegionPriceObjectType.AttrTypes, map[string]attr.Value{ + "id": types.StringValue(price.ID), + "hourly": types.Float64Value(float64(price.Hourly)), + "monthly": types.Float64Value(float64(price.Monthly)), + }) + if d.HasError() { + return nil, d + } + + result[i] = obj + } + + priceList, d := basetypes.NewListValue( + helper.RegionPriceObjectType, + result, + ) + return &priceList, d +} + +type NetworkTransferPriceFilterModel struct { + ID types.String `tfsdk:"id"` + Order types.String `tfsdk:"order"` + OrderBy types.String `tfsdk:"order_by"` + Filters frameworkfilter.FiltersModelType `tfsdk:"filter"` + Types []DataSourceModel `tfsdk:"types"` +} + +func (model *NetworkTransferPriceFilterModel) parseNetworkTransferPrices(networkTransferPrices []linodego.NetworkTransferPrice, +) diag.Diagnostics { + result := make([]DataSourceModel, len(networkTransferPrices)) + + for i := range networkTransferPrices { + var m DataSourceModel + + diags := m.parseNetworkTransferPrice(&networkTransferPrices[i]) + if diags.HasError() { + return diags + } + + result[i] = m + } + + model.Types = result + + return nil +} diff --git a/linode/networktransferprices/tmpl/data_basic.gotf b/linode/networktransferprices/tmpl/data_basic.gotf new file mode 100644 index 000000000..423075e6f --- /dev/null +++ b/linode/networktransferprices/tmpl/data_basic.gotf @@ -0,0 +1,10 @@ +{{ define "network_transfer_prices_data_basic" }} + +data "linode_network_transfer_prices" "foobar" { + filter { + name = "label" + values = ["Network Transfer"] + } +} + +{{ end }} \ No newline at end of file diff --git a/linode/networktransferprices/tmpl/template.go b/linode/networktransferprices/tmpl/template.go new file mode 100644 index 000000000..fe21d70d6 --- /dev/null +++ b/linode/networktransferprices/tmpl/template.go @@ -0,0 +1,12 @@ +package tmpl + +import ( + "testing" + + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" +) + +func DataBasic(t *testing.T) string { + return acceptance.ExecuteTemplate(t, + "network_transfer_prices_data_basic", nil) +} diff --git a/linode/volumetypes/datasource_test.go b/linode/volumetypes/datasource_test.go new file mode 100644 index 000000000..ab9a17285 --- /dev/null +++ b/linode/volumetypes/datasource_test.go @@ -0,0 +1,38 @@ +//go:build integration || volumetypes + +package volumetypes_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" + "github.com/linode/terraform-provider-linode/v2/linode/volumetypes/tmpl" +) + +func TestAccDataSourceVolumeTypes_basic(t *testing.T) { + t.Parallel() + + dataSourceName := "data.linode_volume_types.foobar" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: tmpl.DataBasic(t), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "types.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "types.0.id", "volume"), + resource.TestCheckResourceAttr(dataSourceName, "types.0.label", "Storage Volume"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.transfer"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.price.0.hourly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.price.0.monthly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.region_prices.0.id"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.region_prices.0.hourly"), + resource.TestCheckResourceAttrSet(dataSourceName, "types.0.region_prices.0.monthly"), + ), + }, + }, + }) +} diff --git a/linode/volumetypes/framework_datasource.go b/linode/volumetypes/framework_datasource.go new file mode 100644 index 000000000..f08ecb3b6 --- /dev/null +++ b/linode/volumetypes/framework_datasource.go @@ -0,0 +1,73 @@ +package volumetypes + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" +) + +func NewDataSource() datasource.DataSource { + return &DataSource{ + BaseDataSource: helper.NewBaseDataSource( + helper.BaseDataSourceConfig{ + Name: "linode_volume_types", + Schema: &frameworkDataSourceSchema, + }, + ), + } +} + +type DataSource struct { + helper.BaseDataSource +} + +func (r *DataSource) Read( + ctx context.Context, + req datasource.ReadRequest, + resp *datasource.ReadResponse, +) { + tflog.Debug(ctx, "Read data.linode_volume_types") + + var data VolumeTypeFilterModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + id, d := filterConfig.GenerateID(data.Filters) + if d != nil { + resp.Diagnostics.Append(d) + return + } + data.ID = id + + result, d := filterConfig.GetAndFilter( + ctx, r.Meta.Client, data.Filters, listVolumeTypes, data.Order, data.OrderBy) + if d != nil { + resp.Diagnostics.Append(d) + return + } + + data.parseVolumeTypes(helper.AnySliceToTyped[linodego.VolumeType](result)) + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func listVolumeTypes(ctx context.Context, client *linodego.Client, filter string) ([]any, error) { + tflog.Debug(ctx, "Listing Volume types", map[string]any{ + "filter_header": filter, + }) + + types, err := client.ListVolumeTypes(ctx, &linodego.ListOptions{ + Filter: filter, + }) + if err != nil { + return nil, err + } + + return helper.TypedSliceToAny(types), nil +} diff --git a/linode/volumetypes/framework_datasource_schema.go b/linode/volumetypes/framework_datasource_schema.go new file mode 100644 index 000000000..71d5bd3ad --- /dev/null +++ b/linode/volumetypes/framework_datasource_schema.go @@ -0,0 +1,34 @@ +package volumetypes + +import ( + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" +) + +var volumeTypeSchema = schema.NestedBlockObject{ + Attributes: helper.GetPricingTypeAttributes("Volume Type"), +} + +var filterConfig = frameworkfilter.Config{ + "label": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeString}, + "transfer": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeInt}, +} + +var frameworkDataSourceSchema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "The data source's unique ID.", + Computed: true, + }, + "order_by": filterConfig.OrderBySchema(), + "order": filterConfig.OrderSchema(), + }, + Blocks: map[string]schema.Block{ + "filter": filterConfig.Schema(), + "types": schema.ListNestedBlock{ + Description: "The returned list of Volume types.", + NestedObject: volumeTypeSchema, + }, + }, +} diff --git a/linode/volumetypes/framework_models.go b/linode/volumetypes/framework_models.go new file mode 100644 index 000000000..07a8afed2 --- /dev/null +++ b/linode/volumetypes/framework_models.go @@ -0,0 +1,121 @@ +package volumetypes + +import ( + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" +) + +type DataSourceModel struct { + ID types.String `tfsdk:"id"` + Label types.String `tfsdk:"label"` + Price types.List `tfsdk:"price"` + RegionPrices types.List `tfsdk:"region_prices"` + Transfer types.Int64 `tfsdk:"transfer"` +} + +func (data *DataSourceModel) parseVolumeType(volumeType *linodego.VolumeType, +) diag.Diagnostics { + data.ID = types.StringValue(volumeType.ID) + + price, diags := flattenPrice(volumeType.Price) + if diags.HasError() { + return diags + } + data.Price = *price + + data.Label = types.StringValue(volumeType.Label) + + regionPrices, d := flattenRegionPrices(volumeType.RegionPrices) + if d.HasError() { + return d + } + data.RegionPrices = *regionPrices + + data.Transfer = types.Int64Value(int64(volumeType.Transfer)) + + return nil +} + +func flattenPrice(price linodego.VolumeTypePrice) ( + *basetypes.ListValue, diag.Diagnostics, +) { + result := make(map[string]attr.Value) + + result["hourly"] = types.Float64Value(float64(price.Hourly)) + result["monthly"] = types.Float64Value(float64(price.Monthly)) + + obj, diag := types.ObjectValue(helper.PriceObjectType.AttrTypes, result) + if diag.HasError() { + return nil, diag + } + + objList := []attr.Value{obj} + + resultList, diag := types.ListValue( + helper.PriceObjectType, + objList, + ) + if diag.HasError() { + return nil, diag + } + + return &resultList, nil +} + +func flattenRegionPrices(prices []linodego.VolumeTypeRegionPrice) ( + *basetypes.ListValue, diag.Diagnostics, +) { + result := make([]attr.Value, len(prices)) + + for i, price := range prices { + obj, d := types.ObjectValue(helper.RegionPriceObjectType.AttrTypes, map[string]attr.Value{ + "id": types.StringValue(price.ID), + "hourly": types.Float64Value(float64(price.Hourly)), + "monthly": types.Float64Value(float64(price.Monthly)), + }) + if d.HasError() { + return nil, d + } + + result[i] = obj + } + + priceList, d := basetypes.NewListValue( + helper.RegionPriceObjectType, + result, + ) + return &priceList, d +} + +type VolumeTypeFilterModel struct { + ID types.String `tfsdk:"id"` + Order types.String `tfsdk:"order"` + OrderBy types.String `tfsdk:"order_by"` + Filters frameworkfilter.FiltersModelType `tfsdk:"filter"` + Types []DataSourceModel `tfsdk:"types"` +} + +func (model *VolumeTypeFilterModel) parseVolumeTypes(volumeTypes []linodego.VolumeType, +) diag.Diagnostics { + result := make([]DataSourceModel, len(volumeTypes)) + + for i := range volumeTypes { + var m DataSourceModel + + diags := m.parseVolumeType(&volumeTypes[i]) + if diags.HasError() { + return diags + } + + result[i] = m + } + + model.Types = result + + return nil +} diff --git a/linode/volumetypes/tmpl/data_basic.gotf b/linode/volumetypes/tmpl/data_basic.gotf new file mode 100644 index 000000000..341fba2c9 --- /dev/null +++ b/linode/volumetypes/tmpl/data_basic.gotf @@ -0,0 +1,10 @@ +{{ define "volume_types_data_basic" }} + +data "linode_volume_types" "foobar" { + filter { + name = "label" + values = ["Storage Volume"] + } +} + +{{ end }} \ No newline at end of file diff --git a/linode/volumetypes/tmpl/template.go b/linode/volumetypes/tmpl/template.go new file mode 100644 index 000000000..2ff0f75fe --- /dev/null +++ b/linode/volumetypes/tmpl/template.go @@ -0,0 +1,12 @@ +package tmpl + +import ( + "testing" + + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" +) + +func DataBasic(t *testing.T) string { + return acceptance.ExecuteTemplate(t, + "volume_types_data_basic", nil) +} From 50f6fa8379422fdcfcb42deedf05443084daebab Mon Sep 17 00:00:00 2001 From: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:54:12 -0400 Subject: [PATCH 10/19] Support configuring a provider-level Linode API CA file (#1614) * Add api_ca_path field to provider configuration * Fix gosec issues * Update docs * Update test * Expand ~'s in CA path * Expand config paths * Simplify ExpandPath(...) --- docs/index.md | 4 ++ linode/framework_provider.go | 4 ++ linode/framework_provider_config.go | 50 +++++++++++++++++------ linode/helper/config.go | 33 +++++++++++---- linode/helper/filepath.go | 26 ++++++++++++ linode/helper/filepath_test.go | 25 ++++++++++++ linode/helper/framework_provider_model.go | 2 + linode/helper/http.go | 33 +++++++++++++++ linode/image/resource_test.go | 6 ++- linode/provider.go | 11 +++++ linode/provider_test.go | 1 + 11 files changed, 173 insertions(+), 22 deletions(-) create mode 100644 linode/helper/filepath.go create mode 100644 linode/helper/filepath_test.go create mode 100644 linode/helper/http.go diff --git a/docs/index.md b/docs/index.md index 6d1c4886a..1d94bc100 100644 --- a/docs/index.md +++ b/docs/index.md @@ -80,6 +80,10 @@ This section outlines commonly used provider configuration options. The Linode API version can also be specified using the `LINODE_API_VERSION` environment variable. +* `api_ca_path` (Optional) The path to a CA file to trust when making API requests. + + The Linode API CA file path can also be specified using the `LINODE_CA` environment variable. + * `obj_access_key` - (Optional) The access key to be used in [linode_object_storage_bucket](/docs/resources/object_storage_bucket.md) and [linode_object_storage_object](/docs/resources/object_storage_object.md). The Object Access Key can also be specified using the `LINODE_OBJ_ACCESS_KEY` shell environment variable. diff --git a/linode/framework_provider.go b/linode/framework_provider.go index 7dc261184..30d0c1810 100644 --- a/linode/framework_provider.go +++ b/linode/framework_provider.go @@ -143,6 +143,10 @@ func (p *FrameworkProvider) Schema( Optional: true, Description: "The version of Linode API.", }, + "api_ca_path": schema.StringAttribute{ + Optional: true, + Description: "The path to a Linode API CA file to trust.", + }, "skip_instance_ready_poll": schema.BoolAttribute{ Optional: true, Description: "Skip waiting for a linode_instance resource to be running.", diff --git a/linode/framework_provider_config.go b/linode/framework_provider_config.go index 0b58e6e55..e9d3f115f 100644 --- a/linode/framework_provider_config.go +++ b/linode/framework_provider_config.go @@ -157,6 +157,13 @@ func (fp *FrameworkProvider) HandleDefaults( ) } + if lpm.APICAPath.IsNull() { + lpm.APICAPath = GetStringFromEnv( + linodego.APIHostCert, + types.StringNull(), + ) + } + if lpm.SkipInstanceReadyPoll.IsNull() { lpm.SkipInstanceReadyPoll = types.BoolValue(false) } @@ -229,17 +236,6 @@ func (fp *FrameworkProvider) InitProvider( return } - loggingTransport := helper.NewAPILoggerTransport( - logging.NewSubsystemLoggingHTTPTransport( - helper.APILoggerSubsystem, - http.DefaultTransport, - ), - ) - - oauth2Client := &http.Client{ - Transport: loggingTransport, - } - accessToken := lpm.AccessToken.ValueString() APIURL := lpm.APIURL.ValueString() APIVersion := lpm.APIVersion.ValueString() @@ -259,14 +255,44 @@ func (fp *FrameworkProvider) InitProvider( eventPollMilliseconds := lpm.EventPollMilliseconds.ValueInt64() // LKENodeReadyPollMilliseconds := lpm.LKEEventPollMilliseconds.ValueInt64() + httpTransport := http.DefaultTransport.(*http.Transport).Clone() + + if !lpm.APICAPath.IsNull() { + caPath, err := helper.ExpandPath(lpm.APICAPath.ValueString()) + if err != nil { + diags.AddError("Failed to expand api_ca_path", err.Error()) + return + } + + if err := helper.AddRootCAToTransport(caPath, httpTransport); err != nil { + diags.AddError("Failed to add root CA to HTTP transport", err.Error()) + return + } + } + + oauth2Client := &http.Client{ + Transport: helper.NewAPILoggerTransport( + logging.NewSubsystemLoggingHTTPTransport( + helper.APILoggerSubsystem, + httpTransport, + ), + ), + } + client := linodego.NewClient(oauth2Client) // Load the config file if it exists if _, err := os.Stat(configPath); err == nil { tflog.Info(ctx, "Using Linode profile", map[string]any{ "config_path": lpm.ConfigPath, }) + + configPathExpanded, err := helper.ExpandPath(configPath) + if err != nil { + diags.AddError("Failed to expand config path", err.Error()) + } + err = client.LoadConfig(&linodego.LoadConfigOptions{ - Path: configPath, + Path: configPathExpanded, Profile: configProfile, }) if err != nil { diff --git a/linode/helper/config.go b/linode/helper/config.go index c803744ad..9f79e4755 100644 --- a/linode/helper/config.go +++ b/linode/helper/config.go @@ -30,6 +30,7 @@ type Config struct { AccessToken string APIURL string APIVersion string + APICAPath string UAPrefix string ConfigPath string @@ -55,15 +56,26 @@ type Config struct { // Client returns a fully initialized Linode client. func (c *Config) Client(ctx context.Context) (*linodego.Client, error) { - loggingTransport := NewAPILoggerTransport( - logging.NewSubsystemLoggingHTTPTransport( - APILoggerSubsystem, - http.DefaultTransport, - ), - ) + httpTransport := http.DefaultTransport.(*http.Transport).Clone() + + if c.APICAPath != "" { + caPath, err := ExpandPath(c.APICAPath) + if err != nil { + return nil, fmt.Errorf("failed to expand api_ca_path: %w", err) + } + + if err := AddRootCAToTransport(caPath, httpTransport); err != nil { + return nil, fmt.Errorf("failed to add root CA %s to HTTP transport: %w", c.APICAPath, err) + } + } oauth2Client := &http.Client{ - Transport: loggingTransport, + Transport: NewAPILoggerTransport( + logging.NewSubsystemLoggingHTTPTransport( + APILoggerSubsystem, + httpTransport, + ), + ), } client := linodego.NewClient(oauth2Client) @@ -72,11 +84,16 @@ func (c *Config) Client(ctx context.Context) (*linodego.Client, error) { // Load the config file if it exists if _, err := os.Stat(c.ConfigPath); err == nil { + configPath, err := ExpandPath(c.ConfigPath) + if err != nil { + return nil, fmt.Errorf("failed to expand config path: %w", err) + } + tflog.Info(ctx, "Using Linode profile", map[string]any{ "config_path": c.ConfigPath, }) err = client.LoadConfig(&linodego.LoadConfigOptions{ - Path: c.ConfigPath, + Path: configPath, Profile: c.ConfigProfile, }) if err != nil { diff --git a/linode/helper/filepath.go b/linode/helper/filepath.go new file mode 100644 index 000000000..c57343b10 --- /dev/null +++ b/linode/helper/filepath.go @@ -0,0 +1,26 @@ +package helper + +import ( + "fmt" + "os" + "path/filepath" + "strings" +) + +// ExpandPath expands the given path, replacing ~'s with the user's +// home directory. +// NOTE: This does not implement feature-complete tilde expansion. +func ExpandPath(path string) (string, error) { + segments := strings.Split(path, string(os.PathSeparator)) + + if segments[0] == "~" { + homePath, err := os.UserHomeDir() + if err != nil { + return "", fmt.Errorf("could not expand home path: %w", err) + } + + segments[0] = homePath + } + + return filepath.Join(segments...), nil +} diff --git a/linode/helper/filepath_test.go b/linode/helper/filepath_test.go new file mode 100644 index 000000000..0554c7c1f --- /dev/null +++ b/linode/helper/filepath_test.go @@ -0,0 +1,25 @@ +//go:build unit + +package helper + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestExpandPath(t *testing.T) { + homePath, err := os.UserHomeDir() + require.NoError(t, err) + + expandedPath, err := ExpandPath(filepath.Join("~", "foo", "bar")) + require.NoError(t, err) + + require.Equal(t, filepath.Join(homePath, "foo", "bar"), expandedPath) + + expandedPath, err = ExpandPath("") + require.NoError(t, err) + require.Equal(t, "", expandedPath) +} diff --git a/linode/helper/framework_provider_model.go b/linode/helper/framework_provider_model.go index 9daf87274..36c6ea6e4 100644 --- a/linode/helper/framework_provider_model.go +++ b/linode/helper/framework_provider_model.go @@ -11,6 +11,7 @@ func GetFrameworkProviderModelFromSDKv2ProviderConfig(config *Config) *Framework AccessToken: types.StringValue(config.AccessToken), APIURL: types.StringValue(config.APIURL), APIVersion: types.StringValue(config.APIVersion), + APICAPath: types.StringValue(config.APICAPath), UAPrefix: types.StringValue(config.UAPrefix), ConfigPath: types.StringValue(config.ConfigPath), ConfigProfile: types.StringValue(config.ConfigProfile), @@ -34,6 +35,7 @@ type FrameworkProviderModel struct { AccessToken types.String `tfsdk:"token"` APIURL types.String `tfsdk:"url"` APIVersion types.String `tfsdk:"api_version"` + APICAPath types.String `tfsdk:"api_ca_path"` UAPrefix types.String `tfsdk:"ua_prefix"` ConfigPath types.String `tfsdk:"config_path"` diff --git a/linode/helper/http.go b/linode/helper/http.go new file mode 100644 index 000000000..4ca3e4e5e --- /dev/null +++ b/linode/helper/http.go @@ -0,0 +1,33 @@ +package helper + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "net/http" + "os" + "path/filepath" +) + +// AddRootCAToTransport applies the cert file at the given path to the given *http.Transport +func AddRootCAToTransport(cert string, transport *http.Transport) error { + certData, err := os.ReadFile(filepath.Clean(cert)) + if err != nil { + return fmt.Errorf("failed to read cert file %s: %w", cert, err) + } + + tlsConfig := transport.TLSClientConfig + if tlsConfig == nil { + tlsConfig = &tls.Config{ + MinVersion: tls.VersionTLS12, + } + } + + if tlsConfig.RootCAs == nil { + tlsConfig.RootCAs = x509.NewCertPool() + } + + tlsConfig.RootCAs.AppendCertsFromPEM(certData) + + return nil +} diff --git a/linode/image/resource_test.go b/linode/image/resource_test.go index 8184c5d7b..f40af614b 100644 --- a/linode/image/resource_test.go +++ b/linode/image/resource_test.go @@ -36,8 +36,10 @@ var testImageBytesNew = []byte{ 0xe4, 0x02, 0x00, 0x7a, 0x7a, 0x6f, 0xed, 0x03, 0x00, 0x00, 0x00, } -var testRegion string -var testRegions []string +var ( + testRegion string + testRegions []string +) func init() { resource.AddTestSweepers("linode_image", &resource.Sweeper{ diff --git a/linode/provider.go b/linode/provider.go index dbd3ff674..8a9fcbf56 100644 --- a/linode/provider.go +++ b/linode/provider.go @@ -61,6 +61,11 @@ func Provider() *schema.Provider { Optional: true, Description: "The version of Linode API.", }, + "api_ca_path": { + Type: schema.TypeString, + Optional: true, + Description: "The path to a Linode API CA file to trust.", + }, "skip_instance_ready_poll": { Type: schema.TypeBool, @@ -182,6 +187,12 @@ func handleDefault(config *helper.Config, d *schema.ResourceData) diag.Diagnosti config.APIVersion = os.Getenv("LINODE_API_VERSION") } + if v, ok := d.GetOk("api_ca_path"); ok { + config.APICAPath = v.(string) + } else { + config.APICAPath = os.Getenv(linodego.APIHostCert) + } + if v, ok := d.GetOk("config_path"); ok { config.ConfigPath = v.(string) } else { diff --git a/linode/provider_test.go b/linode/provider_test.go index 3adee1b52..6e35801e6 100644 --- a/linode/provider_test.go +++ b/linode/provider_test.go @@ -20,6 +20,7 @@ func TestAccProvider_Overrides(t *testing.T) { token = 54321 api_url = https://cool.linode.com api_version = v4reallycoolapiversion +api_cert_path = cert.pem [cool] token = %s From 9c72dd6022a196049cf84e549cb51c59e46f504b Mon Sep 17 00:00:00 2001 From: Ye Chen <127243817+yec-akamai@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:18:48 -0400 Subject: [PATCH 11/19] fix set pg (#1615) --- linode/instance/resource.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linode/instance/resource.go b/linode/instance/resource.go index 76c6c240f..ead045ad8 100644 --- a/linode/instance/resource.go +++ b/linode/instance/resource.go @@ -136,8 +136,8 @@ func readResource(ctx context.Context, d *schema.ResourceData, meta interface{}) if compliantOnly, ok := d.GetOk("placement_group.0.compliant_only"); ok { placementGroupMap["compliant_only"] = compliantOnly.(bool) } - d.Set("placement_group", []map[string]interface{}{placementGroupMap}) } + d.Set("placement_group", []map[string]interface{}{placementGroupMap}) disks, swapSize := flattenInstanceDisks(instanceDisks) d.Set("disk", disks) From 58fc6dee71f2d7a57712bf5f801866cf13e018af Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Wed, 16 Oct 2024 13:19:34 -0400 Subject: [PATCH 12/19] Fix placement group refresh (#1619) --- linode/instance/resource.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/linode/instance/resource.go b/linode/instance/resource.go index ead045ad8..39eda575f 100644 --- a/linode/instance/resource.go +++ b/linode/instance/resource.go @@ -136,8 +136,10 @@ func readResource(ctx context.Context, d *schema.ResourceData, meta interface{}) if compliantOnly, ok := d.GetOk("placement_group.0.compliant_only"); ok { placementGroupMap["compliant_only"] = compliantOnly.(bool) } + d.Set("placement_group", []map[string]interface{}{placementGroupMap}) + } else { + d.Set("placement_group", nil) } - d.Set("placement_group", []map[string]interface{}{placementGroupMap}) disks, swapSize := flattenInstanceDisks(instanceDisks) d.Set("disk", disks) From 0696e0dc743cfdc4102f8d05625d92a5c39b7299 Mon Sep 17 00:00:00 2001 From: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:48:46 -0400 Subject: [PATCH 13/19] Support reconstructing absolute paths in ExpandPath(...) (#1627) --- linode/helper/filepath.go | 9 ++++++--- linode/helper/filepath_test.go | 9 ++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/linode/helper/filepath.go b/linode/helper/filepath.go index c57343b10..aa73efeb3 100644 --- a/linode/helper/filepath.go +++ b/linode/helper/filepath.go @@ -3,15 +3,16 @@ package helper import ( "fmt" "os" - "path/filepath" "strings" ) +const pathSeparatorString = string(os.PathSeparator) + // ExpandPath expands the given path, replacing ~'s with the user's // home directory. // NOTE: This does not implement feature-complete tilde expansion. func ExpandPath(path string) (string, error) { - segments := strings.Split(path, string(os.PathSeparator)) + segments := strings.Split(path, pathSeparatorString) if segments[0] == "~" { homePath, err := os.UserHomeDir() @@ -22,5 +23,7 @@ func ExpandPath(path string) (string, error) { segments[0] = homePath } - return filepath.Join(segments...), nil + // We don't use filepath.Join(...) here because it does not + // support rebuilding paths starting with `/`. + return strings.Join(segments, pathSeparatorString), nil } diff --git a/linode/helper/filepath_test.go b/linode/helper/filepath_test.go index 0554c7c1f..2c6fc1697 100644 --- a/linode/helper/filepath_test.go +++ b/linode/helper/filepath_test.go @@ -5,6 +5,7 @@ package helper import ( "os" "path/filepath" + "strings" "testing" "github.com/stretchr/testify/require" @@ -16,10 +17,16 @@ func TestExpandPath(t *testing.T) { expandedPath, err := ExpandPath(filepath.Join("~", "foo", "bar")) require.NoError(t, err) - require.Equal(t, filepath.Join(homePath, "foo", "bar"), expandedPath) expandedPath, err = ExpandPath("") require.NoError(t, err) require.Equal(t, "", expandedPath) + + // /foo/bar + absPath := strings.Join([]string{"", "foo", "bar"}, string(os.PathSeparator)) + + expandedPath, err = ExpandPath(absPath) + require.NoError(t, err) + require.Equal(t, absPath, expandedPath) } From f3b02a3e2be6e3b64cbde382e659a8176df97935 Mon Sep 17 00:00:00 2001 From: Youjung Kim <126618609+ykim-1@users.noreply.github.com> Date: Mon, 21 Oct 2024 08:49:13 -0700 Subject: [PATCH 14/19] test: add missing test scope `vpcsubnets` to test matrix account (#1626) * add vpcsubnets to matrix account 2 * change test tag to provider and add to test account 1 --- .github/workflows/integration_tests.yml | 4 ++-- linode/provider_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index fe9b89003..e798cca5f 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -42,11 +42,11 @@ jobs: run: | case "${{ matrix.user }}" in "USER_1") - echo "TEST_TAGS=acceptance,backup,domain,domainrecord,domains,domainzonefile,helper,instance" >> $GITHUB_ENV + echo "TEST_TAGS=acceptance,backup,domain,domainrecord,domains,domainzonefile,helper,instance,provider" >> $GITHUB_ENV echo "LINODE_TOKEN=${{ secrets.LINODE_TOKEN_USER_1 }}" >> $GITHUB_ENV ;; "USER_2") - echo "TEST_TAGS=firewall,firewalldevice,firewalls,image,images,instancenetworking,instancesharedips,instancetype,instancetypes,ipv6range,ipv6ranges,kernel,kernels,nb,nbconfig,nbconfigs,nbnode,nbs,sshkey,sshkeys,vlan,volume,volumes,vpc,vpcs" >> $GITHUB_ENV + echo "TEST_TAGS=firewall,firewalldevice,firewalls,image,images,instancenetworking,instancesharedips,instancetype,instancetypes,ipv6range,ipv6ranges,kernel,kernels,nb,nbconfig,nbconfigs,nbnode,nbs,sshkey,sshkeys,vlan,volume,volumes,vpc,vpcs,vpcsubnets" >> $GITHUB_ENV echo "LINODE_TOKEN=${{ secrets.LINODE_TOKEN_USER_2 }}" >> $GITHUB_ENV ;; "USER_3") diff --git a/linode/provider_test.go b/linode/provider_test.go index 6e35801e6..f4d2ca739 100644 --- a/linode/provider_test.go +++ b/linode/provider_test.go @@ -1,4 +1,4 @@ -//go:build integration || vpcsubnets +//go:build integration || provider package linode_test From 2cbcbfa685b9e04fe95e9f5b631b2b667546b74d Mon Sep 17 00:00:00 2001 From: Youjung Kim <126618609+ykim-1@users.noreply.github.com> Date: Mon, 21 Oct 2024 12:39:07 -0700 Subject: [PATCH 15/19] ignore updated field assertions in firewall resource tests (#1628) --- linode/firewall/framework_resource_test.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/linode/firewall/framework_resource_test.go b/linode/firewall/framework_resource_test.go index 6db229064..c309fb2be 100644 --- a/linode/firewall/framework_resource_test.go +++ b/linode/firewall/framework_resource_test.go @@ -118,7 +118,7 @@ func TestAccLinodeFirewall_basic(t *testing.T) { ResourceName: testFirewallResName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"created"}, + ImportStateVerifyIgnore: []string{"created", "updated"}, }, }, }) @@ -154,7 +154,7 @@ func TestAccLinodeFirewall_minimum(t *testing.T) { ResourceName: testFirewallResName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"created"}, + ImportStateVerifyIgnore: []string{"created", "updated"}, }, }, }) @@ -225,7 +225,7 @@ func TestAccLinodeFirewall_multipleRules(t *testing.T) { ResourceName: testFirewallResName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"created"}, + ImportStateVerifyIgnore: []string{"created", "updated"}, }, }, }) @@ -263,7 +263,7 @@ func TestAccLinodeFirewall_no_device(t *testing.T) { ResourceName: testFirewallResName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"created"}, + ImportStateVerifyIgnore: []string{"created", "updated"}, }, }, }) @@ -462,9 +462,10 @@ func TestAccLinodeFirewall_noIPv6(t *testing.T) { ), }, { - ResourceName: testFirewallResName, - ImportState: true, - ImportStateVerify: true, + ResourceName: testFirewallResName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"created", "updated"}, }, }, }) @@ -496,7 +497,7 @@ func TestAccLinodeFirewall_noRules(t *testing.T) { ResourceName: testFirewallResName, ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"created"}, + ImportStateVerifyIgnore: []string{"created", "updated"}, }, }, }) From a170bcc7008e537100e614cc3a15318e67c98035 Mon Sep 17 00:00:00 2001 From: Erik Zilber Date: Tue, 22 Oct 2024 11:29:26 -0400 Subject: [PATCH 16/19] Added support for Block Storage Encryption (#1623) * Implemented instance changes * Implemented volume changes * Bump linodego version * Ran go mod tidy --- docs/data-sources/instances.md | 2 ++ docs/data-sources/volume.md | 2 ++ docs/resources/volume.md | 2 ++ go.mod | 2 +- go.sum | 4 +-- linode/instance/datasource_test.go | 35 +++++++++++++++++++ linode/instance/flatten.go | 2 ++ linode/instance/resource.go | 1 + linode/instance/schema_datasource.go | 6 ++++ linode/instance/schema_resource.go | 6 ++++ linode/instance/tmpl/template.go | 9 +++++ .../data_with_block_storage_encryption.gotf | 20 +++++++++++ linode/volume/datasource_test.go | 31 ++++++++++++++++ linode/volume/framework_models.go | 5 +++ linode/volume/framework_models_unit_test.go | 2 ++ linode/volume/framework_resource.go | 7 ++-- linode/volume/framework_schema_datasource.go | 5 +++ linode/volume/framework_schema_resource.go | 12 +++++++ .../data_with_block_storage_encryption.gotf | 14 ++++++++ linode/volume/tmpl/template.go | 5 +++ 20 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 linode/instance/tmpl/templates/data_with_block_storage_encryption.gotf create mode 100644 linode/volume/tmpl/data_with_block_storage_encryption.gotf diff --git a/docs/data-sources/instances.md b/docs/data-sources/instances.md index 57d796926..da947af8f 100644 --- a/docs/data-sources/instances.md +++ b/docs/data-sources/instances.md @@ -75,6 +75,8 @@ Each Linode instance will be stored in the `instances` attribute and will export * `tags` - A list of tags applied to this object. Tags are case-insensitive and are for organizational purposes only. +* `capabilities` - A list of capabilities of this Linode instance. + * `private_ip` - If true, the Linode has private networking enabled, allowing use of the 192.168.128.0/17 network within the Linode's region. * `alerts.0.cpu` - The percentage of CPU usage required to trigger an alert. If the average CPU usage over two hours exceeds this value, we'll send you an alert. If this is set to 0, the alert is disabled. diff --git a/docs/data-sources/volume.md b/docs/data-sources/volume.md index 7742cf7a7..308695a79 100644 --- a/docs/data-sources/volume.md +++ b/docs/data-sources/volume.md @@ -48,3 +48,5 @@ The Linode Volume resource exports the following attributes: - `linode_id` - If a Volume is attached to a specific Linode, the ID of that Linode will be displayed here. If the Volume is unattached, this value will be null. - `filesystem_path` - The full filesystem path for the Volume based on the Volume's label. Path is /dev/disk/by-id/scsi-0LinodeVolume + Volume label. + +- `encryption` - Whether Block Storage Disk Encryption is enabled or disabled on this Volume. Note: Block Storage Disk Encryption is not currently available to all users. diff --git a/docs/resources/volume.md b/docs/resources/volume.md index 3dd2d3bcc..fe2f3a760 100644 --- a/docs/resources/volume.md +++ b/docs/resources/volume.md @@ -81,6 +81,8 @@ The following arguments are supported: * `tags` - (Optional) A list of tags applied to this object. Tags are case-insensitive and are for organizational purposes only. +* `encryption` - (Optional) Whether Block Storage Disk Encryption is enabled or disabled on this Volume. Note: Block Storage Disk Encryption is not currently available to all users. + ### Timeouts The `timeouts` block allows you to specify [timeouts](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts) for certain actions: diff --git a/go.mod b/go.mod index 9a23c4b9f..ea92aa174 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/hashicorp/terraform-plugin-mux v0.16.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 github.com/hashicorp/terraform-plugin-testing v1.10.0 - github.com/linode/linodego v1.41.0 + github.com/linode/linodego v1.42.0 github.com/linode/linodego/k8s v1.25.2 github.com/stretchr/testify v1.9.0 golang.org/x/crypto v0.28.0 diff --git a/go.sum b/go.sum index a1f50f3e6..1c731765e 100644 --- a/go.sum +++ b/go.sum @@ -189,8 +189,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/linode/linodego v1.41.0 h1:GcP7JIBr9iLRJ9FwAtb9/WCT1DuPJS/xUApapfdjtiY= -github.com/linode/linodego v1.41.0/go.mod h1:Ow4/XZ0yvWBzt3iAHwchvhSx30AyLintsSMvvQ2/SJY= +github.com/linode/linodego v1.42.0 h1:ZSbi4MtvwrfB9Y6bknesorvvueBGGilcmh2D5dq76RM= +github.com/linode/linodego v1.42.0/go.mod h1:2yzmY6pegPBDgx2HDllmt0eIk2IlzqcgK6NR0wFCFRY= github.com/linode/linodego/k8s v1.25.2 h1:PY6S0sAD3xANVvM9WY38bz9GqMTjIbytC8IJJ9Cv23o= github.com/linode/linodego/k8s v1.25.2/go.mod h1:DC1XCSRZRGsmaa/ggpDPSDUmOM6aK1bhSIP6+f9Cwhc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= diff --git a/linode/instance/datasource_test.go b/linode/instance/datasource_test.go index 3e1b879da..07dfcb105 100644 --- a/linode/instance/datasource_test.go +++ b/linode/instance/datasource_test.go @@ -50,6 +50,41 @@ func TestAccDataSourceInstances_basic(t *testing.T) { }) } +func TestAccDataSourceInstances_withBlockStorageEncryption(t *testing.T) { + t.Parallel() + + resName := "data.linode_instances.foobar" + instanceName := acctest.RandomWithPrefix("tf_test") + + // Resolve a region with support for Block Storage Encryption + targetRegion, err := acceptance.GetRandomRegionWithCaps( + []string{"Linodes", "Block Storage Encryption"}, + "core", + ) + if err != nil { + t.Fatal(err) + } + + rootPass := acctest.RandString(64) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + CheckDestroy: acceptance.CheckInstanceDestroy, + + Steps: []resource.TestStep{ + { + Config: tmpl.DataWithBlockStorageEncryption(t, instanceName, targetRegion, rootPass), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resName, "instances.#", "1"), + resource.TestCheckResourceAttrSet(resName, "instances.0.id"), + resource.TestCheckTypeSetElemAttr(resName, "instances.0.capabilities.*", "Block Storage Encryption"), + ), + }, + }, + }) +} + func TestAccDataSourceInstances_withPG(t *testing.T) { t.Parallel() diff --git a/linode/instance/flatten.go b/linode/instance/flatten.go index b3566bf07..adf6decd8 100644 --- a/linode/instance/flatten.go +++ b/linode/instance/flatten.go @@ -46,6 +46,7 @@ func flattenInstance( result["watchdog_enabled"] = instance.WatchdogEnabled result["group"] = instance.Group result["tags"] = instance.Tags + result["capabilities"] = instance.Capabilities result["image"] = instance.Image result["host_uuid"] = instance.HostUUID result["has_user_data"] = instance.HasUserData @@ -215,6 +216,7 @@ func flattenInstanceSimple(instance *linodego.Instance) (map[string]interface{}, result["watchdog_enabled"] = instance.WatchdogEnabled result["group"] = instance.Group result["tags"] = instance.Tags + result["capabilities"] = instance.Capabilities result["image"] = instance.Image result["host_uuid"] = instance.HostUUID result["backups"] = flattenInstanceBackups(*instance) diff --git a/linode/instance/resource.go b/linode/instance/resource.go index 39eda575f..3b688b2a0 100644 --- a/linode/instance/resource.go +++ b/linode/instance/resource.go @@ -112,6 +112,7 @@ func readResource(ctx context.Context, d *schema.ResourceData, meta interface{}) d.Set("watchdog_enabled", instance.WatchdogEnabled) d.Set("group", instance.Group) d.Set("tags", instance.Tags) + d.Set("capabilities", instance.Capabilities) d.Set("booted", isInstanceBooted(instance)) d.Set("host_uuid", instance.HostUUID) d.Set("has_user_data", instance.HasUserData) diff --git a/linode/instance/schema_datasource.go b/linode/instance/schema_datasource.go index 66e344901..b762529db 100644 --- a/linode/instance/schema_datasource.go +++ b/linode/instance/schema_datasource.go @@ -33,6 +33,12 @@ var instanceDataSourceSchema = map[string]*schema.Schema{ Elem: &schema.Schema{Type: schema.TypeString}, Computed: true, }, + "capabilities": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + Description: "A list of capabilities of this Linode instance.", + }, "boot_config_label": { Type: schema.TypeString, Description: "The Label of the Instance Config that should be used to boot the Linode instance.", diff --git a/linode/instance/schema_resource.go b/linode/instance/schema_resource.go index cb65f77ae..70e12c386 100644 --- a/linode/instance/schema_resource.go +++ b/linode/instance/schema_resource.go @@ -267,6 +267,12 @@ var resourceSchema = map[string]*schema.Schema{ Description: "An array of tags applied to this object. Tags are for organizational purposes only.", Computed: true, }, + "capabilities": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Computed: true, + Description: "A list of capabilities of this Linode instance.", + }, "boot_config_label": { Type: schema.TypeString, Description: "The Label of the Instance Config that should be used to boot the Linode instance.", diff --git a/linode/instance/tmpl/template.go b/linode/instance/tmpl/template.go index 2dd51a57d..ef236d0fb 100644 --- a/linode/instance/tmpl/template.go +++ b/linode/instance/tmpl/template.go @@ -623,6 +623,15 @@ func DataBasic(t *testing.T, label, region string, rootPass string) string { }) } +func DataWithBlockStorageEncryption(t *testing.T, label, region string, rootPass string) string { + return acceptance.ExecuteTemplate(t, + "instance_data_with_block_storage_encryption", TemplateData{ + Label: label, + Region: region, + RootPass: rootPass, + }) +} + func DataWithPG(t *testing.T, label, region, assignedGroup string, groups []string) string { return acceptance.ExecuteTemplate(t, "instance_data_with_pg", TemplateData{ diff --git a/linode/instance/tmpl/templates/data_with_block_storage_encryption.gotf b/linode/instance/tmpl/templates/data_with_block_storage_encryption.gotf new file mode 100644 index 000000000..75efd8043 --- /dev/null +++ b/linode/instance/tmpl/templates/data_with_block_storage_encryption.gotf @@ -0,0 +1,20 @@ +{{ define "instance_data_with_block_storage_encryption" }} + +{{ template "e2e_test_firewall" . }} + +resource "linode_instance" "foobar" { + label = "{{.Label}}" + type = "g6-nanode-1" + region = "{{ .Region }}" + root_pass = "{{ .RootPass }}" + firewall_id = linode_firewall.e2e_test_firewall.id +} + +data "linode_instances" "foobar" { + filter { + name = "id" + values = [linode_instance.foobar.id] + } +} + +{{ end }} \ No newline at end of file diff --git a/linode/volume/datasource_test.go b/linode/volume/datasource_test.go index f091da567..944a0d37f 100644 --- a/linode/volume/datasource_test.go +++ b/linode/volume/datasource_test.go @@ -31,6 +31,37 @@ func TestAccDataSourceVolume_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "linode_id", "0"), resource.TestCheckResourceAttrSet(resourceName, "created"), resource.TestCheckResourceAttrSet(resourceName, "updated"), + resource.TestCheckResourceAttr(resourceName, "encryption", "disabled"), + ), + }, + }, + }) +} + +func TestAccDataSourceVolume_withBlockStorageEncryption(t *testing.T) { + t.Parallel() + + volumeName := acctest.RandomWithPrefix("tf_test") + resourceName := "data.linode_volume.foobar" + + // Resolve a region with support for Block Storage Encryption + targetRegion, err := acceptance.GetRandomRegionWithCaps( + []string{"Linodes", "Block Storage Encryption"}, + "core", + ) + if err != nil { + t.Fatal(err) + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: tmpl.DataWithBlockStorageEncryption(t, volumeName, targetRegion), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "region", targetRegion), + resource.TestCheckResourceAttr(resourceName, "encryption", "enabled"), ), }, }, diff --git a/linode/volume/framework_models.go b/linode/volume/framework_models.go index 832b71366..5cc24ed60 100644 --- a/linode/volume/framework_models.go +++ b/linode/volume/framework_models.go @@ -24,6 +24,7 @@ type VolumeDataSourceModel struct { Status types.String `tfsdk:"status"` Created types.String `tfsdk:"created"` Updated types.String `tfsdk:"updated"` + Encryption types.String `tfsdk:"encryption"` } func (data *VolumeDataSourceModel) ParseComputedAttributes( @@ -44,6 +45,7 @@ func (data *VolumeDataSourceModel) ParseComputedAttributes( data.FilesystemPath = types.StringValue(volume.FilesystemPath) data.Created = types.StringValue(volume.Created.Format(time.RFC3339)) data.Updated = types.StringValue(volume.Updated.Format(time.RFC3339)) + data.Encryption = types.StringValue(volume.Encryption) return diags } @@ -76,6 +78,7 @@ type VolumeResourceModel struct { Tags types.Set `tfsdk:"tags"` Status types.String `tfsdk:"status"` Timeouts timeouts.Value `tfsdk:"timeouts"` + Encryption types.String `tfsdk:"encryption"` } func (data *VolumeResourceModel) FlattenVolume(volume *linodego.Volume, preserveKnown bool) diag.Diagnostics { @@ -91,6 +94,7 @@ func (data *VolumeResourceModel) FlattenVolume(volume *linodego.Volume, preserve data.Label = helper.KeepOrUpdateString(data.Label, volume.Label, preserveKnown) data.Region = helper.KeepOrUpdateString(data.Region, volume.Region, preserveKnown) data.Size = helper.KeepOrUpdateInt64(data.Size, int64(volume.Size), preserveKnown) + data.Encryption = helper.KeepOrUpdateString(data.Encryption, volume.Encryption, preserveKnown) // planned breaking change: // data.LinodeID = helper.KeepOrUpdateIntPointer(data.LinodeID, volume.LinodeID, preserveKnown) @@ -123,6 +127,7 @@ func (data *VolumeResourceModel) CopyFrom(other VolumeResourceModel, preserveKno data.ID = helper.KeepOrUpdateValue(data.ID, other.ID, preserveKnown) data.Label = helper.KeepOrUpdateValue(data.Label, other.Label, preserveKnown) data.Region = helper.KeepOrUpdateValue(data.Region, other.Region, preserveKnown) + data.Encryption = helper.KeepOrUpdateValue(data.Encryption, other.Encryption, preserveKnown) data.Size = helper.KeepOrUpdateValue(data.Size, other.Size, preserveKnown) data.LinodeID = helper.KeepOrUpdateValue(data.LinodeID, other.LinodeID, preserveKnown) data.FilesystemPath = helper.KeepOrUpdateValue(data.FilesystemPath, other.FilesystemPath, preserveKnown) diff --git a/linode/volume/framework_models_unit_test.go b/linode/volume/framework_models_unit_test.go index 67366a2ce..cba0c3aba 100644 --- a/linode/volume/framework_models_unit_test.go +++ b/linode/volume/framework_models_unit_test.go @@ -29,6 +29,7 @@ func TestVolumeModelParsing(t *testing.T) { Tags: []string{"example tag", "another example"}, Created: &createdTime, Updated: &updatedTime, + Encryption: "disabled", } ctx := context.Background() @@ -43,6 +44,7 @@ func TestVolumeModelParsing(t *testing.T) { assert.Equal(t, types.Int64Value(30), data.Size) assert.Equal(t, types.Int64Value(12346), data.LinodeID) assert.Equal(t, types.StringValue("/dev/disk/by-id/scsi-0Linode_Volume_my-volume"), data.FilesystemPath) + assert.Equal(t, types.StringValue("disabled"), data.Encryption) assert.NotContains(t, data.Tags.String(), "example tag") assert.NotContains(t, data.Tags.String(), "another example") diff --git a/linode/volume/framework_resource.go b/linode/volume/framework_resource.go index 23bf0bad6..d05625ff3 100644 --- a/linode/volume/framework_resource.go +++ b/linode/volume/framework_resource.go @@ -216,9 +216,10 @@ func (r *Resource) CreateVolume( size := helper.FrameworkSafeInt64ToInt(data.Size.ValueInt64(), diags) createOpts := linodego.VolumeCreateOptions{ - Label: data.Label.ValueString(), - Region: data.Region.ValueString(), - Size: size, + Label: data.Label.ValueString(), + Region: data.Region.ValueString(), + Size: size, + Encryption: data.Encryption.ValueString(), } diags.Append(data.Tags.ElementsAs(ctx, &createOpts.Tags, false)...) diff --git a/linode/volume/framework_schema_datasource.go b/linode/volume/framework_schema_datasource.go index f1f952b69..93ce1c7bb 100644 --- a/linode/volume/framework_schema_datasource.go +++ b/linode/volume/framework_schema_datasource.go @@ -48,6 +48,11 @@ var VolumeAttributes = map[string]schema.Attribute{ Description: "Datetime string representing when the Volume was last updated.", Computed: true, }, + "encryption": schema.StringAttribute{ + Description: "Whether Block Storage Disk Encryption is enabled or disabled on this Volume. " + + "Note: Block Storage Disk Encryption is not currently available to all users.", + Computed: true, + }, } var frameworkDataSourceSchema = schema.Schema{ diff --git a/linode/volume/framework_schema_resource.go b/linode/volume/framework_schema_resource.go index db1b5d93c..aa297fcf5 100644 --- a/linode/volume/framework_schema_resource.go +++ b/linode/volume/framework_schema_resource.go @@ -3,6 +3,8 @@ package volume import ( "context" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/path" @@ -111,5 +113,15 @@ var frameworkResourceSchema = schema.Schema{ }, Default: helper.EmptySetDefault(types.StringType), }, + "encryption": schema.StringAttribute{ + Description: "Whether Block Storage Disk Encryption is enabled or disabled on this Volume. " + + "Note: Block Storage Disk Encryption is not currently available to all users.", + Optional: true, + Computed: true, + Default: stringdefault.StaticString("disabled"), + Validators: []validator.String{ + stringvalidator.OneOf("enabled", "disabled"), + }, + }, }, } diff --git a/linode/volume/tmpl/data_with_block_storage_encryption.gotf b/linode/volume/tmpl/data_with_block_storage_encryption.gotf new file mode 100644 index 000000000..44bbf3bc1 --- /dev/null +++ b/linode/volume/tmpl/data_with_block_storage_encryption.gotf @@ -0,0 +1,14 @@ +{{ define "volume_data_with_block_storage_encryption" }} + +resource "linode_volume" "foobar" { + label = "{{.Label}}" + region = "{{ .Region }}" + tags = ["tf_test"] + encryption = "enabled" +} + +data "linode_volume" "foobar" { + id = "${linode_volume.foobar.id}" +} + +{{ end }} \ No newline at end of file diff --git a/linode/volume/tmpl/template.go b/linode/volume/tmpl/template.go index 5ca1da350..accda98a7 100644 --- a/linode/volume/tmpl/template.go +++ b/linode/volume/tmpl/template.go @@ -64,3 +64,8 @@ func DataBasic(t *testing.T, volume, region string) string { return acceptance.ExecuteTemplate(t, "volume_data_basic", TemplateData{Label: volume, Region: region}) } + +func DataWithBlockStorageEncryption(t *testing.T, volume, region string) string { + return acceptance.ExecuteTemplate(t, + "volume_data_with_block_storage_encryption", TemplateData{Label: volume, Region: region}) +} From 43a1cfa15ef9dc6b05c66a4c78e80479ef57428b Mon Sep 17 00:00:00 2001 From: Ye Chen <127243817+yec-akamai@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:29:38 -0400 Subject: [PATCH 17/19] fix: Instance disk nil pointer issue (#1624) * fix disk id * revert change to AddDiskResource --- linode/instancedisk/framework_resource.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/linode/instancedisk/framework_resource.go b/linode/instancedisk/framework_resource.go index e357ca9ee..6cac26e33 100644 --- a/linode/instancedisk/framework_resource.go +++ b/linode/instancedisk/framework_resource.go @@ -119,34 +119,35 @@ func (r *Resource) Create( return } + diskID := disk.ID // Add resource to TF states earlier to prevent // dangling resources (resources created but not managed by TF) AddDiskResource(ctx, *disk, resp, plan) - ctx = tflog.SetField(ctx, "disk_id", disk.ID) + ctx = tflog.SetField(ctx, "disk_id", diskID) _, err = p.WaitForFinished(ctx, timeoutSeconds) if err != nil { resp.Diagnostics.AddError( - fmt.Sprintf("Failed to Wait for the Disk Creation Event on Linode Disk (%d)", disk.ID), + fmt.Sprintf("Failed to Wait for the Disk Creation Event on Linode Disk (%d)", diskID), err.Error(), ) } if _, err := client.WaitForInstanceDiskStatus( - ctx, linodeID, disk.ID, linodego.DiskReady, timeoutSeconds, + ctx, linodeID, diskID, linodego.DiskReady, timeoutSeconds, ); err != nil { resp.Diagnostics.AddError( - fmt.Sprintf("Failed to Wait for Disk (%d) to be Ready", disk.ID), err.Error(), + fmt.Sprintf("Failed to Wait for Disk (%d) to be Ready", diskID), err.Error(), ) } // get latest status of the disk tflog.Trace(ctx, "client.GetInstanceDisk(...)") - disk, err = client.GetInstanceDisk(ctx, linodeID, disk.ID) + disk, err = client.GetInstanceDisk(ctx, linodeID, diskID) if err != nil { resp.Diagnostics.AddError( - fmt.Sprintf("Failed to Get Disk %d of Linode Instance %d", disk.ID, linodeID), + fmt.Sprintf("Failed to Get Disk %d of Linode Instance %d", diskID, linodeID), err.Error(), ) } From 83aae021480d6bd5e599be4b2b2740458fac89ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:25:29 -0400 Subject: [PATCH 18/19] build(deps): bump github.com/aws/aws-sdk-go-v2/service/s3 (#1621) Bumps [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) from 1.65.0 to 1.66.0. - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.65.0...service/s3/v1.66.0) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/service/s3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 16 ++++++++-------- go.sum | 32 ++++++++++++++++---------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index ea92aa174..9f7fb795b 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,11 @@ go 1.22.0 toolchain go1.22.5 require ( - github.com/aws/aws-sdk-go-v2 v1.32.0 + github.com/aws/aws-sdk-go-v2 v1.32.2 github.com/aws/aws-sdk-go-v2/config v1.27.23 github.com/aws/aws-sdk-go-v2/credentials v1.17.23 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 - github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0 + github.com/aws/aws-sdk-go-v2/service/s3 v1.66.0 github.com/aws/smithy-go v1.22.0 github.com/go-resty/resty/v2 v2.14.0 github.com/google/go-cmp v0.6.0 @@ -40,14 +40,14 @@ require ( github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.19 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect diff --git a/go.sum b/go.sum index 1c731765e..9d7797856 100644 --- a/go.sum +++ b/go.sum @@ -9,8 +9,8 @@ github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/aws/aws-sdk-go-v2 v1.32.0 h1:GuHp7GvMN74PXD5C97KT5D87UhIy4bQPkflQKbfkndg= -github.com/aws/aws-sdk-go-v2 v1.32.0/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= +github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= +github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= github.com/aws/aws-sdk-go-v2/config v1.27.23 h1:Cr/gJEa9NAS7CDAjbnB7tHYb3aLZI2gVggfmSAasDac= @@ -21,24 +21,24 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 h1:6eKRM6fgeXG4krRO9XKz755vuRhT5UyB9M1W6vjA3JU= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4/go.mod h1:h0TjcRi+nTob6fksqubKOe+Hra8uqfgmN+vuw4xRwWE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19 h1:Q/k5wCeJkSWs+62kDfOillkNIJ5NqmE3iOfm48g/W8c= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19/go.mod h1:Wns1C66VvtA2Bv/cUBuKZKQKdjo7EVMhp90aAa+8oTI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19 h1:AYLE0lUfKvN6icFTR/p+NmD1amYKTbqHQ1Nm+jwE6BM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19/go.mod h1:1giLakj64GjuH1NBzF/DXqly5DWHtMTaOzRZ53nFX0I= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.19 h1:FKdiFzTxlTRO71p0C7VrLbkkdW8qfMKF5+ej6bTmkT0= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.19/go.mod h1:abO3pCj7WLQPTllnSeYImqFfkGrmJV0JovWo/gqT5N0= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 h1:7edmS3VOBDhK00b/MwGtGglCm7hhwNYnjJs/PgFdMQE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21/go.mod h1:Q9o5h4HoIWG8XfzxqiuK/CGUbepCJ8uTlaE3bAbxytQ= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.0 h1:FQNWhRuSq8QwW74GtU0MrveNhZbqvHsA4dkA9w8fTDQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.0/go.mod h1:j/zZ3zmWfGCK91K73YsfHP53BSTLSjL/y6YN39XbBLM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0 h1:AdbiDUgQZmM28rDIZbiSwFxz8+3B94aOXxzs6oH+EA0= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0/go.mod h1:uV476Bd80tiDTX4X2redMtagQUg65aU/gzPojSJ4kSI= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.0 h1:1NKXS8XfhMM0bg5wVYa/eOH8AM2f6JijugbKEyQFTIg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.0/go.mod h1:ph931DUfVfgrhZR7py9olSvHCiRpvaGxNvlWBcXxFds= -github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0 h1:2dSm7frMrw2tdJ0QvyccQNJyPGaP24dyDgZ6h1QJMGU= -github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0/go.mod h1:4XSVpw66upN8wND3JZA29eXl2NOZvfFVq7DIP6xvfuQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 h1:4FMHqLfk0efmTqhXVRL5xYRqlEBNBiRI7N6w4jsEdd4= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2/go.mod h1:LWoqeWlK9OZeJxsROW2RqrSPvQHKTpp69r/iDjwsSaw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 h1:t7iUP9+4wdc5lt3E41huP+GvQZJD38WLsgVp4iOtAjg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2/go.mod h1:/niFCtmuQNxqx9v8WAPq5qh7EH25U4BF6tjoyq9bObM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.66.0 h1:xA6XhTF7PE89BCNHJbQi8VvPzcgMtmGC5dr8S8N7lHk= +github.com/aws/aws-sdk-go-v2/service/s3 v1.66.0/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8= github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc= github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 h1:lCEv9f8f+zJ8kcFeAjRZsekLd/x5SAm96Cva+VbUdo8= From 343d70da1bbdc2a923fcf3130fbbbbd42b66d4d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:25:50 -0400 Subject: [PATCH 19/19] build(deps): bump github.com/hashicorp/terraform-plugin-framework-validators (#1625) Bumps [github.com/hashicorp/terraform-plugin-framework-validators](https://github.com/hashicorp/terraform-plugin-framework-validators) from 0.13.0 to 0.14.0. - [Release notes](https://github.com/hashicorp/terraform-plugin-framework-validators/releases) - [Changelog](https://github.com/hashicorp/terraform-plugin-framework-validators/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/terraform-plugin-framework-validators/compare/v0.13.0...v0.14.0) --- updated-dependencies: - dependency-name: github.com/hashicorp/terraform-plugin-framework-validators dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9f7fb795b..e4085c31d 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/hashicorp/terraform-plugin-framework-nettypes v0.2.0 github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1 github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 - github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 + github.com/hashicorp/terraform-plugin-framework-validators v0.14.0 github.com/hashicorp/terraform-plugin-go v0.24.0 github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-mux v0.16.0 diff --git a/go.sum b/go.sum index 9d7797856..1debe410d 100644 --- a/go.sum +++ b/go.sum @@ -147,8 +147,8 @@ github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1 h1:gm5b1kHgFFhaK github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1/go.mod h1:MsjL1sQ9L7wGwzJ5RjcI6FzEMdyoBnw+XK8ZnOvQOLY= github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 h1:v3DapR8gsp3EM8fKMh6up9cJUFQ2iRaFsYLP8UJnCco= github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0/go.mod h1:c3PnGE9pHBDfdEVG9t1S1C9ia5LW+gkFR0CygXlM8ak= -github.com/hashicorp/terraform-plugin-framework-validators v0.13.0 h1:bxZfGo9DIUoLLtHMElsu+zwqI4IsMZQBRRy4iLzZJ8E= -github.com/hashicorp/terraform-plugin-framework-validators v0.13.0/go.mod h1:wGeI02gEhj9nPANU62F2jCaHjXulejm/X+af4PdZaNo= +github.com/hashicorp/terraform-plugin-framework-validators v0.14.0 h1:3PCn9iyzdVOgHYOBmncpSSOxjQhCTYmc+PGvbdlqSaI= +github.com/hashicorp/terraform-plugin-framework-validators v0.14.0/go.mod h1:LwDKNdzxrDY/mHBrlC6aYfE2fQ3Dk3gaJD64vNiXvo4= github.com/hashicorp/terraform-plugin-go v0.24.0 h1:2WpHhginCdVhFIrWHxDEg6RBn3YaWzR2o6qUeIEat2U= github.com/hashicorp/terraform-plugin-go v0.24.0/go.mod h1:tUQ53lAsOyYSckFGEefGC5C8BAaO0ENqzFd3bQeuYQg= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=