Propagate resource revision to/from the backend (#32040)

* Set revision on resources retrieved from the backend

Adds a new `MarshalOption` that ensures the resource revision is
set when unmarshalling a backend item. The new `WithRevision` option
was also applied everywhere that the legacy `WithResourceID` was
being used.

* Prevent storing resource revision in the backend item value

The revision follows the same semantics as the resource id for
marshalling. This prevents both items from showing up in the value
of the backend item, which can prevent compare and swap operations
from completing succesfully. Each backend is responsible for
persisting the revision in some manner.

The existing PreserveResourceID was reused to prevent having to
make multiple copies of a resource when clearing the id and revision.
The marshal option will be updated in a follow up when the resource
id is removed.

* Ignore revision in resource comparisons
This commit is contained in:
rosstimothy
2023-09-26 16:58:04 +00:00
committed by GitHub
parent 042d56ec15
commit e035f4dbf3
100 changed files with 558 additions and 315 deletions
+1 -1
View File
@@ -135,7 +135,7 @@ func TestUpsertServer(t *testing.T) {
addServers(s.GetAuthServers())
addServers(s.GetNodes(ctx, apidefaults.Namespace))
addServers(s.GetProxies())
require.Empty(t, cmp.Diff(allServers, []types.Server{tt.wantServer}, cmpopts.IgnoreFields(types.Metadata{}, "ID")))
require.Empty(t, cmp.Diff(allServers, []types.Server{tt.wantServer}, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
})
}
}
+19 -15
View File
@@ -37,6 +37,7 @@ import (
"github.com/pquerna/otp/totp"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"golang.org/x/exp/slices"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api"
@@ -1782,33 +1783,33 @@ func TestDatabasesCRUDRBAC(t *testing.T) {
db, err := devClt.GetDatabase(ctx, devDatabase.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(devDatabase, db,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Admin can get both databases.
db, err = adminClt.GetDatabase(ctx, adminDatabase.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(adminDatabase, db,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
db, err = adminClt.GetDatabase(ctx, devDatabase.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(devDatabase, db,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// When listing databases, dev should only see one.
dbs, err := devClt.GetDatabases(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Database{devDatabase}, dbs,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Admin should see both.
dbs, err = adminClt.GetDatabases(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Database{adminDatabase, devDatabase}, dbs,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Dev shouldn't be able to delete dev database...
@@ -1902,7 +1903,7 @@ func mustGetDatabases(t *testing.T, client *Client, wantDatabases []types.Databa
require.NoError(t, err)
require.Empty(t, cmp.Diff(wantDatabases, actualDatabases,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.EquateEmpty(),
))
}
@@ -1957,7 +1958,7 @@ func TestKubernetesClusterCRUD_DiscoveryService(t *testing.T) {
t.Run("Read", func(t *testing.T) {
clusters, err := discoveryClt.GetKubernetesClusters(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.KubeCluster{eksCluster}, clusters))
require.Empty(t, cmp.Diff([]types.KubeCluster{eksCluster}, clusters, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
})
t.Run("Update", func(t *testing.T) {
require.NoError(t, discoveryClt.UpdateKubernetesCluster(ctx, eksCluster))
@@ -2480,33 +2481,33 @@ func TestApps(t *testing.T) {
app, err := devClt.GetApp(ctx, devApp.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(devApp, app,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Admin can get both apps.
app, err = adminClt.GetApp(ctx, adminApp.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(adminApp, app,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
app, err = adminClt.GetApp(ctx, devApp.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(devApp, app,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// When listing apps, dev should only see one.
apps, err := devClt.GetApps(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Application{devApp}, apps,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Admin should see both.
apps, err = adminClt.GetApps(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Application{adminApp, devApp}, apps,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Dev shouldn't be able to delete dev app...
@@ -2531,7 +2532,7 @@ func TestApps(t *testing.T) {
apps, err = adminClt.GetApps(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Application{adminApp}, apps,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Admin should be able to delete all.
@@ -3609,7 +3610,10 @@ func TestListResources_KindUserGroup(t *testing.T) {
userGroups, err := types.ResourcesWithLabels(res.Resources).AsUserGroups()
require.NoError(t, err)
require.ElementsMatch(t, []types.UserGroup{testUg1, testUg2, testUg3}, userGroups)
slices.SortFunc(userGroups, func(a, b types.UserGroup) int {
return strings.Compare(a.GetName(), b.GetName())
})
require.Empty(t, cmp.Diff([]types.UserGroup{testUg2, testUg3, testUg1}, userGroups, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
})
t.Run("start keys", func(t *testing.T) {
@@ -6378,7 +6382,7 @@ func TestCreateAccessRequest(t *testing.T) {
// We have to ignore the name here, as it's auto-generated by the underlying access request
// logic.
require.Empty(t, cmp.Diff(test.expected, accessRequests[0],
cmpopts.IgnoreFields(types.Metadata{}, "Name", "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "Name", "ID", "Revision"),
cmpopts.IgnoreFields(types.AccessRequestSpecV3{}),
))
})
+27 -27
View File
@@ -2441,7 +2441,7 @@ func TestNodesCRUD(t *testing.T) {
require.NoError(t, err)
require.Len(t, nodes, 2)
require.Empty(t, cmp.Diff([]types.Server{node1, node2}, nodes,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// GetNodes should not fail if namespace is empty
_, err = clt.GetNodes(ctx, "")
@@ -2453,7 +2453,7 @@ func TestNodesCRUD(t *testing.T) {
node, err := clt.GetNode(ctx, apidefaults.Namespace, "node1")
require.NoError(t, err)
require.Empty(t, cmp.Diff(node1, node,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// GetNode should fail if node name isn't provided
_, err = clt.GetNode(ctx, apidefaults.Namespace, "")
@@ -2552,7 +2552,7 @@ func TestLocksCRUD(t *testing.T) {
require.NoError(t, err)
require.Len(t, locks, 2)
require.Empty(t, cmp.Diff([]types.Lock{lock1, lock2}, locks,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
})
t.Run("GetLocks with targets", func(t *testing.T) {
t.Parallel()
@@ -2561,7 +2561,7 @@ func TestLocksCRUD(t *testing.T) {
require.NoError(t, err)
require.Len(t, locks, 2)
require.Empty(t, cmp.Diff([]types.Lock{lock1, lock2}, locks,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Match only one of the locks.
roleTarget := types.LockTarget{Role: "role-A"}
@@ -2569,7 +2569,7 @@ func TestLocksCRUD(t *testing.T) {
require.NoError(t, err)
require.Len(t, locks, 1)
require.Empty(t, cmp.Diff([]types.Lock{lock1}, locks,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Match none of the locks.
locks, err = clt.GetLocks(ctx, false, roleTarget)
@@ -2582,7 +2582,7 @@ func TestLocksCRUD(t *testing.T) {
lock, err := clt.GetLock(ctx, lock1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(lock1, lock,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Attempt to get a nonexistent lock.
_, err = clt.GetLock(ctx, "lock3")
@@ -2662,7 +2662,7 @@ func TestApplicationServersCRUD(t *testing.T) {
out, err = clt.GetApplicationServers(ctx, apidefaults.Namespace)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.AppServer{server1, server2, server3}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Update an app server.
@@ -2672,7 +2672,7 @@ func TestApplicationServersCRUD(t *testing.T) {
out, err = clt.GetApplicationServers(ctx, apidefaults.Namespace)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.AppServer{server1, server2, server3}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete an app server.
@@ -2681,7 +2681,7 @@ func TestApplicationServersCRUD(t *testing.T) {
out, err = clt.GetApplicationServers(ctx, apidefaults.Namespace)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.AppServer{server2, server3}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete all app servers.
@@ -2732,14 +2732,14 @@ func TestAppsCRUD(t *testing.T) {
out, err = clt.GetApps(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Application{app1, app2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific app.
app, err := clt.GetApp(ctx, app2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(app2, app,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch an app that doesn't exist.
@@ -2757,7 +2757,7 @@ func TestAppsCRUD(t *testing.T) {
app, err = clt.GetApp(ctx, app1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(app1, app,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete an app.
@@ -2766,7 +2766,7 @@ func TestAppsCRUD(t *testing.T) {
out, err = clt.GetApps(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Application{app2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete an app that doesn't exist.
@@ -2813,7 +2813,7 @@ func TestAppServersCRUD(t *testing.T) {
appServer := resources.Resources[0].(types.AppServer)
require.Empty(t, cmp.Diff(appServer, appServer1,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
require.NoError(t, clt.DeleteApplicationServer(ctx, apidefaults.Namespace, "hostID", appServer1.GetName()))
@@ -2866,7 +2866,7 @@ func TestAppServersCRUD(t *testing.T) {
app2.SetOrigin(types.OriginOkta)
appServer = resources.Resources[0].(types.AppServer)
require.Empty(t, cmp.Diff(appServer, appServer2,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
require.NoError(t, clt.DeleteApplicationServer(ctx, apidefaults.Namespace, "hostID", appServer2.GetName()))
@@ -2921,14 +2921,14 @@ func TestDatabasesCRUD(t *testing.T) {
out, err = clt.GetDatabases(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Database{db1, db2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific database.
db, err := clt.GetDatabase(ctx, db2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(db2, db,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch a database that doesn't exist.
@@ -2946,7 +2946,7 @@ func TestDatabasesCRUD(t *testing.T) {
db, err = clt.GetDatabase(ctx, db1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(db1, db,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete a database.
@@ -2955,7 +2955,7 @@ func TestDatabasesCRUD(t *testing.T) {
out, err = clt.GetDatabases(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Database{db2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete a database that doesn't exist.
@@ -3037,7 +3037,7 @@ func TestDatabaseServicesCRUD(t *testing.T) {
out, err = types.ResourcesWithLabels(listServicesResp.Resources).AsDatabaseServices()
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.DatabaseService{db1, db2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Update a DatabaseService.
@@ -3059,7 +3059,7 @@ func TestDatabaseServicesCRUD(t *testing.T) {
out, err = types.ResourcesWithLabels(listServicesResp.Resources).AsDatabaseServices()
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.DatabaseService{db1, db2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete a DatabaseService.
@@ -3075,7 +3075,7 @@ func TestDatabaseServicesCRUD(t *testing.T) {
out, err = types.ResourcesWithLabels(listServicesResp.Resources).AsDatabaseServices()
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.DatabaseService{db2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete a DatabaseService that doesn't exist.
@@ -3138,7 +3138,7 @@ func TestServerInfoCRUD(t *testing.T) {
}
requireResourcesEqual := func(t *testing.T, expected, actual interface{}) {
require.Empty(t, cmp.Diff(expected, actual, cmpopts.IgnoreFields(types.Metadata{}, "ID")))
require.Empty(t, cmp.Diff(expected, actual, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
t.Run("ServerInfoGetters", func(t *testing.T) {
@@ -3240,7 +3240,7 @@ func TestSAMLIdPServiceProvidersCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextKey)
require.Empty(t, cmp.Diff([]types.SAMLIdPServiceProvider{sp1, sp2}, listResp,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Update a service provider.
@@ -3253,7 +3253,7 @@ func TestSAMLIdPServiceProvidersCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextKey)
require.Empty(t, cmp.Diff([]types.SAMLIdPServiceProvider{sp1, sp2}, listResp,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete a service provider.
@@ -3263,7 +3263,7 @@ func TestSAMLIdPServiceProvidersCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextKey)
require.Empty(t, cmp.Diff([]types.SAMLIdPServiceProvider{sp2}, listResp,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete a service provider that doesn't exist.
@@ -4161,7 +4161,7 @@ func TestRoleVersions(t *testing.T) {
return
}
require.Empty(t, cmp.Diff(tc.expectedRole, gotRole,
cmpopts.IgnoreFields(types.RoleV6{}, "Metadata.ID", "Metadata.Labels")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision", "Labels")))
// The downgraded label value won't match exactly because it
// includes the client version, so just check it's not empty
// and ignore it in the role diff.
+1 -1
View File
@@ -1339,7 +1339,7 @@ func resourceFromYAML(t *testing.T, value string) types.Resource {
func resourceDiff(res1, res2 types.Resource) string {
return cmp.Diff(res1, res2,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Namespace"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision", "Namespace"),
cmpopts.EquateEmpty())
}
+7 -7
View File
@@ -61,7 +61,7 @@ func TestOktaImportRules(t *testing.T) {
require.NoError(t, err)
require.Empty(t, listResp.NextPageToken)
require.Empty(t, cmp.Diff([]*types.OktaImportRuleV1{r1, r2, r3}, listResp.ImportRules,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
r1.SetExpiry(time.Now().Add(30 * time.Minute))
updateResp, err := svc.UpdateOktaImportRule(ctx, &oktapb.UpdateOktaImportRuleRequest{ImportRule: r1})
@@ -71,7 +71,7 @@ func TestOktaImportRules(t *testing.T) {
r, err := svc.GetOktaImportRule(ctx, &oktapb.GetOktaImportRuleRequest{Name: r1.GetName()})
require.NoError(t, err)
require.Empty(t, cmp.Diff(r1, r,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
_, err = svc.DeleteOktaImportRule(ctx, &oktapb.DeleteOktaImportRuleRequest{Name: r1.GetName()})
require.NoError(t, err)
@@ -80,7 +80,7 @@ func TestOktaImportRules(t *testing.T) {
require.NoError(t, err)
require.Empty(t, listResp.NextPageToken)
require.Empty(t, cmp.Diff([]*types.OktaImportRuleV1{r2, r3}, listResp.ImportRules,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
_, err = svc.DeleteAllOktaImportRules(ctx, &oktapb.DeleteAllOktaImportRulesRequest{})
require.NoError(t, err)
@@ -119,7 +119,7 @@ func TestOktaAssignments(t *testing.T) {
require.NoError(t, err)
require.Empty(t, listResp.NextPageToken)
require.Empty(t, cmp.Diff([]*types.OktaAssignmentV1{a1, a2, a3}, listResp.Assignments,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
a1.SetExpiry(time.Now().Add(30 * time.Minute))
updateResp, err := svc.UpdateOktaAssignment(ctx, &oktapb.UpdateOktaAssignmentRequest{Assignment: a1})
@@ -129,7 +129,7 @@ func TestOktaAssignments(t *testing.T) {
a, err := svc.GetOktaAssignment(ctx, &oktapb.GetOktaAssignmentRequest{Name: a1.GetName()})
require.NoError(t, err)
require.Empty(t, cmp.Diff(a1, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
_, err = svc.UpdateOktaAssignmentStatus(ctx, &oktapb.UpdateOktaAssignmentStatusRequest{Name: a1.GetName(),
Status: types.OktaAssignmentSpecV1_PROCESSING})
@@ -140,7 +140,7 @@ func TestOktaAssignments(t *testing.T) {
require.NoError(t, err)
a1.SetLastTransition(a.GetLastTransition())
require.Empty(t, cmp.Diff(a1, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
_, err = svc.DeleteOktaAssignment(ctx, &oktapb.DeleteOktaAssignmentRequest{Name: a1.GetName()})
require.NoError(t, err)
@@ -149,7 +149,7 @@ func TestOktaAssignments(t *testing.T) {
require.NoError(t, err)
require.Empty(t, listResp.NextPageToken)
require.Empty(t, cmp.Diff([]*types.OktaAssignmentV1{a2, a3}, listResp.Assignments,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
_, err = svc.DeleteAllOktaAssignments(ctx, &oktapb.DeleteAllOktaAssignmentsRequest{})
require.NoError(t, err)
+7 -8
View File
@@ -1118,7 +1118,7 @@ func TestGetCurrentUser(t *testing.T) {
currentUser, err := client1.GetCurrentUser(ctx)
require.NoError(t, err)
require.Equal(t, &types.UserV2{
require.Empty(t, cmp.Diff(&types.UserV2{
Kind: "user",
SubKind: "",
Version: "v2",
@@ -1128,12 +1128,11 @@ func TestGetCurrentUser(t *testing.T) {
Description: "",
Labels: nil,
Expires: nil,
ID: currentUser.GetMetadata().ID,
},
Spec: types.UserSpecV2{
Roles: []string{"user:user1"},
},
}, currentUser)
}, currentUser, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
func TestGetCurrentUserRoles(t *testing.T) {
@@ -1148,7 +1147,7 @@ func TestGetCurrentUserRoles(t *testing.T) {
roles, err := client1.GetCurrentUserRoles(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff(roles, []types.Role{user1Role}, cmpopts.IgnoreFields(types.Metadata{}, "ID")))
require.Empty(t, cmp.Diff(roles, []types.Role{user1Role}, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
func TestAuthPreferenceSettings(t *testing.T) {
@@ -4096,7 +4095,7 @@ func TestGRPCServer_CreateTokenV2(t *testing.T) {
require.Empty(t, cmp.Diff(
tt.token,
token,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
}
})
@@ -4263,7 +4262,7 @@ func TestGRPCServer_UpsertTokenV2(t *testing.T) {
require.Empty(t, cmp.Diff(
tt.token,
token,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
}
})
@@ -4353,7 +4352,7 @@ func TestGRPCServer_GetTokens(t *testing.T) {
require.Empty(t, cmp.Diff(
expectTokens,
tokens,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
} else {
require.Empty(t, tokens)
@@ -4423,7 +4422,7 @@ func TestGRPCServer_GetToken(t *testing.T) {
require.Empty(t, cmp.Diff(
token,
pt,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
} else {
require.Nil(t, token)
+4 -2
View File
@@ -451,6 +451,7 @@ func TestGetCertAuthority(t *testing.T) {
assertion: func(t *testing.T, authority types.CertAuthority, err error) {
require.NoError(t, err)
require.Empty(t, cmp.Diff(authority, ca,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.IgnoreFields(types.SSHKeyPair{}, "PrivateKey"),
cmpopts.IgnoreFields(types.TLSKeyPair{}, "Key"),
cmpopts.IgnoreFields(types.JWTKeyPair{}, "PrivateKey"),
@@ -470,7 +471,7 @@ func TestGetCertAuthority(t *testing.T) {
},
assertion: func(t *testing.T, authority types.CertAuthority, err error) {
require.NoError(t, err)
require.Empty(t, cmp.Diff(authority, ca))
require.Empty(t, cmp.Diff(authority, ca, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
},
},
}
@@ -542,6 +543,7 @@ func TestGetCertAuthorities(t *testing.T) {
assertion: func(t *testing.T, resp *trustpb.GetCertAuthoritiesResponse, err error) {
require.NoError(t, err)
require.Empty(t, cmp.Diff(expectedCAs, resp.CertAuthoritiesV2,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.IgnoreFields(types.SSHKeyPair{}, "PrivateKey"),
cmpopts.IgnoreFields(types.TLSKeyPair{}, "Key"),
cmpopts.IgnoreFields(types.JWTKeyPair{}, "PrivateKey"),
@@ -563,7 +565,7 @@ func TestGetCertAuthorities(t *testing.T) {
},
assertion: func(t *testing.T, resp *trustpb.GetCertAuthoritiesResponse, err error) {
require.NoError(t, err)
require.Empty(t, cmp.Diff(expectedCAs, resp.CertAuthoritiesV2))
require.Empty(t, cmp.Diff(expectedCAs, resp.CertAuthoritiesV2, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
},
},
}
+6 -9
View File
@@ -22,6 +22,7 @@ import (
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/gravitational/trace"
"github.com/stretchr/testify/require"
@@ -53,9 +54,8 @@ func TestRemoteClusterStatus(t *testing.T) {
// Initially, no tunnels exist and status should be "offline".
wantRC.SetConnectionStatus(teleport.RemoteClusterStatusOffline)
gotRC, err := a.GetRemoteCluster(rc.GetName())
gotRC.SetResourceID(0)
require.NoError(t, err)
require.Empty(t, cmp.Diff(rc, gotRC))
require.Empty(t, cmp.Diff(rc, gotRC, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Create several tunnel connections.
lastHeartbeat := a.clock.Now().UTC()
@@ -86,8 +86,7 @@ func TestRemoteClusterStatus(t *testing.T) {
wantRC.SetLastHeartbeat(tc2.GetLastHeartbeat())
gotRC, err = a.GetRemoteCluster(rc.GetName())
require.NoError(t, err)
gotRC.SetResourceID(0)
require.Empty(t, cmp.Diff(rc, gotRC))
require.Empty(t, cmp.Diff(rc, gotRC, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Delete the latest connection.
require.NoError(t, a.DeleteTunnelConnection(tc2.GetClusterName(), tc2.GetName()))
@@ -99,9 +98,8 @@ func TestRemoteClusterStatus(t *testing.T) {
// heartbeat.
wantRC.SetConnectionStatus(teleport.RemoteClusterStatusOnline)
gotRC, err = a.GetRemoteCluster(rc.GetName())
gotRC.SetResourceID(0)
require.NoError(t, err)
require.Empty(t, cmp.Diff(rc, gotRC))
require.Empty(t, cmp.Diff(rc, gotRC, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Delete the remaining connection
require.NoError(t, a.DeleteTunnelConnection(tc1.GetClusterName(), tc1.GetName()))
@@ -112,9 +110,8 @@ func TestRemoteClusterStatus(t *testing.T) {
// The last_heartbeat should remain the same.
wantRC.SetConnectionStatus(teleport.RemoteClusterStatusOffline)
gotRC, err = a.GetRemoteCluster(rc.GetName())
gotRC.SetResourceID(0)
require.NoError(t, err)
require.Empty(t, cmp.Diff(rc, gotRC))
require.Empty(t, cmp.Diff(rc, gotRC, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
func TestRefreshRemoteClusters(t *testing.T) {
@@ -191,7 +188,7 @@ func TestRefreshRemoteClusters(t *testing.T) {
var updated int
for _, cluster := range clusters {
old := allClusters[cluster.GetName()]
if cmp.Diff(old, cluster) != "" {
if cmp.Diff(old, cluster, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")) != "" {
updated++
}
}
+1 -1
View File
@@ -45,7 +45,7 @@ const (
var (
// cmpOpts are general cmpOpts for all comparisons across the service tests.
cmpOpts = []cmp.Option{
cmpopts.IgnoreFields(header.Metadata{}, "ID"),
cmpopts.IgnoreFields(header.Metadata{}, "ID", "Revision"),
cmpopts.SortSlices(func(a, b *userloginstate.UserLoginState) bool {
return a.GetName() < b.GetName()
}),
+1 -1
View File
@@ -910,6 +910,6 @@ func createUserAndRole(client *testClient, username string, allowedLogins []stri
func resourceDiff(res1, res2 types.Resource) string {
return cmp.Diff(res1, res2,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Namespace"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision", "Namespace"),
cmpopts.EquateEmpty())
}
+16 -28
View File
@@ -336,8 +336,7 @@ func TestCA(t *testing.T) {
out, err := p.cache.GetCertAuthority(ctx, ca.GetID(), true)
require.NoError(t, err)
ca.SetResourceID(out.GetResourceID())
require.Empty(t, cmp.Diff(ca, out))
require.Empty(t, cmp.Diff(ca, out, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = p.trustS.DeleteCertAuthority(ctx, ca.GetID())
require.NoError(t, err)
@@ -1048,7 +1047,6 @@ func initStrategy(t *testing.T) {
normalizeCA := func(ca types.CertAuthority) types.CertAuthority {
ca = ca.Clone()
ca.SetResourceID(0)
ca.SetExpiry(time.Time{})
types.RemoveCASecrets(ca)
return ca
@@ -1057,7 +1055,7 @@ func initStrategy(t *testing.T) {
out, err := p.cache.GetCertAuthority(ctx, ca.GetID(), false)
require.NoError(t, err)
require.Empty(t, cmp.Diff(normalizeCA(ca), normalizeCA(out)))
require.Empty(t, cmp.Diff(normalizeCA(ca), normalizeCA(out), cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// fail again, make sure last recent data is still served
// on errors
@@ -1072,7 +1070,7 @@ func initStrategy(t *testing.T) {
out2, err := p.cache.GetCertAuthority(ctx, ca.GetID(), false)
require.NoError(t, err)
require.Equal(t, out.GetResourceID(), out2.GetResourceID())
require.Empty(t, cmp.Diff(normalizeCA(ca), normalizeCA(out)))
require.Empty(t, cmp.Diff(normalizeCA(ca), normalizeCA(out), cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// add modification and expect the resource to recover
ca.SetRoleMap(types.RoleMap{types.RoleMapping{Remote: "test", Local: []string{"local-test"}}})
@@ -1089,7 +1087,7 @@ func initStrategy(t *testing.T) {
// new value is available now
out, err = p.cache.GetCertAuthority(ctx, ca.GetID(), false)
require.NoError(t, err)
require.Empty(t, cmp.Diff(normalizeCA(ca), normalizeCA(out)))
require.Empty(t, cmp.Diff(normalizeCA(ca), normalizeCA(out), cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
// TestRecovery tests error recovery scenario
@@ -1132,9 +1130,8 @@ func TestRecovery(t *testing.T) {
out, err := p.cache.GetCertAuthority(context.Background(), ca2.GetID(), false)
require.NoError(t, err)
ca2.SetResourceID(out.GetResourceID())
types.RemoveCASecrets(ca2)
require.Empty(t, cmp.Diff(ca2, out))
require.Empty(t, cmp.Diff(ca2, out, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
// TestTokens tests static and dynamic tokens
@@ -1168,8 +1165,7 @@ func TestTokens(t *testing.T) {
out, err := p.cache.GetStaticTokens()
require.NoError(t, err)
staticTokens.SetResourceID(out.GetResourceID())
require.Empty(t, cmp.Diff(staticTokens, out))
require.Empty(t, cmp.Diff(staticTokens, out, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
expires := time.Now().Add(10 * time.Hour).Truncate(time.Second).UTC()
token, err := types.NewProvisionToken("token", types.SystemRoles{types.RoleAuth, types.RoleNode}, expires)
@@ -1187,8 +1183,7 @@ func TestTokens(t *testing.T) {
tout, err := p.cache.GetToken(ctx, token.GetName())
require.NoError(t, err)
token.SetResourceID(tout.GetResourceID())
require.Empty(t, cmp.Diff(token, tout))
require.Empty(t, cmp.Diff(token, tout, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = p.provisionerS.DeleteToken(ctx, token.GetName())
require.NoError(t, err)
@@ -1230,8 +1225,7 @@ func TestAuthPreference(t *testing.T) {
outAuthPref, err := p.cache.GetAuthPreference(ctx)
require.NoError(t, err)
authPref.SetResourceID(outAuthPref.GetResourceID())
require.Empty(t, cmp.Diff(outAuthPref, authPref))
require.Empty(t, cmp.Diff(outAuthPref, authPref, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
func TestClusterNetworkingConfig(t *testing.T) {
@@ -1260,8 +1254,7 @@ func TestClusterNetworkingConfig(t *testing.T) {
outNetConfig, err := p.cache.GetClusterNetworkingConfig(ctx)
require.NoError(t, err)
netConfig.SetResourceID(outNetConfig.GetResourceID())
require.Empty(t, cmp.Diff(outNetConfig, netConfig))
require.Empty(t, cmp.Diff(outNetConfig, netConfig, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
func TestSessionRecordingConfig(t *testing.T) {
@@ -1290,8 +1283,7 @@ func TestSessionRecordingConfig(t *testing.T) {
outRecConfig, err := p.cache.GetSessionRecordingConfig(ctx)
require.NoError(t, err)
recConfig.SetResourceID(outRecConfig.GetResourceID())
require.Empty(t, cmp.Diff(outRecConfig, recConfig))
require.Empty(t, cmp.Diff(outRecConfig, recConfig, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
func TestClusterAuditConfig(t *testing.T) {
@@ -1319,8 +1311,7 @@ func TestClusterAuditConfig(t *testing.T) {
outAuditConfig, err := p.cache.GetClusterAuditConfig(ctx)
require.NoError(t, err)
auditConfig.SetResourceID(outAuditConfig.GetResourceID())
require.Empty(t, cmp.Diff(outAuditConfig, auditConfig))
require.Empty(t, cmp.Diff(outAuditConfig, auditConfig, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
func TestClusterName(t *testing.T) {
@@ -1347,8 +1338,7 @@ func TestClusterName(t *testing.T) {
outName, err := p.cache.GetClusterName()
require.NoError(t, err)
clusterName.SetResourceID(outName.GetResourceID())
require.Empty(t, cmp.Diff(outName, clusterName))
require.Empty(t, cmp.Diff(outName, clusterName, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
// TestNamespaces tests caching of namespaces
@@ -1376,8 +1366,7 @@ func TestNamespaces(t *testing.T) {
out, err := p.cache.GetNamespace(ns.GetName())
require.NoError(t, err)
ns.SetResourceID(out.GetResourceID())
require.Empty(t, cmp.Diff(ns, out))
require.Empty(t, cmp.Diff(ns, out, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// update namespace metadata
ns.Metadata.Labels = map[string]string{"a": "b"}
@@ -1397,8 +1386,7 @@ func TestNamespaces(t *testing.T) {
out, err = p.cache.GetNamespace(ns.GetName())
require.NoError(t, err)
ns.SetResourceID(out.GetResourceID())
require.Empty(t, cmp.Diff(ns, out))
require.Empty(t, cmp.Diff(ns, out, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = p.presenceS.DeleteNamespace(ns.GetName())
require.NoError(t, err)
@@ -2204,8 +2192,8 @@ func testResources[T types.Resource](t *testing.T, p *testPack, funcs testFuncs[
require.NoError(t, err)
cmpOpts := []cmp.Option{
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(header.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.IgnoreFields(header.Metadata{}, "ID", "Revision"),
}
// Check that the resource is now in the backend.
+8 -8
View File
@@ -70,7 +70,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.KubeClusters{kube0}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -87,7 +87,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.KubeClusters{kube0, kube1}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -104,7 +104,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.KubeClusters{kube0, kube1}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -121,7 +121,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.KubeClusters{kube0, kube1}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -137,7 +137,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.KubeClusters{kube0, kube1, kube2}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -154,7 +154,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.KubeClusters{kube0, kube1, kube2}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// make sure credentials were updated as well.
require.Equal(t, strings.TrimPrefix(kubeMock.URL, "https://"), testCtx.KubeServer.fwd.clusterDetails["kube2"].kubeCreds.getTargetAddr())
@@ -172,7 +172,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.KubeClusters{kube0, kube2}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -186,7 +186,7 @@ func TestWatcher(t *testing.T) {
select {
case a := <-reconcileCh:
require.Empty(t, cmp.Diff(types.KubeClusters{kube0}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
+8
View File
@@ -72,6 +72,7 @@ func MarshalAccessList(accessList *accesslist.AccessList, opts ...MarshalOption)
if !cfg.PreserveResourceID {
copy := *accessList
copy.SetResourceID(0)
copy.SetRevision("")
accessList = &copy
}
return utils.FastMarshal(accessList)
@@ -96,6 +97,9 @@ func UnmarshalAccessList(data []byte, opts ...MarshalOption) (*accesslist.Access
if cfg.ID != 0 {
accessList.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
accessList.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
accessList.SetExpiry(cfg.Expires)
}
@@ -138,6 +142,7 @@ func MarshalAccessListMember(member *accesslist.AccessListMember, opts ...Marsha
if !cfg.PreserveResourceID {
copy := *member
copy.SetResourceID(0)
copy.SetRevision("")
member = &copy
}
return utils.FastMarshal(member)
@@ -162,6 +167,9 @@ func UnmarshalAccessListMember(data []byte, opts ...MarshalOption) (*accesslist.
if cfg.ID != 0 {
member.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
member.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
member.SetExpiry(cfg.Expires)
}
+4
View File
@@ -1577,6 +1577,9 @@ func UnmarshalAccessRequest(data []byte, opts ...MarshalOption) (types.AccessReq
if cfg.ID != 0 {
req.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
req.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
req.SetExpiry(cfg.Expires)
}
@@ -1601,6 +1604,7 @@ func MarshalAccessRequest(accessRequest types.AccessRequest, opts ...MarshalOpti
// to prevent unexpected data races
copy := *accessRequest
copy.SetResourceID(0)
copy.SetRevision("")
accessRequest = &copy
}
return utils.FastMarshal(accessRequest)
+8
View File
@@ -67,6 +67,7 @@ func MarshalApp(app types.Application, opts ...MarshalOption) ([]byte, error) {
if !cfg.PreserveResourceID {
copy := *app
copy.SetResourceID(0)
copy.SetRevision("")
app = &copy
}
return utils.FastMarshal(app)
@@ -100,6 +101,9 @@ func UnmarshalApp(data []byte, opts ...MarshalOption) (types.Application, error)
if cfg.ID != 0 {
app.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
app.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
app.SetExpiry(cfg.Expires)
}
@@ -124,6 +128,7 @@ func MarshalAppServer(appServer types.AppServer, opts ...MarshalOption) ([]byte,
if !cfg.PreserveResourceID {
copy := *appServer
copy.SetResourceID(0)
copy.SetRevision("")
appServer = &copy
}
return utils.FastMarshal(appServer)
@@ -157,6 +162,9 @@ func UnmarshalAppServer(data []byte, opts ...MarshalOption) (types.AppServer, er
if cfg.ID != 0 {
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
+4
View File
@@ -59,6 +59,9 @@ func UnmarshalClusterAuditConfig(bytes []byte, opts ...MarshalOption) (types.Clu
if cfg.ID != 0 {
auditConfig.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
auditConfig.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
auditConfig.SetExpiry(cfg.Expires)
}
@@ -83,6 +86,7 @@ func MarshalClusterAuditConfig(auditConfig types.ClusterAuditConfig, opts ...Mar
// to prevent unexpected data races
copy := *auditConfig
copy.SetResourceID(0)
copy.SetRevision("")
auditConfig = &copy
}
return utils.FastMarshal(auditConfig)
+3
View File
@@ -117,6 +117,9 @@ func UnmarshalAuthPreference(bytes []byte, opts ...MarshalOption) (types.AuthPre
if cfg.ID != 0 {
authPreference.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
authPreference.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
authPreference.SetExpiry(cfg.Expires)
}
+5 -1
View File
@@ -47,7 +47,7 @@ import (
func CertAuthoritiesEquivalent(lhs, rhs types.CertAuthority) bool {
return cmp.Equal(lhs, rhs,
ignoreProtoXXXFields(),
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
// Optimize types.CAKeySet comparison.
cmp.Comparer(func(a, b types.CAKeySet) bool {
// Note that Clone drops XXX_ fields. And it's benchmarked that cloning
@@ -473,6 +473,9 @@ func UnmarshalCertAuthority(bytes []byte, opts ...MarshalOption) (types.CertAuth
if cfg.ID != 0 {
ca.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
ca.SetRevision(cfg.Revision)
}
// Correct problems with existing CAs that contain non-UTC times, which
// causes panics when doing a gogoproto Clone; should only ever be
// possible with LastRotated, but we enforce it on all the times anyway.
@@ -509,6 +512,7 @@ func MarshalCertAuthority(certAuthority types.CertAuthority, opts ...MarshalOpti
// to prevent unexpected data races
copy := *certAuthority
copy.SetResourceID(0)
copy.SetRevision("")
certAuthority = &copy
}
return utils.FastMarshal(certAuthority)
+4
View File
@@ -58,6 +58,9 @@ func UnmarshalClusterName(bytes []byte, opts ...MarshalOption) (types.ClusterNam
if cfg.ID != 0 {
clusterName.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
clusterName.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
clusterName.SetExpiry(cfg.Expires)
}
@@ -83,6 +86,7 @@ func MarshalClusterName(clusterName types.ClusterName, opts ...MarshalOption) ([
// to prevent unexpected data races
copy := *clusterName
copy.SetResourceID(0)
copy.SetRevision("")
clusterName = &copy
}
return utils.FastMarshal(clusterName)
+1 -1
View File
@@ -29,7 +29,7 @@ import (
func CompareResources(resA, resB types.Resource) int {
equal := cmp.Equal(resA, resB,
ignoreProtoXXXFields(),
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.IgnoreFields(types.DatabaseV3{}, "Status"),
cmpopts.EquateEmpty(),
)
+5
View File
@@ -66,6 +66,7 @@ func MarshalConnectionDiagnostic(s types.ConnectionDiagnostic, opts ...MarshalOp
// to prevent unexpected data races
copy := *s
copy.SetResourceID(0)
copy.SetRevision("")
s = &copy
}
@@ -106,6 +107,10 @@ func UnmarshalConnectionDiagnostic(data []byte, opts ...MarshalOption) (types.Co
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
+4
View File
@@ -97,6 +97,7 @@ func MarshalDatabase(database types.Database, opts ...MarshalOption) ([]byte, er
// to prevent unexpected data races
copy := *database
copy.SetResourceID(0)
copy.SetRevision("")
database = &copy
}
return utils.FastMarshal(database)
@@ -130,6 +131,9 @@ func UnmarshalDatabase(data []byte, opts ...MarshalOption) (types.Database, erro
if cfg.ID != 0 {
database.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
database.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
database.SetExpiry(cfg.Expires)
}
+4
View File
@@ -41,6 +41,7 @@ func MarshalDatabaseServer(databaseServer types.DatabaseServer, opts ...MarshalO
// to prevent unexpected data races
copy := *databaseServer
copy.SetResourceID(0)
copy.SetRevision("")
databaseServer = &copy
}
return utils.FastMarshal(databaseServer)
@@ -74,6 +75,9 @@ func UnmarshalDatabaseServer(data []byte, opts ...MarshalOption) (types.Database
if cfg.ID != 0 {
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
+4
View File
@@ -55,6 +55,7 @@ func MarshalDatabaseService(databaseService types.DatabaseService, opts ...Marsh
// to prevent unexpected data races
copy := *databaseService
copy.SetResourceID(0)
copy.SetRevision("")
databaseService = &copy
}
return utils.FastMarshal(databaseService)
@@ -88,6 +89,9 @@ func UnmarshalDatabaseService(data []byte, opts ...MarshalOption) (types.Databas
if cfg.ID != 0 {
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
+8
View File
@@ -60,6 +60,7 @@ func MarshalWindowsDesktop(s types.WindowsDesktop, opts ...MarshalOption) ([]byt
// to prevent unexpected data races
copy := *s
copy.SetResourceID(0)
copy.SetRevision("")
s = &copy
}
return utils.FastMarshal(s)
@@ -93,6 +94,9 @@ func UnmarshalWindowsDesktop(data []byte, opts ...MarshalOption) (types.WindowsD
if cfg.ID != 0 {
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
@@ -119,6 +123,7 @@ func MarshalWindowsDesktopService(s types.WindowsDesktopService, opts ...Marshal
// to prevent unexpected data races
copy := *s
copy.SetResourceID(0)
copy.SetRevision("")
s = &copy
}
return utils.FastMarshal(s)
@@ -152,6 +157,9 @@ func UnmarshalWindowsDesktopService(data []byte, opts ...MarshalOption) (types.W
if cfg.ID != 0 {
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
+1
View File
@@ -167,6 +167,7 @@ func marshalGithubConnector(githubConnector types.GithubConnector, opts ...Marsh
// to prevent unexpected data races
copy := *githubConnector
copy.SetResourceID(0)
copy.SetRevision("")
githubConnector = &copy
}
return utils.FastMarshal(githubConnector)
+4
View File
@@ -46,6 +46,9 @@ func UnmarshalInstaller(data []byte, opts ...MarshalOption) (types.Installer, er
if cfg.ID != 0 {
installer.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
installer.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
installer.SetExpiry(cfg.Expires)
}
@@ -68,6 +71,7 @@ func MarshalInstaller(installer types.Installer, opts ...MarshalOption) ([]byte,
// to prevent unexpected data races
copy := *installer
copy.SetResourceID(0)
copy.SetRevision("")
installer = &copy
}
return utils.FastMarshal(installer)
+4
View File
@@ -62,6 +62,7 @@ func MarshalIntegration(ig types.Integration, opts ...MarshalOption) ([]byte, er
if !cfg.PreserveResourceID {
copy := *g
copy.SetResourceID(0)
copy.SetRevision("")
g = &copy
}
return utils.FastMarshal(g)
@@ -91,6 +92,9 @@ func UnmarshalIntegration(data []byte, opts ...MarshalOption) (types.Integration
if cfg.ID != 0 {
ig.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
ig.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
ig.SetExpiry(cfg.Expires)
}
+8
View File
@@ -77,6 +77,7 @@ func MarshalKubeServer(kubeServer types.KubeServer, opts ...MarshalOption) ([]by
if !cfg.PreserveResourceID {
copy := *server
copy.SetResourceID(0)
copy.SetRevision("")
server = &copy
}
return utils.FastMarshal(server)
@@ -110,6 +111,9 @@ func UnmarshalKubeServer(data []byte, opts ...MarshalOption) (types.KubeServer,
if cfg.ID != 0 {
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
@@ -134,6 +138,7 @@ func MarshalKubeCluster(kubeCluster types.KubeCluster, opts ...MarshalOption) ([
if !cfg.PreserveResourceID {
copy := *cluster
copy.SetResourceID(0)
copy.SetRevision("")
cluster = &copy
}
return utils.FastMarshal(cluster)
@@ -167,6 +172,9 @@ func UnmarshalKubeCluster(data []byte, opts ...MarshalOption) (types.KubeCluster
if cfg.ID != 0 {
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
+1
View File
@@ -64,6 +64,7 @@ func MarshalLicense(license types.License, opts ...MarshalOption) ([]byte, error
// to prevent unexpected data races
copy := *license
copy.SetResourceID(0)
copy.SetRevision("")
license = &copy
}
return utils.FastMarshal(license)
+4 -4
View File
@@ -54,7 +54,7 @@ func (s *AccessService) GetRoles(ctx context.Context) ([]types.Role, error) {
out := make([]types.Role, 0, len(result.Items))
for _, item := range result.Items {
role, err := services.UnmarshalRole(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
// Try to get the role name for the error, it allows admins to take action
// against the "bad" role.
@@ -132,7 +132,7 @@ func (s *AccessService) GetRole(ctx context.Context, name string) (types.Role, e
return nil, trace.Wrap(err)
}
return services.UnmarshalRole(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
}
// DeleteRole deletes a role from the backend
@@ -161,7 +161,7 @@ func (s *AccessService) GetLock(ctx context.Context, name string) (types.Lock, e
}
return nil, trace.Wrap(err)
}
return services.UnmarshalLock(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
return services.UnmarshalLock(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
}
// GetLocks gets all/in-force locks that match at least one of the targets when specified.
@@ -174,7 +174,7 @@ func (s *AccessService) GetLocks(ctx context.Context, inForceOnly bool, targets
out := []types.Lock{}
for _, item := range result.Items {
lock, err := services.UnmarshalLock(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
lock, err := services.UnmarshalLock(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
+3 -3
View File
@@ -57,7 +57,7 @@ func TestAccessListCRUD(t *testing.T) {
require.Empty(t, out)
cmpOpts := []cmp.Option{
cmpopts.IgnoreFields(header.Metadata{}, "ID"),
cmpopts.IgnoreFields(header.Metadata{}, "ID", "Revision"),
}
// Create both access lists.
@@ -179,7 +179,7 @@ func TestAccessListUpsertWithMembers(t *testing.T) {
accessList1 := newAccessList(t, "accessList1")
cmpOpts := []cmp.Option{
cmpopts.IgnoreFields(header.Metadata{}, "ID"),
cmpopts.IgnoreFields(header.Metadata{}, "ID", "Revision"),
}
t.Run("create access list", func(t *testing.T) {
@@ -256,7 +256,7 @@ func TestAccessListMembersCRUD(t *testing.T) {
accessList2 := newAccessList(t, "accessList2")
cmpOpts := []cmp.Option{
cmpopts.IgnoreFields(header.Metadata{}, "ID"),
cmpopts.IgnoreFields(header.Metadata{}, "ID", "Revision"),
}
// Create both access lists.
+6 -6
View File
@@ -78,7 +78,7 @@ func TestLockCRUD(t *testing.T) {
require.NoError(t, err)
require.Len(t, locks, 2)
require.Empty(t, cmp.Diff([]types.Lock{lock1, lock2}, locks,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
})
t.Run("GetLocks with targets", func(t *testing.T) {
@@ -88,7 +88,7 @@ func TestLockCRUD(t *testing.T) {
require.NoError(t, err)
require.Len(t, locks, 2)
require.Empty(t, cmp.Diff([]types.Lock{lock1, lock2}, locks,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Match only one of the locks.
roleTarget := types.LockTarget{Role: "role-A"}
@@ -96,7 +96,7 @@ func TestLockCRUD(t *testing.T) {
require.NoError(t, err)
require.Len(t, locks, 1)
require.Empty(t, cmp.Diff([]types.Lock{lock1}, locks,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Match none of the locks.
locks, err = access.GetLocks(ctx, false, roleTarget)
@@ -109,7 +109,7 @@ func TestLockCRUD(t *testing.T) {
lock, err := access.GetLock(ctx, lock1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(lock1, lock,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Attempt to get a nonexistent lock.
_, err = access.GetLock(ctx, "lock3")
@@ -166,7 +166,7 @@ func TestLockCRUD(t *testing.T) {
require.NoError(t, err)
require.Len(t, locks, 2)
require.Empty(t, cmp.Diff(newRemoteLocks, locks,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
for _, lock := range locks {
require.True(t, strings.HasPrefix(lock.GetName(), clusterName+"/"))
}
@@ -181,7 +181,7 @@ func TestLockCRUD(t *testing.T) {
require.NoError(t, err)
require.Len(t, locks, 1)
require.Empty(t, cmp.Diff(newRemoteLocks, locks,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
_, err = access.GetLock(ctx, lock2.GetName())
require.Error(t, err)
require.True(t, trace.IsNotFound(err))
+2 -2
View File
@@ -46,7 +46,7 @@ func (s *AppService) GetApps(ctx context.Context) ([]types.Application, error) {
apps := make([]types.Application, len(result.Items))
for i, item := range result.Items {
app, err := services.UnmarshalApp(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -65,7 +65,7 @@ func (s *AppService) GetApp(ctx context.Context, name string) (types.Application
return nil, trace.Wrap(err)
}
app, err := services.UnmarshalApp(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
+4 -4
View File
@@ -71,14 +71,14 @@ func TestAppsCRUD(t *testing.T) {
out, err = service.GetApps(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Application{app1, app2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific application.
app, err := service.GetApp(ctx, app2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(app2, app,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch an application that doesn't exist.
@@ -96,7 +96,7 @@ func TestAppsCRUD(t *testing.T) {
app, err = service.GetApp(ctx, app1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(app1, app,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete an application.
@@ -105,7 +105,7 @@ func TestAppsCRUD(t *testing.T) {
out, err = service.GetApps(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Application{app2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete an application that doesn't exist.
+6 -6
View File
@@ -68,7 +68,7 @@ func (s *ClusterConfigurationService) GetClusterName(opts ...services.MarshalOpt
return nil, trace.Wrap(err)
}
return services.UnmarshalClusterName(item.Value,
services.AddOptions(opts, services.WithResourceID(item.ID))...)
services.AddOptions(opts, services.WithResourceID(item.ID), services.WithRevision(item.Revision))...)
}
// DeleteClusterName deletes types.ClusterName from the backend.
@@ -133,7 +133,7 @@ func (s *ClusterConfigurationService) GetStaticTokens() (types.StaticTokens, err
return nil, trace.Wrap(err)
}
return services.UnmarshalStaticTokens(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
}
// SetStaticTokens sets the list of static tokens used to provision nodes.
@@ -178,7 +178,7 @@ func (s *ClusterConfigurationService) GetAuthPreference(ctx context.Context) (ty
return nil, trace.Wrap(err)
}
return services.UnmarshalAuthPreference(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
}
// SetAuthPreference sets the cluster authentication preferences
@@ -229,7 +229,7 @@ func (s *ClusterConfigurationService) GetClusterAuditConfig(ctx context.Context,
}
return nil, trace.Wrap(err)
}
return services.UnmarshalClusterAuditConfig(item.Value, append(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires))...)
return services.UnmarshalClusterAuditConfig(item.Value, append(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))...)
}
// SetClusterAuditConfig sets the cluster audit config on the backend.
@@ -273,7 +273,7 @@ func (s *ClusterConfigurationService) GetClusterNetworkingConfig(ctx context.Con
}
return nil, trace.Wrap(err)
}
return services.UnmarshalClusterNetworkingConfig(item.Value, append(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires))...)
return services.UnmarshalClusterNetworkingConfig(item.Value, append(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))...)
}
// SetClusterNetworkingConfig sets the cluster networking config
@@ -323,7 +323,7 @@ func (s *ClusterConfigurationService) GetSessionRecordingConfig(ctx context.Cont
}
return nil, trace.Wrap(err)
}
return services.UnmarshalSessionRecordingConfig(item.Value, append(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires))...)
return services.UnmarshalSessionRecordingConfig(item.Value, append(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))...)
}
// SetSessionRecordingConfig sets session recording config on the backend.
+1 -1
View File
@@ -135,7 +135,7 @@ func (s *ConnectionDiagnosticService) GetConnectionDiagnostic(ctx context.Contex
}
connectionDiagnostic, err := services.UnmarshalConnectionDiagnostic(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
+2 -2
View File
@@ -46,7 +46,7 @@ func (s *DatabaseService) GetDatabases(ctx context.Context) ([]types.Database, e
databases := make([]types.Database, len(result.Items))
for i, item := range result.Items {
database, err := services.UnmarshalDatabase(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -65,7 +65,7 @@ func (s *DatabaseService) GetDatabase(ctx context.Context, name string) (types.D
return nil, trace.Wrap(err)
}
database, err := services.UnmarshalDatabase(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
+4 -4
View File
@@ -84,14 +84,14 @@ func TestDatabasesCRUD(t *testing.T) {
out, err = service.GetDatabases(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Database{dbBadURI, db1, db2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific database.
db, err := service.GetDatabase(ctx, db2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(db2, db,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch a database that doesn't exist.
@@ -109,7 +109,7 @@ func TestDatabasesCRUD(t *testing.T) {
db, err = service.GetDatabase(ctx, db1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(db1, db,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete a database.
@@ -118,7 +118,7 @@ func TestDatabasesCRUD(t *testing.T) {
out, err = service.GetDatabases(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Database{dbBadURI, db2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete a database that doesn't exist.
+3 -3
View File
@@ -47,7 +47,7 @@ func (s *WindowsDesktopService) GetWindowsDesktops(ctx context.Context, filter t
var desktops []types.WindowsDesktop
for _, item := range result.Items {
desktop, err := services.UnmarshalWindowsDesktop(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -184,7 +184,7 @@ func (s *WindowsDesktopService) ListWindowsDesktops(ctx context.Context, req typ
}
desktop, err := services.UnmarshalWindowsDesktop(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return false, trace.Wrap(err)
}
@@ -249,7 +249,7 @@ func (s *WindowsDesktopService) ListWindowsDesktopServices(ctx context.Context,
}
desktop, err := services.UnmarshalWindowsDesktopService(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return false, trace.Wrap(err)
}
+1 -1
View File
@@ -76,7 +76,7 @@ func TestListWindowsDesktops(t *testing.T) {
require.NoError(t, err)
require.Empty(t, out.NextKey)
require.Empty(t, cmp.Diff([]types.WindowsDesktop{d1, d2, d3}, out.Desktops,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Test pagination.
+2
View File
@@ -507,6 +507,7 @@ func itemToAccessRequest(item backend.Item, opts ...services.MarshalOption) (typ
opts,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
req, err := services.UnmarshalAccessRequest(
item.Value,
@@ -541,6 +542,7 @@ func itemToPluginData(item backend.Item) (types.PluginData, error) {
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
+38 -1
View File
@@ -358,7 +358,7 @@ func (p *certAuthorityParser) parse(event backend.Event) (types.Resource, error)
}, nil
case types.OpPut:
ca, err := services.UnmarshalCertAuthority(event.Item.Value,
services.WithResourceID(event.Item.ID), services.WithExpires(event.Item.Expires))
services.WithResourceID(event.Item.ID), services.WithExpires(event.Item.Expires), services.WithRevision(event.Item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -389,6 +389,7 @@ func (p *provisionTokenParser) parse(event backend.Event) (types.Resource, error
token, err := services.UnmarshalProvisionToken(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -422,6 +423,7 @@ func (p *staticTokensParser) parse(event backend.Event) (types.Resource, error)
tokens, err := services.UnmarshalStaticTokens(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -456,6 +458,7 @@ func (p *clusterAuditConfigParser) parse(event backend.Event) (types.Resource, e
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -490,6 +493,7 @@ func (p *clusterNetworkingConfigParser) parse(event backend.Event) (types.Resour
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -524,6 +528,7 @@ func (p *authPreferenceParser) parse(event backend.Event) (types.Resource, error
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -558,6 +563,7 @@ func (p *uiConfigParser) parse(event backend.Event) (types.Resource, error) {
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -592,6 +598,7 @@ func (p *sessionRecordingConfigParser) parse(event backend.Event) (types.Resourc
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -625,6 +632,7 @@ func (p *clusterNameParser) parse(event backend.Event) (types.Resource, error) {
clusterName, err := services.UnmarshalClusterName(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -665,6 +673,7 @@ func (p *namespaceParser) parse(event backend.Event) (types.Resource, error) {
namespace, err := services.UnmarshalNamespace(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -693,6 +702,7 @@ func (p *roleParser) parse(event backend.Event) (types.Resource, error) {
resource, err := services.UnmarshalRole(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -779,6 +789,7 @@ func (p *userParser) parse(event backend.Event) (types.Resource, error) {
resource, err := services.UnmarshalUser(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -861,6 +872,7 @@ func (p *tunnelConnectionParser) parse(event backend.Event) (types.Resource, err
resource, err := services.UnmarshalTunnelConnection(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -889,6 +901,7 @@ func (p *reverseTunnelParser) parse(event backend.Event) (types.Resource, error)
resource, err := services.UnmarshalReverseTunnel(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -993,6 +1006,7 @@ func (p *webSessionParser) parse(event backend.Event) (types.Resource, error) {
resource, err := services.UnmarshalWebSession(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -1021,6 +1035,7 @@ func (p *webTokenParser) parse(event backend.Event) (types.Resource, error) {
resource, err := services.UnmarshalWebToken(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -1062,6 +1077,7 @@ func (p *kubeServerParser) parse(event backend.Event) (types.Resource, error) {
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1099,6 +1115,7 @@ func (p *databaseServerParser) parse(event backend.Event) (types.Resource, error
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1124,6 +1141,7 @@ func (p *databaseServiceParser) parse(event backend.Event) (types.Resource, erro
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1148,6 +1166,7 @@ func (p *kubeClusterParser) parse(event backend.Event) (types.Resource, error) {
return services.UnmarshalKubeCluster(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1172,6 +1191,7 @@ func (p *appParser) parse(event backend.Event) (types.Resource, error) {
return services.UnmarshalApp(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1196,6 +1216,7 @@ func (p *databaseParser) parse(event backend.Event) (types.Resource, error) {
return services.UnmarshalDatabase(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1211,6 +1232,7 @@ func parseServer(event backend.Event, kind string) (types.Resource, error) {
kind,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -1247,6 +1269,7 @@ func (p *remoteClusterParser) parse(event backend.Event) (types.Resource, error)
resource, err := services.UnmarshalRemoteCluster(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -1276,6 +1299,7 @@ func (p *lockParser) parse(event backend.Event) (types.Resource, error) {
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1308,6 +1332,7 @@ func (p *networkRestrictionsParser) parse(event backend.Event) (types.Resource,
resource, err := services.UnmarshalNetworkRestrictions(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -1337,6 +1362,7 @@ func (p *windowsDesktopServicesParser) parse(event backend.Event) (types.Resourc
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1374,6 +1400,7 @@ func (p *windowsDesktopsParser) parse(event backend.Event) (types.Resource, erro
event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1402,6 +1429,7 @@ func (p *installerParser) parse(event backend.Event) (types.Resource, error) {
inst, err := services.UnmarshalInstaller(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -1436,6 +1464,7 @@ func (p *pluginParser) parse(event backend.Event) (types.Resource, error) {
plugin, err := services.UnmarshalPlugin(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -1464,6 +1493,7 @@ func (p *samlIDPServiceProviderParser) parse(event backend.Event) (types.Resourc
return services.UnmarshalSAMLIdPServiceProvider(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1488,6 +1518,7 @@ func (p *userGroupParser) parse(event backend.Event) (types.Resource, error) {
return services.UnmarshalUserGroup(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1512,6 +1543,7 @@ func (p *oktaImportRuleParser) parse(event backend.Event) (types.Resource, error
return services.UnmarshalOktaImportRule(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1536,6 +1568,7 @@ func (p *oktaAssignmentParser) parse(event backend.Event) (types.Resource, error
return services.UnmarshalOktaAssignment(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1560,6 +1593,7 @@ func (p *integrationParser) parse(event backend.Event) (types.Resource, error) {
return services.UnmarshalIntegration(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1619,6 +1653,7 @@ func (p *accessListParser) parse(event backend.Event) (types.Resource, error) {
return services.UnmarshalAccessList(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1643,6 +1678,7 @@ func (p *userLoginStateParser) parse(event backend.Event) (types.Resource, error
return services.UnmarshalUserLoginState(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
@@ -1667,6 +1703,7 @@ func (p *accessListMemberParser) parse(event backend.Event) (types.Resource, err
return services.UnmarshalAccessListMember(event.Item.Value,
services.WithResourceID(event.Item.ID),
services.WithExpires(event.Item.Expires),
services.WithRevision(event.Item.Revision),
)
default:
return nil, trace.BadParameter("event %v is not supported", event.Type)
+2 -2
View File
@@ -183,7 +183,7 @@ func (s *Service[T]) GetResource(ctx context.Context, name string) (resource T,
return resource, trace.Wrap(err)
}
resource, err = s.unmarshalFunc(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
return resource, trace.Wrap(err)
}
@@ -257,7 +257,7 @@ func (s *Service[T]) UpdateAndSwapResource(ctx context.Context, name string, mod
}
resource, err := s.unmarshalFunc(existingItem.Value,
services.WithResourceID(existingItem.ID), services.WithExpires(existingItem.Expires))
services.WithResourceID(existingItem.ID), services.WithExpires(existingItem.Expires), services.WithRevision(existingItem.Revision))
if err != nil {
return trace.Wrap(err)
}
+13 -10
View File
@@ -87,6 +87,9 @@ func unmarshalResource(data []byte, opts ...services.MarshalOption) (*testResour
if cfg.ID != 0 {
r.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
r.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
r.SetExpiry(cfg.Expires)
}
@@ -134,7 +137,7 @@ func TestGenericCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]*testResource{r1, r2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a paginated list of resources.
@@ -153,21 +156,21 @@ func TestGenericCRUD(t *testing.T) {
require.Equal(t, 2, numPages)
require.Empty(t, cmp.Diff([]*testResource{r1, r2}, paginatedOut,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a list of all resources
allResources, err := service.GetResources(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff(paginatedOut, allResources,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific service provider.
r, err := service.GetResource(ctx, r2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(r2, r,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch a resource that doesn't exist.
@@ -185,7 +188,7 @@ func TestGenericCRUD(t *testing.T) {
r, err = service.GetResource(ctx, r1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(r1, r,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Update a resource that doesn't exist.
@@ -200,7 +203,7 @@ func TestGenericCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]*testResource{r2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Upsert a resource (create).
@@ -210,7 +213,7 @@ func TestGenericCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]*testResource{r1, r2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Upsert a resource (update).
@@ -221,7 +224,7 @@ func TestGenericCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]*testResource{r1, r2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Update and swap a value
@@ -234,7 +237,7 @@ func TestGenericCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]*testResource{r1, r2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete a resource that doesn't exist.
@@ -249,7 +252,7 @@ func TestGenericCRUD(t *testing.T) {
r, err = unmarshalResource(item.Value)
require.NoError(t, err)
require.Empty(t, cmp.Diff(r1, r,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
return nil
+2 -2
View File
@@ -46,7 +46,7 @@ func (s *KubernetesService) GetKubernetesClusters(ctx context.Context) ([]types.
kubeClusters := make([]types.KubeCluster, len(result.Items))
for i, item := range result.Items {
cluster, err := services.UnmarshalKubeCluster(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -65,7 +65,7 @@ func (s *KubernetesService) GetKubernetesCluster(ctx context.Context, name strin
return nil, trace.Wrap(err)
}
cluster, err := services.UnmarshalKubeCluster(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
+4 -4
View File
@@ -67,14 +67,14 @@ func TestKubernetesCRUD(t *testing.T) {
out, err = service.GetKubernetesClusters(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.KubeCluster{kubeCluster1, kubeCluster2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific Kubernetes.
cluster, err := service.GetKubernetesCluster(ctx, kubeCluster2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(kubeCluster2, cluster,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch a Kubernetes that doesn't exist.
@@ -92,7 +92,7 @@ func TestKubernetesCRUD(t *testing.T) {
cluster, err = service.GetKubernetesCluster(ctx, kubeCluster1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(kubeCluster1, cluster,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete a Kubernetes.
@@ -101,7 +101,7 @@ func TestKubernetesCRUD(t *testing.T) {
out, err = service.GetKubernetesClusters(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.KubeCluster{kubeCluster2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete a Kubernetes that doesn't exist.
+15 -15
View File
@@ -118,13 +118,13 @@ func TestOktaImportRuleCRUD(t *testing.T) {
importRule, err := service.CreateOktaImportRule(ctx, importRule1)
require.NoError(t, err)
require.Empty(t, cmp.Diff(importRule1, importRule,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
importRule, err = service.CreateOktaImportRule(ctx, importRule2)
require.NoError(t, err)
require.Empty(t, cmp.Diff(importRule2, importRule,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch all import rules.
@@ -132,7 +132,7 @@ func TestOktaImportRuleCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]types.OktaImportRule{importRule1, importRule2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a paginated list of import rules
@@ -149,14 +149,14 @@ func TestOktaImportRuleCRUD(t *testing.T) {
require.Len(t, paginatedOut, 2)
require.Empty(t, cmp.Diff([]types.OktaImportRule{importRule1, importRule2}, paginatedOut,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific import rule.
importRule, err = service.GetOktaImportRule(ctx, importRule2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(importRule2, importRule,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch an import rule that doesn't exist.
@@ -174,7 +174,7 @@ func TestOktaImportRuleCRUD(t *testing.T) {
importRule, err = service.GetOktaImportRule(ctx, importRule1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(importRule1, importRule,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete an import rule
@@ -184,7 +184,7 @@ func TestOktaImportRuleCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]types.OktaImportRule{importRule2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete an import rule that doesn't exist.
@@ -330,13 +330,13 @@ func TestOktaAssignmentCRUD(t *testing.T) {
assignment, err := service.CreateOktaAssignment(ctx, assignment1)
require.NoError(t, err)
require.Empty(t, cmp.Diff(assignment1, assignment,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
assignment, err = service.CreateOktaAssignment(ctx, assignment2)
require.NoError(t, err)
require.Empty(t, cmp.Diff(assignment2, assignment,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch all assignments.
@@ -344,7 +344,7 @@ func TestOktaAssignmentCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]types.OktaAssignment{assignment1, assignment2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a paginated list of assignments
@@ -363,14 +363,14 @@ func TestOktaAssignmentCRUD(t *testing.T) {
require.Equal(t, 2, numPages)
require.Empty(t, cmp.Diff([]types.OktaAssignment{assignment1, assignment2}, paginatedOut,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific assignment.
assignment, err = service.GetOktaAssignment(ctx, assignment2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(assignment2, assignment,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch an assignment that doesn't exist.
@@ -392,7 +392,7 @@ func TestOktaAssignmentCRUD(t *testing.T) {
assignment, err = service.GetOktaAssignment(ctx, assignment1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(assignment1, assignment,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fail to update the status for an assignment due to a bad transition.
@@ -410,7 +410,7 @@ func TestOktaAssignmentCRUD(t *testing.T) {
assignment, err = service.GetOktaAssignment(ctx, assignment1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(assignment1, assignment,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete an assignment
@@ -420,7 +420,7 @@ func TestOktaAssignmentCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]types.OktaAssignment{assignment2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete an assignment that doesn't exist.
@@ -83,7 +83,7 @@ func TestPluginStaticCredentialsCRUD(t *testing.T) {
cred, err := service.GetPluginStaticCredentials(ctx, cred1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(cred1, cred,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch a static credential that doesn't exist.
@@ -101,7 +101,7 @@ func TestPluginStaticCredentialsCRUD(t *testing.T) {
})
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.PluginStaticCredentials{cred1}, creds,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
creds, err = service.GetPluginStaticCredentialsByLabels(ctx, map[string]string{
@@ -109,7 +109,7 @@ func TestPluginStaticCredentialsCRUD(t *testing.T) {
})
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.PluginStaticCredentials{cred1, cred2}, creds,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
creds, err = service.GetPluginStaticCredentialsByLabels(ctx, map[string]string{
@@ -118,7 +118,7 @@ func TestPluginStaticCredentialsCRUD(t *testing.T) {
})
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.PluginStaticCredentials{cred2}, creds,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete a static credential.
+3 -3
View File
@@ -92,7 +92,7 @@ func (s *PluginsService) GetPlugin(ctx context.Context, name string, withSecrets
}
plugin, err := services.UnmarshalPlugin(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -139,7 +139,7 @@ func (s *PluginsService) ListPlugins(ctx context.Context, limit int, startKey st
plugins := make([]types.Plugin, 0, len(result.Items))
for _, item := range result.Items {
plugin, err := services.UnmarshalPlugin(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
plugin, err := services.UnmarshalPlugin(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, "", trace.Wrap(err)
}
@@ -199,7 +199,7 @@ func (s *PluginsService) updateAndSwap(ctx context.Context, name string, modify
}
plugin, err := services.UnmarshalPlugin(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return trace.Wrap(err)
}
+6 -6
View File
@@ -76,14 +76,14 @@ func TestPluginsCRUD(t *testing.T) {
out, err = service.GetPlugins(ctx, true)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Plugin{plugin1, plugin2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific plugin.
cluster, err := service.GetPlugin(ctx, plugin2.GetName(), true)
require.NoError(t, err)
require.Empty(t, cmp.Diff(plugin2, cluster,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch a plugin that doesn't exist.
@@ -104,7 +104,7 @@ func TestPluginsCRUD(t *testing.T) {
require.NoError(t, err)
// Fields other than Status should remain unchanged
require.Empty(t, cmp.Diff(plugin1, cluster,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.IgnoreFields(types.PluginV1{}, "Status"),
))
require.Empty(t, cmp.Diff(status, cluster.GetStatus()))
@@ -124,7 +124,7 @@ func TestPluginsCRUD(t *testing.T) {
out, err = service.GetPlugins(ctx, true)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.Plugin{plugin2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete a plugin that doesn't exist.
@@ -192,7 +192,7 @@ func TestListPlugins(t *testing.T) {
fetchedPlugins = append(fetchedPlugins, page3...)
require.Empty(t, cmp.Diff(insertedPlugins, fetchedPlugins,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
})
@@ -202,7 +202,7 @@ func TestListPlugins(t *testing.T) {
require.Empty(t, nextKey)
require.Empty(t, cmp.Diff(insertedPlugins, fetchedPlugins,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
})
}
+35 -16
View File
@@ -76,7 +76,7 @@ func (s *PresenceService) GetNamespaces() ([]types.Namespace, error) {
continue
}
ns, err := services.UnmarshalNamespace(
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -122,7 +122,7 @@ func (s *PresenceService) GetNamespace(name string) (*types.Namespace, error) {
return nil, trace.Wrap(err)
}
return services.UnmarshalNamespace(
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
}
// DeleteNamespace deletes a namespace with all the keys from the backend
@@ -149,6 +149,7 @@ func (s *PresenceService) GetServerInfos(ctx context.Context) stream.Stream[type
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
if err != nil {
s.log.Warnf("Skipping server info at %s, failed to unmarshal: %v", item.Key, err)
@@ -171,7 +172,7 @@ func (s *PresenceService) GetServerInfo(ctx context.Context, name string) (types
return nil, trace.Wrap(err)
}
si, err := services.UnmarshalServerInfo(
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires),
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision),
)
return si, trace.Wrap(err)
}
@@ -237,6 +238,7 @@ func (s *PresenceService) getServers(ctx context.Context, kind, prefix string) (
item.Value, kind,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -291,6 +293,7 @@ func (s *PresenceService) GetNode(ctx context.Context, namespace, name string) (
types.KindNode,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
}
@@ -315,6 +318,7 @@ func (s *PresenceService) GetNodes(ctx context.Context, namespace string) ([]typ
[]services.MarshalOption{
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
}...,
)
if err != nil {
@@ -436,7 +440,7 @@ func (s *PresenceService) GetReverseTunnel(name string, opts ...services.Marshal
return nil, trace.Wrap(err)
}
return services.UnmarshalReverseTunnel(item.Value,
services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires))...)
services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))...)
}
// GetReverseTunnels returns a list of registered servers
@@ -452,7 +456,7 @@ func (s *PresenceService) GetReverseTunnels(ctx context.Context, opts ...service
}
for i, item := range result.Items {
tunnel, err := services.UnmarshalReverseTunnel(
item.Value, services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires))...)
item.Value, services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))...)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -499,7 +503,7 @@ func (s *PresenceService) GetTrustedCluster(ctx context.Context, name string) (t
if err != nil {
return nil, trace.Wrap(err)
}
return services.UnmarshalTrustedCluster(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
return services.UnmarshalTrustedCluster(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
}
// GetTrustedClusters returns all TrustedClusters in the backend.
@@ -512,7 +516,7 @@ func (s *PresenceService) GetTrustedClusters(ctx context.Context) ([]types.Trust
out := make([]types.TrustedCluster, len(result.Items))
for i, item := range result.Items {
tc, err := services.UnmarshalTrustedCluster(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -569,7 +573,7 @@ func (s *PresenceService) GetTunnelConnection(clusterName, connectionName string
return nil, trace.Wrap(err)
}
conn, err := services.UnmarshalTunnelConnection(item.Value,
services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires))...)
services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))...)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -589,7 +593,7 @@ func (s *PresenceService) GetTunnelConnections(clusterName string, opts ...servi
conns := make([]types.TunnelConnection, len(result.Items))
for i, item := range result.Items {
conn, err := services.UnmarshalTunnelConnection(item.Value,
services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires))...)
services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))...)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -612,7 +616,8 @@ func (s *PresenceService) GetAllTunnelConnections(opts ...services.MarshalOption
conn, err := services.UnmarshalTunnelConnection(item.Value,
services.AddOptions(opts,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires))...)
services.WithExpires(item.Expires),
services.WithRevision(item.Revision))...)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -714,7 +719,7 @@ func (s *PresenceService) GetRemoteClusters(opts ...services.MarshalOption) ([]t
clusters := make([]types.RemoteCluster, len(result.Items))
for i, item := range result.Items {
cluster, err := services.UnmarshalRemoteCluster(item.Value,
services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires))...)
services.AddOptions(opts, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))...)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -736,7 +741,7 @@ func (s *PresenceService) getRemoteCluster(ctx context.Context, clusterName stri
return nil, nil, trace.Wrap(err)
}
rc, err := services.UnmarshalRemoteCluster(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, nil, trace.Wrap(err)
}
@@ -1145,7 +1150,8 @@ func (s *PresenceService) getKubernetesServers(ctx context.Context) ([]types.Kub
server, err := services.UnmarshalKubeServer(
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires))
services.WithExpires(item.Expires),
services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -1170,7 +1176,8 @@ func (s *PresenceService) GetDatabaseServers(ctx context.Context, namespace stri
item.Value,
services.AddOptions(opts,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires))...)
services.WithExpires(item.Expires),
services.WithRevision(item.Revision))...)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -1263,7 +1270,8 @@ func (s *PresenceService) getApplicationServers(ctx context.Context, namespace s
server, err := services.UnmarshalAppServer(
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires))
services.WithExpires(item.Expires),
services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -1371,6 +1379,7 @@ func (s *PresenceService) GetWindowsDesktopServices(ctx context.Context) ([]type
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -1389,6 +1398,7 @@ func (s *PresenceService) GetWindowsDesktopService(ctx context.Context, name str
result.Value,
services.WithResourceID(result.ID),
services.WithExpires(result.Expires),
services.WithRevision(result.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
@@ -1480,7 +1490,8 @@ func (s *PresenceService) GetUserGroups(ctx context.Context, opts ...services.Ma
item.Value,
services.AddOptions(opts,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires))...)
services.WithExpires(item.Expires),
services.WithRevision(item.Revision))...)
if err != nil {
return nil, trace.Wrap(err)
}
@@ -1807,6 +1818,7 @@ func backendItemToDatabaseServer(item backend.Item) (types.ResourceWithLabels, e
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
}
@@ -1817,6 +1829,7 @@ func backendItemToDatabaseService(item backend.Item) (types.ResourceWithLabels,
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
}
@@ -1827,6 +1840,8 @@ func backendItemToApplicationServer(item backend.Item) (types.ResourceWithLabels
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
services.WithRevision(item.Revision),
)
}
@@ -1837,6 +1852,7 @@ func backendItemToKubernetesServer(item backend.Item) (types.ResourceWithLabels,
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
}
@@ -1849,6 +1865,7 @@ func backendItemToServer(kind string) backendItemToResourceFunc {
item.Value, kind,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
}
}
@@ -1860,6 +1877,7 @@ func backendItemToWindowsDesktopService(item backend.Item) (types.ResourceWithLa
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
}
@@ -1870,6 +1888,7 @@ func backendItemToUserGroup(item backend.Item) (types.ResourceWithLabels, error)
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
}
+10 -11
View File
@@ -252,7 +252,7 @@ func TestApplicationServersCRUD(t *testing.T) {
servers := types.AppServers(out)
require.NoError(t, servers.SortByCustom(types.SortBy{Field: types.ResourceMetadataName}))
require.Empty(t, cmp.Diff([]types.AppServer{serverA, serverB}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Delete an app server.
err = presence.DeleteApplicationServer(ctx, serverA.GetNamespace(), serverA.GetHostID(), serverA.GetName())
@@ -262,7 +262,7 @@ func TestApplicationServersCRUD(t *testing.T) {
out, err = presence.GetApplicationServers(ctx, apidefaults.Namespace)
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.AppServer{serverB}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Upsert server with TTL.
serverA.SetExpiry(clock.Now().UTC().Add(time.Hour))
@@ -337,8 +337,7 @@ func TestDatabaseServersCRUD(t *testing.T) {
// Check again, expect a single server to be found.
out, err = presence.GetDatabaseServers(ctx, server.GetNamespace())
require.NoError(t, err)
server.SetResourceID(out[0].GetResourceID())
require.EqualValues(t, []types.DatabaseServer{server}, out)
require.Empty(t, cmp.Diff([]types.DatabaseServer{server}, out, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Make sure can't delete with empty namespace or host ID or name.
err = presence.DeleteDatabaseServer(ctx, server.GetNamespace(), server.GetHostID(), "")
@@ -424,7 +423,7 @@ func TestNodeCRUD(t *testing.T) {
require.NoError(t, err)
require.EqualValues(t, len(nodes), 2)
require.Empty(t, cmp.Diff([]types.Server{node1, node2}, nodes,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// GetNodes should fail if namespace isn't provided
_, err = presence.GetNodes(ctx, "")
@@ -436,7 +435,7 @@ func TestNodeCRUD(t *testing.T) {
node, err := presence.GetNode(ctx, apidefaults.Namespace, "node1")
require.NoError(t, err)
require.Empty(t, cmp.Diff(node1, node,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// GetNode should fail if node name isn't provided
_, err = presence.GetNode(ctx, apidefaults.Namespace, "")
@@ -1374,15 +1373,15 @@ func TestServerInfoCRUD(t *testing.T) {
out, err = stream.Collect(presence.GetServerInfos(ctx))
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.ServerInfo{serverInfoA, serverInfoB}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
outInfo, err := presence.GetServerInfo(ctx, serverInfoA.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(serverInfoA, outInfo, cmpopts.IgnoreFields(types.Metadata{}, "ID")))
require.Empty(t, cmp.Diff(serverInfoA, outInfo, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
outInfo, err = presence.GetServerInfo(ctx, serverInfoB.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(serverInfoB, outInfo, cmpopts.IgnoreFields(types.Metadata{}, "ID")))
require.Empty(t, cmp.Diff(serverInfoB, outInfo, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
_, err = presence.GetServerInfo(ctx, "nonexistant")
require.True(t, trace.IsNotFound(err))
@@ -1392,7 +1391,7 @@ func TestServerInfoCRUD(t *testing.T) {
out, err = stream.Collect(presence.GetServerInfos(ctx))
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.ServerInfo{serverInfoB}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Update server info.
serverInfoB.SetStaticLabels(map[string]string{
@@ -1403,7 +1402,7 @@ func TestServerInfoCRUD(t *testing.T) {
out, err = stream.Collect(presence.GetServerInfos(ctx))
require.NoError(t, err)
require.Empty(t, cmp.Diff([]types.ServerInfo{serverInfoB}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Delete all server infos.
require.NoError(t, presence.DeleteAllServerInfos(ctx))
+2 -1
View File
@@ -100,7 +100,7 @@ func (s *ProvisioningService) GetToken(ctx context.Context, token string) (types
return nil, trace.Wrap(err)
}
return services.UnmarshalProvisionToken(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
return services.UnmarshalProvisionToken(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
}
// DeleteToken deletes a token by ID
@@ -128,6 +128,7 @@ func (s *ProvisioningService) GetTokens(ctx context.Context) ([]types.ProvisionT
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
+1
View File
@@ -141,6 +141,7 @@ func itemToUser(item backend.Item) (types.User, error) {
item.Value,
services.WithResourceID(item.ID),
services.WithExpires(item.Expires),
services.WithRevision(item.Revision),
)
if err != nil {
return nil, trace.Wrap(err)
+3 -3
View File
@@ -23,10 +23,10 @@ import (
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/jonboulle/clockwork"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/bcrypt"
"google.golang.org/protobuf/testing/protocmp"
apidefaults "github.com/gravitational/teleport/api/defaults"
"github.com/gravitational/teleport/api/types"
@@ -50,7 +50,7 @@ func TestCreateResourcesProvisionToken(t *testing.T) {
s := NewProvisioningService(tt.bk)
fetchedToken, err := s.GetToken(ctx, "foo")
require.NoError(t, err)
require.Empty(t, cmp.Diff(token, fetchedToken))
require.Empty(t, cmp.Diff(token, fetchedToken, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
func TestUserResource(t *testing.T) {
@@ -248,5 +248,5 @@ func TestBootstrapLock(t *testing.T) {
l, err := tt.suite.Access.GetLock(ctx, "test")
require.NoError(t, err)
require.Empty(t, cmp.Diff(nl, l, protocmp.Transform()))
require.Empty(t, cmp.Diff(nl, l, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
+1 -1
View File
@@ -66,7 +66,7 @@ func (s *RestrictionsService) GetNetworkRestrictions(ctx context.Context) (types
return nil, trace.Wrap(err)
}
return services.UnmarshalNetworkRestrictions(item.Value,
services.WithResourceID(item.ID), services.WithExpires(item.Expires))
services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
}
// SetNetworkRestrictions upserts NetworkRestrictions
@@ -122,7 +122,7 @@ func TestSAMLIdPServiceProviderCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]types.SAMLIdPServiceProvider{sp1, sp2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a paginated list of service providers
@@ -141,14 +141,14 @@ func TestSAMLIdPServiceProviderCRUD(t *testing.T) {
require.Equal(t, 2, numPages)
require.Empty(t, cmp.Diff([]types.SAMLIdPServiceProvider{sp1, sp2}, paginatedOut,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific service provider.
sp, err := service.GetSAMLIdPServiceProvider(ctx, sp2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(sp2, sp,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch a service provider that doesn't exist.
@@ -167,7 +167,7 @@ func TestSAMLIdPServiceProviderCRUD(t *testing.T) {
sp, err = service.GetSAMLIdPServiceProvider(ctx, sp1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(sp1, sp,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Update a service provider to an existing entity ID.
@@ -193,7 +193,7 @@ func TestSAMLIdPServiceProviderCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]types.SAMLIdPServiceProvider{sp2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete a service provider that doesn't exist.
+3 -3
View File
@@ -177,7 +177,7 @@ func (s *CA) ActivateCertAuthority(id types.CertAuthID) error {
}
certAuthority, err := services.UnmarshalCertAuthority(
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return trace.Wrap(err)
}
@@ -240,7 +240,7 @@ func (s *CA) GetCertAuthority(ctx context.Context, id types.CertAuthID, loadSign
if err != nil {
return nil, trace.Wrap(err)
}
ca, err := services.UnmarshalCertAuthority(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
ca, err := services.UnmarshalCertAuthority(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -275,7 +275,7 @@ func (s *CA) GetCertAuthorities(ctx context.Context, caType types.CertAuthType,
// Marshal values into a []types.CertAuthority slice.
cas := make([]types.CertAuthority, len(result.Items))
for i, item := range result.Items {
ca, err := services.UnmarshalCertAuthority(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
ca, err := services.UnmarshalCertAuthority(item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
+1 -1
View File
@@ -50,7 +50,7 @@ func TestUserLoginStateCRUD(t *testing.T) {
state2 := newUserLoginState(t, "state2")
cmpOpts := []cmp.Option{
cmpopts.IgnoreFields(header.Metadata{}, "ID"),
cmpopts.IgnoreFields(header.Metadata{}, "ID", "Revision"),
}
// Neither state should exist.
+5 -5
View File
@@ -72,7 +72,7 @@ func TestUserGroupCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]types.UserGroup{g1, g2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a paginated list of user groups.
@@ -91,14 +91,14 @@ func TestUserGroupCRUD(t *testing.T) {
require.Equal(t, 2, numPages)
require.Empty(t, cmp.Diff([]types.UserGroup{g1, g2}, paginatedOut,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Fetch a specific user group.
sp, err := service.GetUserGroup(ctx, g2.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(g2, sp,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to fetch a user group that doesn't exist.
@@ -116,7 +116,7 @@ func TestUserGroupCRUD(t *testing.T) {
sp, err = service.GetUserGroup(ctx, g1.GetName())
require.NoError(t, err)
require.Empty(t, cmp.Diff(g1, sp,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Delete a user group.
@@ -126,7 +126,7 @@ func TestUserGroupCRUD(t *testing.T) {
require.NoError(t, err)
require.Empty(t, nextToken)
require.Empty(t, cmp.Diff([]types.UserGroup{g2}, out,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
// Try to delete a user group that doesn't exist.
+2 -2
View File
@@ -89,7 +89,7 @@ func (s *IdentityService) GetUsers(withSecrets bool) ([]types.User, error) {
continue
}
u, err := services.UnmarshalUser(
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, trace.Wrap(err)
}
@@ -334,7 +334,7 @@ func (s *IdentityService) getUser(ctx context.Context, user string, withSecrets
}
u, err := services.UnmarshalUser(
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires))
item.Value, services.WithResourceID(item.ID), services.WithExpires(item.Expires), services.WithRevision(item.Revision))
if err != nil {
return nil, nil, trace.Wrap(err)
}
+3 -2
View File
@@ -28,6 +28,7 @@ import (
"github.com/go-webauthn/webauthn/protocol"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/google/uuid"
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
@@ -1074,14 +1075,14 @@ func TestIdentityService_UpdateAndSwapUser(t *testing.T) {
}
// Assert update response.
if diff := cmp.Diff(want, updated); diff != "" {
if diff := cmp.Diff(want, updated, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")); diff != "" {
t.Errorf("UpdateAndSwapUser return mismatch (-want +got)\n%s", diff)
}
// Assert stored.
stored, err := identity.GetUser(test.user, test.withSecrets)
require.NoError(t, err, "GetUser failed")
if diff := cmp.Diff(want, stored); diff != "" {
if diff := cmp.Diff(want, stored, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")); diff != "" {
t.Errorf("UpdateAndSwapUser storage mismatch (-want +got)\n%s", diff)
}
})
+4
View File
@@ -96,6 +96,9 @@ func UnmarshalLock(bytes []byte, opts ...MarshalOption) (types.Lock, error) {
if cfg.ID != 0 {
lock.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
lock.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
lock.SetExpiry(cfg.Expires)
}
@@ -123,6 +126,7 @@ func MarshalLock(lock types.Lock, opts ...MarshalOption) ([]byte, error) {
// to prevent unexpected data races
copy := *lock
copy.SetResourceID(0)
copy.SetRevision("")
lock = &copy
}
return utils.FastMarshal(lock)
+4
View File
@@ -38,6 +38,7 @@ func MarshalNamespace(resource types.Namespace, opts ...MarshalOption) ([]byte,
// to prevent unexpected data races
copy := resource
copy.SetResourceID(0)
copy.SetRevision("")
resource = copy
}
return utils.FastMarshal(resource)
@@ -68,6 +69,9 @@ func UnmarshalNamespace(data []byte, opts ...MarshalOption) (*types.Namespace, e
if cfg.ID != 0 {
namespace.Metadata.ID = cfg.ID
}
if cfg.Revision != "" {
namespace.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
namespace.Metadata.Expires = &cfg.Expires
}
+4
View File
@@ -48,6 +48,9 @@ func UnmarshalClusterNetworkingConfig(bytes []byte, opts ...MarshalOption) (type
if cfg.ID != 0 {
netConfig.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
netConfig.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
netConfig.SetExpiry(cfg.Expires)
}
@@ -72,6 +75,7 @@ func MarshalClusterNetworkingConfig(netConfig types.ClusterNetworkingConfig, opt
// to prevent unexpected data races
copy := *netConfig
copy.SetResourceID(0)
copy.SetRevision("")
netConfig = &copy
}
return utils.FastMarshal(netConfig)
+4
View File
@@ -123,6 +123,9 @@ func UnmarshalOIDCConnector(bytes []byte, opts ...MarshalOption) (types.OIDCConn
if cfg.ID != 0 {
c.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
c.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
c.SetExpiry(cfg.Expires)
}
@@ -150,6 +153,7 @@ func MarshalOIDCConnector(oidcConnector types.OIDCConnector, opts ...MarshalOpti
// to prevent unexpected data races
copy := *oidcConnector
copy.SetResourceID(0)
copy.SetRevision("")
oidcConnector = &copy
}
return utils.FastMarshal(oidcConnector)
+8
View File
@@ -94,6 +94,7 @@ func MarshalOktaImportRule(importRule types.OktaImportRule, opts ...MarshalOptio
if !cfg.PreserveResourceID {
copy := *i
copy.SetResourceID(0)
copy.SetRevision("")
i = &copy
}
return utils.FastMarshal(i)
@@ -127,6 +128,9 @@ func UnmarshalOktaImportRule(data []byte, opts ...MarshalOption) (types.OktaImpo
if cfg.ID != 0 {
i.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
i.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
i.SetExpiry(cfg.Expires)
}
@@ -151,6 +155,7 @@ func MarshalOktaAssignment(assignment types.OktaAssignment, opts ...MarshalOptio
if !cfg.PreserveResourceID {
copy := *a
copy.SetResourceID(0)
copy.SetRevision("")
a = &copy
}
return utils.FastMarshal(a)
@@ -184,6 +189,9 @@ func UnmarshalOktaAssignment(data []byte, opts ...MarshalOption) (types.OktaAssi
if cfg.ID != 0 {
a.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
a.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
a.SetExpiry(cfg.Expires)
}
+3
View File
@@ -65,6 +65,9 @@ func UnmarshalPluginData(raw []byte, opts ...MarshalOption) (types.PluginData, e
if cfg.ID != 0 {
data.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
data.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
data.SetExpiry(cfg.Expires)
}
@@ -55,6 +55,7 @@ func MarshalPluginStaticCredentials(pluginStaticCredentials types.PluginStaticCr
if !cfg.PreserveResourceID {
copy := *pluginStaticCredentials
copy.SetResourceID(0)
copy.SetRevision("")
pluginStaticCredentials = &copy
}
data, err := protojson.Marshal(protoadapt.MessageV2Of(pluginStaticCredentials))
@@ -92,6 +93,9 @@ func UnmarshalPluginStaticCredentials(data []byte, opts ...MarshalOption) (types
if cfg.ID != 0 {
pluginStaticCredentials.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
pluginStaticCredentials.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
pluginStaticCredentials.SetExpiry(cfg.Expires)
}
+4
View File
@@ -54,6 +54,7 @@ func MarshalPlugin(plugin types.Plugin, opts ...MarshalOption) ([]byte, error) {
if !cfg.PreserveResourceID {
copy := *plugin
copy.SetResourceID(0)
copy.SetRevision("")
plugin = &copy
}
var buf bytes.Buffer
@@ -92,6 +93,9 @@ func UnmarshalPlugin(data []byte, opts ...MarshalOption) (types.Plugin, error) {
if cfg.ID != 0 {
plugin.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
plugin.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
plugin.SetExpiry(cfg.Expires)
}
+7
View File
@@ -86,6 +86,9 @@ func UnmarshalProvisionToken(data []byte, opts ...MarshalOption) (types.Provisio
if cfg.ID != 0 {
v2.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
v2.SetRevision(cfg.Revision)
}
return v2, nil
case types.V2:
var p types.ProvisionTokenV2
@@ -98,6 +101,9 @@ func UnmarshalProvisionToken(data []byte, opts ...MarshalOption) (types.Provisio
if cfg.ID != 0 {
p.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
p.SetRevision(cfg.Revision)
}
return &p, nil
}
return nil, trace.BadParameter("server resource version %v is not supported", h.Version)
@@ -121,6 +127,7 @@ func MarshalProvisionToken(provisionToken types.ProvisionToken, opts ...MarshalO
// to prevent unexpected data races
copy := *provisionToken
copy.SetResourceID(0)
copy.SetRevision("")
provisionToken = &copy
}
if cfg.GetVersion() == types.V1 {
+4
View File
@@ -48,6 +48,9 @@ func UnmarshalRemoteCluster(bytes []byte, opts ...MarshalOption) (types.RemoteCl
if cfg.ID != 0 {
cluster.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
cluster.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
cluster.SetExpiry(cfg.Expires)
}
@@ -73,6 +76,7 @@ func MarshalRemoteCluster(remoteCluster types.RemoteCluster, opts ...MarshalOpti
// to prevent unexpected data races
copy := *remoteCluster
copy.SetResourceID(0)
copy.SetRevision("")
remoteCluster = &copy
}
return utils.FastMarshal(remoteCluster)
+12 -1
View File
@@ -30,12 +30,15 @@ import (
// MarshalConfig specifies marshaling options
type MarshalConfig struct {
// Version specifies particular version we should marshal resources with
// Version specifies a particular version we should marshal resources with
Version string
// ID is a record ID to assign
ID int64
// Revision of the resource to assign.
Revision string
// PreserveResourceID preserves resource IDs in resource
// specs when marshaling
PreserveResourceID bool
@@ -81,6 +84,14 @@ func WithResourceID(id int64) MarshalOption {
}
}
// WithRevision assigns Revision to the resource
func WithRevision(rev string) MarshalOption {
return func(c *MarshalConfig) error {
c.Revision = rev
return nil
}
}
// WithExpires assigns expiry value
func WithExpires(expires time.Time) MarshalOption {
return func(c *MarshalConfig) error {
+4
View File
@@ -67,6 +67,9 @@ func UnmarshalNetworkRestrictions(bytes []byte, opts ...MarshalOption) (types.Ne
if cfg.ID != 0 {
nr.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
nr.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
nr.SetExpiry(cfg.Expires)
}
@@ -93,6 +96,7 @@ func MarshalNetworkRestrictions(restrictions types.NetworkRestrictions, opts ...
// to prevent unexpected data races
copy := *restrictions
copy.SetResourceID(0)
copy.SetRevision("")
restrictions = &copy
}
return utils.FastMarshal(restrictions)
+4
View File
@@ -3133,6 +3133,9 @@ func UnmarshalRole(bytes []byte, opts ...MarshalOption) (types.Role, error) {
if cfg.ID != 0 {
role.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
role.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
role.SetExpiry(cfg.Expires)
}
@@ -3160,6 +3163,7 @@ func MarshalRole(role types.Role, opts ...MarshalOption) ([]byte, error) {
// to prevent unexpected data races
copy := *role
copy.SetResourceID(0)
copy.SetRevision("")
role = &copy
}
return utils.FastMarshal(role)
+4
View File
@@ -299,6 +299,9 @@ func UnmarshalSAMLConnector(bytes []byte, opts ...MarshalOption) (types.SAMLConn
if cfg.ID != 0 {
c.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
c.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
c.SetExpiry(cfg.Expires)
}
@@ -327,6 +330,7 @@ func MarshalSAMLConnector(samlConnector types.SAMLConnector, opts ...MarshalOpti
// to prevent unexpected data races
copy := *samlConnector
copy.SetResourceID(0)
copy.SetRevision("")
samlConnector = &copy
}
return utils.FastMarshal(samlConnector)
@@ -62,6 +62,7 @@ func MarshalSAMLIdPServiceProvider(serviceProvider types.SAMLIdPServiceProvider,
if !cfg.PreserveResourceID {
copy := *sp
copy.SetResourceID(0)
copy.SetRevision("")
sp = &copy
}
return utils.FastMarshal(sp)
@@ -95,6 +96,9 @@ func UnmarshalSAMLIdPServiceProvider(data []byte, opts ...MarshalOption) (types.
if cfg.ID != 0 {
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
+4
View File
@@ -301,6 +301,9 @@ func UnmarshalSemaphore(bytes []byte, opts ...MarshalOption) (types.Semaphore, e
if cfg.ID != 0 {
semaphore.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
semaphore.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
semaphore.SetExpiry(cfg.Expires)
}
@@ -325,6 +328,7 @@ func MarshalSemaphore(semaphore types.Semaphore, opts ...MarshalOption) ([]byte,
// to prevent unexpected data races
copy := *semaphore
copy.SetResourceID(0)
copy.SetRevision("")
semaphore = &copy
}
return utils.FastMarshal(semaphore)
+4
View File
@@ -363,6 +363,9 @@ func UnmarshalServer(bytes []byte, kind string, opts ...MarshalOption) (types.Se
if cfg.ID != 0 {
s.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
s.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
s.SetExpiry(cfg.Expires)
}
@@ -394,6 +397,7 @@ func MarshalServer(server types.Server, opts ...MarshalOption) ([]byte, error) {
// to prevent unexpected data races
copy := *server
copy.SetResourceID(0)
copy.SetRevision("")
server = &copy
}
return utils.FastMarshal(server)
+4
View File
@@ -45,6 +45,9 @@ func UnmarshalServerInfo(bytes []byte, opts ...MarshalOption) (types.ServerInfo,
if cfg.ID != 0 {
si.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
si.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
si.SetExpiry(cfg.Expires)
}
@@ -73,6 +76,7 @@ func MarshalServerInfo(si types.ServerInfo, opts ...MarshalOption) ([]byte, erro
// to prevent unexpected data races
copy := *si
copy.SetResourceID(0)
copy.SetRevision("")
si = &copy
}
bytes, err := utils.FastMarshal(si)
+10 -8
View File
@@ -43,22 +43,24 @@ func TestOptions(t *testing.T) {
require.Len(t, out, 0)
// make sure original option list is not affected
in := []MarshalOption{}
out = AddOptions(in, WithResourceID(1))
require.Len(t, out, 1)
var in []MarshalOption
out = AddOptions(in, WithResourceID(1), WithRevision("abc"))
require.Len(t, out, 2)
require.Len(t, in, 0)
cfg, err := CollectOptions(out)
require.NoError(t, err)
require.Equal(t, cfg.ID, int64(1))
require.Equal(t, int64(1), cfg.ID)
require.Equal(t, "abc", cfg.Revision)
// Add a couple of other parameters
out = AddOptions(in, WithResourceID(2), WithVersion(types.V2))
require.Len(t, out, 2)
out = AddOptions(in, WithResourceID(2), WithVersion(types.V2), WithRevision("xyz"))
require.Len(t, out, 3)
require.Len(t, in, 0)
cfg, err = CollectOptions(out)
require.NoError(t, err)
require.Equal(t, cfg.ID, int64(2))
require.Equal(t, cfg.Version, types.V2)
require.Equal(t, int64(2), cfg.ID)
require.Equal(t, types.V2, cfg.Version)
require.Equal(t, "xyz", cfg.Revision)
}
// TestCommandLabels tests command labels
+5
View File
@@ -53,6 +53,9 @@ func UnmarshalWebSession(bytes []byte, opts ...MarshalOption) (types.WebSession,
if cfg.ID != 0 {
ws.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
ws.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
ws.SetExpiry(cfg.Expires)
}
@@ -80,6 +83,7 @@ func MarshalWebSession(webSession types.WebSession, opts ...MarshalOption) ([]by
// to prevent unexpected data races
copy := *webSession
copy.SetResourceID(0)
copy.SetRevision("")
webSession = &copy
}
return utils.FastMarshal(webSession)
@@ -106,6 +110,7 @@ func MarshalWebToken(webToken types.WebToken, opts ...MarshalOption) ([]byte, er
// to prevent unexpected data races
copy := *webToken
copy.SetResourceID(0)
copy.SetRevision("")
webToken = &copy
}
return utils.FastMarshal(webToken)
+4
View File
@@ -57,6 +57,9 @@ func UnmarshalSessionRecordingConfig(bytes []byte, opts ...MarshalOption) (types
if cfg.ID != 0 {
recConfig.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
recConfig.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
recConfig.SetExpiry(cfg.Expires)
}
@@ -84,6 +87,7 @@ func MarshalSessionRecordingConfig(recConfig types.SessionRecordingConfig, opts
// to prevent unexpected data races
copy := *recConfig
copy.SetResourceID(0)
copy.SetRevision("")
recConfig = &copy
}
return utils.FastMarshal(recConfig)
+4
View File
@@ -46,6 +46,9 @@ func UnmarshalStaticTokens(bytes []byte, opts ...MarshalOption) (types.StaticTok
if cfg.ID != 0 {
staticTokens.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
staticTokens.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
staticTokens.SetExpiry(cfg.Expires)
}
@@ -70,6 +73,7 @@ func MarshalStaticTokens(staticToken types.StaticTokens, opts ...MarshalOption)
// to prevent unexpected data races
copy := *staticToken
copy.SetResourceID(0)
copy.SetRevision("")
staticToken = &copy
}
return utils.FastMarshal(staticToken)
+22 -39
View File
@@ -309,23 +309,22 @@ func (s *ServicesTestSuite) CertAuthCRUD(t *testing.T) {
out, err := s.CAS.GetCertAuthority(ctx, ca.GetID(), true)
require.NoError(t, err)
ca.SetResourceID(out.GetResourceID())
require.Equal(t, out, ca)
require.Empty(t, cmp.Diff(out, ca, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
cas, err := s.CAS.GetCertAuthorities(ctx, types.UserCA, false)
require.NoError(t, err)
ca2 := ca.Clone().(*types.CertAuthorityV2)
ca2.Spec.ActiveKeys.SSH[0].PrivateKey = nil
ca2.Spec.ActiveKeys.TLS[0].Key = nil
require.Equal(t, cas[0], ca2)
require.Empty(t, cmp.Diff(cas[0], ca2, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
cas, err = s.CAS.GetCertAuthorities(ctx, types.UserCA, true)
require.NoError(t, err)
require.Equal(t, cas[0], ca)
require.Empty(t, cmp.Diff(cas[0], ca, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
cas, err = s.CAS.GetCertAuthorities(ctx, types.UserCA, true)
require.NoError(t, err)
require.Equal(t, cas[0], ca)
require.Empty(t, cmp.Diff(cas[0], ca, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.CAS.DeleteCertAuthority(ctx, *ca.ID())
require.NoError(t, err)
@@ -349,8 +348,7 @@ func (s *ServicesTestSuite) CertAuthCRUD(t *testing.T) {
out, err = s.CAS.GetCertAuthority(ctx, ca.GetID(), true)
require.NoError(t, err)
newCA.SetResourceID(out.GetResourceID())
require.Empty(t, cmp.Diff(&newCA, out, cmpopts.EquateApproxTime(time.Second)))
require.Empty(t, cmp.Diff(&newCA, out, cmpopts.EquateApproxTime(time.Second), cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
// NewServer creates a new server resource
@@ -382,14 +380,12 @@ func (s *ServicesTestSuite) ServerCRUD(t *testing.T) {
node, err := s.PresenceS.GetNode(ctx, srv.Metadata.Namespace, srv.GetName())
require.NoError(t, err)
srv.SetResourceID(node.GetResourceID())
require.Empty(t, cmp.Diff(node, srv))
require.Empty(t, cmp.Diff(node, srv, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
out, err = s.PresenceS.GetNodes(ctx, srv.Metadata.Namespace)
require.NoError(t, err)
require.Len(t, out, 1)
srv.SetResourceID(out[0].GetResourceID())
require.Empty(t, cmp.Diff(out, []types.Server{srv}))
require.Empty(t, cmp.Diff(out, []types.Server{srv}, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.PresenceS.DeleteNode(ctx, srv.Metadata.Namespace, srv.GetName())
require.NoError(t, err)
@@ -409,8 +405,7 @@ func (s *ServicesTestSuite) ServerCRUD(t *testing.T) {
out, err = s.PresenceS.GetProxies()
require.NoError(t, err)
require.Len(t, out, 1)
proxy.SetResourceID(out[0].GetResourceID())
require.Empty(t, cmp.Diff(out, []types.Server{proxy}))
require.Empty(t, cmp.Diff(out, []types.Server{proxy}, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.PresenceS.DeleteProxy(ctx, proxy.GetName())
require.NoError(t, err)
@@ -430,8 +425,7 @@ func (s *ServicesTestSuite) ServerCRUD(t *testing.T) {
out, err = s.PresenceS.GetAuthServers()
require.NoError(t, err)
require.Len(t, out, 1)
auth.SetResourceID(out[0].GetResourceID())
require.Empty(t, cmp.Diff(out, []types.Server{auth}))
require.Empty(t, cmp.Diff(out, []types.Server{auth}, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
// AppServerCRUD tests CRUD functionality for services.Server.
@@ -465,8 +459,7 @@ func (s *ServicesTestSuite) AppServerCRUD(t *testing.T) {
out, err = s.PresenceS.GetApplicationServers(ctx, server.GetNamespace())
require.NoError(t, err)
require.Len(t, out, 1)
server.SetResourceID(out[0].GetResourceID())
require.Empty(t, cmp.Diff([]types.AppServer{server}, out))
require.Empty(t, cmp.Diff([]types.AppServer{server}, out, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
// Remove the application.
err = s.PresenceS.DeleteApplicationServer(ctx, server.Metadata.Namespace, server.GetHostID(), server.GetName())
@@ -504,8 +497,7 @@ func (s *ServicesTestSuite) ReverseTunnelsCRUD(t *testing.T) {
out, err = s.PresenceS.GetReverseTunnels(context.Background())
require.NoError(t, err)
require.Len(t, out, 1)
tunnel.SetResourceID(out[0].GetResourceID())
require.Empty(t, cmp.Diff(out, []types.ReverseTunnel{tunnel}))
require.Empty(t, cmp.Diff(out, []types.ReverseTunnel{tunnel}, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.PresenceS.DeleteReverseTunnel(tunnel.Spec.ClusterName)
require.NoError(t, err)
@@ -699,16 +691,14 @@ func (s *ServicesTestSuite) RolesCRUD(t *testing.T) {
require.NoError(t, err)
rout, err := s.Access.GetRole(ctx, role.Metadata.Name)
require.NoError(t, err)
role.SetResourceID(rout.GetResourceID())
require.Empty(t, cmp.Diff(rout, &role))
require.Empty(t, cmp.Diff(rout, &role, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
role.Spec.Allow.Logins = []string{"bob"}
err = s.Access.UpsertRole(ctx, &role)
require.NoError(t, err)
rout, err = s.Access.GetRole(ctx, role.Metadata.Name)
require.NoError(t, err)
role.SetResourceID(rout.GetResourceID())
require.Empty(t, cmp.Diff(rout, &role))
require.Empty(t, cmp.Diff(rout, &role, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.Access.DeleteRole(ctx, role.Metadata.Name)
require.NoError(t, err)
@@ -820,13 +810,12 @@ func (s *ServicesTestSuite) TunnelConnectionsCRUD(t *testing.T) {
out, err = s.PresenceS.GetTunnelConnections(clusterName)
require.NoError(t, err)
require.Equal(t, len(out), 1)
conn.SetResourceID(out[0].GetResourceID())
require.Empty(t, cmp.Diff(out[0], conn))
require.Empty(t, cmp.Diff(out[0], conn, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
out, err = s.PresenceS.GetAllTunnelConnections()
require.NoError(t, err)
require.Equal(t, len(out), 1)
require.Empty(t, cmp.Diff(out[0], conn))
require.Empty(t, cmp.Diff(out[0], conn, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
dt = dt.Add(time.Hour)
conn.SetLastHeartbeat(dt)
@@ -837,8 +826,7 @@ func (s *ServicesTestSuite) TunnelConnectionsCRUD(t *testing.T) {
out, err = s.PresenceS.GetTunnelConnections(clusterName)
require.NoError(t, err)
require.Equal(t, len(out), 1)
conn.SetResourceID(out[0].GetResourceID())
require.Empty(t, cmp.Diff(out[0], conn))
require.Empty(t, cmp.Diff(out[0], conn, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.PresenceS.DeleteAllTunnelConnections()
require.NoError(t, err)
@@ -857,8 +845,7 @@ func (s *ServicesTestSuite) TunnelConnectionsCRUD(t *testing.T) {
out, err = s.PresenceS.GetTunnelConnections(clusterName)
require.NoError(t, err)
require.Equal(t, len(out), 1)
conn.SetResourceID(out[0].GetResourceID())
require.Empty(t, cmp.Diff(out[0], conn))
require.Empty(t, cmp.Diff(out[0], conn, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.PresenceS.DeleteTunnelConnection(clusterName, conn.GetName())
require.NoError(t, err)
@@ -945,8 +932,7 @@ func (s *ServicesTestSuite) RemoteClustersCRUD(t *testing.T) {
out, err = s.PresenceS.GetRemoteClusters()
require.NoError(t, err)
require.Equal(t, len(out), 1)
rc.SetResourceID(out[0].GetResourceID())
require.Empty(t, cmp.Diff(out[0], rc))
require.Empty(t, cmp.Diff(out[0], rc, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.PresenceS.DeleteAllRemoteClusters()
require.NoError(t, err)
@@ -962,7 +948,7 @@ func (s *ServicesTestSuite) RemoteClustersCRUD(t *testing.T) {
out, err = s.PresenceS.GetRemoteClusters()
require.NoError(t, err)
require.Equal(t, len(out), 1)
require.Empty(t, cmp.Diff(out[0], rc))
require.Empty(t, cmp.Diff(out[0], rc, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.PresenceS.DeleteRemoteCluster(ctx, clusterName)
require.NoError(t, err)
@@ -1027,8 +1013,7 @@ func (s *ServicesTestSuite) StaticTokens(t *testing.T) {
out, err := s.ConfigS.GetStaticTokens()
require.NoError(t, err)
staticTokens.SetResourceID(out.GetResourceID())
require.Empty(t, cmp.Diff(staticTokens, out))
require.Empty(t, cmp.Diff(staticTokens, out, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.ConfigS.DeleteStaticTokens()
require.NoError(t, err)
@@ -1074,8 +1059,7 @@ func (s *ServicesTestSuite) ClusterName(t *testing.T, opts ...Option) {
gotName, err := s.ConfigS.GetClusterName()
require.NoError(t, err)
clusterName.SetResourceID(gotName.GetResourceID())
require.Empty(t, cmp.Diff(clusterName, gotName))
require.Empty(t, cmp.Diff(clusterName, gotName, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
err = s.ConfigS.DeleteClusterName()
require.NoError(t, err)
@@ -1088,8 +1072,7 @@ func (s *ServicesTestSuite) ClusterName(t *testing.T, opts ...Option) {
gotName, err = s.ConfigS.GetClusterName()
require.NoError(t, err)
clusterName.SetResourceID(gotName.GetResourceID())
require.Empty(t, cmp.Diff(clusterName, gotName))
require.Empty(t, cmp.Diff(clusterName, gotName, cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")))
}
// ClusterNetworkingConfig tests cluster networking configuration.
+4
View File
@@ -161,6 +161,9 @@ func UnmarshalTrustedCluster(bytes []byte, opts ...MarshalOption) (types.Trusted
if cfg.ID != 0 {
trustedCluster.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
trustedCluster.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
trustedCluster.SetExpiry(cfg.Expires)
}
@@ -189,6 +192,7 @@ func MarshalTrustedCluster(trustedCluster types.TrustedCluster, opts ...MarshalO
// to prevent unexpected data races
copy := *trustedCluster
copy.SetResourceID(0)
copy.SetRevision("")
trustedCluster = &copy
}
return utils.FastMarshal(trustedCluster)
+4
View File
@@ -65,6 +65,9 @@ func UnmarshalReverseTunnel(bytes []byte, opts ...MarshalOption) (types.ReverseT
if cfg.ID != 0 {
r.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
r.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
r.SetExpiry(cfg.Expires)
}
@@ -91,6 +94,7 @@ func MarshalReverseTunnel(reverseTunnel types.ReverseTunnel, opts ...MarshalOpti
// to prevent unexpected data races
copy := *reverseTunnel
copy.SetResourceID(0)
copy.SetRevision("")
reverseTunnel = &copy
}
return utils.FastMarshal(reverseTunnel)
+4
View File
@@ -82,6 +82,9 @@ func UnmarshalTunnelConnection(data []byte, opts ...MarshalOption) (types.Tunnel
if cfg.ID != 0 {
r.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
r.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
r.SetExpiry(cfg.Expires)
}
@@ -108,6 +111,7 @@ func MarshalTunnelConnection(tunnelConnection types.TunnelConnection, opts ...Ma
// to prevent unexpected data races
copy := *tunnelConnection
copy.SetResourceID(0)
copy.SetRevision("")
tunnelConnection = &copy
}
return utils.FastMarshal(tunnelConnection)
+4
View File
@@ -45,6 +45,9 @@ func UnmarshalUIConfig(data []byte, opts ...MarshalOption) (types.UIConfig, erro
if cfg.ID != 0 {
uiconfig.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
uiconfig.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
uiconfig.SetExpiry(cfg.Expires)
}
@@ -67,6 +70,7 @@ func MarshalUIConfig(uiconfig types.UIConfig, opts ...MarshalOption) ([]byte, er
// to prevent unexpected data races
copy := *uiconfig
copy.SetResourceID(0)
copy.SetRevision("")
uiconfig = &copy
}
return utils.FastMarshal(uiconfig)
+4 -2
View File
@@ -196,7 +196,8 @@ func TestUnifiedResourceWatcher(t *testing.T) {
expectedRes,
res,
cmpopts.EquateEmpty(),
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.IgnoreFields(header.Metadata{}, "ID", "Revision"),
// Ignore order.
cmpopts.SortSlices(func(a, b types.ResourceWithLabels) bool { return a.GetName() < b.GetName() }),
))
@@ -223,7 +224,8 @@ func TestUnifiedResourceWatcher(t *testing.T) {
expectedRes,
res,
cmpopts.EquateEmpty(),
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.IgnoreFields(header.Metadata{}, "ID", "Revision"),
// Ignore order.
cmpopts.SortSlices(func(a, b types.ResourceWithLabels) bool { return a.GetName() < b.GetName() }),
))
+5 -1
View File
@@ -56,7 +56,7 @@ func ValidateUserRoles(ctx context.Context, u types.User, roleGetter RoleGetter)
func UsersEquals(u types.User, other types.User) bool {
return cmp.Equal(u, other,
ignoreProtoXXXFields(),
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.SortSlices(func(a, b *types.MFADevice) bool {
return a.Metadata.Name < b.Metadata.Name
}),
@@ -105,6 +105,9 @@ func UnmarshalUser(bytes []byte, opts ...MarshalOption) (types.User, error) {
if cfg.ID != 0 {
u.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
u.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
u.SetExpiry(cfg.Expires)
}
@@ -132,6 +135,7 @@ func MarshalUser(user types.User, opts ...MarshalOption) ([]byte, error) {
// to prevent unexpected data races
copy := *user
copy.SetResourceID(0)
copy.SetRevision("")
user = &copy
}
return utils.FastMarshal(user)
+3
View File
@@ -84,6 +84,9 @@ func UnmarshalUserLoginState(data []byte, opts ...MarshalOption) (*userloginstat
if cfg.ID != 0 {
uls.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
uls.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
uls.SetExpiry(cfg.Expires)
}
+4
View File
@@ -57,6 +57,7 @@ func MarshalUserGroup(group types.UserGroup, opts ...MarshalOption) ([]byte, err
if !cfg.PreserveResourceID {
copy := *g
copy.SetResourceID(0)
copy.SetRevision("")
g = &copy
}
return utils.FastMarshal(g)
@@ -90,6 +91,9 @@ func UnmarshalUserGroup(data []byte, opts ...MarshalOption) (types.UserGroup, er
if cfg.ID != 0 {
g.SetResourceID(cfg.ID)
}
if cfg.Revision != "" {
g.SetRevision(cfg.Revision)
}
if !cfg.Expires.IsZero() {
g.SetExpiry(cfg.Expires)
}
+5 -5
View File
@@ -523,7 +523,7 @@ func expectLockInForce(t *testing.T, expectedLock types.Lock, err error) {
func resourceDiff(res1, res2 types.Resource) string {
return cmp.Diff(res1, res2,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.EquateEmpty())
}
@@ -1276,7 +1276,7 @@ func TestOktaAssignmentWatcher(t *testing.T) {
require.Empty(t,
cmp.Diff(expected,
changeset,
cmpopts.IgnoreFields(types.Metadata{}, "ID")),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")),
"should be no differences in the changeset after adding the first assignment")
case <-w.Done():
t.Fatal("Watcher has unexpectedly exited.")
@@ -1300,7 +1300,7 @@ func TestOktaAssignmentWatcher(t *testing.T) {
cmp.Diff(
expected,
changeset,
cmpopts.IgnoreFields(types.Metadata{}, "ID")),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")),
"should be no difference in the changeset after adding the second assignment")
case <-w.Done():
t.Fatal("Watcher has unexpectedly exited.")
@@ -1324,7 +1324,7 @@ func TestOktaAssignmentWatcher(t *testing.T) {
cmp.Diff(
expected,
changeset,
cmpopts.IgnoreFields(types.Metadata{}, "ID")),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")),
"should be no difference in the changeset after update")
case <-w.Done():
t.Fatal("Watcher has unexpectedly exited.")
@@ -1346,7 +1346,7 @@ func TestOktaAssignmentWatcher(t *testing.T) {
cmp.Diff(
expected,
changeset,
cmpopts.IgnoreFields(types.Metadata{}, "ID")),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision")),
"should be no difference in the changeset after deleting the first assignment")
case <-w.Done():
t.Fatal("Watcher has unexpectedly exited.")
+1 -1
View File
@@ -415,7 +415,7 @@ func TestStart(t *testing.T) {
sort.Sort(types.AppServers(servers))
require.Empty(t, cmp.Diff([]types.AppServer{serverAWS, serverFoo}, servers,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Expires")))
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision", "Expires")))
// Check the expiry time is correct.
for _, server := range servers {
+8 -8
View File
@@ -62,7 +62,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.Apps{app0}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -79,7 +79,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.Apps{app0, app1}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -96,7 +96,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.Apps{app0, app1}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -113,7 +113,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.Apps{app0, app1}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -129,7 +129,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.Apps{app0, app1, app2}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -145,7 +145,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.Apps{app0, app1, app2}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -161,7 +161,7 @@ func TestWatcher(t *testing.T) {
case a := <-reconcileCh:
sort.Sort(a)
require.Empty(t, cmp.Diff(types.Apps{app0, app2}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
@@ -175,7 +175,7 @@ func TestWatcher(t *testing.T) {
select {
case a := <-reconcileCh:
require.Empty(t, cmp.Diff(types.Apps{app0}, a,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
))
case <-time.After(time.Second):
t.Fatal("Didn't receive reconcile event after 1s.")
+1 -1
View File
@@ -341,7 +341,7 @@ func assertReconciledResource(t *testing.T, ch chan types.Databases, databases t
sort.Sort(d)
require.Equal(t, len(d), len(databases))
require.Empty(t, cmp.Diff(databases, d,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.IgnoreFields(types.DatabaseStatusV3{}, "CACert"),
))
case <-time.After(time.Second):
+1 -1
View File
@@ -1483,7 +1483,7 @@ func TestDiscoveryDatabase(t *testing.T) {
actualDatabases, err := tlsServer.Auth().GetDatabases(ctx)
require.NoError(t, err)
require.Empty(t, cmp.Diff(tc.expectDatabases, actualDatabases,
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision"),
cmpopts.IgnoreFields(types.DatabaseStatusV3{}, "CACert"),
))
case <-time.After(time.Second):
+5 -5
View File
@@ -913,7 +913,7 @@ func (test *dynamicResourceTest[T]) run(t *testing.T) {
resources = mustDecodeJSON[[]T](t, buf)
require.Len(t, resources, 3)
require.Empty(t, cmp.Diff([]T{test.fooResource, test.fooBar1Resource, test.fooBar2Resource}, resources,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Namespace"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision", "Namespace"),
))
// Fetch specific resource.
@@ -923,7 +923,7 @@ func (test *dynamicResourceTest[T]) run(t *testing.T) {
resources = mustDecodeJSON[[]T](t, buf)
require.Len(t, resources, 1)
require.Empty(t, cmp.Diff([]T{test.fooResource}, resources,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Namespace"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision", "Namespace"),
))
// Remove a resource.
@@ -936,7 +936,7 @@ func (test *dynamicResourceTest[T]) run(t *testing.T) {
resources = mustDecodeJSON[[]T](t, buf)
require.Len(t, resources, 2)
require.Empty(t, cmp.Diff([]T{test.fooBar1Resource, test.fooBar2Resource}, resources,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Namespace"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision", "Namespace"),
))
if !test.runDiscoveredNameChecks {
@@ -950,7 +950,7 @@ func (test *dynamicResourceTest[T]) run(t *testing.T) {
resources = mustDecodeJSON[[]T](t, buf)
require.Len(t, resources, 2)
require.Empty(t, cmp.Diff([]T{test.fooBar1Resource, test.fooBar2Resource}, resources,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Namespace"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision", "Namespace"),
))
// Removing multiple resources ("foo-bar-1" and "foo-bar-2") by discovered name is an error.
@@ -967,7 +967,7 @@ func (test *dynamicResourceTest[T]) run(t *testing.T) {
resources = mustDecodeJSON[[]T](t, buf)
require.Len(t, resources, 1)
require.Empty(t, cmp.Diff([]T{test.fooBar1Resource}, resources,
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Namespace"),
cmpopts.IgnoreFields(types.Metadata{}, "ID", "Revision", "Namespace"),
))
}