Skip to content

Bump terraform-provider-linode to v4.3.0 - #59

Open
cmcgalliard wants to merge 1 commit into
mainfrom
bump-terraform-4.3.0
Open

Bump terraform-provider-linode to v4.3.0#59
cmcgalliard wants to merge 1 commit into
mainfrom
bump-terraform-4.3.0

Conversation

@cmcgalliard

Copy link
Copy Markdown
Collaborator

What

Bumps the upstream pin from terraform-provider-linode v2.37.0 → v4.3.0, crossing two major versions, and regenerates everything.

Supersedes #58 (the v2.41.2 bump). If this lands, #58 can be closed.

Breaking changes

Please read this section before merging — this cannot be a silent bump.

1. The MySQL and PostgreSQL CRDs are removed. Upstream deleted linode_database_mysql and linode_database_postgresql. Users must migrate to MySQLv2 / PostgreSQLv2.

2. Long-deprecated fields are gone, following upstream:

Resource Field
Domain, Instance group
Bucket, Key.bucketAccess, Object cluster
lke.Cluster status.atProvider.dashboardUrl
User placementGroupGrant, globalGrants.addPlacementGroups

AccountSettings.longviewSubscription became computed-only upstream, so it moves from spec to status.atProvider.

3. Three fields change shape from map to single-element list: updates on MySQLv2/PostgreSQLv2, and status.atProvider.vpcNat11 on networking.IP.

These were previously pinned to TypeMap by hand as a workaround for the schema gap described below, which rendered them as map[string]string. That shape cannot represent their numeric fields (dayOfWeek, duration, hourOfDay, subnetId, vpcId), so it could not have been carrying a working value. They now match their real shape, alongside the other nested attributes.

Aside from these, the CRD diff is additive: 1675 properties added, 30 removed (all of them the upstream removals above), verified by diffing every property of every CRD against main.

The interesting part: two upjet schema-conversion gaps

v4 leans on the Terraform Plugin Framework much more heavily, and upjet's tfjson→SDKv2 converter doesn't understand two of the shapes it uses. Both produce attributes with no type at all, failing generation with invalid schema type TypeInvalid:

  • nested attributes (nested_type) — 14 fields, e.g. vpc.ipv4/ipv6, nodebalancer.vpcs, image.imageSharing (which nests two levels deep), database.*.privateNetwork/updates
  • bare cty object types — 3 fields: networking_ip.assigned_entity, .vpc_nat_1_1, reserved_ip_assignment.assigned_entity

config/provider.go now reconstructs both. Two notes on the implementation:

It runs as a default resource option, which is the only hook that reaches Plugin Framework resources. config.NewProvider derives SDKv2 resources from config.Provider.TerraformProvider but converts framework resources through its own internal GetV2ResourceMap, and Resource.TerraformResource is the only object common to both paths.

It deliberately does not route nested attributes through the converter's nested-block handling. That path infers Optional/Computed from MinItems/MaxItems, because blocks carry no such flags, and so can't express a computed-only field like nodebalancer.lke_cluster. Nested attributes do carry the flags, so they're honoured directly — which is why the computed-only fields land in status.atProvider and the configurable ones in spec.forProvider, as verified below.

Other changes

  • linodego v1 → v2 dropped resty for net/http, so the API response counter middleware is now an http.Response hook. It also picked up a guard for a short or missing Authorization header, which the old token-prefix slice would have panicked on.
  • upjet → v1.11.2, for a version that builds against the newer terraform-plugin-go / terraform-plugin-framework v4 requires.
  • The crossplane-runtime fork replace is dropped — the one commit it carried is upstream as of v1.20.0.
  • golangci-lint → v2.13.1, config migrated to the v2 format via golangci-lint migrate, and the action bumped to v9.3.0. Required, not optional: 1.x refuses to load a module declaring a newer Go version than it was built with.
  • Go 1.23 → 1.25 in go.mod and CI.
  • docs/developer.md gains the make submodules and goimports prerequisites, both of which currently fail make generate from a clean checkout with an unhelpful error.

Verification

  • make generate — clean, 35 resources
  • go build ./..., go vet ./..., go test ./... — all pass
  • golangci-lint run (v2.13.1) — 0 issues
  • make build — Go build passes; the Docker image step was not run locally (no daemon), so CI should be watched for it
  • CRD property-level diff against main — reviewed in full, summarized above
  • All 30 removed fields confirmed absent from the v4.3.0 provider schema, i.e. genuine upstream removals rather than conversion regressions
  • All 17 reconstructed fields confirmed present in the generated CRDs with correct structural types and correct spec/status placement

Not exercised against a live cluster or the Linode API — worth a make local-deploy pass on the DBaaS v2 and VPC resources before release, since those carry the reconstructed schemas.

Known follow-up

terraform-provider-linode v4.3.0 requires k8s.io/apimachinery v0.35.5, while upjet v1.11.2 pins crossplane-runtime v1.20, which pins controller-runtime v0.19.0 — a version skew that main did not have. I tried aligning controller-runtime to v0.23.3; crossplane-runtime v1.20 doesn't implement its expanded SubResourceWriter interface, so closing the skew means moving to crossplane-runtime v2, which upjet v1.11.2 (the latest release) doesn't support. Everything builds and tests clean as-is, so this is left as a follow-up rather than expanded into this PR.

🤖 Generated with Claude Code

Moves the upstream pin from v2.37.0 to v4.3.0, which crosses two major
versions and so carries a few breaking changes.

The provider module path changed to .../terraform-provider-linode/v4, and
upjet is bumped to v1.11.2 to get a version that builds against the newer
terraform-plugin-go and terraform-plugin-framework that v4 requires. The
crossplane-runtime fork replace directive is dropped: the single commit it
carried is upstream as of v1.20.0.

linodego v2 replaced resty with net/http, so the API response counter
middleware is now an http.Response hook. It also grew a guard for a short
or missing Authorization header, which the old token-prefix slice would
have panicked on.

Breaking: linode_database_mysql and linode_database_postgresql were
removed upstream, so the MySQL and PostgreSQL CRDs go away with them.
Users migrate to MySQLv2 and PostgreSQLv2.

Breaking: upstream also dropped several long-deprecated fields, which
disappear from the CRDs along with them - group (domain, instance),
cluster (object storage bucket/key/object), lke_cluster.dashboard_url,
and user placement_group_grant plus global_grants.add_placement_groups.
account_settings.longview_subscription became computed-only, so it moves
from spec to status.

Breaking: updates on the database v2 resources and vpc_nat_1_1 on
networking IP change from map to a single-element list, matching their
real shape. They were previously forced to a map as a workaround for the
schema gap described below, which typed them map[string]string - a shape
that could not represent their numeric fields, so it could not have been
carrying a working value.

v4 leans on the Terraform Plugin Framework much more heavily, and upjet's
tfjson to SDKv2 schema converter does not understand two of the shapes it
uses: nested attributes ("nested_type") and attributes whose cty type is
a bare object. Both come out with no type at all, which fails code
generation with "invalid schema type TypeInvalid". config/provider.go now
reconstructs them as a default resource option, which is the only hook
that covers Plugin Framework resources - upjet derives the SDKv2 provider
from config.Provider.TerraformProvider but converts framework resources
internally, and only Resource.TerraformResource is common to both.

golangci-lint moves to v2.13.1 and the config is migrated to the v2
format, because 1.x refuses to load a module declaring a Go version
newer than the one it was built with.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the Linode Terraform provider from v2.37.0 to v4.3.0 and regenerates the Crossplane provider APIs, CRDs, controllers, and examples.

Changes:

  • Handles Plugin Framework nested/object schema conversion.
  • Removes legacy MySQL/PostgreSQL resources and updates generated schemas.
  • Updates Linode client middleware, Go tooling, linting, CI, and developer guidance.

Reviewed changes

Copilot reviewed 119 out of 147 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Makefile Bumps provider, Go, and lint versions.
.github/workflows/ci.yml Updates CI Go and lint tooling.
docs/developer.md Documents generation prerequisites.
config/provider.go Reconstructs unsupported framework schemas.
config/networkingip/config.go Removes obsolete map override.
config/externalname.go Removes legacy database resources.
config/databasepostgresql/config.go Retains only PostgreSQLv2 configuration.
config/databasemysql/config.go Retains only MySQLv2 configuration.
internal/clients/linode.go Migrates response metrics to net/http.
internal/controller/zz_setup.go Stops registering legacy database controllers.
internal/controller/database/mysql/zz_controller.go Removes legacy MySQL controller.
internal/controller/database/postgresql/zz_controller.go Removes legacy PostgreSQL controller.
internal/controller/accountsettings/accountsettings/zz_controller.go Adds generated change logging support.
internal/controller/database/accesscontrols/zz_controller.go Adds generated change logging support.
internal/controller/database/mysqlv2/zz_controller.go Adds generated change logging support.
internal/controller/database/postgresqlv2/zz_controller.go Adds generated change logging support.
internal/controller/domain/domain/zz_controller.go Adds generated change logging support.
internal/controller/domain/record/zz_controller.go Adds generated change logging support.
internal/controller/firewall/device/zz_controller.go Adds generated change logging support.
internal/controller/firewall/firewall/zz_controller.go Adds generated change logging support.
internal/controller/image/image/zz_controller.go Adds generated change logging support.
internal/controller/instance/config/zz_controller.go Adds generated change logging support.
internal/controller/instance/disk/zz_controller.go Adds generated change logging support.
internal/controller/instance/instance/zz_controller.go Adds generated change logging support.
internal/controller/instance/ip/zz_controller.go Adds generated change logging support.
internal/controller/instance/sharedips/zz_controller.go Adds generated change logging support.
internal/controller/ipv6/ipv6range/zz_controller.go Adds generated change logging support.
internal/controller/lke/cluster/zz_controller.go Adds generated change logging support.
internal/controller/lke/nodepool/zz_controller.go Adds generated change logging support.
internal/controller/networking/ip/zz_controller.go Adds generated change logging support.
internal/controller/nodebalancer/config/zz_controller.go Adds generated change logging support.
internal/controller/nodebalancer/node/zz_controller.go Adds generated change logging support.
internal/controller/nodebalancer/nodebalancer/zz_controller.go Adds generated change logging support.
internal/controller/objectstorage/bucket/zz_controller.go Adds generated change logging support.
internal/controller/objectstorage/key/zz_controller.go Adds generated change logging support.
internal/controller/objectstorage/object/zz_controller.go Adds generated change logging support.
internal/controller/placementgroup/placementgroup/zz_controller.go Adds generated change logging support.
internal/controller/placementgroupassignment/placementgroupassignment/zz_controller.go Adds generated change logging support.
internal/controller/rdns/rdns/zz_controller.go Adds generated change logging support.
internal/controller/reserved/ipassignment/zz_controller.go Adds generated change logging support.
internal/controller/sshkey/sshkey/zz_controller.go Adds generated change logging support.
internal/controller/stackscript/stackscript/zz_controller.go Adds generated change logging support.
internal/controller/token/token/zz_controller.go Adds generated change logging support.
internal/controller/user/user/zz_controller.go Adds generated change logging support.
internal/controller/volume/volume/zz_controller.go Adds generated change logging support.
internal/controller/vpc/subnet/zz_controller.go Adds generated change logging support.
internal/controller/vpc/vpc/zz_controller.go Adds generated change logging support.
apis/accountsettings/v1alpha1/zz_accountsettings_types.go Updates account settings fields.
apis/accountsettings/v1alpha1/zz_generated.deepcopy.go Regenerates account settings copies.
apis/database/v1alpha1/zz_mysql_terraformed.go Removes legacy MySQL integration.
apis/database/v1alpha1/zz_postgresql_terraformed.go Removes legacy PostgreSQL integration.
apis/database/v1alpha1/zz_generated.conversion_hubs.go Removes legacy conversion hubs.
apis/database/v1alpha1/zz_generated.managed.go Removes legacy managed methods.
apis/database/v1alpha1/zz_generated.managedlist.go Removes legacy managed lists.
apis/domain/v1alpha1/zz_domain_types.go Removes deprecated domain group.
apis/domain/v1alpha1/zz_generated.deepcopy.go Regenerates domain copies.
apis/firewall/v1alpha1/zz_firewall_types.go Adds interface and status fields.
apis/firewall/v1alpha1/zz_generated.deepcopy.go Regenerates firewall copies.
apis/image/v1alpha1/zz_image_types.go Adds image-sharing observations.
apis/image/v1alpha1/zz_generated.deepcopy.go Regenerates image copies.
apis/instance/v1alpha1/zz_disk_types.go Updates disk schema documentation.
apis/lke/v1alpha1/zz_nodepool_types.go Adds node-pool fields.
apis/networking/v1alpha1/zz_ip_types.go Reconstructs IP object fields.
apis/networking/v1alpha1/zz_generated.deepcopy.go Regenerates networking copies.
apis/nodebalancer/v1alpha1/zz_config_types.go Adds UDP configuration fields.
apis/nodebalancer/v1alpha1/zz_node_types.go Adds VPC node fields.
apis/objectstorage/v1alpha1/zz_bucket_types.go Removes cluster and requires region.
apis/objectstorage/v1alpha1/zz_key_types.go Removes bucket-access cluster.
apis/objectstorage/v1alpha1/zz_object_types.go Removes cluster and requires region.
apis/objectstorage/v1alpha1/zz_generated.deepcopy.go Regenerates object-storage copies.
apis/reserved/v1alpha1/zz_ipassignment_types.go Adds reconstructed assignment observations.
apis/reserved/v1alpha1/zz_generated.deepcopy.go Regenerates assignment copies.
apis/user/v1alpha1/zz_user_types.go Removes deprecated placement grants.
apis/user/v1alpha1/zz_generated.deepcopy.go Regenerates user copies.
apis/volume/v1alpha1/zz_volume_types.go Adds volume readiness observation.
apis/volume/v1alpha1/zz_generated.deepcopy.go Regenerates volume copies.
apis/vpc/v1alpha1/zz_subnet_types.go Adds IPv6 and attachment observations.
apis/vpc/v1alpha1/zz_vpc_types.go Adds IPv4/IPv6 and VPC type fields.
examples-generated/accountsettings/v1alpha1/accountsettings.yaml Removes computed-only setting input.
examples-generated/database/v1alpha1/accesscontrols.yaml Migrates example to MySQLv2.
examples-generated/database/v1alpha1/mysql.yaml Removes legacy MySQL example.
examples-generated/database/v1alpha1/postgresql.yaml Removes legacy PostgreSQL example.
examples-generated/instance/v1alpha1/ip.yaml Updates example image.
examples-generated/ipv6/v1alpha1/ipv6range.yaml Updates example image.
examples-generated/lke/v1alpha1/cluster.yaml Updates Kubernetes version.
examples-generated/nodebalancer/v1alpha1/config.yaml Demonstrates UDP check port.
examples-generated/nodebalancer/v1alpha1/nodebalancer.yaml Demonstrates UDP throttling.
examples-generated/rdns/v1alpha1/rdns.yaml Updates example image.
examples-generated/reserved/v1alpha1/ipassignment.yaml Adds reserved-IP assignment example.
package/crds/accountsettings.linode.upbound.io_accountsettings.yaml Regenerates account settings CRD.
package/crds/database.linode.upbound.io_accesscontrols.yaml Regenerates access-control CRD.
package/crds/domain.linode.upbound.io_domains.yaml Removes deprecated domain group.
package/crds/domain.linode.upbound.io_records.yaml Regenerates record CRD.
package/crds/firewall.linode.upbound.io_devices.yaml Regenerates firewall-device CRD.
package/crds/firewall.linode.upbound.io_firewalls.yaml Adds firewall fields.
package/crds/image.linode.upbound.io_images.yaml Adds image-sharing status.
package/crds/instance.linode.upbound.io_disks.yaml Updates disk schema.
package/crds/instance.linode.upbound.io_ips.yaml Regenerates instance-IP CRD.
package/crds/instance.linode.upbound.io_sharedips.yaml Regenerates shared-IP CRD.
package/crds/ipv6.linode.upbound.io_ipv6ranges.yaml Regenerates IPv6-range CRD.
package/crds/linode.upbound.io_providerconfigs.yaml Updates generator metadata.
package/crds/linode.upbound.io_providerconfigusages.yaml Updates generator metadata.
package/crds/linode.upbound.io_storeconfigs.yaml Updates generator metadata.
package/crds/lke.linode.upbound.io_nodepools.yaml Adds node-pool fields.
package/crds/networking.linode.upbound.io_ips.yaml Reconstructs IP object schemas.
package/crds/nodebalancer.linode.upbound.io_configs.yaml Adds UDP fields.
package/crds/nodebalancer.linode.upbound.io_nodes.yaml Adds VPC node fields.
package/crds/objectstorage.linode.upbound.io_buckets.yaml Removes cluster and requires region.
package/crds/objectstorage.linode.upbound.io_keys.yaml Removes bucket-access cluster.
package/crds/objectstorage.linode.upbound.io_objects.yaml Removes cluster and requires region.
package/crds/placementgroup.linode.upbound.io_placementgroups.yaml Updates generator metadata.
package/crds/placementgroupassignment.linode.upbound.io_placementgroupassignments.yaml Updates generator metadata.
package/crds/rdns.linode.upbound.io_rdns.yaml Updates generator metadata.
package/crds/reserved.linode.upbound.io_ipassignments.yaml Adds assignment observations.
package/crds/sshkey.linode.upbound.io_sshkeys.yaml Updates generator metadata.
package/crds/stackscript.linode.upbound.io_stackscripts.yaml Updates generator metadata.
package/crds/token.linode.upbound.io_tokens.yaml Updates generator metadata.
package/crds/user.linode.upbound.io_users.yaml Removes deprecated placement grants.
package/crds/volume.linode.upbound.io_volumes.yaml Adds volume readiness status.
package/crds/vpc.linode.upbound.io_subnets.yaml Adds IPv6 and attachment fields.
package/crds/vpc.linode.upbound.io_vpcs.yaml Adds IP configuration and VPC type.
Files not reviewed (20)
  • apis/accountsettings/v1alpha1/zz_accountsettings_types.go: Generated file
  • apis/accountsettings/v1alpha1/zz_generated.deepcopy.go: Generated file
  • apis/database/v1alpha1/zz_generated.conversion_hubs.go: Generated file
  • apis/database/v1alpha1/zz_generated.deepcopy.go: Generated file
  • apis/database/v1alpha1/zz_generated.managed.go: Generated file
  • apis/database/v1alpha1/zz_generated.managedlist.go: Generated file
  • apis/database/v1alpha1/zz_mysqlv2_types.go: Generated file
  • apis/database/v1alpha1/zz_postgresqlv2_types.go: Generated file
  • apis/domain/v1alpha1/zz_domain_types.go: Generated file
  • apis/domain/v1alpha1/zz_generated.deepcopy.go: Generated file
  • apis/firewall/v1alpha1/zz_firewall_types.go: Generated file
  • apis/firewall/v1alpha1/zz_generated.deepcopy.go: Generated file
  • apis/image/v1alpha1/zz_generated.deepcopy.go: Generated file
  • apis/image/v1alpha1/zz_image_types.go: Generated file
  • apis/instance/v1alpha1/zz_disk_types.go: Generated file
  • apis/lke/v1alpha1/zz_cluster_types.go: Generated file
  • apis/lke/v1alpha1/zz_generated.deepcopy.go: Generated file
  • apis/lke/v1alpha1/zz_nodepool_types.go: Generated file
  • apis/networking/v1alpha1/zz_generated.deepcopy.go: Generated file
  • apis/networking/v1alpha1/zz_ip_types.go: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +18 to +19
// An existing IPv6 prefix owned by the current account or a forward slash (/) followed by a valid prefix length. If unspecified, a range with the default prefix will be allocated for this VPC.
// The IPv4 range assigned to this VPC.
Comment thread docs/developer.md
Comment on lines +13 to +16
The code generator shells out to `goimports`, which is not vendored, so it has
to be on your `PATH`:
```console
go install golang.org/x/tools/cmd/goimports@latest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants