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

Remove default token volume and volume_mount from Pod state #1096

Merged
merged 7 commits into from
Dec 21, 2020

Conversation

dak1n1
Copy link
Contributor

@dak1n1 dak1n1 commented Dec 15, 2020

Fixes #1085

Acceptance tests

  • Have you added an acceptance test for the functionality being added?
  • Have you run the acceptance tests on this branch?

Output from acceptance testing:

Release Note

Release note for CHANGELOG:

Ensure default service account token is not saved in Pod state.

References

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

@ghost ghost added the size/XS label Dec 15, 2020
if nameMatchesDefaultToken && volume.Secret != nil {
for _, secretVolume := range volume.Secret.Items {
if secretVolume.Path == "/var/run/secrets/kubernetes.io/serviceaccount" {
removeVolume(i, in.Volumes)
Copy link
Collaborator

@jrhouston jrhouston Dec 16, 2020

Choose a reason for hiding this comment

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

The reason this isn't working is because your removeVolume func returns a new slice, so you need to assign that new slice to in.Volumes.

// we need to remove it prior to recording the state.
if in.AutomountServiceAccountToken != nil && *in.AutomountServiceAccountToken == true {
for i, volume := range in.Volumes {
nameMatchesDefaultToken, err := regexp.MatchString("default-token-([a-z0-9]{5})", volume.Name)
Copy link
Collaborator

@jrhouston jrhouston Dec 16, 2020

Choose a reason for hiding this comment

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

What I would do is put this logic here in the loop that expands the volumes and use a continue statement to skip it, rather than removing it here.

edit: we'll have to change that code to use append rather than creating a fixed size array

@ghost ghost added size/S and removed size/XS labels Dec 16, 2020
@dak1n1
Copy link
Contributor Author

dak1n1 commented Dec 16, 2020

Hmm, well this does look neater. And it successfully skips adding both the volume and volumeMount to state... well, almost. It adds them as empty blocks if I put the logic into flattenVolumes() and flattenContainerVolumeMounts(), rather than in flattenPodSpec() . ("Empty blocks" meaning: volume{} and volume_mount{}). Here is the state for context:

https://gist.githubusercontent.com/dak1n1/3ec5fc36cb9c4ab16d7d5ed8c159009c/raw/bc670e3486d17d5eb7eafe8016ebb1e63d09d06f/gistfile1.txt

However, if I remove these at the PodSpec level, it omits the blocks entirely, which prevents the diff. I'm going to explore that route next.

@dak1n1
Copy link
Contributor Author

dak1n1 commented Dec 16, 2020

Got it working! Pods are no longer destroyed on each apply.

[dakini@dax pod_with_volume]$ terraform show 
[...]
            volume_mount {
                mount_path        = "/etc/test"
                mount_propagation = "None"
                name              = "pvc"
                read_only         = false
            }
        }

        volume {
            name = "pvc"

            persistent_volume_claim {
                claim_name = "test"
                read_only  = false
            }
        }
    }
}
[dakini@dax pod_with_volume]$ terraform plan
kubernetes_persistent_volume_claim.test: Refreshing state... [id=default/test]
kubernetes_pod.main: Refreshing state... [id=default/test]

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

@dak1n1 dak1n1 marked this pull request as ready for review December 16, 2020 21:19
@dak1n1 dak1n1 requested a review from jrhouston December 16, 2020 21:19
@@ -107,6 +108,17 @@ func flattenPodSpec(in v1.PodSpec) ([]interface{}, error) {
}

if len(in.Volumes) > 0 {
for i, volume := range in.Volumes {
// To avoid perpetual diff, remove the default service account token volume from PodSpec.
nameMatchesDefaultToken, err := regexp.MatchString("default-token-([a-z0-9]{5})", volume.Name)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, I just realized we are going to have to be a bit more clever than this.

When the token get's auto-mounted it takes the name from the service account, so only if they don't supply a service account will it be called default, otherwise it will be the name of the service account. You can see how it does this in the admission controller code for it: kubernetes/blob/master/plugin/pkg/admission/serviceaccount/admission.go#L46

So we'll have to actually pass down the serviceAccount name and make the regex match that. 😢

We could just match on -token- but that creates a surprising edge case for someone to discover.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh, nice! That is really helpful. I hadn't thought to test with a service account specified. I'll put in a test to catch these cases and make it clever enough to handle them. Thanks!

@dak1n1
Copy link
Contributor Author

dak1n1 commented Dec 17, 2020

It works now. I'll put the test into PR #1074, since that contains the test for bug #1085

@dak1n1 dak1n1 requested a review from jrhouston December 17, 2020 20:27
Copy link
Collaborator

@jrhouston jrhouston left a comment

Choose a reason for hiding this comment

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

Looks good just a couple of nits.

kubernetes/structures_pod.go Show resolved Hide resolved
kubernetes/structures_container.go Show resolved Hide resolved
Copy link
Collaborator

@jrhouston jrhouston left a comment

Choose a reason for hiding this comment

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

🚀

@dak1n1 dak1n1 merged commit 695f78a into hashicorp:master Dec 21, 2020
@ghost
Copy link

ghost commented Jan 21, 2021

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

@ghost ghost locked as resolved and limited conversation to collaborators Jan 21, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pod with volume is recreated on each apply
2 participants