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/aws/aws-sdk-go v1.44.289
|
||||||
github.com/coredns/coredns v1.10.1
|
github.com/coredns/coredns v1.10.1
|
||||||
github.com/coreos/go-oidc v2.1.0+incompatible
|
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/docker/go-connections v0.4.0
|
||||||
github.com/envoyproxy/go-control-plane v0.11.1
|
github.com/envoyproxy/go-control-plane v0.11.1
|
||||||
github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e
|
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.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 h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o=
|
||||||
github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
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=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
|
|
@ -7,11 +7,23 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
mapset "github.com/deckarep/golang-set/v2"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/agent/dns"
|
"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
|
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.
|
// ValidateName returns an error a name is not a valid resource name.
|
||||||
// The error will contain reference to what constitutes a valid resource name.
|
// The error will contain reference to what constitutes a valid resource name.
|
||||||
func ValidateName(name string) error {
|
func ValidateName(name string) error {
|
||||||
|
@ -20,3 +32,55 @@ func ValidateName(name string) error {
|
||||||
}
|
}
|
||||||
return nil
|
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/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect
|
||||||
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // 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/distribution v2.8.2+incompatible // indirect
|
||||||
github.com/docker/docker v24.0.5+incompatible // indirect
|
github.com/docker/docker v24.0.5+incompatible // indirect
|
||||||
github.com/docker/go-connections v0.4.0 // 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.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 h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
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=
|
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/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect
|
||||||
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // 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/distribution v2.8.2+incompatible // indirect
|
||||||
github.com/docker/go-units v0.5.0 // indirect
|
github.com/docker/go-units v0.5.0 // indirect
|
||||||
github.com/emicklei/go-restful/v3 v3.10.1 // 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.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 h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
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=
|
github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY=
|
||||||
|
|
Loading…
Reference in New Issue