Skip to content

feat: add getImportIDFn#677

Open
fernandezcuesta wants to merge 1 commit into
crossplane:mainfrom
fernandezcuesta:676--add-optionalk-getimportidfn
Open

feat: add getImportIDFn#677
fernandezcuesta wants to merge 1 commit into
crossplane:mainfrom
fernandezcuesta:676--add-optionalk-getimportidfn

Conversation

@fernandezcuesta

@fernandezcuesta fernandezcuesta commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Description of your changes

Some Terraform providers store resource IDs in a different format than what their import function expects. Until now, upjet used a single function (GetIDFn) to produce the ID for both purposes, making it impossible to support these providers correctly.

This PR introduces an optional GetImportIDFn field to ExternalName. When set, upjet uses it to produce the ID passed to terraform import, while continuing to use GetIDFn for the state file used by terraform refresh. When unset, the existing behavior is preserved.

Fixes #676

I have:

  • Read and followed Upjet's contribution process.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR if necessary.

How has this code been tested

Built provider-mongodbatlas 1.2.0-rc.1 on top of these changes, now I can set a custom function for GetImportIDFn for those resources where the upstream TF provider works as explained above.

Signed-off-by: Jesús Fernández <7312236+fernandezcuesta@users.noreply.github.com>
@fernandezcuesta fernandezcuesta marked this pull request as draft June 16, 2026 17:17
@fernandezcuesta fernandezcuesta marked this pull request as ready for review June 16, 2026 17:20
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an optional GetImportIDFn field to the ExternalName struct, then updates WorkspaceStore.Workspace to compute tfStateID via GetIDFn, call EnsureTFState with that value, and—when GetImportIDFn is set—override w.terraformID with the import-specific ID format.

Changes

Separate Terraform Import ID from State ID

Layer / File(s) Summary
ExternalName contract and Workspace wiring
pkg/config/resource.go, pkg/terraform/store.go
GetImportIDFn GetIDFn is added to ExternalName with docs noting nil falls back to GetIDFn. In Workspace, tfStateID is derived via GetIDFn and passed to EnsureTFState; w.terraformID is set to tfStateID but optionally overwritten by GetImportIDFn when configured.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues


Thanks for this contribution! A couple of clarifying questions to help understand the design decisions:

  • When GetImportIDFn returns an error in store.go, the error is wrapped with errGetID — is that intentional, or should there be a distinct sentinel (e.g., errGetImportID) to make it easier to distinguish which function failed during debugging?
  • Could you share a concrete example of a provider where terraform import and terraform state require different ID formats? That context would help reviewers understand why the two IDs need to diverge, and whether any edge cases (e.g., both functions returning the same ID) need to be guarded against.
🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add getImportIDFn' is descriptive and directly related to the main changeset, which adds a new GetImportIDFn field to control Terraform import ID formatting.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Configuration Api Breaking Changes ✅ Passed PR adds optional GetImportIDFn field to ExternalName struct—backward compatible. No exported types/functions removed, renamed, or required parameters added. No breaking changes detected.
Generated Code Manual Edits ✅ Passed The file apis/configuration/v1alpha1/zz_generated.deepcopy.go was added, not manually edited. It's auto-generated by controller-gen when source files with +kubebuilder:object:generate=true tags are...
Template Breaking Changes ✅ Passed The PR adds NEW library implementation files in pkg/controller/ (external*.go) that provide base Connector types used by generated controllers. These are not template files—actual templates are in...
Description check ✅ Passed The PR description clearly explains the changes: introducing an optional GetImportIDFn field to support providers with different ID formats for import vs state storage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
pkg/terraform/store.go (1)

260-278: 💤 Low value

Thanks for implementing this separation cleanly!

The logic correctly ensures that:

  1. tfStateID (from GetIDFn) is used for EnsureTFState — maintaining state consistency
  2. w.terraformID can be overridden via GetImportIDFn — enabling different import formats

This aligns well with the downstream usage in workspace.go where w.terraformID is explicitly noted as the import ID.

One small suggestion for debugging ergonomics: both error paths (lines 263 and 274) wrap with the same errGetID message. If a provider developer hits an error, it might be tricky to know which function failed. Would you consider differentiating them? For example:

💡 Optional: Differentiate error messages
 tfStateID, err := fp.Config.ExternalName.GetIDFn(ctx, externalName, fp.parameters, fp.Setup.Map())
 if err != nil {
-    return nil, errors.Wrap(err, errGetID)
+    return nil, errors.Wrap(err, "cannot get state ID")
 }

 // ...
 if fp.Config.ExternalName.GetImportIDFn != nil {
     w.terraformID, err = fp.Config.ExternalName.GetImportIDFn(ctx, externalName, fp.parameters, fp.Setup.Map())
     if err != nil {
-        return nil, errors.Wrap(err, errGetID)
+        return nil, errors.Wrap(err, "cannot get import ID")
     }
 }

This is purely optional — the current approach is consistent with the existing pattern. What do you think?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/terraform/store.go` around lines 260 - 278, The error handling for
GetIDFn and GetImportIDFn both wrap errors with the same errGetID message,
making it difficult to distinguish which function failed during debugging. In
the error wrapping calls after GetIDFn (line 263) and GetImportIDFn (line 274),
use differentiated error messages for each path. For example, keep errGetID for
the GetIDFn error and create or use a separate error constant (such as
errGetImportID) for the GetImportIDFn error path to help provider developers
quickly identify which function failed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/terraform/store.go`:
- Around line 260-278: The error handling for GetIDFn and GetImportIDFn both
wrap errors with the same errGetID message, making it difficult to distinguish
which function failed during debugging. In the error wrapping calls after
GetIDFn (line 263) and GetImportIDFn (line 274), use differentiated error
messages for each path. For example, keep errGetID for the GetIDFn error and
create or use a separate error constant (such as errGetImportID) for the
GetImportIDFn error path to help provider developers quickly identify which
function failed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 52f2ccf6-f4ec-437e-bae2-415036e32894

📥 Commits

Reviewing files that changed from the base of the PR and between 59c4552 and b2a38c0.

📒 Files selected for processing (2)
  • pkg/config/resource.go
  • pkg/terraform/store.go

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.

Add optional GetImportIDFn to ExternalName for providers where import ID differs from state ID

1 participant