-
Notifications
You must be signed in to change notification settings - Fork 1.2k
⚠️ Envtest refactor, support for 1.20+ API servers (secure serving) #1486
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
⚠️ Envtest refactor, support for 1.20+ API servers (secure serving) #1486
Conversation
/assign @alvaroaleman |
94acd08
to
0abb95a
Compare
One thing i've noticed - control plane wont start again after stop because temp directory with certificates was removed during stop procedure and didn't create again. Throws panic like this:
I was solve it with crutch like this: https://github.com/kubernetes-sigs/controller-runtime/pull/1477/files#diff-c6321f65a2defa4f1d2a0810e6262d27a4a7e55c75db83330bf396a3148bc72aR109. Probably, it might be worked around more elegant way. Also, suggest to get back such test, which seemd to be removed here: https://github.com/kubernetes-sigs/controller-runtime/pull/1486/files#diff-c4ae583bca86061bdfa2f60d76bdf50eba0f945fd1f3b56bea8edcb4e268ee0cL147 ( pkg/internal/testing/integration/internal/integration_tests/integration_test.go Line 147) :) |
Good catch on the restart issue. I'll take a look. There's some weird interplay between "I want a manually specified certdir" & "I want to be able to restart and get a new temp dir". |
Actually, I think the extent of this should probably be discussed. It's not clear to me that this is a use case we can safely support while keeping our existing semantics -- if we clean up the work dir, we invalidate all existing users that have been provisioned under most auth strategies. We can just recreate the work dir, but it's not clear to me that that's not gonna be surprising. I'll put the functionality to do that back in for now, but I think we probably want to deprecate that bit of functionality and just say "if you want a new control plane instance, ask for one". I wonder what the use case here is? |
Ok, I've fixed the "can't re-start a ControlPlane" issue and added a basic test. |
cbc2eb8
to
f2e2c75
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, looking forward to using it :)
Left you a few comments inline, will give this a test spin later this week with the envtest suites in our project.
} | ||
} else if insec := s.InsecureServing; insec != nil { | ||
if insec.Port == "" || insec.Address == "" { | ||
port, host, err := addr.Suggest("") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we pass InsecureServing.Address
down to addr.Suggest
?
port, host, err := addr.Suggest("") | |
if insec.Port == "" { | |
port, host, err := addr.Suggest(insec.Address) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was mostly intending on porting the suggestion logic as-is from what it is currently to avoid breaking things -- the old code never passed anything to addr.Suggest
AFAICT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, also checked how it was done before. This was just a suggestion on top, nothing critical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I gave this a test spin now in our envtest suites and found a few issues, you might wanna address (mainly to make it more backwards-compatible and easier to upgrade to for users).
Also noticed some nits along the way.
Apart from the mentioned issues, everything worked pretty well! :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initial, somewhat cursory pass. This change is simply too big for me to be able to properly review it 🙃
pkg/manager/manager_suite_test.go
Outdated
// so we grab the transport right after it gets created so that we can | ||
// type-assert on it (hopefully)? | ||
// hopefully this doesn't break 🤞 | ||
clientTransport = rt.(*http.Transport) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about intead of asserting here just changing var clientTransport *http.Transport
to http.RoundTripper
and doing the type assertion when we close the keep-alives? That would make this easier to debug if something fails (right now we'd just get a NPD, right?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
meh, then we have more type assertions, though :-/
I can def put a better panic message in though, which should help there.
}) | ||
}) | ||
|
||
It("should produce unique serials among all generated certificates of all types", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, does this have any practical relevance? I know the RFC requires it, but is it used for anything other than CRLs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't actually remember. I remember thinking when I wrote TinyCA, "hmm, I should do this semi-correctly and generate unique serials at least", but I don't remember exactly why I thought that
// might want to reconsider. | ||
|
||
localhostAddrs, err := net.LookupHost("localhost") | ||
Expect(err).NotTo(HaveOccurred(), "should be able to find IPs for localhost") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure you want to do this lookup? I have seen it returning very surprising results at times :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we actually do this currently within the code (perhaps unfortunately, depending on how you're looking at it), so it's there for compat reasons. This just adds a test for that behavior.
// required on 1.20+, fine to leave on for <1.20 | ||
"service-account-issuer": []string{s.SecureServing.URL("https", "/").String()}, | ||
"service-account-key-file": []string{filepath.Join(s.CertDir, saCertFile)}, | ||
"service-account-signing-key-file": []string{filepath.Join(s.CertDir, saKeyFile)}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does the Apiserver needs this if the CM creates the SAs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You know, I'm not sure, but it does 🤷♀️ I'll look it up.
@alvaroaleman I think what I'm gonna do here is finish addressing the comments from @timebertt and you, and then break this up into 3-4 smallers PRs, which should be more digestable. |
I've split the refactor of testing and the introduction of structured arguments into two separate PRs. |
Gotta rebase juggle now. |
f2e2c75
to
15dcbe3
Compare
15dcbe3
to
d4c8079
Compare
Ok, I split the license change out into a separate PR to hopefully reduce the noise on this one as well a bit. |
d4c8079
to
7ed222c
Compare
This introduces secure serving by default, transparently switching configs to connect to secure endpoints. Similarly, the insecure endpoints are now disabled by default -- they must be explicitly disabled if you want to use them (note that this will only work on API servers <=1.19). This also turns on flags around the tokenrequest endpoint which are required to be on in 1.20, and have been available for all the versions that we currently support (back to 1.16). There's a whole new set of control plane APIs for provisioning users, and the old "just get a single account" APIs of the internal package are mostly deprecated. The default `Environment.Config` is *NOT* deprecated however -- this is intended to continue working as normal in order to avoid breaking everyone and to keep things in envtest working easily -- most tests will be fine with an admin user. For users that want RBAC, individual users may be provisioned with the ControlPlane.AddUser method.
This adds a full test suite for TinyCA, which was missing before, and is especially needed with the new envtest client cert generation.
Previously, envtest had separate logic that overrode testing/process.BinPathFinder, mainly because the latter used to be in a separate module. Since they're now in the same module and BinPathFinder is internal, we can just unify the logic and remove some of our hacks.
This adds fairly comprehensive tests for the control plane components, which either didn't exist before the refactor or existed very loosely in the form of general integration tests.
This exposes a few pieces of the new APIs in internal/testing as public in envtest. These types are effectively part of public APIs (they're referenced by public methods or fields of APIServer, ControlPlane, etc), so we should let users name them.
This makes sure that you can start a ControlPlane after stopping it. This preserves existing functionality. Note that the ability to re-use users or keep data around is *not* preserved -- use a fixed CertDir if you want this.
7ed222c
to
6fd12aa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: DirectXMan12, vincepri The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
The only place I've seen lll complain much is flag help, error messsages, and such, which aren't really a problem when they're long. Other stuff like complexity is probably best left to review, IMO.
/lgtm |
This introduces (pluggable) authentication support to envtest, which is required for 1.20+ API servers. The default authentication provider is cert-based, since we already have TinyCA, and cert-based auth can provision users both before & after starting the API server. Theoretically, other options should be available as well. Correspondingly, RBAC is now turned on for authorization, but this should not impact existing users (see below).
We continue to provide support for the legacy helpers on controlplane to fetch a rest config & kubectl, but deprecate them in favor of methods to provision a new user. The
RESTConfig
field on envtest, however, is not deprecated.We also deprecate insecure serving, since it's going away anyway, and add some new fields to support this. Theoretically, this should be largely transparent to end users, since I tried to backfill all legacy functionality with secure equivalents automatically (e.g. all "give me connection details" should now give an admin user, which should be transparent in terms of permissions). However if any users are manually constructing a RESTConfig without using the envtest fields or helper methods (i.e. just grabbing the API server URL from envtest), this will break them, so it's technically a breaking change.
Lmk if you spot anything that looks more seriously breaking, but AFAICT by-and-large this should just be a transparent switch with a nice new benefit of "also you can now test controller RBAC".
Closes #1357
Depends on #1541
Depends on #1540