Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: DiffConfig fails when provider's kubeconfig is set to file path #2771

Merged
merged 5 commits into from
Jan 27, 2024

Conversation

EronWright
Copy link
Contributor

@EronWright EronWright commented Jan 26, 2024

Proposed changes

This PR refactors the kubeconfig loading code to be more consistent between DiffConfig and Configure. Previously the DiffConfig method did not support file-based kubeconfigs, and would throw a spurious parser error.

DiffConfig loads the kubeconfig to be able to detect cluster replacement, by comparing the active cluster info. Unlike Configure, it doesn't have support for ambient kubeconfigs. When an ambient config is in use, or the config is invalid (e.g. the context or cluster properties refer to a non-existent entry), then the replacement logic is skipped.

This PR also fixes a panic in DiffConfig that would occur if cluster or context is a computed value; the provider will conservatively suggest replacement as it does when kubeconfig is a computed value.

Testing

New test cases were added for cluster change detection.

New tests were added for the parsing code that was consolidated into utils.go. The tests now cover file-, string-, and object-based resource property values for kubeconfig.

Related issues (optional)

Closes: #2663
Related: #1032

@EronWright EronWright changed the title Refactor kubeconfig parsing Fix: DiffConfig fails when provider's kubeconfig is set to file path Jan 26, 2024
Base automatically changed from eronwright/issue-2767 to master January 26, 2024 18:58
@EronWright EronWright marked this pull request as ready for review January 26, 2024 19:49
Copy link

Does the PR have any schema changes?

Looking good! No breaking changes found.
No new resources/functions.

Copy link

codecov bot commented Jan 26, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (df718a6) 23.12% compared to head (822cc73) 23.41%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2771      +/-   ##
==========================================
+ Coverage   23.12%   23.41%   +0.28%     
==========================================
  Files          48       48              
  Lines        9620     9629       +9     
==========================================
+ Hits         2225     2255      +30     
+ Misses       7240     7224      -16     
+ Partials      155      150       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Comment on lines +424 to +434
oldActiveCluster, oldFound := getActiveClusterFromConfig(oldConfig, olds)
activeCluster, found := getActiveClusterFromConfig(newConfig, news)
if !oldFound || !found {
// The config is either ambient or invalid, so we can't draw any conclusions.
} else if !reflect.DeepEqual(oldActiveCluster, activeCluster) {
// one of these properties must have changed for the active cluster to change.
for _, key := range []string{"kubeconfig", "context", "cluster"} {
if slices.Contains(diffs, key) {
replaces = append(replaces, key)
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change makes the replacement logic be slightly less conservative, because it now won't suggest a replacement when the old or new cluster info couldn't be resolved, e.g. when the config is ambient or the context doesn't match anything. Given that this PR fixes a problem in parseKubeconfigPropertyValue, we're more likely to reach this logic than in the past.

For example, imagine that olds["kubeconfig"] was empty and news["kubeconfig"] had the value ~/.kube/config. They're actually the same configuration, but oldFound would be false and found would be true. The provider should not do replacement in that case. Prior to this PR, DiffConfig would have returned an error before reaching this block, which the engine would have ignored and not triggered replacement.

Rather than blindly using the diffs as the replaces, it makes more sense to pick out the specific field that is causing replacement. Imagine that the diffs also included a change to an unrelated property such as suppressDeprecationWarnings.

Comment on lines +377 to +385
// and force a replacement. Note that getActiveClusterFromConfig relies on all three of the below properties.
for _, key := range []resource.PropertyKey{"kubeconfig", "context", "cluster"} {
if news[key].IsComputed() {
return &pulumirpc.DiffResponse{
Changes: pulumirpc.DiffResponse_DIFF_SOME,
Diffs: []string{string(key)},
Replaces: []string{string(key)},
}, nil
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This fix is to avoid a panic that otherwise occurs in getActiveClusterFromConfig if either context or cluster has a computed value. I think it is safe to be more conservative during preview since it is not determinative as to whether a resource would actually be replaced.

} else {
return nil, fmt.Errorf("unexpected kubeconfig format, type: %v", kubeconfig.TypeString())
}
config, err := clientcmd.Load(cfg)
config, err := parseKubeconfigString(cfg)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change is the essential one that teaches DiffConfig to support a file-based kubeconfig property, by reusing the logic of Configure.

@EronWright EronWright merged commit 3c6513e into master Jan 27, 2024
20 checks passed
@EronWright EronWright deleted the eronwright/issue-2663 branch January 27, 2024 03:29
lumiere-bot bot added a commit to coolguy1771/home-ops that referenced this pull request Feb 24, 2024
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@pulumi/kubernetes](https://pulumi.com)
([source](https://togithub.com/pulumi/pulumi-kubernetes)) | dependencies
| minor | [`4.7.1` ->
`4.8.0`](https://renovatebot.com/diffs/npm/@pulumi%2fkubernetes/4.7.1/4.8.0)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

### Release Notes

<details>
<summary>pulumi/pulumi-kubernetes (@&#8203;pulumi/kubernetes)</summary>

###
[`v4.8.0`](https://togithub.com/pulumi/pulumi-kubernetes/blob/HEAD/CHANGELOG.md#480-February-22-2024)

[Compare
Source](https://togithub.com/pulumi/pulumi-kubernetes/compare/v4.7.1...v4.8.0)

- Fix DiffConfig issue when when provider's kubeconfig is set to file
path
([pulumi/pulumi-kubernetes#2771)
- Fix for replacement having incorrect status messages
([pulumi/pulumi-kubernetes#2810)
- Use output properties for await logic
([pulumi/pulumi-kubernetes#2790)
- Support for metadata.generateName (CSA)
([pulumi/pulumi-kubernetes#2808)
- Fix unmarshalling of Helm values yaml file
([pulumi/pulumi-kubernetes#2815)
- Handle unknowns in Helm Release resource
([pulumi/pulumi-kubernetes#2822)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://togithub.com/renovatebot/renovate).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yMTAuMCIsInVwZGF0ZWRJblZlciI6IjM3LjIxMC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

Co-authored-by: lumiere-bot[bot] <98047013+lumiere-bot[bot]@users.noreply.github.com>
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.

DiffConfig fails when provider's kubeconfig is set to file path
2 participants