Backport #9156 to 1.8.x (#9164)

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.
This commit is contained in:
Matt Keeler 2020-11-11 15:12:10 -05:00 committed by GitHub
parent 95ed6ec143
commit 0c2eea2918
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 17 additions and 14 deletions

3
.changelog/9156.txt Normal file
View File

@ -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
.changelog/_666.txt Normal file
View File

@ -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.
```

View File

@ -216,10 +216,7 @@ func (s *Snapshot) Checks(node string) (memdb.ResultIterator, error) {
// performed within a single transaction to avoid race conditions on state // performed within a single transaction to avoid race conditions on state
// updates. // updates.
func (s *Restore) Registration(idx uint64, req *structs.RegisterRequest) error { func (s *Restore) Registration(idx uint64, req *structs.RegisterRequest) error {
if err := s.store.ensureRegistrationTxn(s.tx, idx, true, req); err != nil { return s.store.ensureRegistrationTxn(s.tx, idx, true, req, true)
return err
}
return nil
} }
// EnsureRegistration is used to make sure a node, service, and check // EnsureRegistration is used to make sure a node, service, and check
@ -229,7 +226,7 @@ func (s *Store) EnsureRegistration(idx uint64, req *structs.RegisterRequest) err
tx := s.db.Txn(true) tx := s.db.Txn(true)
defer tx.Abort() 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 return err
} }
@ -251,8 +248,8 @@ func (s *Store) ensureCheckIfNodeMatches(tx *memdb.Txn, idx uint64, preserveInde
// ensureRegistrationTxn is used to make sure a node, service, and check // ensureRegistrationTxn is used to make sure a node, service, and check
// registration is performed within a single transaction to avoid race // registration is performed within a single transaction to avoid race
// conditions on state updates. // conditions on state updates.
func (s *Store) ensureRegistrationTxn(tx *memdb.Txn, idx uint64, preserveIndexes bool, req *structs.RegisterRequest) error { func (s *Store) ensureRegistrationTxn(tx *memdb.Txn, idx uint64, preserveIndexes bool, req *structs.RegisterRequest, restore bool) error {
if _, err := s.validateRegisterRequestTxn(tx, req); err != nil { if _, err := s.validateRegisterRequestTxn(tx, req, restore); err != nil {
return err return err
} }

View File

@ -322,7 +322,7 @@ func (s *Store) catalogChecksForNodeService(tx *memdb.Txn, node string, service
return tx.Get("checks", "node_service", node, 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 return nil, nil
} }

View File

@ -69,7 +69,7 @@ func (s *Snapshot) Tombstones() (memdb.ResultIterator, error) {
// KVS is used when restoring from a snapshot. Use KVSSet for general inserts. // KVS is used when restoring from a snapshot. Use KVSSet for general inserts.
func (s *Restore) KVS(entry *structs.DirEntry) error { 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) return fmt.Errorf("failed inserting kvs entry: %s", err)
} }
@ -155,7 +155,7 @@ func (s *Store) kvsSetTxn(tx *memdb.Txn, idx uint64, entry *structs.DirEntry, up
entry.ModifyIndex = idx entry.ModifyIndex = idx
// Store the kv pair in the state store and update the index. // 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) return fmt.Errorf("failed inserting kvs entry: %s", err)
} }

View File

@ -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 { if err := tx.Insert("kvs", entry); err != nil {
return err return err
} }

View File

@ -146,7 +146,7 @@ func (s *Snapshot) Sessions() (memdb.ResultIterator, error) {
// Session is used when restoring from a snapshot. For general inserts, use // Session is used when restoring from a snapshot. For general inserts, use
// SessionCreate. // SessionCreate.
func (s *Restore) Session(sess *structs.Session) error { 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) return fmt.Errorf("failed inserting session: %s", err)
} }
@ -214,7 +214,7 @@ func (s *Store) sessionCreateTxn(tx *memdb.Txn, idx uint64, sess *structs.Sessio
} }
// Insert the session // 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) return fmt.Errorf("failed inserting session: %s", err)
} }

View File

@ -48,7 +48,7 @@ func (s *Store) sessionDeleteWithSession(tx *memdb.Txn, session *structs.Session
return nil 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 { if err := tx.Insert("sessions", session); err != nil {
return err return err
} }