nomad: implement policy delete endpoint
This commit is contained in:
parent
e4f5f305ea
commit
e3e243f433
|
@ -1,6 +1,7 @@
|
|||
package nomad
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
metrics "github.com/armon/go-metrics"
|
||||
|
@ -24,13 +25,26 @@ func (a *ACL) UpsertPolicy(args *structs.AllocListRequest, reply *structs.AllocL
|
|||
return nil
|
||||
}
|
||||
|
||||
// DeletePolicy is used to delete a policy
|
||||
func (a *ACL) DeletePolicy(args *structs.AllocListRequest, reply *structs.AllocListResponse) error {
|
||||
if done, err := a.srv.forward("ACL.DeletePolicy", args, args, reply); done {
|
||||
// DeletePolicies is used to delete policies
|
||||
func (a *ACL) DeletePolicies(args *structs.ACLPolicyDeleteRequest, reply *structs.GenericResponse) error {
|
||||
if done, err := a.srv.forward("ACL.DeletePolicies", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
defer metrics.MeasureSince([]string{"nomad", "acl", "delete_policy"}, time.Now())
|
||||
// TODO
|
||||
defer metrics.MeasureSince([]string{"nomad", "acl", "delete_policies"}, time.Now())
|
||||
|
||||
// Validate non-zero set of policies
|
||||
if len(args.Names) == 0 {
|
||||
return fmt.Errorf("must specify as least one policy")
|
||||
}
|
||||
|
||||
// Update via Raft
|
||||
_, index, err := a.srv.raftApply(structs.ACLPolicyDeleteRequestType, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update the index
|
||||
reply.Index = index
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -220,3 +220,26 @@ func TestACLEndpoint_List_Blocking(t *testing.T) {
|
|||
assert.Equal(t, uint64(3), resp2.Index)
|
||||
assert.Equal(t, 0, len(resp2.Policies))
|
||||
}
|
||||
|
||||
func TestACLEndpoint_DeletePolicy(t *testing.T) {
|
||||
t.Parallel()
|
||||
s1 := testServer(t, nil)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
testutil.WaitForLeader(t, s1.RPC)
|
||||
|
||||
// Create the register request
|
||||
p1 := mock.ACLPolicy()
|
||||
s1.fsm.State().UpsertACLPolicies(1000, []*structs.ACLPolicy{p1})
|
||||
|
||||
// Lookup the policies
|
||||
req := &structs.ACLPolicyDeleteRequest{
|
||||
Names: []string{p1.Name},
|
||||
WriteRequest: structs.WriteRequest{Region: "global"},
|
||||
}
|
||||
var resp structs.GenericResponse
|
||||
if err := msgpackrpc.CallWithCodec(codec, "ACL.DeletePolicies", req, &resp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
assert.NotEqual(t, uint64(0), resp.Index)
|
||||
}
|
||||
|
|
17
nomad/fsm.go
17
nomad/fsm.go
|
@ -168,6 +168,8 @@ func (n *nomadFSM) Apply(log *raft.Log) interface{} {
|
|||
return n.applyDeploymentDelete(buf[1:], log.Index)
|
||||
case structs.JobStabilityRequestType:
|
||||
return n.applyJobStability(buf[1:], log.Index)
|
||||
case structs.ACLPolicyDeleteRequestType:
|
||||
return n.applyACLPolicyDelete(buf[1:], log.Index)
|
||||
default:
|
||||
if ignoreUnknown {
|
||||
n.logger.Printf("[WARN] nomad.fsm: ignoring unknown message type (%d), upgrade to newer version", msgType)
|
||||
|
@ -670,6 +672,21 @@ func (n *nomadFSM) applyJobStability(buf []byte, index uint64) interface{} {
|
|||
return nil
|
||||
}
|
||||
|
||||
// applyACLPolicyDelete is used to delete a set of policies
|
||||
func (n *nomadFSM) applyACLPolicyDelete(buf []byte, index uint64) interface{} {
|
||||
defer metrics.MeasureSince([]string{"nomad", "fsm", "apply_acl_policy_delete"}, time.Now())
|
||||
var req structs.ACLPolicyDeleteRequest
|
||||
if err := structs.Decode(buf, &req); err != nil {
|
||||
panic(fmt.Errorf("failed to decode request: %v", err))
|
||||
}
|
||||
|
||||
if err := n.state.DeleteACLPolicies(index, req.Names); err != nil {
|
||||
n.logger.Printf("[ERR] nomad.fsm: DeleteACLPolicies failed: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *nomadFSM) Snapshot() (raft.FSMSnapshot, error) {
|
||||
// Create a new snapshot
|
||||
snap, err := n.state.Snapshot()
|
||||
|
|
|
@ -1518,6 +1518,34 @@ func TestFSM_DeleteDeployment(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestFSM_DeleteACLPolicies(t *testing.T) {
|
||||
t.Parallel()
|
||||
fsm := testFSM(t)
|
||||
|
||||
policy := mock.ACLPolicy()
|
||||
err := fsm.State().UpsertACLPolicies(1000, []*structs.ACLPolicy{policy})
|
||||
assert.Nil(t, err)
|
||||
|
||||
req := structs.ACLPolicyDeleteRequest{
|
||||
Names: []string{policy.Name},
|
||||
}
|
||||
buf, err := structs.Encode(structs.ACLPolicyDeleteRequestType, req)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
resp := fsm.Apply(makeLog(buf))
|
||||
if resp != nil {
|
||||
t.Fatalf("resp: %v", resp)
|
||||
}
|
||||
|
||||
// Verify we are NOT registered
|
||||
ws := memdb.NewWatchSet()
|
||||
out, err := fsm.State().ACLPolicyByName(ws, policy.Name)
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, out)
|
||||
}
|
||||
|
||||
func testSnapshotRestore(t *testing.T, fsm *nomadFSM) *nomadFSM {
|
||||
// Snapshot
|
||||
snap, err := fsm.Snapshot()
|
||||
|
|
|
@ -59,6 +59,8 @@ const (
|
|||
DeploymentAllocHealthRequestType
|
||||
DeploymentDeleteRequestType
|
||||
JobStabilityRequestType
|
||||
ACLPolicyUpsertRequestType
|
||||
ACLPolicyDeleteRequestType
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -5371,3 +5373,9 @@ type SingleACLPolicyResponse struct {
|
|||
Policy *ACLPolicy
|
||||
QueryMeta
|
||||
}
|
||||
|
||||
// ACLPolicyDeleteRequest is used to delete a set of policies
|
||||
type ACLPolicyDeleteRequest struct {
|
||||
Names []string
|
||||
WriteRequest
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue