mirror of https://github.com/status-im/consul.git
resource: misc finalizer apis (#19474)
This commit is contained in:
parent
a72f868218
commit
aaac20f4a8
1
go.mod
1
go.mod
|
@ -24,6 +24,7 @@ require (
|
|||
github.com/aws/aws-sdk-go v1.44.289
|
||||
github.com/coredns/coredns v1.10.1
|
||||
github.com/coreos/go-oidc v2.1.0+incompatible
|
||||
github.com/deckarep/golang-set/v2 v2.3.1
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/envoyproxy/go-control-plane v0.11.1
|
||||
github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e
|
||||
|
|
2
go.sum
2
go.sum
|
@ -210,6 +210,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set/v2 v2.3.1 h1:vjmkvJt/IV27WXPyYQpAh4bRyWJc5Y435D17XQ9QU5A=
|
||||
github.com/deckarep/golang-set/v2 v2.3.1/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
||||
github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o=
|
||||
github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
|
|
|
@ -7,11 +7,23 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
|
||||
"github.com/hashicorp/consul/agent/dns"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
)
|
||||
|
||||
// MaxNameLength is the maximum length of a resource name.
|
||||
const MaxNameLength = 63
|
||||
|
||||
// DeletionTimestampKey is the key in a resource's metadata that stores the timestamp
|
||||
// when a resource was marked for deletion. This only applies to resources with finalizers.
|
||||
const DeletionTimestampKey = "deletionTimestamp"
|
||||
|
||||
// FinalizerKey is the key in resource's metadata that stores the whitespace separated
|
||||
// list of finalizers.
|
||||
const FinalizerKey = "finalizers"
|
||||
|
||||
// ValidateName returns an error a name is not a valid resource name.
|
||||
// The error will contain reference to what constitutes a valid resource name.
|
||||
func ValidateName(name string) error {
|
||||
|
@ -20,3 +32,55 @@ func ValidateName(name string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsMarkedForDeletion returns true if a resource has been marked for deletion,
|
||||
// false otherwise.
|
||||
func IsMarkedForDeletion(res *pbresource.Resource) bool {
|
||||
if res.Metadata == nil {
|
||||
return false
|
||||
}
|
||||
_, ok := res.Metadata[DeletionTimestampKey]
|
||||
return ok
|
||||
}
|
||||
|
||||
// HasFinalizers returns true if a resource has one or more finalizers, false otherwise.
|
||||
func HasFinalizers(res *pbresource.Resource) bool {
|
||||
return GetFinalizers(res).Cardinality() >= 1
|
||||
}
|
||||
|
||||
// HasFinalizer returns true if a resource has a given finalizers, false otherwise.
|
||||
func HasFinalizer(res *pbresource.Resource, finalizer string) bool {
|
||||
return GetFinalizers(res).Contains(finalizer)
|
||||
}
|
||||
|
||||
// AddFinalizer adds a finalizer to the given resource.
|
||||
func AddFinalizer(res *pbresource.Resource, finalizer string) {
|
||||
finalizerSet := GetFinalizers(res)
|
||||
finalizerSet.Add(finalizer)
|
||||
if res.Metadata == nil {
|
||||
res.Metadata = map[string]string{}
|
||||
}
|
||||
res.Metadata[FinalizerKey] = strings.Join(finalizerSet.ToSlice(), " ")
|
||||
}
|
||||
|
||||
// RemoveFinalizer removes a finalizer from the given resource.
|
||||
func RemoveFinalizer(res *pbresource.Resource, finalizer string) {
|
||||
finalizerSet := GetFinalizers(res)
|
||||
finalizerSet.Remove(finalizer)
|
||||
if res.Metadata == nil {
|
||||
res.Metadata = map[string]string{}
|
||||
}
|
||||
res.Metadata[FinalizerKey] = strings.Join(finalizerSet.ToSlice(), " ")
|
||||
}
|
||||
|
||||
// GetFinalizers returns the set of finalizers for the given resource.
|
||||
func GetFinalizers(res *pbresource.Resource) mapset.Set[string] {
|
||||
if res.Metadata == nil {
|
||||
return mapset.NewSet[string]()
|
||||
}
|
||||
finalizers, ok := res.Metadata[FinalizerKey]
|
||||
if !ok {
|
||||
return mapset.NewSet[string]()
|
||||
}
|
||||
return mapset.NewSet[string](strings.Fields(finalizers)...)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package resource_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1"
|
||||
)
|
||||
|
||||
func TestFinalizer(t *testing.T) {
|
||||
t.Run("no finalizers", func(t *testing.T) {
|
||||
res := rtest.Resource(pbtenancy.NamespaceType, "ns1").Build()
|
||||
require.False(t, resource.HasFinalizers(res))
|
||||
require.False(t, resource.HasFinalizer(res, "finalizer1"))
|
||||
require.Equal(t, mapset.NewSet[string](), resource.GetFinalizers(res))
|
||||
resource.RemoveFinalizer(res, "finalizer")
|
||||
})
|
||||
|
||||
t.Run("add finalizer", func(t *testing.T) {
|
||||
res := rtest.Resource(pbtenancy.NamespaceType, "ns1").Build()
|
||||
resource.AddFinalizer(res, "finalizer1")
|
||||
require.True(t, resource.HasFinalizers(res))
|
||||
require.True(t, resource.HasFinalizer(res, "finalizer1"))
|
||||
require.False(t, resource.HasFinalizer(res, "finalizer2"))
|
||||
require.Equal(t, mapset.NewSet[string]("finalizer1"), resource.GetFinalizers(res))
|
||||
|
||||
// add duplicate -> noop
|
||||
resource.AddFinalizer(res, "finalizer1")
|
||||
require.Equal(t, mapset.NewSet[string]("finalizer1"), resource.GetFinalizers(res))
|
||||
})
|
||||
|
||||
t.Run("remove finalizer", func(t *testing.T) {
|
||||
res := rtest.Resource(pbtenancy.NamespaceType, "ns1").Build()
|
||||
resource.AddFinalizer(res, "finalizer1")
|
||||
resource.AddFinalizer(res, "finalizer2")
|
||||
resource.RemoveFinalizer(res, "finalizer1")
|
||||
require.False(t, resource.HasFinalizer(res, "finalizer1"))
|
||||
require.True(t, resource.HasFinalizer(res, "finalizer2"))
|
||||
require.Equal(t, mapset.NewSet[string]("finalizer2"), resource.GetFinalizers(res))
|
||||
|
||||
// remove non-existent -> noop
|
||||
resource.RemoveFinalizer(res, "finalizer3")
|
||||
require.Equal(t, mapset.NewSet[string]("finalizer2"), resource.GetFinalizers(res))
|
||||
})
|
||||
|
||||
}
|
|
@ -53,6 +53,7 @@ require (
|
|||
github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/deckarep/golang-set/v2 v2.3.1 // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/docker v24.0.5+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
|
|
|
@ -163,6 +163,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set/v2 v2.3.1 h1:vjmkvJt/IV27WXPyYQpAh4bRyWJc5Y435D17XQ9QU5A=
|
||||
github.com/deckarep/golang-set/v2 v2.3.1/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=
|
||||
|
|
|
@ -68,6 +68,7 @@ require (
|
|||
github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/deckarep/golang-set/v2 v2.3.1 // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
|
||||
|
|
|
@ -159,6 +159,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set/v2 v2.3.1 h1:vjmkvJt/IV27WXPyYQpAh4bRyWJc5Y435D17XQ9QU5A=
|
||||
github.com/deckarep/golang-set/v2 v2.3.1/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=
|
||||
|
|
Loading…
Reference in New Issue