Commit Graph

4830 Commits

Author SHA1 Message Date
Piotr Kazmierczak
b697de9dda client: correct consul block validation in the consul_hook (#18751) 2023-10-13 15:15:04 +02:00
James Rasell
e02dd2a331 vault: use an importable const for Vault header string. (#18740) 2023-10-13 07:39:06 +01:00
Piotr Kazmierczak
91753308b3 WI: set the right identity name for Consul tasks (#18742)
Consul tasks should only have 1 identity of the form consul/{consul_cluster_name}.
2023-10-12 20:34:15 +02:00
Tim Gross
3633ca0f8c auth: add client-only ACL (#18730)
The RPC handlers expect to see `nil` ACL objects whenever ACLs are disabled. By
using `nil` as a sentinel value, we have the risk of nil pointer exceptions and
improper handling of `nil` when returned from our various auth methods that can
lead to privilege escalation bugs. This is the third in a series to eliminate
the use of `nil` ACLs as a sentinel value for when ACLs are disabled.

This patch involves creating a new "virtual" ACL object for checking permissions
on client operations and a matching `AuthenticateClientOnly` method for
client-only RPCs that can produce that ACL.

Unlike the server ACLs PR, this also includes a special case for "legacy" client
RPCs where the client was not previously sending the secret as it
should (leaning on mTLS only). Those client RPCs were fixed in Nomad 1.6.0, but
it'll take a while before we can guarantee they'll be present during upgrades.

Ref: https://github.com/hashicorp/nomad-enterprise/pull/1218
Ref: https://github.com/hashicorp/nomad/pull/18703
Ref: https://github.com/hashicorp/nomad/pull/18715
Ref: https://github.com/hashicorp/nomad/pull/16799
2023-10-12 12:21:48 -04:00
Tim Gross
c7f97722ef consul hook: get WIs only for own task group (#18732)
The WID manager will only sign WI tokens for the allocation's task group. We're
accidentally looping over all the task groups, which for jobs with multiple task
groups results in a failure in the `consul_hook`.
2023-10-11 17:01:28 -04:00
Tim Gross
7ca619fe97 deps: remove Vault SDK (#18725)
Nomad imports the Vault SDK to get testing helpers, but it turns out the only
thing actually in use was a single string constant for the Vault namespace
header. Remove this dependency and hardcode the constant to reduce dependency
churn.
2023-10-11 10:42:09 -04:00
Tim Gross
e22c5b82f3 WID manager: request signed identities for services (#18650)
Includes changes to WID Manager that make it request signed identities for
services, as well as a few improvements to WIHandle introduced in #18672.

---------

Co-authored-by: Piotr Kazmierczak <470696+pkazmierczak@users.noreply.github.com>
2023-10-11 12:07:16 +02:00
Tim Gross
928a82a184 WID manager: save and restore signed WIs from client state DB (#18661)
When clients are restarted and the identity hook runs when we restore
allocations, the running allocations are likely to have already-signed Workload
Identities that are unexpired. Save these to the client's local state DB so that
we can avoid a thundering herd of RPCs during client restart. When we restore,
we'll check if there's at least one expired signed WI before making any initial
signing request.

Included:
* Renames `getIdentities` to `getInitialIdentities` to make the workflow more clear.
* Renames the existing `widmgr_test.go` file of integration tests, which is in its
  own package to avoid circular imports to `widmgr_int_test.go`
2023-10-09 09:16:23 -04:00
Piotr Kazmierczak
597d835220 wi: introduce workload identity handler (#18672)
Any code that tracks workloads and their identities should not rely on string
comparisons, especially since we support 2 types of workload identities: those
that identify tasks and those that identify services. This means we cannot rely
on task.Name for workload-identity pairs.

The new type structs.WIHandle solves this problem by providing a uniform way of
identifying workloads and their identities.
2023-10-06 18:32:47 +02:00
Seth Hoenig
e3c8700ded deps: upgrade to go-set/v2 (#18638)
No functional changes, just cleaning up deprecated usages that are
removed in v2 and replace one call of .Slice with .ForEach to avoid
making the intermediate copy.
2023-10-05 11:56:17 -05:00
Luiz Aoqui
d425c90e0f client: remove null dynamic metadata keys (#18664)
Setting a null value to a node metadata is expected to remove it from
subsequent reads. This is true both for static node metadata (defined in
the agent configuration file) as well as for dynamic node metadata
(defined via the Nomad API).

Null values for static metadata must be persisted to indicate that the
value has been removed, but strictly dynamic metadata null values can be
removed from state and client memory.
2023-10-05 11:41:44 -04:00
Luiz Aoqui
ed204e0fd9 client: ensure task only runs with prestart hooks (#18662)
Since the allocation in the task runner is updated in a separate
goroutine, a race condition may happen where the task is started but the
prestart hooks are skipped because the allocation became terminal.

Checking for a terminal allocation before proceeding with the task start
ensures the task only runs if the prestart hooks are also executed.

Since `shouldShutdown()` only uses terminal allocation status, it
remains `true` after the first transition, so it's safe to check it
again after the prestart hooks as it will never revert to `false`.
2023-10-05 10:16:57 -04:00
Piotr Kazmierczak
03cf9ae7ff vault: eliminate vaultclient test import cycle (#18652)
Eliminates the vaultclient test import cycle by putting the test file into the
client package and making vaultclient objects public.

Ref hashicorp/team-nomad#404
2023-10-05 09:17:16 +02:00
Tim Gross
bf65e44a09 consul: only fetch Consul tokens for Consul-specific identities (#18649)
Only the workload identities signed specifically for Consul, named
for the task or service, should result in authenticating to Consul to get tokens.
2023-10-04 11:12:50 -04:00
Matthew Salsamendi
aa9ff3a5b3 fix: use interpolated address when performing health checks (#18584)
* fix: use interpolated address when performing health checks

* Fix tests, add changelog

* Update .changelog/18584.txt

Co-authored-by: Seth Hoenig <shoenig@duck.com>

---------

Co-authored-by: Seth Hoenig <shoenig@duck.com>
2023-10-04 07:58:55 -05:00
Tim Gross
fb7582d596 services: get Consul token from hook resources (#18600)
When Workload Identity is being used with Consul, the `consul_hook` will add
Consul tokens to the alloc hook resources. Update the `group_service_hook` and
`service_hook` to use those tokens when available for registering and
deregistering Consul workloads.
2023-10-04 08:35:18 -04:00
Tim Gross
52ef476a72 sids_hook: read tokens from consul_hook when available (#18594)
The `sids_hook` runs for Connect sidecar/gateway tasks and gets Consul Service
Identity (SI) tokens for use by the Envoy bootstrap hook. When Workload Identity
is being used with Consul, the `consul_hook` will have already added these
tokens to the alloc hook resources. Update the `sids_hook` to use those tokens
instead and write them to the expected area of the taskdir.
2023-10-03 09:12:13 -04:00
Piotr Kazmierczak
3d62438876 consul: consul taskrunner hook should only write tokens that belong to its task (#18635)
Ref hashicorp/team-nomad#404
2023-10-02 19:49:02 +02:00
Michael Schurter
3f9bd17687 client: prevent watching stale alloc state (#18612)
When waiting on a previous alloc we must query against the leader before
switching to a stale query with index set.

Also check to ensure the response is fresh before using it like #18269
2023-09-29 12:46:28 -07:00
Tim Gross
aaee3076c2 consul: allow consul block in task scope (#18597)
To support Workload Identity with Consul for templates, we want templates to be
able to use the WI created at the task scope (either implicitly or set by the
user). But to allow different tasks within a group to be assigned to different
clusters as we're doing for Vault, we need to be able to set the `consul` block
with its `cluster` field at the task level to override the group.
2023-09-29 15:03:48 -04:00
Piotr Kazmierczak
5dab41881b client: new consul_hook (#18557)
This PR introduces a new allocrunner-level consul_hook which iterates over
services and tasks, if their provider is consul, fetches consul tokens for all of
them, stores them in AllocHookResources and in task secret dirs.

Ref: hashicorp/team-nomad#404

---------

Co-authored-by: Tim Gross <tgross@hashicorp.com>
2023-09-29 17:41:48 +02:00
Piotr Kazmierczak
0a75a42d94 WI: WIDMgr should expose default identity signatures (#18610)
Since the identity_hook is meant to be the central place that makes signed
identities available to other hooks, it should also expose the default identity
that is signed by the plan applier.

Ref: hashicorp/team-nomad#404
2023-09-29 15:17:59 +02:00
Tim Gross
5001bf4547 consul: use constant instead of "default" literal (#18611)
Use the constant `structs.ConsulDefaultCluster` instead of the string literal
"default", as we've done for Vault.
2023-09-28 16:50:21 -04:00
Michael Schurter
e73026dd4c client: prevent using stale allocs (#18601)
Similar to #18269, it is possible that even if Node.GetClientAllocs
retrieves fresh allocs that the subsequent Alloc.GetAllocs call
retrieves stale allocs. While `diffAlloc(existing, updated)` properly
ignores stale alloc *updates*, alloc deletions have no such check.

So if a client retrieves an alloc created at index 123, and then a
subsequent Alloc.GetAllocs call hits a new server which returns results
at index 100, the client will stop the alloc created at 123 because it
will be missing from the stale response.

This change applies the same logic as #18269 and ensures only fresh
responses are used.

Glossary:
* fresh - modified at an index > the query index
* stale - modified at an index <= the query index
2023-09-28 11:42:57 -07:00
Luiz Aoqui
868aba57bb vault: update identity name to start with vault_ (#18591)
* vault: update identity name to start with `vault_`

In the original proposal, workload identities used to derive Vault
tokens were expected to be called just `vault`. But in order to support
multiple Vault clusters it is necessary to associate identities with
specific Vault cluster configuration.

This commit implements a new proposal to have Vault identities named as
`vault_<cluster>`.
2023-09-27 15:53:28 -03:00
Luiz Aoqui
19241964a4 config: fix some issues with workload identity and multi Consul and Vault (#18590)
* config: fix multi consul and vault config parse

Capture the loop variable when parsing multiple Consul and Vault
configuration blocks so the duration parse function uses the correct
field when it's called later on.

* client: build Vault client with right config

When setting up the multiple Vault clients, the code was always loading
the default configuration, resulting in all clients to be configured the
same way.

* config: fix WorkloadIdentityConfig.Copy() method

Ensure `WorkloadIdentityConfig.Copy()` does not return the original
pointer for the `TTL` field.
2023-09-27 14:41:11 -03:00
Tim Gross
02a5aab359 consul: provide workload's Consul token to service client (#18559)
This is a work-in-progress changeset to provide workload-specific Consul tokens
that are created by the `consul_hook` and attached to workload registration
requests by the `group_service_hook` and `service_hook`.

This requires unreleased updates to Consul's `api` package, so this changeset
includes a temporary `replace` directive in the go.mod file.
2023-09-26 14:13:29 -04:00
Tim Gross
20eadc7b29 config: move Consul getter out of fingerprinter (#18556) 2023-09-22 10:58:39 -04:00
Daniel Bennett
7bd5c6e84e test: Refactor mock CSI manager (#18554)
and MockCSIManager to support the call counting
that csi_hook_test expects

instead of implementing csimanager
interfaces in two separate places:
* client/allocrunner/csi_hook_test
* client/csi_endpoint_test

they can both use the same mocks defined in
client/pluginmanager/csimanager/
alongside the actual implementations of them.

also refactor TestCSINode_DetachVolume
to use use it like Node_ExpandVolume
so we can also test the happy path there
2023-09-21 16:03:53 -05:00
Piotr Kazmierczak
86d2cdcf80 client: split identity_hook across allocrunner and taskrunner (#18431)
This commit splits identity_hook between the allocrunner and taskrunner. The
allocrunner-level part of the hook signs each task identity, and the
taskrunner-level part picks it up and stores secrets for each task.

The code revamps the WIDMgr, which is now split into 2 interfaces:
IdentityManager which manages renewals of signatures and handles sending
updates to subscribers via Watch method, and IdentitySigner which only does the
signing.

This work is necessary for having a unified Consul login workflow that comes
with the new Consul integration. A new, allocrunner-level consul_hook will now
be the only hook doing Consul authentication.
2023-09-21 17:31:27 +02:00
Tim Gross
fdc6c2151d vault: select Vault API client by cluster name (#18533)
Nomad Enterprise will support configuring multiple Vault clients. Instead of
having a single Vault client field in the Nomad client, we'll have a function
that callers can parameterize by the Vault cluster name that returns the
correctly configured Vault API client wrapper.
2023-09-19 14:35:01 -04:00
Daniel Bennett
4895d708b4 csi: implement NodeExpandVolume (#18522)
following ControllerExpandVolume
in c6dbba7cde,
which expands the disk at e.g. a cloud vendor,
the controller plugin may say that we also need
to issue NodeExpandVolume for the node plugin to
make the new disk space available to task(s) that
have claims on the volume by e.g. expanding
the filesystem on the node.

csi spec:
https://github.com/container-storage-interface/spec/blob/c918b7f/spec.md#nodeexpandvolume
2023-09-18 10:30:15 -05:00
Seth Hoenig
591394fb62 drivers: plumb hardware topology via grpc into drivers (#18504)
* drivers: plumb hardware topology via grpc into drivers

This PR swaps out the temporary use of detecting system hardware manually
in each driver for using the Client's detected topology by plumbing the
data over gRPC. This ensures that Client configuration is taken to account
consistently in all references to system topology.

* cr: use enum instead of bool for core grade

* cr: fix test slit tables to be possible
2023-09-18 08:58:07 -05:00
Daniel Bennett
c6dbba7cde csi: implement ControllerExpandVolume (#18359)
the first half of volume expansion,
this allows a user to update requested capacity
("capacity_min" and "capacity_max") in a volume
specification file, and re-issue either Register
or Create volume commands (or api calls).

the requested capacity will now be "reconciled"
with the current real capacity of the volume,
issuing a ControllerExpandVolume RPC call
to a running controller plugin, if requested
"capacity_min" is higher than the current
capacity on the volume in state.

csi spec:
https://github.com/container-storage-interface/spec/blob/c918b7f/spec.md#controllerexpandvolume

note: this does not yet cover NodeExpandVolume
2023-09-14 14:13:04 -05:00
Shantanu Gadgil
12580c345a bubble up the error message from go-getter (#18444) 2023-09-13 09:36:39 -04:00
Seth Hoenig
2e1974a574 client: refactor cpuset partitioning (#18371)
* client: refactor cpuset partitioning

This PR updates the way Nomad client manages the split between tasks
that make use of resources.cpus vs. resources.cores.

Previously, each task was explicitly assigned which CPU cores they were
able to run on. Every time a task was started or destroyed, all other
tasks' cpusets would need to be updated. This was inefficient and would
crush the Linux kernel when a client would try to run ~400 or so tasks.

Now, we make use of cgroup heirarchy and cpuset inheritence to efficiently
manage cpusets.

* cr: tweaks for feedback
2023-09-12 09:11:11 -05:00
James Rasell
668dc5f7a7 client: fix role permission issue with duplicate policies. (#18419)
This change deduplicates the ACL policy list generated from ACL
roles referenced within an ACL token on the client.

Previously the list could contain duplicates, which would cause
erronous permission denied errors when calling client related RPC/
HTTP API endpoints. This is because the client calls the ACL get
policies endpoint which subsequently ensures the caller has
permission to view the ACL policies. This check is performed by
comparing the requested list args with the policies referenced by
the caller ACL token. When a duplicate is present, this check
fails, as the check must ensure the slices match exactly.
2023-09-11 12:52:08 +01:00
Michael Schurter
ef24e40b39 identity: support jwt expiration and rotation (#18262)
Implements expirations and renewals for alternate workload identity tokens.
2023-09-08 14:50:34 -07:00
Daniel Bennett
22cbb913db csi: rename volume Mounter to Manager (#18434)
to align with its broader purpose,
and the volumeManager implementation
2023-09-08 15:33:46 -05:00
Tim Gross
b022346575 fingerprint: backoff on Consul fingerprint after initial success (#18426)
In the original design of Consul fingerprinting, we would poll every period so
that we could change the client's fingerprint if Consul became unavailable. As
of 1.4.0 (ref #14673) we no longer update the fingerprint in order to avoid
excessive `Node.Register` RPCs when someone's Consul cluster is flapping.

This allows us to safely backoff Consul fingerprinting on success, just as we
have with Vault.
2023-09-08 08:17:07 -04:00
Tim Gross
a8e68e6479 fingerprint: add support for fingerprinting multiple Consul clusters (#18392)
fingerprint: add support for fingerprinting multiple Consul clusters

Add fingerprinting we'll need to accept multiple Consul clusters in upcoming
Nomad Enterprise features. The fingerprinter will create a map of Consul clients
by cluster name. In Nomad CE, all but the default cluster will be ignored and
there will be no visible behavior change.

Ref: https://github.com/hashicorp/team-nomad/issues/404
2023-09-07 14:05:35 -04:00
Tim Gross
c145e8b30f fingerprint: add warning in CE when there are multiple vaults (#18412)
Nomad CE only supports a single (default) Vault cluster, so log a warning if the
user has configured multiple Vaults.
2023-09-07 09:51:48 -04:00
Piotr Kazmierczak
2fffb96604 client: new Consul client (#18370)
This PR introduces a new Consul client that returns SI tokens based on requests
that contain JWTs.
2023-09-05 20:55:36 +02:00
Luiz Aoqui
b614ef3b01 client: fix panic on alloc restore (#18356)
When restoring an allocation `WIDMgr` was not being set in the alloc
runner config, resulting in a nil panic when the task runner attempted
to start.

Since we will often require the same configuration values when creating
or restoring a new allocation, this commit moves the logic to a shared
function to ensure that `addAlloc` and `restoreState` configure alloc
runners with the same values.
2023-09-01 11:42:00 -03:00
Seth Hoenig
05c3322214 Revert "client: include response body in output for successful HTTP checks (#18345)" (#18362)
* Revert "client: include response body in output for successful HTTP checks (#18345)"

This reverts commit d0a93f12d1.

* cr: add comment about dropping ok output

Co-authored-by: Luiz Aoqui <luiz@hashicorp.com>

---------

Co-authored-by: Luiz Aoqui <luiz@hashicorp.com>
2023-08-30 08:22:28 -05:00
Matthew Salsamendi
d0a93f12d1 client: include response body in output for successful HTTP checks (#18345) 2023-08-28 19:15:06 -04:00
stswidwinski
f25480c9e9 Ensure that the index processed by the client is at least as new as the last one processed. (#18269)
Ensure that the index processed by the client is at least as new as the last index processed so that stale data does not impact the running allocations.
2023-08-25 15:54:58 -07:00
James Rasell
a9d5beb141 test: use correct parallel test setup func (#18326) 2023-08-25 13:51:36 +01:00
Seth Hoenig
f5b0da1d55 all: swap exp packages for maps, slices (#18311) 2023-08-23 15:42:13 -05:00
Luiz Aoqui
14a38bee7b client: 404 when accessing files for GC'ed alloc (#18232)
When an allocation is garbage collected from the client, but not from
the servers, the API request is routed to the client and the client
does attempt to read the file, but the alloc dir has already been
deleted, resulting in a 500 error.

This happens because the client GC only destroys the alloc runner
(deleting the alloc dir), but it keeps a reference to the alloc runner
until the alloc is garbage collected from the servers as well.

This commit adjusts this logic by checking if the alloc runner (and the
alloc files) has been destroyed, returning a 404 if so.
2023-08-21 16:09:24 -04:00