2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2017-11-30 01:33:57 +00:00
|
|
|
package fsm
|
|
|
|
|
|
|
|
import (
|
2022-08-11 18:47:10 +00:00
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
|
2022-02-14 17:45:45 +00:00
|
|
|
"github.com/hashicorp/consul-net-rpc/go-msgpack/codec"
|
2017-11-30 01:33:57 +00:00
|
|
|
"github.com/hashicorp/raft"
|
2022-08-11 18:47:10 +00:00
|
|
|
"github.com/mitchellh/mapstructure"
|
2021-04-14 20:48:04 +00:00
|
|
|
|
|
|
|
"github.com/hashicorp/consul/agent/consul/state"
|
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
2023-02-17 21:14:46 +00:00
|
|
|
"github.com/hashicorp/consul/proto/private/pbpeering"
|
2017-11-30 01:33:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
registerPersister(persistOSS)
|
|
|
|
|
|
|
|
registerRestorer(structs.RegisterRequestType, restoreRegistration)
|
|
|
|
registerRestorer(structs.KVSRequestType, restoreKV)
|
|
|
|
registerRestorer(structs.TombstoneRequestType, restoreTombstone)
|
|
|
|
registerRestorer(structs.SessionRequestType, restoreSession)
|
|
|
|
registerRestorer(structs.CoordinateBatchUpdateType, restoreCoordinates)
|
|
|
|
registerRestorer(structs.PreparedQueryRequestType, restorePreparedQuery)
|
|
|
|
registerRestorer(structs.AutopilotRequestType, restoreAutopilot)
|
2020-10-06 18:24:05 +00:00
|
|
|
registerRestorer(structs.IntentionRequestType, restoreLegacyIntention)
|
2018-03-21 18:33:19 +00:00
|
|
|
registerRestorer(structs.ConnectCARequestType, restoreConnectCA)
|
2018-07-11 18:34:49 +00:00
|
|
|
registerRestorer(structs.ConnectCAProviderStateType, restoreConnectCAProviderState)
|
2018-08-16 18:58:50 +00:00
|
|
|
registerRestorer(structs.ConnectCAConfigType, restoreConnectCAConfig)
|
2018-10-19 16:04:07 +00:00
|
|
|
registerRestorer(structs.IndexRequestType, restoreIndex)
|
2018-10-31 20:00:46 +00:00
|
|
|
registerRestorer(structs.ACLTokenSetRequestType, restoreToken)
|
|
|
|
registerRestorer(structs.ACLPolicySetRequestType, restorePolicy)
|
2019-03-20 23:13:13 +00:00
|
|
|
registerRestorer(structs.ConfigEntryRequestType, restoreConfigEntry)
|
2019-04-15 20:43:19 +00:00
|
|
|
registerRestorer(structs.ACLRoleSetRequestType, restoreRole)
|
2019-04-26 17:49:28 +00:00
|
|
|
registerRestorer(structs.ACLBindingRuleSetRequestType, restoreBindingRule)
|
|
|
|
registerRestorer(structs.ACLAuthMethodSetRequestType, restoreAuthMethod)
|
2020-03-09 20:59:02 +00:00
|
|
|
registerRestorer(structs.FederationStateRequestType, restoreFederationState)
|
2020-10-06 15:08:37 +00:00
|
|
|
registerRestorer(structs.SystemMetadataRequestType, restoreSystemMetadata)
|
2021-12-02 23:42:47 +00:00
|
|
|
registerRestorer(structs.ServiceVirtualIPRequestType, restoreServiceVirtualIP)
|
|
|
|
registerRestorer(structs.FreeVirtualIPRequestType, restoreFreeVirtualIP)
|
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
|
|
|
registerRestorer(structs.PeeringWriteType, restorePeering)
|
|
|
|
registerRestorer(structs.PeeringTrustBundleWriteType, restorePeeringTrustBundle)
|
2022-08-02 22:20:07 +00:00
|
|
|
registerRestorer(structs.PeeringSecretsWriteType, restorePeeringSecrets)
|
2017-11-30 01:33:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func persistOSS(s *snapshot, sink raft.SnapshotSink, encoder *codec.Encoder) error {
|
2021-12-02 23:42:47 +00:00
|
|
|
if err := s.persistVirtualIPs(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-11-30 01:33:57 +00:00
|
|
|
if err := s.persistNodes(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := s.persistSessions(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := s.persistACLs(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := s.persistKVs(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := s.persistTombstones(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := s.persistPreparedQueries(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := s.persistAutopilot(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-10-06 18:24:05 +00:00
|
|
|
if err := s.persistLegacyIntentions(sink, encoder); err != nil {
|
2018-03-06 17:31:21 +00:00
|
|
|
return err
|
|
|
|
}
|
2018-03-21 18:33:19 +00:00
|
|
|
if err := s.persistConnectCA(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-07-11 18:34:49 +00:00
|
|
|
if err := s.persistConnectCAProviderState(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-08-16 18:58:50 +00:00
|
|
|
if err := s.persistConnectCAConfig(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-03-20 23:13:13 +00:00
|
|
|
if err := s.persistConfigEntries(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-03-09 20:59:02 +00:00
|
|
|
if err := s.persistFederationStates(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-10-06 15:08:37 +00:00
|
|
|
if err := s.persistSystemMetadata(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-10-19 16:04:07 +00:00
|
|
|
if err := s.persistIndex(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
|
|
|
if err := s.persistPeerings(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := s.persistPeeringTrustBundles(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-08-02 22:20:07 +00:00
|
|
|
if err := s.persistPeeringSecrets(sink, encoder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-11-30 01:33:57 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *snapshot) persistNodes(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
|
|
|
|
|
|
|
// Get all the nodes
|
|
|
|
nodes, err := s.state.Nodes()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register each node
|
|
|
|
for node := nodes.Next(); node != nil; node = nodes.Next() {
|
|
|
|
n := node.(*structs.Node)
|
2021-08-17 18:29:39 +00:00
|
|
|
nodeEntMeta := n.GetEnterpriseMeta()
|
|
|
|
|
2022-05-12 21:04:44 +00:00
|
|
|
req := n.ToRegisterRequest()
|
2017-11-30 01:33:57 +00:00
|
|
|
|
|
|
|
// Register the node itself
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.RegisterRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register each service this node has
|
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
|
|
|
services, err := s.state.Services(n.Node, nodeEntMeta, n.PeerName)
|
2017-11-30 01:33:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for service := services.Next(); service != nil; service = services.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.RegisterRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
req.Service = service.(*structs.ServiceNode).ToNodeService()
|
|
|
|
if err := encoder.Encode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register each check this node has
|
|
|
|
req.Service = nil
|
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
|
|
|
checks, err := s.state.Checks(n.Node, nodeEntMeta, n.PeerName)
|
2017-11-30 01:33:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for check := checks.Next(); check != nil; check = checks.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.RegisterRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
req.Check = check.(*structs.HealthCheck)
|
|
|
|
if err := encoder.Encode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save the coordinates separately since they are not part of the
|
|
|
|
// register request interface. To avoid copying them out, we turn
|
|
|
|
// them into batches with a single coordinate each.
|
|
|
|
coords, err := s.state.Coordinates()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for coord := coords.Next(); coord != nil; coord = coords.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.CoordinateBatchUpdateType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
updates := structs.Coordinates{coord.(*structs.Coordinate)}
|
|
|
|
if err := encoder.Encode(&updates); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *snapshot) persistSessions(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
|
|
|
sessions, err := s.state.Sessions()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for session := sessions.Next(); session != nil; session = sessions.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.SessionRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(session.(*structs.Session)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *snapshot) persistACLs(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
2018-10-19 16:04:07 +00:00
|
|
|
tokens, err := s.state.ACLTokens()
|
2017-11-30 01:33:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-04-08 17:05:51 +00:00
|
|
|
// Don't check expiration times. Wait for explicit deletions.
|
|
|
|
|
2018-10-19 16:04:07 +00:00
|
|
|
for token := tokens.Next(); token != nil; token = tokens.Next() {
|
2018-10-31 20:00:46 +00:00
|
|
|
if _, err := sink.Write([]byte{byte(structs.ACLTokenSetRequestType)}); err != nil {
|
2017-11-30 01:33:57 +00:00
|
|
|
return err
|
|
|
|
}
|
2018-10-19 16:04:07 +00:00
|
|
|
if err := encoder.Encode(token.(*structs.ACLToken)); err != nil {
|
2017-11-30 01:33:57 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-19 16:04:07 +00:00
|
|
|
policies, err := s.state.ACLPolicies()
|
2017-11-30 01:33:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-10-19 16:04:07 +00:00
|
|
|
|
|
|
|
for policy := policies.Next(); policy != nil; policy = policies.Next() {
|
2018-10-31 20:00:46 +00:00
|
|
|
if _, err := sink.Write([]byte{byte(structs.ACLPolicySetRequestType)}); err != nil {
|
2017-11-30 01:33:57 +00:00
|
|
|
return err
|
|
|
|
}
|
2018-10-19 16:04:07 +00:00
|
|
|
if err := encoder.Encode(policy.(*structs.ACLPolicy)); err != nil {
|
2017-11-30 01:33:57 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-15 20:43:19 +00:00
|
|
|
roles, err := s.state.ACLRoles()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for role := roles.Next(); role != nil; role = roles.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.ACLRoleSetRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(role.(*structs.ACLRole)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-26 17:49:28 +00:00
|
|
|
rules, err := s.state.ACLBindingRules()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for rule := rules.Next(); rule != nil; rule = rules.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.ACLBindingRuleSetRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(rule.(*structs.ACLBindingRule)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
methods, err := s.state.ACLAuthMethods()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-04-14 20:48:04 +00:00
|
|
|
for method := methods.Next(); method != nil; method = methods.Next() {
|
2019-04-26 17:49:28 +00:00
|
|
|
if _, err := sink.Write([]byte{byte(structs.ACLAuthMethodSetRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(method.(*structs.ACLAuthMethod)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-30 01:33:57 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *snapshot) persistKVs(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
|
|
|
entries, err := s.state.KVs()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for entry := entries.Next(); entry != nil; entry = entries.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.KVSRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(entry.(*structs.DirEntry)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *snapshot) persistTombstones(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
|
|
|
stones, err := s.state.Tombstones()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for stone := stones.Next(); stone != nil; stone = stones.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.TombstoneRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// For historical reasons, these are serialized in the snapshots
|
|
|
|
// as KV entries. We want to keep the snapshot format compatible
|
|
|
|
// with pre-0.6 versions for now.
|
|
|
|
s := stone.(*state.Tombstone)
|
|
|
|
fake := &structs.DirEntry{
|
|
|
|
Key: s.Key,
|
|
|
|
RaftIndex: structs.RaftIndex{
|
|
|
|
ModifyIndex: s.Index,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(fake); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *snapshot) persistPreparedQueries(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
|
|
|
queries, err := s.state.PreparedQueries()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, query := range queries {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.PreparedQueryRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(query); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *snapshot) persistAutopilot(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
2018-12-06 02:27:20 +00:00
|
|
|
config, err := s.state.Autopilot()
|
2017-11-30 01:33:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-12-06 02:27:20 +00:00
|
|
|
// Make sure we don't write a nil config out to a snapshot.
|
|
|
|
if config == nil {
|
2017-11-30 01:33:57 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.AutopilotRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-12-06 02:27:20 +00:00
|
|
|
if err := encoder.Encode(config); err != nil {
|
2017-11-30 01:33:57 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-03-21 18:33:19 +00:00
|
|
|
func (s *snapshot) persistConnectCA(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
|
|
|
roots, err := s.state.CARoots()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, r := range roots {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.ConnectCARequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(r); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2018-08-16 18:58:50 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *snapshot) persistConnectCAConfig(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
|
|
|
config, err := s.state.CAConfig()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-12-06 02:27:20 +00:00
|
|
|
// Make sure we don't write a nil config out to a snapshot.
|
|
|
|
if config == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2018-08-16 18:58:50 +00:00
|
|
|
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.ConnectCAConfigType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(config); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-03-21 18:33:19 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-07-11 18:34:49 +00:00
|
|
|
func (s *snapshot) persistConnectCAProviderState(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
|
|
|
state, err := s.state.CAProviderState()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, r := range state {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.ConnectCAProviderStateType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(r); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-06 18:24:05 +00:00
|
|
|
func (s *snapshot) persistLegacyIntentions(sink raft.SnapshotSink,
|
2018-03-06 17:31:21 +00:00
|
|
|
encoder *codec.Encoder) error {
|
2020-10-06 18:24:05 +00:00
|
|
|
//nolint:staticcheck
|
|
|
|
ixns, err := s.state.LegacyIntentions()
|
2018-03-06 17:31:21 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, ixn := range ixns {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.IntentionRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(ixn); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-03-20 23:13:13 +00:00
|
|
|
func (s *snapshot) persistConfigEntries(sink raft.SnapshotSink,
|
|
|
|
encoder *codec.Encoder) error {
|
|
|
|
entries, err := s.state.ConfigEntries()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, entry := range entries {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.ConfigEntryRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-04-02 22:42:12 +00:00
|
|
|
// Encode the entry request without an operation since we don't need it for restoring.
|
|
|
|
// The request is used for its custom decoding/encoding logic around the ConfigEntry
|
|
|
|
// interface.
|
2019-03-28 06:56:35 +00:00
|
|
|
req := &structs.ConfigEntryRequest{
|
|
|
|
Entry: entry,
|
2019-03-20 23:13:13 +00:00
|
|
|
}
|
2019-03-28 06:56:35 +00:00
|
|
|
if err := encoder.Encode(req); err != nil {
|
2019-03-20 23:13:13 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-03-09 20:59:02 +00:00
|
|
|
func (s *snapshot) persistFederationStates(sink raft.SnapshotSink, encoder *codec.Encoder) error {
|
|
|
|
fedStates, err := s.state.FederationStates()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, fedState := range fedStates {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.FederationStateRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// Encode the entry request without an operation since we don't need it for restoring.
|
|
|
|
// The request is used for its custom decoding/encoding logic around the ConfigEntry
|
|
|
|
// interface.
|
|
|
|
req := &structs.FederationStateRequest{
|
|
|
|
Op: structs.FederationStateUpsert,
|
|
|
|
State: fedState,
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-06 15:08:37 +00:00
|
|
|
func (s *snapshot) persistSystemMetadata(sink raft.SnapshotSink, encoder *codec.Encoder) error {
|
|
|
|
entries, err := s.state.SystemMetadataEntries()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, entry := range entries {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.SystemMetadataRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(entry); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-10-19 16:04:07 +00:00
|
|
|
func (s *snapshot) persistIndex(sink raft.SnapshotSink, encoder *codec.Encoder) error {
|
|
|
|
// Get all the indexes
|
|
|
|
iter, err := s.state.Indexes()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for raw := iter.Next(); raw != nil; raw = iter.Next() {
|
|
|
|
// Prepare the request struct
|
|
|
|
idx := raw.(*state.IndexEntry)
|
|
|
|
|
|
|
|
// Write out a node registration
|
|
|
|
sink.Write([]byte{byte(structs.IndexRequestType)})
|
|
|
|
if err := encoder.Encode(idx); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-12-02 23:42:47 +00:00
|
|
|
func (s *snapshot) persistVirtualIPs(sink raft.SnapshotSink, encoder *codec.Encoder) error {
|
|
|
|
serviceVIPs, err := s.state.ServiceVirtualIPs()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for entry := serviceVIPs.Next(); entry != nil; entry = serviceVIPs.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.ServiceVirtualIPRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(entry.(state.ServiceVirtualIP)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
freeVIPs, err := s.state.FreeVirtualIPs()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for entry := freeVIPs.Next(); entry != nil; entry = freeVIPs.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.FreeVirtualIPRequestType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(entry.(state.FreeVirtualIP)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
|
|
|
func (s *snapshot) persistPeerings(sink raft.SnapshotSink, encoder *codec.Encoder) error {
|
|
|
|
peerings, err := s.state.Peerings()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for entry := peerings.Next(); entry != nil; entry = peerings.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.PeeringWriteType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(entry.(*pbpeering.Peering)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *snapshot) persistPeeringTrustBundles(sink raft.SnapshotSink, encoder *codec.Encoder) error {
|
|
|
|
ptbs, err := s.state.PeeringTrustBundles()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for entry := ptbs.Next(); entry != nil; entry = ptbs.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.PeeringTrustBundleWriteType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(entry.(*pbpeering.PeeringTrustBundle)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-08-02 22:20:07 +00:00
|
|
|
func (s *snapshot) persistPeeringSecrets(sink raft.SnapshotSink, encoder *codec.Encoder) error {
|
|
|
|
secrets, err := s.state.PeeringSecrets()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for entry := secrets.Next(); entry != nil; entry = secrets.Next() {
|
|
|
|
if _, err := sink.Write([]byte{byte(structs.PeeringSecretsWriteType)}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := encoder.Encode(entry.(*pbpeering.PeeringSecrets)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreRegistration(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2017-11-30 01:33:57 +00:00
|
|
|
var req structs.RegisterRequest
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.Registration(header.LastIndex, &req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreKV(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2017-11-30 01:33:57 +00:00
|
|
|
var req structs.DirEntry
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.KVS(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreTombstone(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2017-11-30 01:33:57 +00:00
|
|
|
var req structs.DirEntry
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// For historical reasons, these are serialized in the
|
|
|
|
// snapshots as KV entries. We want to keep the snapshot
|
|
|
|
// format compatible with pre-0.6 versions for now.
|
|
|
|
stone := &state.Tombstone{
|
|
|
|
Key: req.Key,
|
|
|
|
Index: req.ModifyIndex,
|
|
|
|
}
|
|
|
|
if err := restore.Tombstone(stone); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreSession(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2017-11-30 01:33:57 +00:00
|
|
|
var req structs.Session
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.Session(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreCoordinates(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2017-11-30 01:33:57 +00:00
|
|
|
var req structs.Coordinates
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.Coordinates(header.LastIndex, req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restorePreparedQuery(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2017-11-30 01:33:57 +00:00
|
|
|
var req structs.PreparedQuery
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.PreparedQuery(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreAutopilot(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2020-09-25 17:46:38 +00:00
|
|
|
var req structs.AutopilotConfig
|
2017-11-30 01:33:57 +00:00
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.Autopilot(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2018-03-06 17:31:21 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreLegacyIntention(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2018-03-06 17:31:21 +00:00
|
|
|
var req structs.Intention
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-10-06 18:24:05 +00:00
|
|
|
//nolint:staticcheck
|
|
|
|
if err := restore.LegacyIntention(&req); err != nil {
|
2018-03-06 17:31:21 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2018-03-21 18:33:19 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreConnectCA(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2018-03-21 18:33:19 +00:00
|
|
|
var req structs.CARoot
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.CARoot(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2018-07-11 18:34:49 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreConnectCAProviderState(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2018-07-11 18:34:49 +00:00
|
|
|
var req structs.CAConsulProviderState
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.CAProviderState(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2018-08-16 18:58:50 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreConnectCAConfig(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2018-08-16 18:58:50 +00:00
|
|
|
var req structs.CAConfiguration
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.CAConfig(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2018-10-19 16:04:07 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreIndex(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2018-10-19 16:04:07 +00:00
|
|
|
var req state.IndexEntry
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return restore.IndexRestore(&req)
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreToken(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2018-10-19 16:04:07 +00:00
|
|
|
var req structs.ACLToken
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-11-13 21:35:54 +00:00
|
|
|
|
2020-06-08 19:44:06 +00:00
|
|
|
// only set if unset - mitigates a bug where converted legacy tokens could end up without a hash
|
|
|
|
req.SetHash(false)
|
|
|
|
|
2018-10-19 16:04:07 +00:00
|
|
|
return restore.ACLToken(&req)
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restorePolicy(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2018-10-19 16:04:07 +00:00
|
|
|
var req structs.ACLPolicy
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return restore.ACLPolicy(&req)
|
|
|
|
}
|
2019-03-20 23:13:13 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreConfigEntry(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2019-03-28 06:56:35 +00:00
|
|
|
var req structs.ConfigEntryRequest
|
2019-03-20 23:13:13 +00:00
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-03-28 06:56:35 +00:00
|
|
|
return restore.ConfigEntry(req.Entry)
|
2019-03-20 23:13:13 +00:00
|
|
|
}
|
2019-04-15 20:43:19 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreRole(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2019-04-15 20:43:19 +00:00
|
|
|
var req structs.ACLRole
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return restore.ACLRole(&req)
|
|
|
|
}
|
2019-04-26 17:49:28 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreBindingRule(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2019-04-26 17:49:28 +00:00
|
|
|
var req structs.ACLBindingRule
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return restore.ACLBindingRule(&req)
|
|
|
|
}
|
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreAuthMethod(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2019-04-26 17:49:28 +00:00
|
|
|
var req structs.ACLAuthMethod
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return restore.ACLAuthMethod(&req)
|
|
|
|
}
|
2020-03-09 20:59:02 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreFederationState(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2020-03-09 20:59:02 +00:00
|
|
|
var req structs.FederationStateRequest
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return restore.FederationState(req.State)
|
|
|
|
}
|
2020-10-06 15:08:37 +00:00
|
|
|
|
2020-10-09 19:57:29 +00:00
|
|
|
func restoreSystemMetadata(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2020-10-06 15:08:37 +00:00
|
|
|
var req structs.SystemMetadataEntry
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return restore.SystemMetadataEntry(&req)
|
|
|
|
}
|
2021-12-02 23:42:47 +00:00
|
|
|
|
|
|
|
func restoreServiceVirtualIP(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
2022-08-11 18:47:10 +00:00
|
|
|
// state.ServiceVirtualIP was changed in a breaking way in 1.13.0 (2e4cb6f77d2be36b02e9be0b289b24e5b0afb794).
|
|
|
|
// We attempt to reconcile the older type by decoding to a map then decoding that map into
|
|
|
|
// structs.PeeredServiceName first, and then structs.ServiceName.
|
|
|
|
var req struct {
|
|
|
|
Service map[string]interface{}
|
|
|
|
IP net.IP
|
|
|
|
|
|
|
|
structs.RaftIndex
|
|
|
|
}
|
2021-12-02 23:42:47 +00:00
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-08-11 18:47:10 +00:00
|
|
|
|
|
|
|
vip := state.ServiceVirtualIP{
|
|
|
|
IP: req.IP,
|
|
|
|
RaftIndex: req.RaftIndex,
|
|
|
|
}
|
|
|
|
|
|
|
|
// PeeredServiceName is the expected primary key type.
|
|
|
|
var psn structs.PeeredServiceName
|
|
|
|
if err := mapstructure.Decode(req.Service, &psn); err != nil {
|
|
|
|
return fmt.Errorf("cannot decode to structs.PeeredServiceName: %w", err)
|
|
|
|
}
|
|
|
|
vip.Service = psn
|
|
|
|
|
|
|
|
// If the expected primary key field is empty, it must be the older ServiceName type.
|
|
|
|
if vip.Service.ServiceName.Name == "" {
|
|
|
|
var sn structs.ServiceName
|
|
|
|
if err := mapstructure.Decode(req.Service, &sn); err != nil {
|
|
|
|
return fmt.Errorf("cannot decode to structs.ServiceName: %w", err)
|
|
|
|
}
|
|
|
|
vip.Service = structs.PeeredServiceName{
|
|
|
|
ServiceName: sn,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := restore.ServiceVirtualIP(vip); err != nil {
|
2021-12-02 23:42:47 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func restoreFreeVirtualIP(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
|
|
|
var req state.FreeVirtualIP
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.FreeVirtualIP(req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
peering: initial sync (#12842)
- Add endpoints related to peering: read, list, generate token, initiate peering
- Update node/service/check table indexing to account for peers
- Foundational changes for pushing service updates to a peer
- Plumb peer name through Health.ServiceNodes path
see: ENT-1765, ENT-1280, ENT-1283, ENT-1283, ENT-1756, ENT-1739, ENT-1750, ENT-1679,
ENT-1709, ENT-1704, ENT-1690, ENT-1689, ENT-1702, ENT-1701, ENT-1683, ENT-1663,
ENT-1650, ENT-1678, ENT-1628, ENT-1658, ENT-1640, ENT-1637, ENT-1597, ENT-1634,
ENT-1613, ENT-1616, ENT-1617, ENT-1591, ENT-1588, ENT-1596, ENT-1572, ENT-1555
Co-authored-by: R.B. Boyer <rb@hashicorp.com>
Co-authored-by: freddygv <freddy@hashicorp.com>
Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
Co-authored-by: Evan Culver <eculver@hashicorp.com>
Co-authored-by: Nitya Dhanushkodi <nitya@hashicorp.com>
2022-04-21 22:34:40 +00:00
|
|
|
|
|
|
|
func restorePeering(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
|
|
|
var req pbpeering.Peering
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.Peering(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func restorePeeringTrustBundle(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
|
|
|
var req pbpeering.PeeringTrustBundle
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.PeeringTrustBundle(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2022-08-02 22:20:07 +00:00
|
|
|
|
|
|
|
func restorePeeringSecrets(header *SnapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
|
|
|
|
var req pbpeering.PeeringSecrets
|
|
|
|
if err := decoder.Decode(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := restore.PeeringSecrets(&req); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|