Skip to content

Commit

Permalink
Backport #9156 to 1.7.x (#9163)
Browse files Browse the repository at this point in the history
The Catalog, Config Entry, KV and Session resources potentially re-validate the input as its coming in. We need to prevent snapshot restoration failures due to missing namespaces or namespaces that are being deleted in enterprise.
  • Loading branch information
mkeeler authored Nov 11, 2020
1 parent fcf054a commit 5d3b10c
Show file tree
Hide file tree
Showing 8 changed files with 17 additions and 14 deletions.
3 changes: 3 additions & 0 deletions .changelog/9156.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
namespace: **(Enterprise Only)** Fixed a bug that could case snapshot restoration to fail when it contained a namespace marked for deletion while still containing other resources in that namespace.
```
3 changes: 3 additions & 0 deletions .changelog/_666.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
namespace: **(Enterprise Only)** Fixed an issue where namespaced services and checks were not being deleted when the containing namespace was deleted.
```
11 changes: 4 additions & 7 deletions agent/consul/state/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,7 @@ func (s *Snapshot) Checks(node string) (memdb.ResultIterator, error) {
// performed within a single transaction to avoid race conditions on state
// updates.
func (s *Restore) Registration(idx uint64, req *structs.RegisterRequest) error {
if err := s.store.ensureRegistrationTxn(s.tx, idx, true, req); err != nil {
return err
}
return nil
return s.store.ensureRegistrationTxn(s.tx, idx, true, req, true)
}

// EnsureRegistration is used to make sure a node, service, and check
Expand All @@ -124,7 +121,7 @@ func (s *Store) EnsureRegistration(idx uint64, req *structs.RegisterRequest) err
tx := s.db.Txn(true)
defer tx.Abort()

if err := s.ensureRegistrationTxn(tx, idx, false, req); err != nil {
if err := s.ensureRegistrationTxn(tx, idx, false, req, false); err != nil {
return err
}

Expand All @@ -146,8 +143,8 @@ func (s *Store) ensureCheckIfNodeMatches(tx *memdb.Txn, idx uint64, preserveInde
// ensureRegistrationTxn is used to make sure a node, service, and check
// registration is performed within a single transaction to avoid race
// conditions on state updates.
func (s *Store) ensureRegistrationTxn(tx *memdb.Txn, idx uint64, preserveIndexes bool, req *structs.RegisterRequest) error {
if _, err := s.validateRegisterRequestTxn(tx, req); err != nil {
func (s *Store) ensureRegistrationTxn(tx *memdb.Txn, idx uint64, preserveIndexes bool, req *structs.RegisterRequest, restore bool) error {
if _, err := s.validateRegisterRequestTxn(tx, req, restore); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion agent/consul/state/catalog_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func (s *Store) catalogChecksForNodeService(tx *memdb.Txn, node string, service
return tx.Get("checks", "node_service", node, service)
}

func (s *Store) validateRegisterRequestTxn(tx *memdb.Txn, args *structs.RegisterRequest) (*structs.EnterpriseMeta, error) {
func (s *Store) validateRegisterRequestTxn(tx *memdb.Txn, args *structs.RegisterRequest, _ bool) (*structs.EnterpriseMeta, error) {
return nil, nil
}

Expand Down
4 changes: 2 additions & 2 deletions agent/consul/state/kvs.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (s *Snapshot) Tombstones() (memdb.ResultIterator, error) {

// KVS is used when restoring from a snapshot. Use KVSSet for general inserts.
func (s *Restore) KVS(entry *structs.DirEntry) error {
if err := s.store.insertKVTxn(s.tx, entry, true); err != nil {
if err := s.store.insertKVTxn(s.tx, entry, true, true); err != nil {
return fmt.Errorf("failed inserting kvs entry: %s", err)
}

Expand Down Expand Up @@ -151,7 +151,7 @@ func (s *Store) kvsSetTxn(tx *memdb.Txn, idx uint64, entry *structs.DirEntry, up
}

// Store the kv pair in the state store and update the index.
if err := s.insertKVTxn(tx, entry, false); err != nil {
if err := s.insertKVTxn(tx, entry, false, false); err != nil {
return fmt.Errorf("failed inserting kvs entry: %s", err)
}

Expand Down
2 changes: 1 addition & 1 deletion agent/consul/state/kvs_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func kvsIndexer() *memdb.StringFieldIndex {
}
}

func (s *Store) insertKVTxn(tx *memdb.Txn, entry *structs.DirEntry, updateMax bool) error {
func (s *Store) insertKVTxn(tx *memdb.Txn, entry *structs.DirEntry, updateMax bool, _ bool) error {
if err := tx.Insert("kvs", entry); err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions agent/consul/state/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func (s *Snapshot) Sessions() (memdb.ResultIterator, error) {
// Session is used when restoring from a snapshot. For general inserts, use
// SessionCreate.
func (s *Restore) Session(sess *structs.Session) error {
if err := s.store.insertSessionTxn(s.tx, sess, sess.ModifyIndex, true); err != nil {
if err := s.store.insertSessionTxn(s.tx, sess, sess.ModifyIndex, true, true); err != nil {
return fmt.Errorf("failed inserting session: %s", err)
}

Expand Down Expand Up @@ -214,7 +214,7 @@ func (s *Store) sessionCreateTxn(tx *memdb.Txn, idx uint64, sess *structs.Sessio
}

// Insert the session
if err := s.insertSessionTxn(tx, sess, idx, false); err != nil {
if err := s.insertSessionTxn(tx, sess, idx, false, false); err != nil {
return fmt.Errorf("failed inserting session: %s", err)
}

Expand Down
2 changes: 1 addition & 1 deletion agent/consul/state/session_oss.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (s *Store) sessionDeleteWithSession(tx *memdb.Txn, session *structs.Session
return nil
}

func (s *Store) insertSessionTxn(tx *memdb.Txn, session *structs.Session, idx uint64, updateMax bool) error {
func (s *Store) insertSessionTxn(tx *memdb.Txn, session *structs.Session, idx uint64, updateMax bool, _ bool) error {
if err := tx.Insert("sessions", session); err != nil {
return err
}
Expand Down

0 comments on commit 5d3b10c

Please sign in to comment.