diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 06c9cab3f..f44a9a603 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,16 +13,8 @@ jobs: name: Analyze (${{ matrix.language }}) runs-on: ubuntu-latest permissions: - # required for all workflows security-events: write - # required to fetch internal or private CodeQL packs - packages: read - - # only required for workflows in private repositories - actions: read - contents: read - strategy: fail-fast: false matrix: diff --git a/go.mod b/go.mod index 30f078d5b..2d329a023 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.7 + github.com/aws/aws-sdk-go-v2 v1.32.8 github.com/aws/aws-sdk-go-v2/config v1.28.5 github.com/aws/aws-sdk-go-v2/credentials v1.17.46 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 - github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 + github.com/aws/aws-sdk-go-v2/service/s3 v1.72.2 github.com/aws/smithy-go v1.22.1 github.com/go-resty/resty/v2 v2.16.2 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.7 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.27 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.8 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.8 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 // indirect diff --git a/go.sum b/go.sum index 3895611a6..cf9dca302 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.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw= -github.com/aws/aws-sdk-go-v2 v1.32.7/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2 v1.32.8 h1:cZV+NUS/eGxKXMtmyhtYPJ7Z4YLoI/V8bkTdRZfYhGo= +github.com/aws/aws-sdk-go-v2 v1.32.8/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= github.com/aws/aws-sdk-go-v2/config v1.28.5 h1:Za41twdCXbuyyWv9LndXxZZv3QhTG1DinqlFsSuvtI0= @@ -21,24 +21,24 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 h1:sDSXIrlsFSFJtWKLQS4PUW github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20/go.mod h1:WZ/c+w0ofps+/OUqMwWgnfrgzZH1DZO1RIkktICsqnY= 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.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26/go.mod h1:3o2Wpy0bogG1kyOPrgkXA8pgIfEEv0+m19O9D5+W8y8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27 h1:jSJjSBzw8VDIbWv+mmvBSP8ezsztMYJGH+eKqi9AmNs= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27/go.mod h1:/DAhLbFRgwhmvJdOfSm+WwikZrCuUJiA4WgJG0fTNSw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27 h1:l+X4K77Dui85pIj5foXDhPlnqcNRG2QUyvca300lXh8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27/go.mod h1:KvZXSFEXm6x84yE8qffKvT3x8J5clWnVFXphpohhzJ8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 h1:GeNJsIFHB+WW5ap2Tec4K6dzcVTsRbsT1Lra46Hv9ME= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26/go.mod h1:zfgMpwHDXX2WGoG84xG2H+ZlPTkJUU4YUvx2svLQYWo= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.27 h1:AmB5QxnD+fBFrg9LcqzkgF/CaYvMyU/BTlejG4t1S7Q= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.27/go.mod h1:Sai7P3xTiyv9ZUYO3IFxMnmiIP759/67iQbU4kdmkyU= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 h1:tB4tNw83KcajNAzaIMhkhVI2Nt8fAZd5A5ro113FEMY= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7/go.mod h1:lvpyBGkZ3tZ9iSsUIcC2EWp+0ywa7aK3BLT+FwZi+mQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 h1:8eUsivBQzZHqe/3FE+cqwfH+0p5Jo8PFM/QYQSmeZ+M= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7/go.mod h1:kLPQvGUmxn/fqiCrDeohwG33bq2pQpGeY62yRO6Nrh0= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 h1:Hi0KGbrnr57bEHWM0bJ1QcBzxLrL/k2DHvGYhb8+W1w= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7/go.mod h1:wKNgWgExdjjrm4qvfbTorkvocEstaoDl4WCvGfeCy9c= -github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 h1:SAfh4pNx5LuTafKKWR02Y+hL3A+3TX8cTKG1OIAJaBk= -github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.8 h1:iwYS40JnrBeA9e9aI5S6KKN4EB2zR4iUVYN0nwVivz4= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.8/go.mod h1:Fm9Mi+ApqmFiknZtGpohVcBGvpTu542VC4XO9YudRi0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8 h1:cWno7lefSH6Pp+mSznagKCgfDGeZRin66UvYUqAkyeA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8/go.mod h1:tPD+VjU3ABTBoEJ3nctu5Nyg4P4yjqSH5bJGGkY4+XE= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.8 h1:/Mn7gTedG86nbpjT4QEKsN1D/fThiYe1qvq7WsBGNHg= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.8/go.mod h1:Ae3va9LPmvjj231ukHB6UeT8nS7wTPfC3tMZSZMwNYg= +github.com/aws/aws-sdk-go-v2/service/s3 v1.72.2 h1:a7aQ3RW+ug4IbhoQp29NZdc7vqrzKZZfWZSaQAXOZvQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.72.2/go.mod h1:xMekrnhmJ5aqmyxtmALs7mlvXw5xRh+eYjOjvrIIFJ4= github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 h1:3zu537oLmsPfDMyjnUS2g+F2vITgy5pB74tHI+JBNoM= github.com/aws/aws-sdk-go-v2/service/sso v1.24.6/go.mod h1:WJSZH2ZvepM6t6jwu4w/Z45Eoi75lPN7DcydSRtJg6Y= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 h1:K0OQAsDywb0ltlFrZm0JHPY3yZp/S9OaoLU33S7vPS8= diff --git a/linode/framework_provider.go b/linode/framework_provider.go index 1853ce124..ebc82c36a 100644 --- a/linode/framework_provider.go +++ b/linode/framework_provider.go @@ -68,8 +68,6 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/rdns" "github.com/linode/terraform-provider-linode/v2/linode/region" "github.com/linode/terraform-provider-linode/v2/linode/regions" - "github.com/linode/terraform-provider-linode/v2/linode/reservedip" - "github.com/linode/terraform-provider-linode/v2/linode/reservedips" "github.com/linode/terraform-provider-linode/v2/linode/sshkey" "github.com/linode/terraform-provider-linode/v2/linode/sshkeys" "github.com/linode/terraform-provider-linode/v2/linode/stackscript" @@ -231,7 +229,6 @@ func (p *FrameworkProvider) Resources(ctx context.Context) []func() resource.Res placementgroup.NewResource, placementgroupassignment.NewResource, instancereservedipassignment.NewResource, - reservedip.NewResource, rdns.NewResource, sshkey.NewResource, stackscript.NewResource, @@ -311,7 +308,5 @@ func (p *FrameworkProvider) DataSources(ctx context.Context) []func() datasource childaccount.NewDataSource, childaccounts.NewDataSource, networkingips.NewDataSource, - reservedip.NewDataSource, - reservedips.NewDataSource, } } diff --git a/linode/instance/resource_test.go b/linode/instance/resource_test.go index 9cad6c6d4..82afbedfe 100644 --- a/linode/instance/resource_test.go +++ b/linode/instance/resource_test.go @@ -2932,7 +2932,7 @@ func TestAccResourceInstance_deleteWithReservedIP(t *testing.T) { testRegion := "us-east" reservedIP := "" instanceName := acctest.RandomWithPrefix("tf_test") - ipResourceName := "linode_reserved_ip.test" + ipResourceName := "linode_networking_ip.test" rootPass := acctest.RandString(16) resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, diff --git a/linode/instance/tmpl/template.go b/linode/instance/tmpl/template.go index aab35fbfe..4f13cb533 100644 --- a/linode/instance/tmpl/template.go +++ b/linode/instance/tmpl/template.go @@ -757,8 +757,11 @@ func WithReservedIP(t *testing.T, label, pubKey, region, rootPass string) string func OnlyReservedIP(t *testing.T, region string) string { return fmt.Sprintf(` -resource "linode_reserved_ip" "test" { +resource "linode_networking_ip" "test" { + type = "ipv4" region = "%s" + public = true + reserved = true } `, region) } diff --git a/linode/instance/tmpl/templates/instance_with_reserved_ip.gotf b/linode/instance/tmpl/templates/instance_with_reserved_ip.gotf index aaf3ee5ac..a13af9d85 100644 --- a/linode/instance/tmpl/templates/instance_with_reserved_ip.gotf +++ b/linode/instance/tmpl/templates/instance_with_reserved_ip.gotf @@ -2,8 +2,11 @@ {{ template "e2e_test_firewall" . }} -resource "linode_reserved_ip" "test" { +resource "linode_networking_ip" "test" { + type = "ipv4" region = "{{ .Region }}" + public = true + reserved = true } resource "linode_instance" "foobar" { @@ -15,7 +18,7 @@ resource "linode_instance" "foobar" { root_pass = "{{ .RootPass }}" authorized_keys = ["{{ .PubKey }}"] - ipv4 = [linode_reserved_ip.test.address] + ipv4 = [linode_networking_ip.test.address] } {{ end }} \ No newline at end of file diff --git a/linode/instancereservedipassignment/tmpl/AddReservedIPToInstance.gotf b/linode/instancereservedipassignment/tmpl/AddReservedIPToInstance.gotf index 3a19e59dc..30ffc6aa3 100644 --- a/linode/instancereservedipassignment/tmpl/AddReservedIPToInstance.gotf +++ b/linode/instancereservedipassignment/tmpl/AddReservedIPToInstance.gotf @@ -11,14 +11,17 @@ resource "linode_instance" "foobar" { firewall_id = linode_firewall.e2e_test_firewall.id } -resource "linode_reserved_ip" "test" { +resource "linode_networking_ip" "test" { + type = "ipv4" region = "{{ .Region }}" + public = true + reserved = true } resource "linode_reserved_ip_assignment" "test" { linode_id = linode_instance.foobar.id public = true - address = linode_reserved_ip.test.address + address = linode_networking_ip.test.address } {{ end }} \ No newline at end of file diff --git a/linode/networkingips/famework_datasource_schema.go b/linode/networkingips/famework_datasource_schema.go index 2aefea03d..2a6088b6e 100644 --- a/linode/networkingips/famework_datasource_schema.go +++ b/linode/networkingips/famework_datasource_schema.go @@ -1,82 +1,82 @@ package networkingips 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/frameworkfilter" ) -var updatedIPObjectType = types.ObjectType{ - AttrTypes: map[string]attr.Type{ - "address": types.StringType, - "region": types.StringType, - "gateway": types.StringType, - "subnet_mask": types.StringType, - "prefix": types.Int64Type, - "type": types.StringType, - "public": types.BoolType, - "rdns": types.StringType, - "linode_id": types.Int64Type, - "reserved": types.BoolType, - }, +var filterConfig = frameworkfilter.Config{ + "type": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeString}, + "region": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeString}, + "rdns": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeString}, + "address": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeString}, + "prefix": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeInt}, + + "gateway": {APIFilterable: false, TypeFunc: frameworkfilter.FilterTypeString}, + "subnet_mask": {APIFilterable: false, TypeFunc: frameworkfilter.FilterTypeString}, + "public": {APIFilterable: false, TypeFunc: frameworkfilter.FilterTypeString}, + "linode_id": {APIFilterable: false, TypeFunc: frameworkfilter.FilterTypeInt}, + "reserved": {APIFilterable: false, TypeFunc: frameworkfilter.FilterTypeBool}, } var frameworkDatasourceSchema = schema.Schema{ Attributes: map[string]schema.Attribute{ - "address": schema.StringAttribute{ - Description: "The IP address.", - // Required: true, - Optional: true, - }, - "gateway": schema.StringAttribute{ - Description: "The default gateway for this address.", - Computed: true, - }, - "subnet_mask": schema.StringAttribute{ - Description: "The mask that separates host bits from network bits for this address.", - Computed: true, - }, - "prefix": schema.Int64Attribute{ - Description: "The number of bits set in the subnet mask.", - Computed: true, - }, - "type": schema.StringAttribute{ - Description: "The type of address this is (ipv4, ipv6, ipv6/pool, ipv6/range).", - Computed: true, - }, - "public": schema.BoolAttribute{ - Description: "Whether this is a public or private IP address.", - Computed: true, - }, - "rdns": schema.StringAttribute{ - Description: "The reverse DNS assigned to this address. For public IPv4 addresses, this will be set to " + - "a default value provided by Linode if not explicitly set.", - Computed: true, - }, - "linode_id": schema.Int64Attribute{ - Description: "The ID of the Linode this address currently belongs to.", - Computed: true, - }, - "region": schema.StringAttribute{ - Description: "The Region this IP address resides in.", - Computed: true, - }, "id": schema.StringAttribute{ - Description: "A unique identifier for this datasource.", + Description: "The data source's unique ID.", Computed: true, }, - "reserved": schema.BoolAttribute{ - Computed: true, - Description: "Whether this IP is reserved or not.", - }, - "ip_addresses": schema.ListAttribute{ - Description: "A list of all IPs.", - Computed: true, - ElementType: updatedIPObjectType, - }, - "filter_reserved": schema.BoolAttribute{ - Description: "Filter IPs by reserved status.", - Optional: true, + "order": filterConfig.OrderSchema(), + "order_by": filterConfig.OrderBySchema(), + }, + Blocks: map[string]schema.Block{ + "filter": filterConfig.Schema(), + "ip_addresses": schema.ListNestedBlock{ + Description: "The returned list of Images.", + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "address": schema.StringAttribute{ + Description: "The IP address.", + Computed: true, + }, + "gateway": schema.StringAttribute{ + Description: "The default gateway for this address.", + Computed: true, + }, + "subnet_mask": schema.StringAttribute{ + Description: "The mask that separates host bits from network bits for this address.", + Computed: true, + }, + "prefix": schema.Int64Attribute{ + Description: "The number of bits set in the subnet mask.", + Computed: true, + }, + "type": schema.StringAttribute{ + Description: "The type of address this is (ipv4, ipv6, ipv6/pool, ipv6/range).", + Computed: true, + }, + "public": schema.BoolAttribute{ + Description: "Whether this is a public or private IP address.", + Computed: true, + }, + "rdns": schema.StringAttribute{ + Description: "The reverse DNS assigned to this address. For public IPv4 addresses, this will be set to " + + "a default value provided by Linode if not explicitly set.", + Computed: true, + }, + "linode_id": schema.Int64Attribute{ + Description: "The ID of the Linode this address currently belongs to.", + Computed: true, + }, + "region": schema.StringAttribute{ + Description: "The Region this IP address resides in.", + Computed: true, + }, + "reserved": schema.BoolAttribute{ + Computed: true, + Description: "Whether this IP is reserved or not.", + }, + }, + }, }, }, } diff --git a/linode/networkingips/framework_datasource.go b/linode/networkingips/framework_datasource.go index 8070f4da4..7ed5a1e82 100644 --- a/linode/networkingips/framework_datasource.go +++ b/linode/networkingips/framework_datasource.go @@ -2,19 +2,18 @@ package networkingips import ( "context" - "encoding/json" - "fmt" "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/types" "github.com/linode/linodego" "github.com/linode/terraform-provider-linode/v2/linode/helper" ) +type DataSource struct { + helper.BaseDataSource +} + func NewDataSource() datasource.DataSource { return &DataSource{ BaseDataSource: helper.NewBaseDataSource( @@ -26,104 +25,57 @@ func NewDataSource() datasource.DataSource { } } -type DataSource struct { - helper.BaseDataSource -} - -type DataSourceModel struct { - Address types.String `tfsdk:"address"` - Gateway types.String `tfsdk:"gateway"` - SubnetMask types.String `tfsdk:"subnet_mask"` - Prefix types.Int64 `tfsdk:"prefix"` - Type types.String `tfsdk:"type"` - Public types.Bool `tfsdk:"public"` - RDNS types.String `tfsdk:"rdns"` - LinodeID types.Int64 `tfsdk:"linode_id"` - Region types.String `tfsdk:"region"` - ID types.String `tfsdk:"id"` - Reserved types.Bool `tfsdk:"reserved"` - IPAddresses types.List `tfsdk:"ip_addresses"` - FilterReserved types.Bool `tfsdk:"filter_reserved"` -} - func (d *DataSource) Read( ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse, ) { - tflog.Debug(ctx, "Read data.linode_networking_ip") + tflog.Debug(ctx, "Read data.linode_networking_ips") - var data DataSourceModel + var data FilterModel resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) if resp.Diagnostics.HasError() { return } - if data.Address.IsNull() { - - // List all IP addresses with filter on reservation status - - filter, err := buildFilter(data) - if err != nil { - resp.Diagnostics.AddError("Unable to build filter", err.Error()) - return - } - - tflog.Debug(ctx, "Generated filter", map[string]interface{}{ - "filter": filter, - }) - - opts := &linodego.ListOptions{Filter: filter} - ips, err := d.Meta.Client.ListIPAddresses(ctx, opts) - if err != nil { - resp.Diagnostics.AddError("Unable to list IP Addresses", err.Error()) - return - } - - ipList := make([]attr.Value, len(ips)) - for i, ip := range ips { - ipObj := map[string]attr.Value{ - "address": types.StringValue(ip.Address), - "region": types.StringValue(ip.Region), - "gateway": types.StringValue(ip.Gateway), - "subnet_mask": types.StringValue(ip.SubnetMask), - "prefix": types.Int64Value(int64(ip.Prefix)), - "type": types.StringValue(string(ip.Type)), - "public": types.BoolValue(ip.Public), - "rdns": types.StringValue(ip.RDNS), - "linode_id": types.Int64Value(int64(ip.LinodeID)), - "reserved": types.BoolValue(ip.Reserved), - } - ipList[i] = types.ObjectValueMust(updatedIPObjectType.AttrTypes, ipObj) - } - - var diags diag.Diagnostics - data.IPAddresses, diags = types.ListValue(updatedIPObjectType, ipList) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } + id, diag := filterConfig.GenerateID(data.Filters) + if diag != nil { + resp.Diagnostics.Append(diag) + return } + data.ID = id - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func buildFilter(data DataSourceModel) (string, error) { - filters := make(map[string]string) - - if !data.FilterReserved.IsNull() { - filters["reserved"] = fmt.Sprintf("%t", data.FilterReserved.ValueBool()) + result, diag := filterConfig.GetAndFilter( + ctx, d.Meta.Client, data.Filters, listFunc, + data.Order, data.OrderBy) + if diag != nil { + resp.Diagnostics.Append(diag) + return } - if len(filters) == 0 { - return "", nil + resp.Diagnostics.Append(data.parseIPAddresses(helper.AnySliceToTyped[linodego.InstanceIP](result))...) + if resp.Diagnostics.HasError() { + return } + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} - jsonFilter, err := json.Marshal(filters) +func listFunc( + ctx context.Context, + client *linodego.Client, + filter string, +) ([]any, error) { + tflog.Trace(ctx, "client.ListIPAddresses(...)", map[string]any{ + "filter": filter, + }) + + images, err := client.ListIPAddresses(ctx, &linodego.ListOptions{ + Filter: filter, + }) if err != nil { - return "", fmt.Errorf("error creating filter: %v", err) + return nil, err } - return string(jsonFilter), nil + return helper.TypedSliceToAny(images), nil } diff --git a/linode/networkingips/framework_datasource_models.go b/linode/networkingips/framework_datasource_models.go new file mode 100644 index 000000000..43a07b971 --- /dev/null +++ b/linode/networkingips/framework_datasource_models.go @@ -0,0 +1,60 @@ +package networkingips + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" +) + +type IPAddressModel struct { + Address types.String `tfsdk:"address"` + Type types.String `tfsdk:"type"` + Region types.String `tfsdk:"region"` + RDNS types.String `tfsdk:"rdns"` + Prefix types.Int64 `tfsdk:"prefix"` + Gateway types.String `tfsdk:"gateway"` + SubnetMask types.String `tfsdk:"subnet_mask"` + Public types.Bool `tfsdk:"public"` + LinodeID types.Int64 `tfsdk:"linode_id"` + Reserved types.Bool `tfsdk:"reserved"` +} + +func (m *IPAddressModel) ParseIP(ip linodego.InstanceIP) { + m.Address = types.StringValue(ip.Address) + m.Type = types.StringValue(string(ip.Type)) + m.Region = types.StringValue(ip.Region) + m.RDNS = types.StringValue(ip.RDNS) + m.Prefix = types.Int64Value(int64(ip.Prefix)) + m.Gateway = types.StringValue(ip.Gateway) + m.SubnetMask = types.StringValue(ip.SubnetMask) + m.Public = types.BoolValue(ip.Public) + m.LinodeID = types.Int64Value(int64(ip.LinodeID)) + m.Reserved = types.BoolValue(ip.Reserved) +} + +// FilterModel describes the Terraform resource data model to match the +// resource schema. +type FilterModel struct { + ID types.String `tfsdk:"id"` + Filters frameworkfilter.FiltersModelType `tfsdk:"filter"` + Order types.String `tfsdk:"order"` + OrderBy types.String `tfsdk:"order_by"` + IPAddresses []IPAddressModel `tfsdk:"ip_addresses"` +} + +func (data *FilterModel) parseIPAddresses( + ips []linodego.InstanceIP, +) diag.Diagnostics { + result := make([]IPAddressModel, len(ips)) + + for i := range ips { + var data IPAddressModel + data.ParseIP(ips[i]) + result[i] = data + } + + data.IPAddresses = result + + return nil +} diff --git a/linode/networkingips/tmpl/data_filter.gotf b/linode/networkingips/tmpl/data_filter.gotf index bb982222e..57139b64a 100644 --- a/linode/networkingips/tmpl/data_filter.gotf +++ b/linode/networkingips/tmpl/data_filter.gotf @@ -1,7 +1,19 @@ {{ define "networking_ip_data_filtered" }} +resource "linode_networking_ip" "test" { + type = "ipv4" + region = "us-mia" + reserved = true + public = true +} + data "linode_networking_ips" "filtered" { - filter_reserved = true + depends_on = [linode_networking_ip.test] + + filter { + name = "reserved" + values = ["true"] + } } {{ end }} \ No newline at end of file diff --git a/linode/networkingips/tmpl/data_list.gotf b/linode/networkingips/tmpl/data_list.gotf index 9258eb4dd..866041424 100644 --- a/linode/networkingips/tmpl/data_list.gotf +++ b/linode/networkingips/tmpl/data_list.gotf @@ -1,6 +1,15 @@ {{ define "networking_ip_data_list" }} +resource "linode_networking_ip" "test" { + type = "ipv4" + region = "us-mia" + reserved = true + public = true + +} + data "linode_networking_ips" "list" { + depends_on = [linode_networking_ip.test] } {{ end }} \ No newline at end of file diff --git a/linode/reservedip/datasource_model.go b/linode/reservedip/datasource_model.go deleted file mode 100644 index 586cd0ac0..000000000 --- a/linode/reservedip/datasource_model.go +++ /dev/null @@ -1,54 +0,0 @@ -package reservedip - -import ( - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/linode/linodego" - "github.com/linode/terraform-provider-linode/v2/linode/helper" - "github.com/linode/terraform-provider-linode/v2/linode/instancenetworking" -) - -type DataSourceModel struct { - ID types.String `tfsdk:"id"` - Address types.String `tfsdk:"address"` - Region types.String `tfsdk:"region"` - Gateway types.String `tfsdk:"gateway"` - SubnetMask types.String `tfsdk:"subnet_mask"` - Prefix types.Int64 `tfsdk:"prefix"` - Type types.String `tfsdk:"type"` - Public types.Bool `tfsdk:"public"` - RDNS types.String `tfsdk:"rdns"` - LinodeID types.Int64 `tfsdk:"linode_id"` - Reserved types.Bool `tfsdk:"reserved"` - IPVPCNAT1To1 types.List `tfsdk:"vpc_nat_1_1"` -} - -func (data *DataSourceModel) parseIP(ip *linodego.InstanceIP) { - data.ID = types.StringValue(ip.Address) - data.Address = types.StringValue(ip.Address) - data.Region = types.StringValue(ip.Region) - data.Gateway = types.StringValue(ip.Gateway) - data.SubnetMask = types.StringValue(ip.SubnetMask) - data.Prefix = types.Int64Value(int64(ip.Prefix)) - data.Type = types.StringValue(string(ip.Type)) - data.Public = types.BoolValue(ip.Public) - data.RDNS = types.StringValue(ip.RDNS) - data.LinodeID = types.Int64Value(int64(ip.LinodeID)) - data.Reserved = types.BoolValue(ip.Reserved) - var resultList types.List - if ip.VPCNAT1To1 == nil { - resultList = types.ListNull(instancenetworking.VPCNAT1To1Type) - } else { - vpcNAT1To1, _ := instancenetworking.FlattenIPVPCNAT1To1(ip.VPCNAT1To1) - - resultList, _ = types.ListValue( - instancenetworking.VPCNAT1To1Type, - []attr.Value{vpcNAT1To1}, - ) - } - data.IPVPCNAT1To1 = helper.KeepOrUpdateValue( - data.IPVPCNAT1To1, - resultList, - true, - ) -} diff --git a/linode/reservedip/datasource_schema.go b/linode/reservedip/datasource_schema.go deleted file mode 100644 index 794efd19d..000000000 --- a/linode/reservedip/datasource_schema.go +++ /dev/null @@ -1,65 +0,0 @@ -package reservedip - -import ( - "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" - "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/linode/terraform-provider-linode/v2/linode/instancenetworking" -) - -var frameworkDataSourceSchema = schema.Schema{ - Attributes: map[string]schema.Attribute{ - "region": schema.StringAttribute{ - Description: "The Region in which to reserve the IP address.", - Optional: true, - }, - "address": schema.StringAttribute{ - Description: "The reserved IP address.", - Required: true, - }, - "gateway": schema.StringAttribute{ - Description: "The default gateway for this address.", - Computed: true, - }, - "subnet_mask": schema.StringAttribute{ - Description: "The mask that separates host bits from network bits for this address.", - Computed: true, - }, - "prefix": schema.Int64Attribute{ - Description: "The number of bits set in the subnet mask.", - Computed: true, - }, - "type": schema.StringAttribute{ - Description: "The type of address this is (ipv4, ipv6, ipv6/pool, ipv6/range).", - Computed: true, - }, - "public": schema.BoolAttribute{ - Description: "Whether this is a public or private IP address.", - Computed: true, - }, - "vpc_nat_1_1": schema.ListAttribute{ - Description: "Contains information about the NAT 1:1 mapping of a public IP address to a VPC subnet.", - Computed: true, - ElementType: instancenetworking.VPCNAT1To1Type, - Validators: []validator.List{ - listvalidator.SizeAtMost(1), - }, - }, - "rdns": schema.StringAttribute{ - Description: "The reverse DNS assigned to this address.", - Computed: true, - }, - "linode_id": schema.Int64Attribute{ - Description: "The ID of the Linode this address currently belongs to.", - Computed: true, - }, - "reserved": schema.BoolAttribute{ - Description: "Whether this IP is reserved or not.", - Computed: true, - }, - "id": schema.StringAttribute{ - Description: "The unique ID of the reserved IP address.", - Computed: true, - }, - }, -} diff --git a/linode/reservedip/datasource_test.go b/linode/reservedip/datasource_test.go deleted file mode 100644 index b946387aa..000000000 --- a/linode/reservedip/datasource_test.go +++ /dev/null @@ -1,40 +0,0 @@ -//go:build integration || reservedip - -package reservedip_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/reservedip/tmpl" -) - -func TestAccDataSource_reservedIP(t *testing.T) { - t.Parallel() - - resourceName := "data.linode_reserved_ip.test" - region, _ := acceptance.GetRandomRegionWithCaps([]string{"linodes"}, "core") - - resource.Test(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, - Steps: []resource.TestStep{ - { - Config: tmpl.DataBasic(t, region), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet(resourceName, "address"), - resource.TestCheckResourceAttrSet(resourceName, "region"), - resource.TestCheckResourceAttrSet(resourceName, "gateway"), - resource.TestCheckResourceAttrSet(resourceName, "subnet_mask"), - resource.TestCheckResourceAttrSet(resourceName, "prefix"), - resource.TestCheckResourceAttrSet(resourceName, "type"), - resource.TestCheckResourceAttrSet(resourceName, "public"), - resource.TestCheckResourceAttrSet(resourceName, "rdns"), - resource.TestCheckResourceAttrSet(resourceName, "linode_id"), - resource.TestCheckResourceAttrSet(resourceName, "reserved"), - ), - }, - }, - }) -} diff --git a/linode/reservedip/framework_datasource.go b/linode/reservedip/framework_datasource.go deleted file mode 100644 index b58d6d92c..000000000 --- a/linode/reservedip/framework_datasource.go +++ /dev/null @@ -1,48 +0,0 @@ -package reservedip - -import ( - "context" - - "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/linode/terraform-provider-linode/v2/linode/helper" -) - -func NewDataSource() datasource.DataSource { - return &DataSource{ - BaseDataSource: helper.NewBaseDataSource( - helper.BaseDataSourceConfig{ - Name: "linode_reserved_ip", - Schema: &frameworkDataSourceSchema, - }, - ), - } -} - -type DataSource struct { - helper.BaseDataSource -} - -func (d *DataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { - tflog.Debug(ctx, "Read data.linode_reserved_ip") - - var data DataSourceModel - resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - if !data.Address.IsNull() { - // Fetch a specific reserved IP - ip, err := d.Meta.Client.GetReservedIPAddress(ctx, data.Address.ValueString()) - if err != nil { - resp.Diagnostics.AddError( - "Unable to get Reserved IP Address", - err.Error(), - ) - return - } - data.parseIP(ip) - } - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} diff --git a/linode/reservedip/framework_models.go b/linode/reservedip/framework_models.go deleted file mode 100644 index 61131f563..000000000 --- a/linode/reservedip/framework_models.go +++ /dev/null @@ -1,66 +0,0 @@ -package reservedip - -import ( - "context" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/linode/linodego" - - "github.com/linode/terraform-provider-linode/v2/linode/helper" - "github.com/linode/terraform-provider-linode/v2/linode/instancenetworking" -) - -type ReservedIPModel struct { - ID types.String `tfsdk:"id"` - Region types.String `tfsdk:"region"` - Address types.String `tfsdk:"address"` - Gateway types.String `tfsdk:"gateway"` - SubnetMask types.String `tfsdk:"subnet_mask"` - Prefix types.Int64 `tfsdk:"prefix"` - Type types.String `tfsdk:"type"` - Public types.Bool `tfsdk:"public"` - RDNS types.String `tfsdk:"rdns"` - LinodeID types.Int64 `tfsdk:"linode_id"` - Reserved types.Bool `tfsdk:"reserved"` - IPVPCNAT1To1 types.List `tfsdk:"vpc_nat_1_1"` -} - -func (m *ReservedIPModel) FlattenReservedIP( - ctx context.Context, - ip linodego.InstanceIP, - preserveKnown bool, -) diag.Diagnostics { - var diags diag.Diagnostics - - m.ID = helper.KeepOrUpdateString(m.ID, ip.Address, preserveKnown) - m.Region = helper.KeepOrUpdateString(m.Region, ip.Region, preserveKnown) - m.Address = helper.KeepOrUpdateString(m.Address, ip.Address, preserveKnown) - m.Gateway = helper.KeepOrUpdateString(m.Gateway, ip.Gateway, preserveKnown) - m.SubnetMask = helper.KeepOrUpdateString(m.SubnetMask, ip.SubnetMask, preserveKnown) - m.Prefix = helper.KeepOrUpdateInt64(m.Prefix, int64(ip.Prefix), preserveKnown) - m.Type = helper.KeepOrUpdateString(m.Type, string(ip.Type), preserveKnown) - m.Public = helper.KeepOrUpdateBool(m.Public, ip.Public, preserveKnown) - m.RDNS = helper.KeepOrUpdateString(m.RDNS, ip.RDNS, preserveKnown) - m.LinodeID = helper.KeepOrUpdateInt64(m.LinodeID, int64(ip.LinodeID), preserveKnown) - m.Reserved = helper.KeepOrUpdateBool(m.Reserved, ip.Reserved, preserveKnown) - var resultList types.List - if ip.VPCNAT1To1 == nil { - resultList = types.ListNull(instancenetworking.VPCNAT1To1Type) - } else { - vpcNAT1To1, _ := instancenetworking.FlattenIPVPCNAT1To1(ip.VPCNAT1To1) - - resultList, _ = types.ListValue( - instancenetworking.VPCNAT1To1Type, - []attr.Value{vpcNAT1To1}, - ) - } - m.IPVPCNAT1To1 = helper.KeepOrUpdateValue( - m.IPVPCNAT1To1, - resultList, - true, - ) - - return diags -} diff --git a/linode/reservedip/framework_resource.go b/linode/reservedip/framework_resource.go deleted file mode 100644 index f95036a73..000000000 --- a/linode/reservedip/framework_resource.go +++ /dev/null @@ -1,154 +0,0 @@ -package reservedip - -import ( - "context" - "fmt" - - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/linode/linodego" - "github.com/linode/terraform-provider-linode/v2/linode/helper" -) - -func NewResource() resource.Resource { - return &Resource{ - BaseResource: helper.NewBaseResource( - helper.BaseResourceConfig{ - Name: "linode_reserved_ip", - IDType: types.StringType, - Schema: &frameworkResourceSchema, - }, - ), - } -} - -type Resource struct { - helper.BaseResource -} - -func (r *Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - tflog.Debug(ctx, "Starting Create for linode_reserved_ip") - var data ReservedIPModel - - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - ctx = populateLogAttributes(ctx, &data) - - client := r.Meta.Client - reserveIP, err := client.ReserveIPAddress(ctx, linodego.ReserveIPOptions{ - Region: data.Region.ValueString(), - }) - if err != nil { - resp.Diagnostics.AddError( - "Failed to reserve IP address", - err.Error(), - ) - return - } - - if reserveIP == nil { - resp.Diagnostics.AddError("nil Pointer", "received nil pointer of the reserved ip") - return - } - - data.ID = types.StringValue(reserveIP.Address) - tflog.Debug(ctx, "Setting ID for reserved IP", map[string]interface{}{ - "id": data.ID.ValueString(), - }) - - diags := data.FlattenReservedIP(ctx, *reserveIP, true) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - tflog.Debug(ctx, "Read linode_reserved_ip") - var data ReservedIPModel - - resp.Diagnostics.Append(req.State.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - if helper.FrameworkAttemptRemoveResourceForEmptyID(ctx, data.ID, resp) { - return - } - - ctx = populateLogAttributes(ctx, &data) - - client := r.Meta.Client - address := data.ID.ValueString() - - reservedIP, err := client.GetReservedIPAddress(ctx, address) - if err != nil { - if lerr, ok := err.(*linodego.Error); ok && lerr.Code == 404 { - resp.Diagnostics.AddWarning( - "Reserved IP No Longer Exists", - fmt.Sprintf( - "Removing reserved IP %s from state because it no longer exists", - data.ID.ValueString(), - ), - ) - resp.State.RemoveResource(ctx) - return - } - resp.Diagnostics.AddError( - "Unable to Refresh the Reserved IP", - fmt.Sprintf( - "Error finding the specified Reserved IP: %s", - err.Error(), - ), - ) - return - } - - resp.Diagnostics.Append(data.FlattenReservedIP(ctx, *reservedIP, false)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func (r *Resource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - // Reserved IPs cannot be updated, so this method is left empty -} - -func (r *Resource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var state ReservedIPModel - - resp.Diagnostics.Append(req.State.Get(ctx, &state)...) - if resp.Diagnostics.HasError() { - return - } - - client := r.Meta.Client - address := state.Address.ValueString() - - tflog.Debug(ctx, "client.DeleteReservedIPAddress(...)") - if err := client.DeleteReservedIPAddress(ctx, address); err != nil { - if lErr, ok := err.(*linodego.Error); (ok && lErr.Code != 404) || !ok { - resp.Diagnostics.AddError( - "Failed to Delete Reserved IP", - fmt.Sprintf( - "failed to delete reserved ip (%s): %s", - address, err.Error(), - ), - ) - } - } -} - -func populateLogAttributes(ctx context.Context, data *ReservedIPModel) context.Context { - return helper.SetLogFieldBulk(ctx, map[string]any{ - "region": data.Region.ValueString(), - "address": data.ID.ValueString(), - }) -} diff --git a/linode/reservedip/framework_schema.go b/linode/reservedip/framework_schema.go deleted file mode 100644 index bba4437a9..000000000 --- a/linode/reservedip/framework_schema.go +++ /dev/null @@ -1,74 +0,0 @@ -package reservedip - -import ( - "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/linode/terraform-provider-linode/v2/linode/instancenetworking" -) - -var frameworkResourceSchema = schema.Schema{ - Attributes: map[string]schema.Attribute{ - "id": schema.StringAttribute{ - Description: "The ID of the reserved IP address, which will be the IP address itself.", - Computed: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - }, - "region": schema.StringAttribute{ - Description: "The Region in which to reserve the IP address.", - Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.RequiresReplace(), - }, - }, - "address": schema.StringAttribute{ - Description: "The reserved IP address.", - Computed: true, - }, - "gateway": schema.StringAttribute{ - Description: "The default gateway for this address.", - Computed: true, - }, - "subnet_mask": schema.StringAttribute{ - Description: "The mask that separates host bits from network bits for this address.", - Computed: true, - }, - "prefix": schema.Int64Attribute{ - Description: "The number of bits set in the subnet mask.", - Computed: true, - }, - "type": schema.StringAttribute{ - Description: "The type of address this is (ipv4, ipv6, ipv6/pool, ipv6/range).", - Computed: true, - }, - "vpc_nat_1_1": schema.ListAttribute{ - Description: "Contains information about the NAT 1:1 mapping of a public IP address to a VPC subnet.", - Computed: true, - ElementType: instancenetworking.VPCNAT1To1Type, - Validators: []validator.List{ - listvalidator.SizeAtMost(1), - }, - }, - "public": schema.BoolAttribute{ - Description: "Whether this is a public or private IP address.", - Computed: true, - }, - "rdns": schema.StringAttribute{ - Description: "The reverse DNS assigned to this address. For public IPv4 addresses, this will be set to " + - "a default value provided by Linode if not explicitly set.", - Computed: true, - }, - "linode_id": schema.Int64Attribute{ - Description: "The ID of the Linode this address currently belongs to.", - Computed: true, - }, - "reserved": schema.BoolAttribute{ - Description: "Whether this IP is reserved or not.", - Computed: true, - }, - }, -} diff --git a/linode/reservedip/resource_test.go b/linode/reservedip/resource_test.go deleted file mode 100644 index 953674ea0..000000000 --- a/linode/reservedip/resource_test.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build integration || reservedip - -package reservedip_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-testing/helper/acctest" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/hashicorp/terraform-plugin-testing/terraform" - "github.com/linode/terraform-provider-linode/v2/linode/acceptance" - "github.com/linode/terraform-provider-linode/v2/linode/reservedip/tmpl" -) - -var testRegion string - -func init() { - region, err := acceptance.GetRandomRegionWithCaps([]string{"linodes"}, "core") - if err != nil { - panic(fmt.Sprintf("Error getting random region: %s", err)) - } - testRegion = region - fmt.Println(testRegion) -} - -func TestAccResource_reserveIP(t *testing.T) { - t.Parallel() - - resName := "linode_reserved_ip.test" - instanceName := acctest.RandomWithPrefix("tf_test") - resource.Test(t, resource.TestCase{ - PreCheck: func() { - acceptance.PreCheck(t) - }, - ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, - CheckDestroy: acceptance.CheckInstanceDestroy, - Steps: []resource.TestStep{ - { - Config: tmpl.ReserveIP(t, instanceName, testRegion), - Check: resource.ComposeTestCheckFunc( - func(s *terraform.State) error { - return nil - }, - resource.TestCheckResourceAttrSet(resName, "id"), - resource.TestCheckResourceAttrSet(resName, "address"), - resource.TestCheckResourceAttr(resName, "region", testRegion), - resource.TestCheckResourceAttr(resName, "reserved", "true"), - ), - }, - }, - }) - - t.Log("Finished TestAccResource_reserveIP") -} diff --git a/linode/reservedip/tmpl/reserved_ip.gotf b/linode/reservedip/tmpl/reserved_ip.gotf deleted file mode 100644 index 6b054eba4..000000000 --- a/linode/reservedip/tmpl/reserved_ip.gotf +++ /dev/null @@ -1,12 +0,0 @@ -{{ define "reserved_ip_data_basic" }} - -resource "linode_reserved_ip" "test" { - region = "{{ .Region }}" -} - -data "linode_reserved_ip" "test" { - address = linode_reserved_ip.test.address -} - -{{ end }} - diff --git a/linode/reservedip/tmpl/reserved_ip_basic.gotf b/linode/reservedip/tmpl/reserved_ip_basic.gotf deleted file mode 100644 index 23e617dcf..000000000 --- a/linode/reservedip/tmpl/reserved_ip_basic.gotf +++ /dev/null @@ -1,7 +0,0 @@ -{{ define "reserved_ip_basic" }} - -resource "linode_reserved_ip" "test" { - region = "{{ .Region }}" -} - -{{ end }} \ No newline at end of file diff --git a/linode/reservedip/tmpl/template.go b/linode/reservedip/tmpl/template.go deleted file mode 100644 index 80f1f70d9..000000000 --- a/linode/reservedip/tmpl/template.go +++ /dev/null @@ -1,27 +0,0 @@ -package tmpl - -import ( - "testing" - - "github.com/linode/terraform-provider-linode/v2/linode/acceptance" -) - -type TemplateData struct { - Region string - Address string -} - -func DataBasic(t *testing.T, region string) string { - return acceptance.ExecuteTemplate(t, - "reserved_ip_data_basic", TemplateData{ - Region: region, - }) -} - -// ReserveIP generates the Terraform configuration for reserving an IP address -func ReserveIP(t *testing.T, name, region string) string { - return acceptance.ExecuteTemplate(t, - "reserved_ip_basic", TemplateData{ - Region: region, - }) -} diff --git a/linode/reservedips/datasource_model.go b/linode/reservedips/datasource_model.go deleted file mode 100644 index 1311cee81..000000000 --- a/linode/reservedips/datasource_model.go +++ /dev/null @@ -1,52 +0,0 @@ -package reservedips - -import ( - "context" - - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/linode/linodego" - "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" - "github.com/linode/terraform-provider-linode/v2/linode/instancenetworking" -) - -type ReservedIPFilterModel struct { - ID types.String `tfsdk:"id"` - Filters frameworkfilter.FiltersModelType `tfsdk:"filter"` - Order types.String `tfsdk:"order"` - OrderBy types.String `tfsdk:"order_by"` - ReservedIPs []ReservedIPObject `tfsdk:"reserved_ips"` -} - -func (data *ReservedIPFilterModel) parseReservedIPs( - ctx context.Context, - ips []linodego.InstanceIP, -) diag.Diagnostics { - result := make([]ReservedIPObject, len(ips)) - for i, ip := range ips { - var ipData ReservedIPObject - ipData.ID = types.StringValue(ip.Address) - ipData.Address = types.StringValue(ip.Address) - ipData.Region = types.StringValue(ip.Region) - ipData.Gateway = types.StringValue(ip.Gateway) - ipData.SubnetMask = types.StringValue(ip.SubnetMask) - ipData.Prefix = types.Int64Value(int64(ip.Prefix)) - ipData.Type = types.StringValue(string(ip.Type)) - ipData.Public = types.BoolValue(ip.Public) - ipData.RDNS = types.StringValue(ip.RDNS) - ipData.LinodeID = types.Int64Value(int64(ip.LinodeID)) - ipData.Reserved = types.BoolValue(ip.Reserved) - - vpcNAT1To1List, diags := types.ListValueFrom(ctx, instancenetworking.VPCNAT1To1Type, ip.VPCNAT1To1) - if diags.HasError() { - return diags - } - ipData.IPVPCNAT1To1 = vpcNAT1To1List - - result[i] = ipData - } - - data.ReservedIPs = result - - return nil -} diff --git a/linode/reservedips/datasource_schema.go b/linode/reservedips/datasource_schema.go deleted file mode 100644 index d26648bdd..000000000 --- a/linode/reservedips/datasource_schema.go +++ /dev/null @@ -1,100 +0,0 @@ -package reservedips - -import ( - "github.com/hashicorp/terraform-plugin-framework/datasource/schema" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/linode/terraform-provider-linode/v2/linode/helper/frameworkfilter" - "github.com/linode/terraform-provider-linode/v2/linode/instancenetworking" -) - -type ReservedIPObject struct { - ID types.String `tfsdk:"id"` - Address types.String `tfsdk:"address"` - Region types.String `tfsdk:"region"` - Gateway types.String `tfsdk:"gateway"` - SubnetMask types.String `tfsdk:"subnet_mask"` - Prefix types.Int64 `tfsdk:"prefix"` - Type types.String `tfsdk:"type"` - Public types.Bool `tfsdk:"public"` - RDNS types.String `tfsdk:"rdns"` - LinodeID types.Int64 `tfsdk:"linode_id"` - Reserved types.Bool `tfsdk:"reserved"` - IPVPCNAT1To1 types.List `tfsdk:"vpc_nat_1_1"` -} - -var ReservedIPAttributes = map[string]schema.Attribute{ - "id": schema.StringAttribute{ - Description: "The unique identifier of the reserved IP.", - Computed: true, - }, - "address": schema.StringAttribute{ - Description: "The IP address.", - Computed: true, - }, - "region": schema.StringAttribute{ - Description: "The region where the IP is located.", - Optional: true, - Computed: true, - }, - "gateway": schema.StringAttribute{ - Description: "The gateway for the reserved IP.", - Computed: true, - }, - "subnet_mask": schema.StringAttribute{ - Description: "The subnet mask for the reserved IP.", - Computed: true, - }, - "prefix": schema.Int64Attribute{ - Description: "The prefix length of the reserved IP.", - Computed: true, - }, - "type": schema.StringAttribute{ - Description: "The type of the reserved IP.", - Computed: true, - }, - "public": schema.BoolAttribute{ - Description: "Whether the IP is public.", - Computed: true, - }, - "rdns": schema.StringAttribute{ - Description: "The reverse DNS for the reserved IP.", - Optional: true, - Computed: true, - }, - "linode_id": schema.Int64Attribute{ - Description: "The Linode ID associated with this reserved IP.", - Computed: true, - }, - "reserved": schema.BoolAttribute{ - Description: "Indicates if this IP is reserved.", - Computed: true, - }, - "vpc_nat_1_1": schema.ListAttribute{ - ElementType: instancenetworking.VPCNAT1To1Type, - Computed: true, - }, -} - -var filterConfig = frameworkfilter.Config{ - "region": {APIFilterable: true, TypeFunc: frameworkfilter.FilterTypeString}, -} - -var frameworkDataSourceSchema = schema.Schema{ - Attributes: map[string]schema.Attribute{ - "id": schema.StringAttribute{ - Description: "The data source's unique ID.", - Computed: true, - }, - "order": filterConfig.OrderSchema(), - "order_by": filterConfig.OrderBySchema(), - }, - Blocks: map[string]schema.Block{ - "filter": filterConfig.Schema(), - "reserved_ips": schema.ListNestedBlock{ - Description: "The returned list of Reserved IPs.", - NestedObject: schema.NestedBlockObject{ - Attributes: ReservedIPAttributes, - }, - }, - }, -} diff --git a/linode/reservedips/datasource_test.go b/linode/reservedips/datasource_test.go deleted file mode 100644 index 82cb99372..000000000 --- a/linode/reservedips/datasource_test.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build integration || reservedips - -package reservedips_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/reservedips/tmpl" -) - -func TestAccDataSource_reservedIPList(t *testing.T) { - t.Parallel() - - resourceName := "data.linode_reserved_ips.test" - - resource.Test(t, resource.TestCase{ - PreCheck: func() { acceptance.PreCheck(t) }, - ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, - Steps: []resource.TestStep{ - { - Config: tmpl.DataList(t), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet(resourceName, "reserved_ips.#"), - ), - }, - }, - }) -} diff --git a/linode/reservedips/framework_datasource.go b/linode/reservedips/framework_datasource.go deleted file mode 100644 index 1a7c793b0..000000000 --- a/linode/reservedips/framework_datasource.go +++ /dev/null @@ -1,80 +0,0 @@ -package reservedips - -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_reserved_ips", - Schema: &frameworkDataSourceSchema, - }, - ), - } -} - -type DataSource struct { - helper.BaseDataSource -} - -func (d *DataSource) Read( - ctx context.Context, - req datasource.ReadRequest, - resp *datasource.ReadResponse, -) { - tflog.Debug(ctx, "Read data.linode_reserved_ips") - - var data ReservedIPFilterModel - - resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) - if resp.Diagnostics.HasError() { - return - } - - id, diag := filterConfig.GenerateID(data.Filters) - if diag != nil { - resp.Diagnostics.Append(diag) - return - } - data.ID = id - - result, diag := filterConfig.GetAndFilter( - ctx, d.Meta.Client, data.Filters, listReservedIPs, - data.Order, data.OrderBy) - if diag != nil { - resp.Diagnostics.Append(diag) - return - } - - resp.Diagnostics.Append(data.parseReservedIPs(ctx, helper.AnySliceToTyped[linodego.InstanceIP](result))...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} - -func listReservedIPs( - ctx context.Context, - client *linodego.Client, - filter string, -) ([]any, error) { - tflog.Trace(ctx, "client.ListReservedIPAddresses", map[string]any{ - "filter": filter, - }) - - ips, err := client.ListReservedIPAddresses(ctx, &linodego.ListOptions{ - Filter: filter, - }) - if err != nil { - return nil, err - } - - return helper.TypedSliceToAny(ips), nil -} diff --git a/linode/reservedips/tmpl/reserved_ip.gotf b/linode/reservedips/tmpl/reserved_ip.gotf deleted file mode 100644 index 444e74851..000000000 --- a/linode/reservedips/tmpl/reserved_ip.gotf +++ /dev/null @@ -1,9 +0,0 @@ -{{ define "reserved_ips_data" }} - -data "linode_reserved_ips" "test" {} - -output "reserved_ips" { - value = data.linode_reserved_ips.test.reserved_ips -} - -{{ end }} \ No newline at end of file diff --git a/linode/reservedips/tmpl/template.go b/linode/reservedips/tmpl/template.go deleted file mode 100644 index 0ec615b98..000000000 --- a/linode/reservedips/tmpl/template.go +++ /dev/null @@ -1,11 +0,0 @@ -package tmpl - -import ( - "testing" - - "github.com/linode/terraform-provider-linode/v2/linode/acceptance" -) - -func DataList(t *testing.T) string { - return acceptance.ExecuteTemplate(t, "reserved_ips_data", nil) -}