github.com/clly/consul@v1.4.5/agent/consul/fsm/snapshot_oss.go (about)

     1  package fsm
     2  
     3  import (
     4  	"github.com/hashicorp/consul/agent/consul/autopilot"
     5  	"github.com/hashicorp/consul/agent/consul/state"
     6  	"github.com/hashicorp/consul/agent/structs"
     7  	"github.com/hashicorp/go-msgpack/codec"
     8  	"github.com/hashicorp/raft"
     9  )
    10  
    11  func init() {
    12  	registerPersister(persistOSS)
    13  
    14  	registerRestorer(structs.RegisterRequestType, restoreRegistration)
    15  	registerRestorer(structs.KVSRequestType, restoreKV)
    16  	registerRestorer(structs.TombstoneRequestType, restoreTombstone)
    17  	registerRestorer(structs.SessionRequestType, restoreSession)
    18  	registerRestorer(structs.ACLRequestType, restoreACL)
    19  	registerRestorer(structs.ACLBootstrapRequestType, restoreACLBootstrap)
    20  	registerRestorer(structs.CoordinateBatchUpdateType, restoreCoordinates)
    21  	registerRestorer(structs.PreparedQueryRequestType, restorePreparedQuery)
    22  	registerRestorer(structs.AutopilotRequestType, restoreAutopilot)
    23  	registerRestorer(structs.IntentionRequestType, restoreIntention)
    24  	registerRestorer(structs.ConnectCARequestType, restoreConnectCA)
    25  	registerRestorer(structs.ConnectCAProviderStateType, restoreConnectCAProviderState)
    26  	registerRestorer(structs.ConnectCAConfigType, restoreConnectCAConfig)
    27  	registerRestorer(structs.IndexRequestType, restoreIndex)
    28  	registerRestorer(structs.ACLTokenSetRequestType, restoreToken)
    29  	registerRestorer(structs.ACLPolicySetRequestType, restorePolicy)
    30  }
    31  
    32  func persistOSS(s *snapshot, sink raft.SnapshotSink, encoder *codec.Encoder) error {
    33  	if err := s.persistNodes(sink, encoder); err != nil {
    34  		return err
    35  	}
    36  	if err := s.persistSessions(sink, encoder); err != nil {
    37  		return err
    38  	}
    39  	if err := s.persistACLs(sink, encoder); err != nil {
    40  		return err
    41  	}
    42  	if err := s.persistKVs(sink, encoder); err != nil {
    43  		return err
    44  	}
    45  	if err := s.persistTombstones(sink, encoder); err != nil {
    46  		return err
    47  	}
    48  	if err := s.persistPreparedQueries(sink, encoder); err != nil {
    49  		return err
    50  	}
    51  	if err := s.persistAutopilot(sink, encoder); err != nil {
    52  		return err
    53  	}
    54  	if err := s.persistIntentions(sink, encoder); err != nil {
    55  		return err
    56  	}
    57  	if err := s.persistConnectCA(sink, encoder); err != nil {
    58  		return err
    59  	}
    60  	if err := s.persistConnectCAProviderState(sink, encoder); err != nil {
    61  		return err
    62  	}
    63  	if err := s.persistConnectCAConfig(sink, encoder); err != nil {
    64  		return err
    65  	}
    66  	if err := s.persistIndex(sink, encoder); err != nil {
    67  		return err
    68  	}
    69  	return nil
    70  }
    71  
    72  func (s *snapshot) persistNodes(sink raft.SnapshotSink,
    73  	encoder *codec.Encoder) error {
    74  
    75  	// Get all the nodes
    76  	nodes, err := s.state.Nodes()
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	// Register each node
    82  	for node := nodes.Next(); node != nil; node = nodes.Next() {
    83  		n := node.(*structs.Node)
    84  		req := structs.RegisterRequest{
    85  			ID:              n.ID,
    86  			Node:            n.Node,
    87  			Datacenter:      n.Datacenter,
    88  			Address:         n.Address,
    89  			TaggedAddresses: n.TaggedAddresses,
    90  			NodeMeta:        n.Meta,
    91  		}
    92  
    93  		// Register the node itself
    94  		if _, err := sink.Write([]byte{byte(structs.RegisterRequestType)}); err != nil {
    95  			return err
    96  		}
    97  		if err := encoder.Encode(&req); err != nil {
    98  			return err
    99  		}
   100  
   101  		// Register each service this node has
   102  		services, err := s.state.Services(n.Node)
   103  		if err != nil {
   104  			return err
   105  		}
   106  		for service := services.Next(); service != nil; service = services.Next() {
   107  			if _, err := sink.Write([]byte{byte(structs.RegisterRequestType)}); err != nil {
   108  				return err
   109  			}
   110  			req.Service = service.(*structs.ServiceNode).ToNodeService()
   111  			if err := encoder.Encode(&req); err != nil {
   112  				return err
   113  			}
   114  		}
   115  
   116  		// Register each check this node has
   117  		req.Service = nil
   118  		checks, err := s.state.Checks(n.Node)
   119  		if err != nil {
   120  			return err
   121  		}
   122  		for check := checks.Next(); check != nil; check = checks.Next() {
   123  			if _, err := sink.Write([]byte{byte(structs.RegisterRequestType)}); err != nil {
   124  				return err
   125  			}
   126  			req.Check = check.(*structs.HealthCheck)
   127  			if err := encoder.Encode(&req); err != nil {
   128  				return err
   129  			}
   130  		}
   131  	}
   132  
   133  	// Save the coordinates separately since they are not part of the
   134  	// register request interface. To avoid copying them out, we turn
   135  	// them into batches with a single coordinate each.
   136  	coords, err := s.state.Coordinates()
   137  	if err != nil {
   138  		return err
   139  	}
   140  	for coord := coords.Next(); coord != nil; coord = coords.Next() {
   141  		if _, err := sink.Write([]byte{byte(structs.CoordinateBatchUpdateType)}); err != nil {
   142  			return err
   143  		}
   144  		updates := structs.Coordinates{coord.(*structs.Coordinate)}
   145  		if err := encoder.Encode(&updates); err != nil {
   146  			return err
   147  		}
   148  	}
   149  	return nil
   150  }
   151  
   152  func (s *snapshot) persistSessions(sink raft.SnapshotSink,
   153  	encoder *codec.Encoder) error {
   154  	sessions, err := s.state.Sessions()
   155  	if err != nil {
   156  		return err
   157  	}
   158  
   159  	for session := sessions.Next(); session != nil; session = sessions.Next() {
   160  		if _, err := sink.Write([]byte{byte(structs.SessionRequestType)}); err != nil {
   161  			return err
   162  		}
   163  		if err := encoder.Encode(session.(*structs.Session)); err != nil {
   164  			return err
   165  		}
   166  	}
   167  	return nil
   168  }
   169  
   170  func (s *snapshot) persistACLs(sink raft.SnapshotSink,
   171  	encoder *codec.Encoder) error {
   172  	tokens, err := s.state.ACLTokens()
   173  	if err != nil {
   174  		return err
   175  	}
   176  
   177  	for token := tokens.Next(); token != nil; token = tokens.Next() {
   178  		if _, err := sink.Write([]byte{byte(structs.ACLTokenSetRequestType)}); err != nil {
   179  			return err
   180  		}
   181  		if err := encoder.Encode(token.(*structs.ACLToken)); err != nil {
   182  			return err
   183  		}
   184  	}
   185  
   186  	policies, err := s.state.ACLPolicies()
   187  	if err != nil {
   188  		return err
   189  	}
   190  
   191  	for policy := policies.Next(); policy != nil; policy = policies.Next() {
   192  		if _, err := sink.Write([]byte{byte(structs.ACLPolicySetRequestType)}); err != nil {
   193  			return err
   194  		}
   195  		if err := encoder.Encode(policy.(*structs.ACLPolicy)); err != nil {
   196  			return err
   197  		}
   198  	}
   199  
   200  	return nil
   201  }
   202  
   203  func (s *snapshot) persistKVs(sink raft.SnapshotSink,
   204  	encoder *codec.Encoder) error {
   205  	entries, err := s.state.KVs()
   206  	if err != nil {
   207  		return err
   208  	}
   209  
   210  	for entry := entries.Next(); entry != nil; entry = entries.Next() {
   211  		if _, err := sink.Write([]byte{byte(structs.KVSRequestType)}); err != nil {
   212  			return err
   213  		}
   214  		if err := encoder.Encode(entry.(*structs.DirEntry)); err != nil {
   215  			return err
   216  		}
   217  	}
   218  	return nil
   219  }
   220  
   221  func (s *snapshot) persistTombstones(sink raft.SnapshotSink,
   222  	encoder *codec.Encoder) error {
   223  	stones, err := s.state.Tombstones()
   224  	if err != nil {
   225  		return err
   226  	}
   227  
   228  	for stone := stones.Next(); stone != nil; stone = stones.Next() {
   229  		if _, err := sink.Write([]byte{byte(structs.TombstoneRequestType)}); err != nil {
   230  			return err
   231  		}
   232  
   233  		// For historical reasons, these are serialized in the snapshots
   234  		// as KV entries. We want to keep the snapshot format compatible
   235  		// with pre-0.6 versions for now.
   236  		s := stone.(*state.Tombstone)
   237  		fake := &structs.DirEntry{
   238  			Key: s.Key,
   239  			RaftIndex: structs.RaftIndex{
   240  				ModifyIndex: s.Index,
   241  			},
   242  		}
   243  		if err := encoder.Encode(fake); err != nil {
   244  			return err
   245  		}
   246  	}
   247  	return nil
   248  }
   249  
   250  func (s *snapshot) persistPreparedQueries(sink raft.SnapshotSink,
   251  	encoder *codec.Encoder) error {
   252  	queries, err := s.state.PreparedQueries()
   253  	if err != nil {
   254  		return err
   255  	}
   256  
   257  	for _, query := range queries {
   258  		if _, err := sink.Write([]byte{byte(structs.PreparedQueryRequestType)}); err != nil {
   259  			return err
   260  		}
   261  		if err := encoder.Encode(query); err != nil {
   262  			return err
   263  		}
   264  	}
   265  	return nil
   266  }
   267  
   268  func (s *snapshot) persistAutopilot(sink raft.SnapshotSink,
   269  	encoder *codec.Encoder) error {
   270  	config, err := s.state.Autopilot()
   271  	if err != nil {
   272  		return err
   273  	}
   274  	// Make sure we don't write a nil config out to a snapshot.
   275  	if config == nil {
   276  		return nil
   277  	}
   278  
   279  	if _, err := sink.Write([]byte{byte(structs.AutopilotRequestType)}); err != nil {
   280  		return err
   281  	}
   282  	if err := encoder.Encode(config); err != nil {
   283  		return err
   284  	}
   285  	return nil
   286  }
   287  
   288  func (s *snapshot) persistConnectCA(sink raft.SnapshotSink,
   289  	encoder *codec.Encoder) error {
   290  	roots, err := s.state.CARoots()
   291  	if err != nil {
   292  		return err
   293  	}
   294  
   295  	for _, r := range roots {
   296  		if _, err := sink.Write([]byte{byte(structs.ConnectCARequestType)}); err != nil {
   297  			return err
   298  		}
   299  		if err := encoder.Encode(r); err != nil {
   300  			return err
   301  		}
   302  	}
   303  
   304  	return nil
   305  }
   306  
   307  func (s *snapshot) persistConnectCAConfig(sink raft.SnapshotSink,
   308  	encoder *codec.Encoder) error {
   309  	config, err := s.state.CAConfig()
   310  	if err != nil {
   311  		return err
   312  	}
   313  	// Make sure we don't write a nil config out to a snapshot.
   314  	if config == nil {
   315  		return nil
   316  	}
   317  
   318  	if _, err := sink.Write([]byte{byte(structs.ConnectCAConfigType)}); err != nil {
   319  		return err
   320  	}
   321  	if err := encoder.Encode(config); err != nil {
   322  		return err
   323  	}
   324  	return nil
   325  }
   326  
   327  func (s *snapshot) persistConnectCAProviderState(sink raft.SnapshotSink,
   328  	encoder *codec.Encoder) error {
   329  	state, err := s.state.CAProviderState()
   330  	if err != nil {
   331  		return err
   332  	}
   333  
   334  	for _, r := range state {
   335  		if _, err := sink.Write([]byte{byte(structs.ConnectCAProviderStateType)}); err != nil {
   336  			return err
   337  		}
   338  		if err := encoder.Encode(r); err != nil {
   339  			return err
   340  		}
   341  	}
   342  	return nil
   343  }
   344  
   345  func (s *snapshot) persistIntentions(sink raft.SnapshotSink,
   346  	encoder *codec.Encoder) error {
   347  	ixns, err := s.state.Intentions()
   348  	if err != nil {
   349  		return err
   350  	}
   351  
   352  	for _, ixn := range ixns {
   353  		if _, err := sink.Write([]byte{byte(structs.IntentionRequestType)}); err != nil {
   354  			return err
   355  		}
   356  		if err := encoder.Encode(ixn); err != nil {
   357  			return err
   358  		}
   359  	}
   360  	return nil
   361  }
   362  
   363  func (s *snapshot) persistIndex(sink raft.SnapshotSink, encoder *codec.Encoder) error {
   364  	// Get all the indexes
   365  	iter, err := s.state.Indexes()
   366  	if err != nil {
   367  		return err
   368  	}
   369  
   370  	for raw := iter.Next(); raw != nil; raw = iter.Next() {
   371  		// Prepare the request struct
   372  		idx := raw.(*state.IndexEntry)
   373  
   374  		// Write out a node registration
   375  		sink.Write([]byte{byte(structs.IndexRequestType)})
   376  		if err := encoder.Encode(idx); err != nil {
   377  			return err
   378  		}
   379  	}
   380  	return nil
   381  }
   382  
   383  func restoreRegistration(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   384  	var req structs.RegisterRequest
   385  	if err := decoder.Decode(&req); err != nil {
   386  		return err
   387  	}
   388  	if err := restore.Registration(header.LastIndex, &req); err != nil {
   389  		return err
   390  	}
   391  	return nil
   392  }
   393  
   394  func restoreKV(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   395  	var req structs.DirEntry
   396  	if err := decoder.Decode(&req); err != nil {
   397  		return err
   398  	}
   399  	if err := restore.KVS(&req); err != nil {
   400  		return err
   401  	}
   402  	return nil
   403  }
   404  
   405  func restoreTombstone(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   406  	var req structs.DirEntry
   407  	if err := decoder.Decode(&req); err != nil {
   408  		return err
   409  	}
   410  
   411  	// For historical reasons, these are serialized in the
   412  	// snapshots as KV entries. We want to keep the snapshot
   413  	// format compatible with pre-0.6 versions for now.
   414  	stone := &state.Tombstone{
   415  		Key:   req.Key,
   416  		Index: req.ModifyIndex,
   417  	}
   418  	if err := restore.Tombstone(stone); err != nil {
   419  		return err
   420  	}
   421  	return nil
   422  }
   423  
   424  func restoreSession(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   425  	var req structs.Session
   426  	if err := decoder.Decode(&req); err != nil {
   427  		return err
   428  	}
   429  	if err := restore.Session(&req); err != nil {
   430  		return err
   431  	}
   432  	return nil
   433  }
   434  
   435  func restoreACL(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   436  	var req structs.ACL
   437  	if err := decoder.Decode(&req); err != nil {
   438  		return err
   439  	}
   440  
   441  	if err := restore.ACLToken(req.Convert()); err != nil {
   442  		return err
   443  	}
   444  	return nil
   445  }
   446  
   447  // DEPRECATED (ACL-Legacy-Compat) - remove once v1 acl compat is removed
   448  func restoreACLBootstrap(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   449  	var req structs.ACLBootstrap
   450  	if err := decoder.Decode(&req); err != nil {
   451  		return err
   452  	}
   453  
   454  	// With V2 ACLs whether bootstrapping has been performed is stored in the index table like nomad
   455  	// so this "restores" into that index table.
   456  	return restore.IndexRestore(&state.IndexEntry{Key: "acl-token-bootstrap", Value: req.ModifyIndex})
   457  }
   458  
   459  func restoreCoordinates(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   460  	var req structs.Coordinates
   461  	if err := decoder.Decode(&req); err != nil {
   462  		return err
   463  	}
   464  	if err := restore.Coordinates(header.LastIndex, req); err != nil {
   465  		return err
   466  	}
   467  	return nil
   468  }
   469  
   470  func restorePreparedQuery(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   471  	var req structs.PreparedQuery
   472  	if err := decoder.Decode(&req); err != nil {
   473  		return err
   474  	}
   475  	if err := restore.PreparedQuery(&req); err != nil {
   476  		return err
   477  	}
   478  	return nil
   479  }
   480  
   481  func restoreAutopilot(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   482  	var req autopilot.Config
   483  	if err := decoder.Decode(&req); err != nil {
   484  		return err
   485  	}
   486  	if err := restore.Autopilot(&req); err != nil {
   487  		return err
   488  	}
   489  	return nil
   490  }
   491  
   492  func restoreIntention(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   493  	var req structs.Intention
   494  	if err := decoder.Decode(&req); err != nil {
   495  		return err
   496  	}
   497  	if err := restore.Intention(&req); err != nil {
   498  		return err
   499  	}
   500  	return nil
   501  }
   502  
   503  func restoreConnectCA(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   504  	var req structs.CARoot
   505  	if err := decoder.Decode(&req); err != nil {
   506  		return err
   507  	}
   508  	if err := restore.CARoot(&req); err != nil {
   509  		return err
   510  	}
   511  	return nil
   512  }
   513  
   514  func restoreConnectCAProviderState(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   515  	var req structs.CAConsulProviderState
   516  	if err := decoder.Decode(&req); err != nil {
   517  		return err
   518  	}
   519  	if err := restore.CAProviderState(&req); err != nil {
   520  		return err
   521  	}
   522  	return nil
   523  }
   524  
   525  func restoreConnectCAConfig(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   526  	var req structs.CAConfiguration
   527  	if err := decoder.Decode(&req); err != nil {
   528  		return err
   529  	}
   530  	if err := restore.CAConfig(&req); err != nil {
   531  		return err
   532  	}
   533  	return nil
   534  }
   535  
   536  func restoreIndex(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   537  	var req state.IndexEntry
   538  	if err := decoder.Decode(&req); err != nil {
   539  		return err
   540  	}
   541  	return restore.IndexRestore(&req)
   542  }
   543  
   544  func restoreToken(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   545  	var req structs.ACLToken
   546  	if err := decoder.Decode(&req); err != nil {
   547  		return err
   548  	}
   549  
   550  	// DEPRECATED (ACL-Legacy-Compat)
   551  	if req.Rules != "" {
   552  		// When we restore a snapshot we may have to correct old HCL in legacy
   553  		// tokens to prevent the in-memory representation from using an older
   554  		// syntax.
   555  		structs.SanitizeLegacyACLToken(&req)
   556  	}
   557  
   558  	return restore.ACLToken(&req)
   559  }
   560  
   561  func restorePolicy(header *snapshotHeader, restore *state.Restore, decoder *codec.Decoder) error {
   562  	var req structs.ACLPolicy
   563  	if err := decoder.Decode(&req); err != nil {
   564  		return err
   565  	}
   566  	return restore.ACLPolicy(&req)
   567  }