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

Allow dynamic KC config updates #591

Merged
merged 12 commits into from
Apr 15, 2022
Merged

Allow dynamic KC config updates #591

merged 12 commits into from
Apr 15, 2022

Conversation

neil-hickey
Copy link
Contributor

@neil-hickey neil-hickey commented Mar 28, 2022

What this PR does / why we need it:

Which issue(s) this PR fixes:

Fixes #179

Does this PR introduce a user-facing change?


Additional Notes for your reviewer:

See this comment for some concerns and questions before I implemented this feature

  • I had a really hard time trying to test this. The reconciler is fairly dumb, so that felt unnecessary. And the config change I wanted an e2e test, but kubectl exec was failing from the test suite - always with errors like

Running 'kubectl exec -n kapp-controller deployment/kapp-controller -- bash -c ls'... OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "bash -c ls": executable file not found in $PATH: unknown

Review Checklist:
  • Follows the developer guidelines
  • Relevant tests are added or updated
  • Relevant docs in this repo added or updated
  • Relevant carvel.dev docs added or updated in a separate PR and there's
    a link to that PR
  • Code is at least as readable and maintainable as it was before this
    change

Additional documentation e.g., Proposal, usage docs, etc.:


@neil-hickey
Copy link
Contributor Author

neil-hickey commented Mar 28, 2022

Implementation Notes:

What happens if I update my ca bundle whilst KC is running?

  • I added the PEM for https://self-signed.badssl.com/ to the caCerts field of our KC configmap. Verified I got an error with curl https://self-signed.badssl.com/ before updating the configmap and then after updating I ran curl https://self-signed.badssl.com/ again whilst kubectl exec'd on the container and it worked.

But what about KC process? Does it pick up the change?

It does not. I added in a http.Get("https://self-signed.badssl.com/ " into one of the controllers. After applying the secret and updating the config - the curl still fails with a bad cert error. Upon running kubectl rollout restart deployment/kapp-controller -n kapp-controller that http.Get() no longer fails. So any http calls within KC will not get the new certs dynamically until the next restart. This feels like a niche case though, as KC is mostly just a fancy exec() for the fetch / template / deploy tools.

NOTE: If we do ever move to using the go library version of these tools instead of invoking binaries, we will likely need to revisit this implementation

What about GoRoutine race conditions whilst os.Setenv'ing?

I validated that the os.Setenv func and os.Getenv are guarded by a r/w lock in golang. So only one goroutine can access it at once. I also printed out the environment variables in each controller to validate that they were picking up the new values dynamically.

Is os.Getenv() global / shared amongst go routines?

Yep - checkout my playground example https://go.dev/play/p/mJoS_uwD6yC

Do we need to have a lock around the /etc/pki/tls/certs/ca-bundle.crt file?

Probably not. Again golang has a lock around the write function. So we should be good here also (given we are not expecting any other process to update the system file.) - which is the assumption the previous code here held

@neil-hickey neil-hickey force-pushed the nh-dynamic-kc-config branch 2 times, most recently from 6e88fb4 to 72faf4f Compare March 28, 2022 23:46
@neil-hickey neil-hickey changed the title Nh dynamic kc config Allow dynamic KC config updates Mar 28, 2022
@neil-hickey
Copy link
Contributor Author

Hmm, I need to give some more thought on our append to /etc/pki/tls/certs/ca-bundle.crt approach. As every update of the config appends the certs to that file. So we get lots of duplication.

@neil-hickey neil-hickey marked this pull request as ready for review April 5, 2022 23:57
Dockerfile Show resolved Hide resolved
@cppforlife cppforlife closed this Apr 6, 2022
@cppforlife cppforlife reopened this Apr 6, 2022
@benmoss
Copy link
Contributor

benmoss commented Apr 7, 2022

This seems like a bug:

I think it's because we noop if we don't find a ConfigMap or Secret, when instead we need to somehow revert to defaults

@neil-hickey
Copy link
Contributor Author

neil-hickey commented Apr 7, 2022

This seems like a bug:

* Create a config (I just copy/pasted the one from https://carvel.dev/kapp-controller/docs/v0.34.0/controller-config/#controller-configuration-spec)

* See that it gets applied

* Delete that secret

* Configuration doesn't change back

I think it's because we noop if we don't find a ConfigMap or Secret, when instead we need to somehow revert to defaults

Good point @benmoss ! I updated the code a bit to accommodate that case. Basically always apply the config (even if there doesn't exist one) -- therefore just set the default (empty string) values.

@benmoss
Copy link
Contributor

benmoss commented Apr 7, 2022

Nice, I was confused by that populated bool anyway, not needing it makes the code easier to understand

pkg/config/config.go Outdated Show resolved Hide resolved
cmd/controller/run.go Outdated Show resolved Hide resolved
pkg/config/config.go Outdated Show resolved Hide resolved
pkg/config/config.go Outdated Show resolved Hide resolved
pkg/config/config.go Outdated Show resolved Hide resolved
pkg/config/reconciler.go Show resolved Hide resolved
pkg/config/reconciler.go Outdated Show resolved Hide resolved
pkg/config/config.go Show resolved Hide resolved
pkg/config/config.go Show resolved Hide resolved
cmd/controller/run.go Outdated Show resolved Hide resolved
pkg/config/reconciler.go Outdated Show resolved Hide resolved
pkg/config/reconciler.go Outdated Show resolved Hide resolved
pkg/config/config.go Outdated Show resolved Hide resolved
@neil-hickey neil-hickey force-pushed the nh-dynamic-kc-config branch 2 times, most recently from bbe1ac9 to a6f11af Compare April 12, 2022 18:59
Dockerfile Show resolved Hide resolved
- Dynamically update config based on secret or configmap updates for KC

Signed-off-by: Neil Hickey <nhickey@vmware.com>
Signed-off-by: Neil Hickey <nhickey@vmware.com>
- We don't need to check if the secret or config exists anymore - we
  just always set the values (even if empty)
- This allows us to restore the values to defaults when the config is
  deleted

Signed-off-by: Neil Hickey <nhickey@vmware.com>
- Allows test to skip the os.File() calls in addTrustedCerts()

Signed-off-by: Neil Hickey <nhickey@vmware.com>
- This allows testing of each use case (create, update, delete)
- Added a stub for the other tests to mock the os.File() calls with temp
  files

Signed-off-by: Neil Hickey <nhickey@vmware.com>
- explicitly unset environment variables on empty values provided
- error check on close() files

Signed-off-by: Neil Hickey <nhickey@vmware.com>
Signed-off-by: Neil Hickey <nhickey@vmware.com>
Signed-off-by: Neil Hickey <nhickey@vmware.com>
- As rename is an atomic operation, this should prevent any read/write
  issues from other programs (think ytt, imgpkg, git) from reading the
  ca-bundle file whilst something is writing to it

Signed-off-by: Neil Hickey <nhickey@vmware.com>
- Turns out returning an error forces the reconciler to requeue and this
  is not what we want
- Use tempDir() for instead of hardcoding
- Remove tempfile after use

Signed-off-by: Neil Hickey <nhickey@vmware.com>
- This is required for an os.Rename()
- Pass the ns into the attachwatches() using KAPPCTRL_SYSTEM_NAMESPACE

Signed-off-by: Neil Hickey <nhickey@vmware.com>
Signed-off-by: Neil Hickey <nhickey@vmware.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Watch kapp-controller-config configmap and apply updated config
5 participants