nomad: implement policy delete endpoint

This commit is contained in:
Armon Dadgar 2017-08-07 20:53:07 -07:00
parent e4f5f305ea
commit e3e243f433
5 changed files with 95 additions and 5 deletions

View File

@ -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
}

View File

@ -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)
}

View File

@ -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()

View File

@ -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()

View File

@ -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
}