From b0132b140c20931b52a5b18605d1ce03c506c0d1 Mon Sep 17 00:00:00 2001 From: Ryan Uber Date: Thu, 27 Aug 2015 21:05:17 -0700 Subject: [PATCH] consul/state: add check deletion method --- consul/state/state_store.go | 36 ++++++++++++++++++++++ consul/state/state_store_test.go | 52 ++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/consul/state/state_store.go b/consul/state/state_store.go index fb894104ab..22c8a779dd 100644 --- a/consul/state/state_store.go +++ b/consul/state/state_store.go @@ -433,3 +433,39 @@ func (s *StateStore) parseChecks(iter memdb.ResultIterator, err error) (structs. } return results, nil } + +// DeleteCheck is used to delete a health check registration. +func (s *StateStore) DeleteCheck(idx uint64, node, id string) error { + tx := s.db.Txn(true) + defer tx.Abort() + + // Call the check deletion + if err := s.deleteCheckTxn(idx, node, id, tx); err != nil { + return err + } + + tx.Commit() + return nil +} + +// deleteCheckTxn is the inner method used to call a health +// check deletion within an existing transaction. +func (s *StateStore) deleteCheckTxn(idx uint64, node, id string, tx *memdb.Txn) error { + // Try to retrieve the existing health check + check, err := tx.First("checks", "id", node, id) + if err != nil { + return fmt.Errorf("check lookup failed: %s", err) + } + + // Delete the check from the DB and update the index + if err := tx.Delete("checks", check); err != nil { + return fmt.Errorf("failed removing check: %s", err) + } + if err := tx.Insert("index", &IndexEntry{"checks", idx}); err != nil { + return fmt.Errorf("failed updating index: %s", err) + } + + // TODO: invalidate sessions + // TODO: watch triggers + return nil +} diff --git a/consul/state/state_store_test.go b/consul/state/state_store_test.go index 230aeb9367..ab9e1d0ff4 100644 --- a/consul/state/state_store_test.go +++ b/consul/state/state_store_test.go @@ -359,3 +359,55 @@ func TestStateStore_EnsureCheck(t *testing.T) { t.Fatalf("bad index: %#v", checks[0]) } } + +func TestStateStore_DeleteCheck(t *testing.T) { + s := testStateStore(t) + + // Create and register a node + node := &structs.Node{ + Node: "node1", + Address: "1.1.1.1", + } + if err := s.EnsureNode(1, node); err != nil { + t.Fatalf("err: %s", err) + } + + // Create the health check struct + check := &structs.HealthCheck{ + Node: "node1", + CheckID: "check1", + Name: "node1 check", + Status: structs.HealthPassing, + Notes: "test check", + Output: "aaa", + } + if err := s.EnsureCheck(2, check); err != nil { + t.Fatalf("err: %s", err) + } + + // Check exists + checks, err := s.NodeChecks("node1") + if err != nil { + t.Fatalf("err: %s", err) + } + if len(checks) != 1 || checks[0].CheckID != "check1" { + t.Fatalf("bad: %#v", checks) + } + + // Delete the check + if err := s.DeleteCheck(3, "node1", "check1"); err != nil { + t.Fatalf("err: %s", err) + } + + // Check is gone + checks, err = s.NodeChecks("node1") + if err != nil { + t.Fatalf("err: %s", err) + } + if len(checks) != 0 { + t.Fatalf("bad: %#v", checks) + } + if n := s.maxIndex("checks"); n != 3 { + t.Fatalf("bad index: %d", n) + } +}