Allow resource updates to omit an owner refs UID (#17423)

This change enables workflows where you are reapplying a resource that should have an owner ref to publish modifications to the resources data without performing a read to figure out the current owner resource incarnations UID.

Basically we want workflows similar to `kubectl apply` or `consul config write` to be able to work seamlessly even for owned resources.

In these cases the users intention is to have the resource owned by the “current” incarnation of the owner resource.
pull/17416/head^2
Matt Keeler 2 years ago committed by GitHub
parent 113202d541
commit 93bad3ea1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -179,6 +179,15 @@ func (s *Server) Write(ctx context.Context, req *pbresource.WriteRequest) (*pbre
return storage.ErrCASFailure return storage.ErrCASFailure
} }
// Fill in an empty Owner UID with the existing owner's UID. If other parts
// of the owner ID like the type or name have changed then the subsequent
// EqualID call will still error as you are not allowed to change the owner.
// This is a small UX nicety to repeatedly "apply" a resource that should
// have an owner without having to care about the current owners incarnation.
if input.Owner != nil && existing.Owner != nil && input.Owner.Uid == "" {
input.Owner.Uid = existing.Owner.Uid
}
// Owner can only be set on creation. Enforce immutability. // Owner can only be set on creation. Enforce immutability.
if !resource.EqualID(input.Owner, existing.Owner) { if !resource.EqualID(input.Owner, existing.Owner) {
return status.Errorf(codes.InvalidArgument, "owner cannot be changed") return status.Errorf(codes.InvalidArgument, "owner cannot be changed")

@ -571,6 +571,25 @@ func TestWrite_Owner_Uid(t *testing.T) {
require.NotEmpty(t, rsp2.Resource.Owner.Uid) require.NotEmpty(t, rsp2.Resource.Owner.Uid)
require.Equal(t, artist.Id.Uid, rsp2.Resource.Owner.Uid) require.Equal(t, artist.Id.Uid, rsp2.Resource.Owner.Uid)
}) })
t.Run("no-uid - update auto resolve", func(t *testing.T) {
artist, err := demo.GenerateV2Artist()
require.NoError(t, err)
uid := ulid.Make().String()
album, err := demo.GenerateV2Album(artist.Id)
require.NoError(t, err)
album.Owner.Uid = uid
_, err = client.Write(testContext(t), &pbresource.WriteRequest{Resource: album})
require.NoError(t, err)
// unset the uid and rewrite the resource
album.Owner.Uid = ""
rsp, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: album})
require.NoError(t, err)
require.Equal(t, uid, rsp.GetResource().GetOwner().GetUid())
})
} }
type blockOnceBackend struct { type blockOnceBackend struct {

Loading…
Cancel
Save