feat(webui): Add Workload Identities list#58971
Conversation
# Conflicts: # lib/cache/workload_identity_test.go
cebc88f to
f1502fa
Compare
f1502fa to
4156c27
Compare
| serversideSearchPanel: ( | ||
| <SearchPanel | ||
| updateSearch={onSearchChange} | ||
| hideAdvancedSearch={true} |
There was a problem hiding this comment.
Why do we hide advanced search?
There was a problem hiding this comment.
It is not implemented for this endpoint. Only a text-contains search is supported.
| ); | ||
| } | ||
|
|
||
| function valueOrEmpty(value: string | null | undefined, empty = '-') { |
There was a problem hiding this comment.
Is the empty parameter actually used anywhere?
There was a problem hiding this comment.
No, but I felt the function was more complete this way and self-documenting.
| sortField: 'name', | ||
| sortDir: 'ASC', | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Am I right that most of these tests don't actually verify what's been rendered? It may be prudent to verify that apart from calling API endpoints, the test verifies that the response has been used to rerender the UI.
There was a problem hiding this comment.
Many don't, that's correct.
Given some of the tests verify the list is rendered correctly (such as "Shows a list") and the list just shows exactly what the API returns, I didn't think it was necessary to validate rendering the list for every case. Can you see an edge-case that I'm not covering?
|
|
||
| export function WorkloadIdentities() { | ||
| const history = useHistory(); | ||
| const location = useLocation<{ prevPageTokens?: readonly string[] }>(); |
There was a problem hiding this comment.
Where does the need for maintaining prevPageTokens come from? Isn't it enough to update the page query param?
There was a problem hiding this comment.
Relying on the query param and paging backwards using the browser back, presents it own set of problems. Namely, you can't know if there is a previous page to go back to.
Do you know an alternate approach?
There was a problem hiding this comment.
Oh I forgot that this must not only work with browser navigation buttons but also when you manually click on the button within the table that gets you to the previous page. In which case you need to maintain some kind of list of the page query params somewhere.
I think I was also confused as this might've been the first time I saw the use of a location state! Connect doesn't use React Router so I didn't have to pay attention to that. I also don't intuitively understand why we need to store prevPageTokens on the location rather than in a separate piece of state. Is this because React Router hooks into browser's history so that if I hold the back button in the browser and jump three pages back, React Router will know the exact prevPageTokens at that point in the navigation history?
There was a problem hiding this comment.
Location state is part of the History API, if I'm not mistaken. Navigating using the browser back/forward will recall the location state at that point including the prevPageTokens supplied when originally navigating to that location.
web/packages/teleport/src/WorkloadIdentity/WorkloadIdentities.tsx
Outdated
Show resolved
Hide resolved
web/packages/teleport/src/WorkloadIdentity/List/WorkloadIdentitiesList.tsx
Show resolved
Hide resolved
web/packages/teleport/src/WorkloadIdentity/List/WorkloadIdentitiesList.tsx
Show resolved
Hide resolved
|
|
||
| export function WorkloadIdentities() { | ||
| const history = useHistory(); | ||
| const location = useLocation<{ prevPageTokens?: readonly string[] }>(); |
There was a problem hiding this comment.
Oh I forgot that this must not only work with browser navigation buttons but also when you manually click on the button within the table that gets you to the previous page. In which case you need to maintain some kind of list of the page query params somewhere.
I think I was also confused as this might've been the first time I saw the use of a location state! Connect doesn't use React Router so I didn't have to pay attention to that. I also don't intuitively understand why we need to store prevPageTokens on the location rather than in a separate piece of state. Is this because React Router hooks into browser's history so that if I hold the back button in the browser and jump three pages back, React Router will know the exact prevPageTokens at that point in the navigation history?
web/packages/teleport/src/WorkloadIdentity/WorkloadIdentities.tsx
Outdated
Show resolved
Hide resolved
web/packages/teleport/src/WorkloadIdentity/List/WorkloadIdentitiesList.tsx
Show resolved
Hide resolved
# Conflicts: # lib/cache/workload_identity.go # lib/cache/workload_identity_test.go # web/packages/teleport/src/services/workloadIdentity/workloadIdentity.ts # web/packages/teleport/src/test/helpers/workloadIdentities.ts
|
@nicholasmarais1158 See the table below for backport results.
|
* Add ACLs for workload identity * Add list workload identities to webapi * Add `newWebPackWithOptions` * Add sorting by name and spiffe id * Add filter by search term * Use `require.ErrorContains` * Refactor `newWebPackWithOptions` * Use `t.Context()` * Add context to uses of `require.NoError` in loops * Tidy-up * Un-deprecate `newWebPack` * Rename `KindWorkloadIdentity` * Add client-side API support for sort and filter * Handle endpoint not supported scenario * Fix cache keys for spiffe id index * Add and use `ListWorkloadIdentitiesV2` RPC * Return `CompareFailedError` for sorting unavailable * Split sort into two fields (field and direction) * Update unsupported sort tests * Make `updateQuery` callback optional on `SearchPanel` * Add workload identities list * Add tests * Add stories * Rename nav item to "Workload Identities" Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com> * Revert change to conditional render (SearchPanel) * Remove mono-spaced text * Suggested code refinements * Join spiffe_id page keys with a pipe * Join spiffe_id page keys with a pipe * Revert "Join spiffe_id page keys with a pipe" This reverts commit 842b9cb. * Base32 hex encode id for cache key * Add missing useCallback dep * Fix word break opportunities on Firefox --------- Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
* Add ACLs for workload identity * Add list workload identities to webapi * Add `newWebPackWithOptions` * Add sorting by name and spiffe id * Add filter by search term * Use `require.ErrorContains` * Refactor `newWebPackWithOptions` * Use `t.Context()` * Add context to uses of `require.NoError` in loops * Tidy-up * Un-deprecate `newWebPack` * Rename `KindWorkloadIdentity` * Add client-side API support for sort and filter * Handle endpoint not supported scenario * Fix cache keys for spiffe id index * Add and use `ListWorkloadIdentitiesV2` RPC * Return `CompareFailedError` for sorting unavailable * Split sort into two fields (field and direction) * Update unsupported sort tests * Make `updateQuery` callback optional on `SearchPanel` * Add workload identities list * Add tests * Add stories * Rename nav item to "Workload Identities" Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com> * Revert change to conditional render (SearchPanel) * Remove mono-spaced text * Suggested code refinements * Join spiffe_id page keys with a pipe * Join spiffe_id page keys with a pipe * Revert "Join spiffe_id page keys with a pipe" This reverts commit 842b9cb. * Base32 hex encode id for cache key * Add missing useCallback dep * Fix word break opportunities on Firefox --------- Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
* Add ACLs for workload identity * Add list workload identities to webapi * Add `newWebPackWithOptions` * Add sorting by name and spiffe id * Add filter by search term * Use `require.ErrorContains` * Refactor `newWebPackWithOptions` * Use `t.Context()` * Add context to uses of `require.NoError` in loops * Tidy-up * Un-deprecate `newWebPack` * Rename `KindWorkloadIdentity` * Add client-side API support for sort and filter * Handle endpoint not supported scenario * Fix cache keys for spiffe id index * Add and use `ListWorkloadIdentitiesV2` RPC * Return `CompareFailedError` for sorting unavailable * Split sort into two fields (field and direction) * Update unsupported sort tests * Make `updateQuery` callback optional on `SearchPanel` * Add workload identities list * Add tests * Add stories * Rename nav item to "Workload Identities" Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com> * Revert change to conditional render (SearchPanel) * Remove mono-spaced text * Suggested code refinements * Join spiffe_id page keys with a pipe * Join spiffe_id page keys with a pipe * Revert "Join spiffe_id page keys with a pipe" This reverts commit 842b9cb. * Base32 hex encode id for cache key * Add missing useCallback dep * Fix word break opportunities on Firefox --------- Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
* feat(webui): Add Workload Identities list (#58971) * Add ACLs for workload identity * Add list workload identities to webapi * Add `newWebPackWithOptions` * Add sorting by name and spiffe id * Add filter by search term * Use `require.ErrorContains` * Refactor `newWebPackWithOptions` * Use `t.Context()` * Add context to uses of `require.NoError` in loops * Tidy-up * Un-deprecate `newWebPack` * Rename `KindWorkloadIdentity` * Add client-side API support for sort and filter * Handle endpoint not supported scenario * Fix cache keys for spiffe id index * Add and use `ListWorkloadIdentitiesV2` RPC * Return `CompareFailedError` for sorting unavailable * Split sort into two fields (field and direction) * Update unsupported sort tests * Make `updateQuery` callback optional on `SearchPanel` * Add workload identities list * Add tests * Add stories * Rename nav item to "Workload Identities" Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com> * Revert change to conditional render (SearchPanel) * Remove mono-spaced text * Suggested code refinements * Join spiffe_id page keys with a pipe * Join spiffe_id page keys with a pipe * Revert "Join spiffe_id page keys with a pipe" This reverts commit 842b9cb. * Base32 hex encode id for cache key * Add missing useCallback dep * Fix word break opportunities on Firefox --------- Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com> * Fix `CopyButton` conflict --------- Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
* Add ACLs for workload identity * Add list workload identities to webapi * Add `newWebPackWithOptions` * Add sorting by name and spiffe id * Add filter by search term * Use `require.ErrorContains` * Refactor `newWebPackWithOptions` * Use `t.Context()` * Add context to uses of `require.NoError` in loops * Tidy-up * Un-deprecate `newWebPack` * Rename `KindWorkloadIdentity` * Add client-side API support for sort and filter * Handle endpoint not supported scenario * Fix cache keys for spiffe id index * Add and use `ListWorkloadIdentitiesV2` RPC * Return `CompareFailedError` for sorting unavailable * Split sort into two fields (field and direction) * Update unsupported sort tests * Make `updateQuery` callback optional on `SearchPanel` * Add workload identities list * Add tests * Add stories * Rename nav item to "Workload Identities" * Revert change to conditional render (SearchPanel) * Remove mono-spaced text * Suggested code refinements * Join spiffe_id page keys with a pipe * Join spiffe_id page keys with a pipe * Revert "Join spiffe_id page keys with a pipe" This reverts commit 842b9cb. * Base32 hex encode id for cache key * Add missing useCallback dep * Fix word break opportunities on Firefox --------- Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
Summary
This change adds a Workload Identities list to the web UI. It's a loose clone of the existing Bot Instances list. It is paginated, can be server-side sorted by name or SPIFFE ID, and supports filtering by search term contained in the name, SPIFFE ID or SPIFFE hint fields.
There are a few differences compared to the Bot Instances implementation;
name:asc. This is mimicked by the server-side implementation (see feat(webapi): AddGET /webapi/sites/:site/workload-identity#58917).Updates: #53582
Changelog: Added a Workload Identities page to the web UI to list workload identities
Changes
Demo
Screen.Recording.2025-09-11.at.17.34.29.mov
Reviewer notes
Create a few Workload Identities using
tctl create(instructions here).Alternatively, I've used a sql script to insert many; workload-identities.sql.
Check storybook to see the edge-cases, such as no permissions, errors and welcome empty state.