Commit Graph

338 Commits

Author SHA1 Message Date
Mayank Bhatt
68547f767d Copy hostNetwork field for kube-cert-agent
For clusters where the control plane nodes aren't running a CNI, the
kube-cert-agent pods deployed by concierge cannot be scheduled as they
don't know to use `hostNetwork: true`. This change allows embedding the
host network setting in the Concierge configuration. (by copying it from
the kube-controller-manager pod spec when generating the kube-cert-agent
Deployment)

Also fixed a stray double comma in one of the nearby tests.
2021-08-26 17:09:59 -07:00
Mo Khan
3077034b2d
Merge branch 'main' into oidc_password_grant 2021-08-24 12:23:52 -04:00
Monis Khan
c356710f1f
Add leader election middleware
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-20 12:18:25 -04:00
Ryan Richard
52409f86e8 Merge branch 'main' into oidc_password_grant 2021-08-16 15:17:55 -07:00
Monis Khan
7a812ac5ed
impersonatorconfig: only unload dynamiccert when proxy is disabled
In the upstream dynamiccertificates package, we rely on two pieces
of code:

1. DynamicServingCertificateController.newTLSContent which calls
   - clientCA.CurrentCABundleContent
   - servingCert.CurrentCertKeyContent
2. unionCAContent.VerifyOptions which calls
   - unionCAContent.CurrentCABundleContent

This results in calls to our tlsServingCertDynamicCertProvider and
impersonationSigningCertProvider.  If we Unset these providers, we
subtly break these consumers.  At best this results in test slowness
and flakes while we wait for reconcile loops to converge.  At worst,
it results in actual errors during runtime.  For example, we
previously would Unset the impersonationSigningCertProvider on any
sync loop error (even a transient one caused by a network blip or
a conflict between writes from different replicas of the concierge).
This would cause us to transiently fail to issue new certificates
from the token credential require API.  It would also cause us to
transiently fail to authenticate previously issued client certs
(which results in occasional Unauthorized errors in CI).

Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-16 16:07:46 -04:00
Ryan Richard
5b96d014b4 Merge branch 'main' into oidc_password_grant 2021-08-12 11:12:57 -07:00
Ryan Richard
84c3c3aa9c Optionally allow OIDC password grant for CLI-based login experience
- Add `AllowPasswordGrant` boolean field to OIDCIdentityProvider's spec
- The oidc upstream watcher controller copies the value of
  `AllowPasswordGrant` into the configuration of the cached provider
- Add password grant to the UpstreamOIDCIdentityProviderI interface
  which is implemented by the cached provider instance for use in the
  authorization endpoint
- Enhance the IDP discovery endpoint to return the supported "flows"
  for each IDP ("cli_password" and/or "browser_authcode")
- Enhance `pinniped get kubeconfig` to help the user choose the desired
  flow for the selected IDP, and to write the flow into the resulting
  kubeconfg
- Enhance `pinniped login oidc` to have a flow flag to tell it which
  client-side flow it should use for auth (CLI-based or browser-based)
- In the Dex config, allow the resource owner password grant, which Dex
  implements to also return ID tokens, for use in integration tests
- Enhance the authorize endpoint to perform password grant when
  requested by the incoming headers. This commit does not include unit
  tests for the enhancements to the authorize endpoint, which will come
  in the next commit
- Extract some shared helpers from the callback endpoint to share the
  code with the authorize endpoint
- Add new integration tests
2021-08-12 10:45:39 -07:00
Monis Khan
a027f1ae2c
jwtcachefiller: update to use CAContentProvider
Signed-off-by: Monis Khan <mok@vmware.com>
2021-08-09 19:16:25 -04:00
Matt Moyer
58bbffded4
Switch to a slimmer distroless base image.
At a high level, it switches us to a distroless base container image, but that also includes several related bits:

- Add a writable /tmp but make the rest of our filesystems read-only at runtime.

- Condense our main server binaries into a single pinniped-server binary. This saves a bunch of space in
  the image due to duplicated library code. The correct behavior is dispatched based on `os.Args[0]`, and
  the `pinniped-server` binary is symlinked to `pinniped-concierge` and `pinniped-supervisor`.

- Strip debug symbols from our binaries. These aren't really useful in a distroless image anyway and all the
  normal stuff you'd expect to work, such as stack traces, still does.

- Add a separate `pinniped-concierge-kube-cert-agent` binary with "sleep" and "print" functionality instead of
  using builtin /bin/sleep and /bin/cat for the kube-cert-agent. This is split from the main server binary
  because the loading/init time of the main server binary was too large for the tiny resource footprint we
  established in our kube-cert-agent PodSpec. Using a separate binary eliminates this issue and the extra
  binary adds only around 1.5MiB of image size.

- Switch the kube-cert-agent code to use a JSON `{"tls.crt": "<b64 cert>", "tls.key": "<b64 key>"}` format.
  This is more robust to unexpected input formatting than the old code, which simply concatenated the files
  with some extra newlines and split on whitespace.

- Update integration tests that made now-invalid assumptions about the `pinniped-server` image.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-08-09 15:05:13 -04:00
Matt Moyer
5f679059d5
Add ClusterIP service to impersonator-config-controller informer.
Prior to this fix, this controller did not correctly react to changes to the ClusterIP service. It would still eventually react with a long delay due to our 5 minute resync interval.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-07-28 11:57:18 -05:00
Monis Khan
8b4ed86071
certs_expirer: be specific about what secret to delete
This change fixes a race that can occur because we have multiple
writers with no leader election lock.

1. TestAPIServingCertificateAutoCreationAndRotation/automatic
   expires the current serving certificate
2. CertsExpirerController 1 deletes expired serving certificate
3. CertsExpirerController 2 starts deletion of expired serving
   certificate but has not done so yet
4. CertsManagerController 1 creates new serving certificate
5. TestAPIServingCertificateAutoCreationAndRotation/automatic
   records the new serving certificate
6. CertsExpirerController 2 finishes deletion, and thus deletes the
   newly created serving certificate instead of the old one
7. CertsManagerController 2 creates new serving certificate
8. TestAPIServingCertificateAutoCreationAndRotation/automatic keeps
   running and eventually times out because it is expecting the
   serving certificate created by CertsManagerController 2 to match
   the value it recorded from CertsManagerController 1 (which will
   never happen since that certificate was incorrectly deleted).

Signed-off-by: Monis Khan <mok@vmware.com>
2021-07-28 09:56:05 -04:00
Ryan Richard
f17f7c0c6a Small refactors in impersonator_config.go suggested by @mattmoyer 2021-07-26 17:46:06 -07:00
Ryan Richard
708164b878 Carefully merge desired annotations into impersonation proxy Service
Don't overwrite annotations that might have come from a human user or
from some other non-Pinniped controller.
2021-07-22 17:09:50 -07:00
Ryan Richard
2bba39d723 TestAgentController unit test is flaky, try to add workaround
TestAgentController really runs the controller and evaluates multiple
calls to the controller's Sync with real informers caching updates.
There is a large amount of non-determinism in this unit test, and it
does not always behave the same way. Because it makes assertions about
the specific errors that should be returned by Sync, it was not
accounting for some errors that are only returned by Sync once in a
while depending on the exact (unpredictable) order of operations.

This commit doesn't fix the non-determinism in the test, but rather
tries to work around it by also allowing other (undesired but
inevitable) error messages to appear in the list of actual error
messages returned by the calls to the Sync function.

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-07-15 13:41:31 -07:00
Matt Moyer
9f91c6c884
Merge branch 'main' into oidc-upstream-watcher-supports-proxy 2021-07-09 07:24:52 -07:00
Ryan Richard
e130da6daa Add unit test assertion for new OIDC client request timeout 2021-07-08 11:47:49 -07:00
Ryan Richard
f0d120a6ca Fix broken upstream OIDC discovery timeout added in previous commit
After noticing that the upstream OIDC discovery calls can hang
indefinitely, I had tried to impose a one minute timeout on them
by giving them a timeout context. However, I hadn't noticed that the
context also gets passed into the JWKS fetching object, which gets
added to our cache and used later. Therefore the timeout context
was added to the cache and timed out while sitting in the cache,
causing later JWKS fetchers to fail.

This commit is trying again to impose a reasonable timeout on these
discovery and JWKS calls, but this time by using http.Client's Timeout
field, which is documented to be a timeout for *each* request/response
cycle, so hopefully this is a more appropriate way to impose a timeout
for this use case. The http.Client instance ends up in the cache on
the JWKS fetcher object, so the timeout should apply to each JWKS
request as well.

Requests that can hang forever are effectively a server-side resource
leak, which could theoretically be taken advantage of in a denial of
service attempt, so it would be nice to avoid having them.
2021-07-08 09:44:02 -07:00
Ryan Richard
f1e63c55d4 Add https_proxy and no_proxy settings for the Supervisor
- Add new optional ytt params for the Supervisor deployment.
- When the Supervisor is making calls to an upstream OIDC provider,
  use these variables if they were provided.
- These settings are integration tested in the main CI pipeline by
  sometimes setting them on deployments in certain cases, and then
  letting the existing integration tests (e.g. TestE2EFullIntegration)
  provide the coverage, so there are no explicit changes to the
  integration tests themselves in this commit.
2021-07-07 12:50:13 -07:00
Guangyuan Wang
76dc39ac2d Use hostname instead of host and split on ":"
Co-authored-by: Christian Ang <angc@vmware.com>
Co-authored-by: Tyler Schultz <tschultz@vmware.com>
2021-06-28 23:03:05 +00:00
Guangyuan Wang
d19d63ad7d Set Proxy on oidc upstream watcher transport
- this allows the oidc upsream watcher to honor the
HTTP_PROXY,HTTPS_PROXY,NO_PROXY environment variables

Co-authored-by: Christian Ang <angc@vmware.com>
2021-06-24 22:35:16 +00:00
Matt Moyer
af4cd1b515
Tolerate NotFound when deleting services in impersonatorconfig.
When a CredentialIssuer is switched from one service type to another (or switched to disabled mode), the `impersonatorconfig` controller will delete the previous Service, if any. Normally one Concierge pod will succeed to delete this initially and any other pods will see a NotFound error.

Before this change, the NotFound would bubble up and cause the strategy to enter a ErrorDuringSetup status until the next reconcile loop. We now handle this case without reporting an error.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-06-03 12:07:19 -05:00
Matt Moyer
01713c7ce1
Don't reconcile Service ports in impersonatorconfig.
These are tricky because a real load balancer controller (e.g., on GKE) will overwrite and set NodePort, so we can't blindly set the desired state of this fields.

For now, we will just skip reconciling these. In the future, we could be more clever about merging them together with the current state.

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-05-27 17:10:25 -05:00
Matt Moyer
ab750f48aa
When merging CredentialIssuer updates, don't overwrite LastUpdated.
If the only thing that has changed about a strategy is the LastUpdated timestamp, then we should not update the object.

Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-05-27 17:09:12 -05:00
Matt Moyer
349d3dad83
Make temporary errors return Pending in impersonatorconfig.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-05-27 11:13:10 -05:00
Matt Moyer
0a47aa4843
Adjust log levels in impersonatorconfig controller.
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-05-26 16:47:02 -05:00
Matt Moyer
1932b03c39
Refactor createOrUpdateService() method.
This updates the code to use a different mechanism for driving desired state:

- Read existing object
- If it does not exist, create desired object
- If it does exist, make a copy and set all the desired fields
- Do a deepequal to see if an update is necessary.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-05-26 15:03:04 -05:00
Matt Moyer
be8118ec2e
Re-enable parallelism on TestImpersonatorConfigControllerSync.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-05-26 12:57:51 -05:00
Matt Moyer
1a4687a40a
Switch impersonatorconfig to all singleton queues.
We also no longer need an initial event, since we don't do anything unless the CredentialIssuer exists, so we'll always be triggered at the appropriate time.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-05-26 12:54:40 -05:00
Matt Moyer
b13c494f93
Migrate off global logger in impersonatorconfig.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-05-26 12:44:05 -05:00
Margo Crawford
e5a61f3b95 IPv6 address in unit tests for ClusterIPs 2021-05-26 10:30:33 -07:00
Margo Crawford
f2021f1b53 Merge branch 'credentialissuer-spec-api' of github.com:vmware-tanzu/pinniped into credentialissuer-spec-api 2021-05-25 17:06:26 -07:00
Margo Crawford
e2fad6932f multiple cluster ips 2021-05-25 17:01:42 -07:00
Matt Moyer
450ce6a4aa
Switch impersonatorconfig to new endpointaddr package.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-05-25 17:44:25 -05:00
Matt Moyer
c970dd1fb0
Merge branch 'main' of github.com:vmware-tanzu/pinniped into credentialissuer-spec-api 2021-05-25 17:32:58 -05:00
Matt Moyer
89eff28549
Convert LDAP code to use endpointaddr package.
Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-05-25 16:17:27 -05:00
Matt Moyer
fabc08b01b
Merge branch 'main' of github.com:vmware-tanzu/pinniped into credentialissuer-spec-api 2021-05-24 15:49:13 -05:00
Margo Crawford
5de9bac4ac Oof... good I wrote an integration test because that's not how updating works!
Now updating the existing service in kubernetes but with the new
annotations
2021-05-24 09:41:49 -07:00
Margo Crawford
150e879a68 Add tests for deleting services 2021-05-21 13:47:06 -07:00
Margo Crawford
b4bb0db6e5 Refactor some shared code between load balancer and cluster ip creation 2021-05-21 09:57:46 -07:00
Margo Crawford
4606f1d8bd More error handling for cluster ip 2021-05-20 16:21:10 -07:00
Ryan Richard
901ddd1870 Merge branch 'main' into ldap_starttls 2021-05-20 13:40:56 -07:00
Ryan Richard
8b549f66d4 Add integration test for LDAP StartTLS 2021-05-20 13:39:48 -07:00
Ryan Richard
7e76b66639 LDAP upstream watcher controller tries using both TLS and StartTLS
- Automatically try to fall back to using StartTLS when using TLS
  doesn't work. Only complain when both don't work.
- Remember (in-memory) which one worked and keeping using that one
  in the future (unless the pod restarts).
2021-05-20 12:46:33 -07:00
Ryan Richard
fff90ed2ca
Merge branch 'main' into initial_ldap_group_support 2021-05-20 12:36:04 -07:00
Margo Crawford
62651eddb0 Took care of some impersonation cluster ip related todos 2021-05-20 11:57:07 -07:00
Matt Moyer
ec25259901
Update impersonatorconfig controller to use new CredentialIssuer update helper.
Signed-off-by: Margo Crawford <margaretc@vmware.com>
2021-05-20 12:26:07 -05:00
Matt Moyer
e4dd83887a
Merge remote-tracking branch 'origin/main' into credentialissuer-spec-api 2021-05-20 10:53:53 -05:00
Ryan Richard
025b37f839 upstreamldap.New() now supports a StartTLS config option
- This enhances our LDAP client code to make it possible to optionally
  dial an LDAP server without TLS and then use StartTLS to upgrade
  the connection to TLS.
- The controller for LDAPIdentityProviders is not using this option
  yet. That will come in a future commit.
2021-05-19 17:17:44 -07:00
Margo Crawford
63c39454f6 WIP on impersonation clusterip service 2021-05-19 17:00:28 -07:00
Matt Moyer
657488fe90
Create CredentialIssuer at install, not runtime.
Previously, our controllers would automatically create a CredentialIssuer with a singleton name. The helpers we had for this also used "raw" client access and did not take advantage of the informer cache pattern.

With this change, the CredentialIssuer is always created at install time in the ytt YAML. The controllers now only update the existing CredentialIssuer status, and they do so using the informer cache as much as possible.

This change is targeted at only the kubecertagent controller to start. The impersonatorconfig controller will be updated in a following PR along with other changes.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
2021-05-19 17:15:25 -05:00