From 8fcafb139cc4ffe0f8b09498e174e6a23bbd67d8 Mon Sep 17 00:00:00 2001 From: Matt Keeler Date: Thu, 14 Mar 2024 12:59:06 -0400 Subject: [PATCH] Add `consul snapshot decode` command (#20824) Add snapshot decoding command --- .changelog/20824.txt | 3 + command/registry.go | 2 + command/snapshot/decode/snapshot_decode.go | 218 +++++++++++++ .../snapshot/decode/snapshot_decode_test.go | 107 +++++++ .../TestSnapshotDecodeCommand/all.ce.golden | 110 +++++++ .../TestSnapshotDecodeCommand/no-kv.ce.golden | 23 ++ .../with-kv.ce.golden | 51 +++ command/snapshot/decode/testdata/all.snap | Bin 0 -> 9179 bytes command/snapshot/decode/testdata/backup.snap | Bin 0 -> 2842 bytes .../decode/testdata/backupWithKV.snap | Bin 0 -> 12657 bytes .../snapshot/decode/testdata/populate-all.sh | 296 ++++++++++++++++++ command/snapshot/snapshot_command.go | 4 + .../builder/destination_multiport_test.go | 2 +- .../builder/local_app_multiport_test.go | 2 +- .../sidecarproxy/builder/local_app_test.go | 4 +- internal/testing/golden/golden.go | 6 +- 16 files changed, 821 insertions(+), 7 deletions(-) create mode 100644 .changelog/20824.txt create mode 100644 command/snapshot/decode/snapshot_decode.go create mode 100644 command/snapshot/decode/snapshot_decode_test.go create mode 100644 command/snapshot/decode/testdata/TestSnapshotDecodeCommand/all.ce.golden create mode 100644 command/snapshot/decode/testdata/TestSnapshotDecodeCommand/no-kv.ce.golden create mode 100644 command/snapshot/decode/testdata/TestSnapshotDecodeCommand/with-kv.ce.golden create mode 100644 command/snapshot/decode/testdata/all.snap create mode 100644 command/snapshot/decode/testdata/backup.snap create mode 100644 command/snapshot/decode/testdata/backupWithKV.snap create mode 100755 command/snapshot/decode/testdata/populate-all.sh diff --git a/.changelog/20824.txt b/.changelog/20824.txt new file mode 100644 index 0000000000..c067616dbe --- /dev/null +++ b/.changelog/20824.txt @@ -0,0 +1,3 @@ +```release-note:improvement +snapshot: Add `consul snapshot decode` CLI command to output a JSON object stream of all the snapshots data. +``` \ No newline at end of file diff --git a/command/registry.go b/command/registry.go index ca0baeeb31..381b86db9a 100644 --- a/command/registry.go +++ b/command/registry.go @@ -129,6 +129,7 @@ import ( exportedservices "github.com/hashicorp/consul/command/services/exportedservices" svcsregister "github.com/hashicorp/consul/command/services/register" "github.com/hashicorp/consul/command/snapshot" + snapdecode "github.com/hashicorp/consul/command/snapshot/decode" snapinspect "github.com/hashicorp/consul/command/snapshot/inspect" snaprestore "github.com/hashicorp/consul/command/snapshot/restore" snapsave "github.com/hashicorp/consul/command/snapshot/save" @@ -276,6 +277,7 @@ func RegisteredCommands(ui cli.Ui) map[string]mcli.CommandFactory { entry{"services export", func(ui cli.Ui) (cli.Command, error) { return svcsexport.New(ui), nil }}, entry{"services exported-services", func(ui cli.Ui) (cli.Command, error) { return exportedservices.New(ui), nil }}, entry{"snapshot", func(cli.Ui) (cli.Command, error) { return snapshot.New(), nil }}, + entry{"snapshot decode", func(ui cli.Ui) (cli.Command, error) { return snapdecode.New(ui), nil }}, entry{"snapshot inspect", func(ui cli.Ui) (cli.Command, error) { return snapinspect.New(ui), nil }}, entry{"snapshot restore", func(ui cli.Ui) (cli.Command, error) { return snaprestore.New(ui), nil }}, entry{"snapshot save", func(ui cli.Ui) (cli.Command, error) { return snapsave.New(ui), nil }}, diff --git a/command/snapshot/decode/snapshot_decode.go b/command/snapshot/decode/snapshot_decode.go new file mode 100644 index 0000000000..03151c093c --- /dev/null +++ b/command/snapshot/decode/snapshot_decode.go @@ -0,0 +1,218 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package decode + +import ( + "encoding/json" + "flag" + "fmt" + "io" + "os" + "path" + "strings" + + "github.com/hashicorp/consul-net-rpc/go-msgpack/codec" + "github.com/hashicorp/consul/agent/consul/fsm" + "github.com/hashicorp/consul/agent/consul/state" + "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/command/flags" + "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/consul/proto/private/pbpeering" + "github.com/hashicorp/consul/snapshot" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-raftchunking" + "github.com/hashicorp/raft" + "github.com/mitchellh/cli" +) + +var requestTypeZeroValues = map[structs.MessageType]func() any{ + structs.RegisterRequestType: func() any { return new(structs.RegisterRequest) }, + structs.KVSRequestType: func() any { return new(structs.KVSRequest) }, + structs.SessionRequestType: func() any { return new(structs.SessionRequest) }, + structs.TombstoneRequestType: func() any { return new(structs.TombstoneRequest) }, + structs.CoordinateBatchUpdateType: func() any { return new(structs.Coordinates) }, + structs.PreparedQueryRequestType: func() any { return new(structs.PreparedQueryRequest) }, + structs.AutopilotRequestType: func() any { return new(structs.AutopilotSetConfigRequest) }, + structs.IntentionRequestType: func() any { return new(structs.IntentionRequest) }, + structs.ConnectCARequestType: func() any { return new(structs.CARequest) }, + structs.ConnectCAProviderStateType: func() any { return new(structs.CAConsulProviderState) }, + structs.ConnectCAConfigType: func() any { return new(structs.CAConfiguration) }, + structs.IndexRequestType: func() any { return new(state.IndexEntry) }, + structs.ACLTokenSetRequestType: func() any { return new(structs.ACLToken) }, + structs.ACLPolicySetRequestType: func() any { return new(structs.ACLPolicy) }, + structs.ConfigEntryRequestType: func() any { return new(structs.ConfigEntryRequest) }, + structs.ACLRoleSetRequestType: func() any { return new(structs.ACLRole) }, + structs.ACLBindingRuleSetRequestType: func() any { return new(structs.ACLBindingRule) }, + structs.ACLAuthMethodSetRequestType: func() any { return new(structs.ACLAuthMethod) }, + structs.ChunkingStateType: func() any { return new(raftchunking.State) }, + structs.FederationStateRequestType: func() any { return new(structs.FederationStateRequest) }, + structs.SystemMetadataRequestType: func() any { return new(structs.SystemMetadataEntry) }, + structs.ServiceVirtualIPRequestType: func() any { return new(state.ServiceVirtualIP) }, + structs.FreeVirtualIPRequestType: func() any { return new(state.FreeVirtualIP) }, + structs.PeeringWriteType: func() any { return new(pbpeering.Peering) }, + structs.PeeringTrustBundleWriteType: func() any { return new(pbpeering.PeeringTrustBundle) }, + structs.PeeringSecretsWriteType: func() any { return new(pbpeering.PeeringSecrets) }, + structs.ResourceOperationType: func() any { return new(pbresource.Resource) }, +} + +func New(ui cli.Ui) *cmd { + c := &cmd{UI: ui} + c.init() + return c +} + +type cmd struct { + UI cli.Ui + flags *flag.FlagSet + help string + format string + + encoder *json.Encoder +} + +func (c *cmd) Write(p []byte) (n int, err error) { + s := string(p) + c.UI.Output(strings.TrimRight(s, "\n")) + return len(s), nil +} + +func (c *cmd) init() { + c.flags = flag.NewFlagSet("", flag.ContinueOnError) + c.help = flags.Usage(help, c.flags) + c.encoder = json.NewEncoder(c) +} + +func (c *cmd) Run(args []string) int { + if err := c.flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + var file string + args = c.flags.Args() + + switch len(args) { + case 0: + c.UI.Error("Missing FILE argument") + return 1 + case 1: + file = args[0] + default: + c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args))) + return 1 + } + + // Open the file. + f, err := os.Open(file) + if err != nil { + c.UI.Error(fmt.Sprintf("Error opening snapshot file: %s", err)) + return 1 + } + defer f.Close() + + var readFile *os.File + var meta *raft.SnapshotMeta + + if strings.ToLower(path.Base(file)) == "state.bin" { + // This is an internal raw raft snapshot not a gzipped archive one + // downloaded from the API, we can read it directly + readFile = f + + // Assume the meta is colocated and error if not. + metaRaw, err := os.ReadFile(path.Join(path.Dir(file), "meta.json")) + if err != nil { + c.UI.Error(fmt.Sprintf("Error reading meta.json from internal snapshot dir: %s", err)) + return 1 + } + var metaDecoded raft.SnapshotMeta + err = json.Unmarshal(metaRaw, &metaDecoded) + if err != nil { + c.UI.Error(fmt.Sprintf("Error parsing meta.json from internal snapshot dir: %s", err)) + return 1 + } + meta = &metaDecoded + } else { + readFile, meta, err = snapshot.Read(hclog.New(nil), f) + if err != nil { + c.UI.Error(fmt.Sprintf("Error reading snapshot: %s", err)) + return 1 + } + defer func() { + if err := readFile.Close(); err != nil { + c.UI.Error(fmt.Sprintf("Failed to close temp snapshot: %v", err)) + } + if err := os.Remove(readFile.Name()); err != nil { + c.UI.Error(fmt.Sprintf("Failed to clean up temp snapshot: %v", err)) + } + }() + } + + err = c.encoder.Encode(map[string]interface{}{ + "Type": "SnapshotHeader", + "Data": meta, + }) + if err != nil { + c.UI.Error(fmt.Sprintf("Error encoding snapshot header to the output stream: %v", err)) + return 1 + } + + err = c.decodeStream(readFile) + if err != nil { + c.UI.Error(fmt.Sprintf("Error extracting snapshot data: %s", err)) + return 1 + } + + return 0 +} + +// enhance utilizes ReadSnapshot to populate the struct with +// all of the snapshot's itemized data +func (c *cmd) decodeStream(file io.Reader) error { + handler := func(header *fsm.SnapshotHeader, msg structs.MessageType, dec *codec.Decoder) error { + name := structs.MessageType.String(msg) + var val interface{} + + if zeroVal, ok := requestTypeZeroValues[msg]; ok { + val = zeroVal() + } + + err := dec.Decode(&val) + if err != nil { + return fmt.Errorf("failed to decode msg type %v, error %v", name, err) + } + + err = c.encoder.Encode(map[string]interface{}{ + "Type": name, + "Data": val, + }) + + if err != nil { + return fmt.Errorf("failed to encode data into the object stream: %w", err) + } + + return nil + } + + return fsm.ReadSnapshot(file, handler) +} + +func (c *cmd) Synopsis() string { + return synopsis +} + +func (c *cmd) Help() string { + return c.help +} + +const synopsis = "Decodes the binary" +const help = ` +Usage: consul snapshot decode [options] FILE + + Decodes snapshot data and outputs a stream of line delimited JSON objects of the form: + + {"Type": "SnapshotHeader", "Data": {""}} + {"Type": "","Data": {}} + {"Type": "","Data": {}} + ... +` diff --git a/command/snapshot/decode/snapshot_decode_test.go b/command/snapshot/decode/snapshot_decode_test.go new file mode 100644 index 0000000000..bd456d558f --- /dev/null +++ b/command/snapshot/decode/snapshot_decode_test.go @@ -0,0 +1,107 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package decode + +import ( + "strings" + "testing" + + "github.com/hashicorp/consul/internal/testing/golden" + "github.com/hashicorp/consul/version/versiontest" + "github.com/mitchellh/cli" + "github.com/stretchr/testify/require" +) + +func TestSnapshotDecodeCommand_noTabs(t *testing.T) { + if strings.ContainsRune(New(cli.NewMockUi()).Help(), '\t') { + t.Fatal("help has tabs") + } +} + +func TestSnapshotDecodeCommand_Validation(t *testing.T) { + ui := cli.NewMockUi() + c := New(ui) + + cases := map[string]struct { + args []string + output string + }{ + "no file": { + []string{}, + "Missing FILE argument", + }, + "extra args": { + []string{"foo", "bar", "baz"}, + "Too many arguments", + }, + } + + for name, tc := range cases { + // Ensure our buffer is always clear + if ui.ErrorWriter != nil { + ui.ErrorWriter.Reset() + } + if ui.OutputWriter != nil { + ui.OutputWriter.Reset() + } + + code := c.Run(tc.args) + if code == 0 { + t.Errorf("%s: expected non-zero exit", name) + } + + output := ui.ErrorWriter.String() + if !strings.Contains(output, tc.output) { + t.Errorf("%s: expected %q to contain %q", name, output, tc.output) + } + } +} + +func TestSnapshotDecodeCommand(t *testing.T) { + cases := map[string]string{ + "no-kv": "./testdata/backup.snap", + "with-kv": "./testdata/backupWithKV.snap", + "all": "./testdata/all.snap", + } + + for name, fpath := range cases { + fpath := fpath + t.Run(name, func(t *testing.T) { + // Inspect the snapshot + ui := cli.NewMockUi() + c := New(ui) + args := []string{fpath} + + code := c.Run(args) + if code != 0 { + t.Fatalf("bad: %d. %#v", code, ui.ErrorWriter.String()) + } + + actual := ui.OutputWriter.String() + fname := t.Name() + ".ce.golden" + if versiontest.IsEnterprise() { + fname = t.Name() + ".ent.golden" + } + want := golden.Get(t, actual, fname) + require.Equal(t, want, actual) + }) + } +} + +func TestSnapshotDecodeInvalidFile(t *testing.T) { + // Attempt to open a non-snapshot file. + filepath := "./testdata/TestSnapshotDecodeCommand/no-kv.golden" + + // Inspect the snapshot + ui := cli.NewMockUi() + c := New(ui) + args := []string{filepath} + + code := c.Run(args) + // Just check it was an error code returned and not a panic - originally this + // would panic. + if code == 0 { + t.Fatalf("should return an error code") + } +} diff --git a/command/snapshot/decode/testdata/TestSnapshotDecodeCommand/all.ce.golden b/command/snapshot/decode/testdata/TestSnapshotDecodeCommand/all.ce.golden new file mode 100644 index 0000000000..f6fc2969b1 --- /dev/null +++ b/command/snapshot/decode/testdata/TestSnapshotDecodeCommand/all.ce.golden @@ -0,0 +1,110 @@ +{"Data":{"Version":1,"ID":"2-62-1710350056693","Index":62,"Term":2,"Peers":"ka4xMjcuMC4wLjE6ODMwMA==","Configuration":{"Servers":[{"Suffrage":0,"ID":"065c1172-84a8-0bd1-269c-d24b2d0fb903","Address":"127.0.0.1:8300"}]},"ConfigurationIndex":1,"Size":25469},"Type":"SnapshotHeader"} +{"Data":"\n\u0007default\u0012\u0019Builtin Default Namespace0\n8\n","Type":"Unknown(65)"} +{"Data":"\n\u0007default\u0012\u0019Builtin Default Partition \t(\t","Type":"Unknown(69)"} +{"Data":{"Service":{"ServiceName":{"Name":"external"},"Peer":""},"IP":"0.0.0.3","ManualIPs":null,"CreateIndex":43,"ModifyIndex":43},"Type":"ServiceVirtualIP"} +{"Data":{"Service":{"ServiceName":{"Name":"foo"},"Peer":""},"IP":"0.0.0.2","ManualIPs":null,"CreateIndex":38,"ModifyIndex":38},"Type":"ServiceVirtualIP"} +{"Data":{"Service":{"ServiceName":{"Name":"web"},"Peer":""},"IP":"0.0.0.1","ManualIPs":null,"CreateIndex":37,"ModifyIndex":37},"Type":"ServiceVirtualIP"} +{"Data":{"IP":"0.0.0.3","IsCounter":true},"Type":"FreeVirtualIP"} +{"Data":{"Datacenter":"dc1","ID":"065c1172-84a8-0bd1-269c-d24b2d0fb903","Node":"mkeeler-C02F44FDMD6R","Address":"127.0.0.1","TaggedAddresses":{"lan":"127.0.0.1","lan_ipv4":"127.0.0.1","wan":"127.0.0.1","wan_ipv4":"127.0.0.1"},"NodeMeta":{"consul-network-segment":"","consul-version":"1.19.0"},"Service":null,"Check":null,"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":21,"ModifyIndex":22},"Type":"Register"} +{"Data":{"Datacenter":"dc1","ID":"065c1172-84a8-0bd1-269c-d24b2d0fb903","Node":"mkeeler-C02F44FDMD6R","Address":"127.0.0.1","TaggedAddresses":{"lan":"127.0.0.1","lan_ipv4":"127.0.0.1","wan":"127.0.0.1","wan_ipv4":"127.0.0.1"},"NodeMeta":{"consul-network-segment":"","consul-version":"1.19.0"},"Service":{"ID":"consul","Service":"consul","Tags":null,"Address":"","Meta":{"grpc_port":"8502","grpc_tls_port":"8503","non_voter":"false","raft_version":"3","read_replica":"false","serf_protocol_current":"2","serf_protocol_max":"5","serf_protocol_min":"1","version":"1.19.0"},"Port":8300,"Weights":{"Passing":1,"Warning":1},"EnableTagOverride":false,"Proxy":{"Mode":"","MeshGateway":{},"Expose":{}},"Connect":{},"PeerName":"","CreateIndex":21,"ModifyIndex":21},"Check":null,"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":21,"ModifyIndex":22},"Type":"Register"} +{"Data":{"Datacenter":"dc1","ID":"065c1172-84a8-0bd1-269c-d24b2d0fb903","Node":"mkeeler-C02F44FDMD6R","Address":"127.0.0.1","TaggedAddresses":{"lan":"127.0.0.1","lan_ipv4":"127.0.0.1","wan":"127.0.0.1","wan_ipv4":"127.0.0.1"},"NodeMeta":{"consul-network-segment":"","consul-version":"1.19.0"},"Service":null,"Check":{"Node":"mkeeler-C02F44FDMD6R","CheckID":"serfHealth","Name":"Serf Health Status","Status":"passing","Notes":"","Output":"Agent alive and reachable","ServiceID":"","ServiceName":"","ServiceTags":null,"Type":"","Interval":"","Timeout":"","ExposedPort":0,"Definition":{},"CreateIndex":21,"ModifyIndex":21},"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":21,"ModifyIndex":22},"Type":"Register"} +{"Data":{"Datacenter":"","Op":"","Session":{"ID":"","Name":"","Node":"","LockDelay":0,"Behavior":"","TTL":"","NodeChecks":null,"ServiceChecks":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"Session"} +{"Data":{"AccessorID":"d56136c7-a3a8-ceac-da70-9bee9755d252","SecretID":"a4794332-5fe2-51e1-3a78-47c684bd181c","Description":"","NodeIdentities":[{"NodeName":"localhost","Datacenter":"dc1"}],"Local":false,"CreateTime":"2024-03-13T13:14:15.109823-04:00","Hash":"ibqA3nqRxdh2zAJSHY+nIphdDX/hpYOmgv3RASkkU1w=","CreateIndex":31,"ModifyIndex":31},"Type":"ACLToken"} +{"Data":{"AccessorID":"00000000-0000-0000-0000-000000000002","SecretID":"anonymous","Description":"Anonymous Token","Local":false,"CreateTime":"2024-03-13T13:14:09.953116-04:00","Hash":"tgCOyeidw+oaoZXQ9mHy6+EnY7atKoGaBzg2ndTwXl0=","CreateIndex":7,"ModifyIndex":7},"Type":"ACLToken"} +{"Data":{"AccessorID":"cbb26776-68df-d4ec-5b38-b40366ebf6c2","SecretID":"root","Description":"Initial Management Token","Policies":[{"ID":"00000000-0000-0000-0000-000000000001","Name":"global-management"}],"Local":false,"CreateTime":"2024-03-13T13:14:09.951135-04:00","Hash":"a5y709jeB8xI19PvumK2BeZG3u+1w3hfzyxf2s3UdDY=","CreateIndex":6,"ModifyIndex":6},"Type":"ACLToken"} +{"Data":{"ID":"00000000-0000-0000-0000-000000000001","Name":"global-management","Description":"A built-in policy that grants read and write access to all Consul features","Rules":"\nacl = \"write\"\nagent_prefix \"\" {\n\tpolicy = \"write\"\n}\nevent_prefix \"\" {\n\tpolicy = \"write\"\n}\nidentity_prefix \"\" {\n\tpolicy = \"write\"\n\tintentions = \"write\"\n}\nkey_prefix \"\" {\n\tpolicy = \"write\"\n}\nkeyring = \"write\"\nnode_prefix \"\" {\n\tpolicy = \"write\"\n}\noperator = \"write\"\nmesh = \"write\"\npeering = \"write\"\nquery_prefix \"\" {\n\tpolicy = \"write\"\n}\nservice_prefix \"\" {\n\tpolicy = \"write\"\n\tintentions = \"write\"\n}\nsession_prefix \"\" {\n\tpolicy = \"write\"\n}\npartition_prefix \"\" {\n\tmesh = \"write\"\n\tpeering = \"write\"\n\tnamespace \"default\" {\n\t\tnode_prefix \"\" {\n\t\t\tpolicy = \"write\"\n\t\t}\n\t\tagent_prefix \"\" {\n\t\t\tpolicy = \"write\"\n\t\t}\n\t}\n\tnamespace_prefix \"\" {\n\t\tacl = \"write\"\n\t\tidentity_prefix \"\" {\n\t\t\tpolicy = \"write\"\n\t\t\tintentions = \"write\"\n\t\t}\n\t\tkey_prefix \"\" {\n\t\t\tpolicy = \"write\"\n\t\t}\n\t\tnode_prefix \"\" {\n\t\t\t# node policy is restricted to read within a namespace\n\t\t\tpolicy = \"read\"\n\t\t}\n\t\tsession_prefix \"\" {\n\t\t\tpolicy = \"write\"\n\t\t}\n\t\tservice_prefix \"\" {\n\t\t\tpolicy = \"write\"\n\t\t\tintentions = \"write\"\n\t\t}\n\t}\n}\n","Hash":"NXp0drmQNPohGVdZ4mkRoOqe6Vtx2wYMuXHvQJNMbiE=","CreateIndex":4,"ModifyIndex":4},"Type":"ACLPolicy"} +{"Data":{"ID":"00000000-0000-0000-0000-000000000002","Name":"builtin/global-read-only","Description":"A built-in policy that grants read-only access to all Consul features","Rules":"\nacl = \"read\"\nagent_prefix \"\" {\n\tpolicy = \"read\"\n}\nevent_prefix \"\" {\n\tpolicy = \"read\"\n}\nidentity_prefix \"\" {\n\tpolicy = \"read\"\n\tintentions = \"read\"\n}\nkey_prefix \"\" {\n\tpolicy = \"read\"\n}\nkeyring = \"read\"\nnode_prefix \"\" {\n\tpolicy = \"read\"\n}\noperator = \"read\"\nmesh = \"read\"\npeering = \"read\"\nquery_prefix \"\" {\n\tpolicy = \"read\"\n}\nservice_prefix \"\" {\n\tpolicy = \"read\"\n\tintentions = \"read\"\n}\nsession_prefix \"\" {\n\tpolicy = \"read\"\n}\npartition_prefix \"\" {\n\tmesh = \"read\"\n\tpeering = \"read\"\n\tnamespace \"default\" {\n\t\tnode_prefix \"\" {\n\t\t\tpolicy = \"read\"\n\t\t}\n\t\tagent_prefix \"\" {\n\t\t\tpolicy = \"read\"\n\t\t}\n\t}\n\tnamespace_prefix \"\" {\n\t\tacl = \"read\"\n\t\tidentity_prefix \"\" {\n\t\t\tpolicy = \"read\"\n\t\t\tintentions = \"read\"\n\t\t}\n\t\tkey_prefix \"\" {\n\t\t\tpolicy = \"read\"\n\t\t}\n\t\tnode_prefix \"\" {\n\t\t\t# node policy is restricted to read within a namespace\n\t\t\tpolicy = \"read\"\n\t\t}\n\t\tsession_prefix \"\" {\n\t\t\tpolicy = \"read\"\n\t\t}\n\t\tservice_prefix \"\" {\n\t\t\tpolicy = \"read\"\n\t\t\tintentions = \"read\"\n\t\t}\n\t}\n}\n","Hash":"l1CO3kg8k1ikfGq3P309ZHfazlibtJ9RSGfDminehaE=","CreateIndex":5,"ModifyIndex":5},"Type":"ACLPolicy"} +{"Data":{"ID":"cefa650e-8538-974a-00a0-833c6aa4634a","Name":"test","Description":"","Rules":"node_prefix \"\" { policy = \"write\" }","Hash":"Utaz0IM7r4OLGrVW3ESeiZVGaaql+03cjTU7UHZiVJs=","CreateIndex":32,"ModifyIndex":32},"Type":"ACLPolicy"} +{"Data":{"ID":"edbab2c0-4bd2-052f-8a08-2f31e65930b2","Name":"test","Description":"","Policies":[{"ID":"cefa650e-8538-974a-00a0-833c6aa4634a","Name":"test"}],"Hash":"lfkCqRLtTKoFk50xI5Hxij13bfzsyg7IN7kYwnMP4Y0=","CreateIndex":33,"ModifyIndex":33},"Type":"ACLRole"} +{"Data":{"ID":"2a7708b7-913a-8c1f-593f-019c7192d549","Description":"","AuthMethod":"test","Selector":"","BindType":"service","BindName":"service","CreateIndex":35,"ModifyIndex":35},"Type":"ACLBindingRule"} +{"Data":{"Name":"test","Type":"jwt","Config":{"JWTValidationPubKeys":["-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENRw6ZwlBOx5XZKjcc1HhU00sDehc\n8nqeeSnRZLv89yT7M7qUOFDtR29FR/AFUSAEOFl1iIYLqNMElHs2VkgAZA==\n-----END PUBLIC KEY-----"]},"CreateIndex":34,"ModifyIndex":34},"Type":"ACLAuthMethod"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","ReapIndex":0,"Token":""},"Type":"Tombstone"} +{"Data":{"Datacenter":"","Op":"","Query":null,"Token":"root"},"Type":"PreparedQuery"} +{"Data":{"Datacenter":"","Config":{"CleanupDeadServers":false,"LastContactThreshold":0,"MaxTrailingLogs":0,"MinQuorum":0,"ServerStabilizationTime":0,"RedundancyZoneTag":"","DisableUpgradeMigration":false,"UpgradeVersionTag":"","CreateIndex":0,"ModifyIndex":0},"CAS":false,"Token":""},"Type":"Autopilot"} +{"Data":{"Op":"","Datacenter":"","Index":0,"Roots":null,"Config":null,"ProviderState":null,"Token":""},"Type":"ConnectCA"} +{"Data":{"ID":"fb:50:9b:45:1a:65:15:c1:68:57:73:5f:da:cd:b8:0d:0f:e2:26:eb:68:66:43:11:85:9d:67:a9:7a:56:9c:b9","PrivateKey":"-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMnCtDuifZocILamO9VdbQtXoY6SGSDVknyV+HwbRRzUoAoGCCqGSM49\nAwEHoUQDQgAEf0yW1ejMmToqCbhtSPvlXylSnS8bxJtJD6fs4VGYh7567DjGfBda\nEdgefebLuDdPPl9xAzNOihV29jSb6WheUQ==\n-----END EC PRIVATE KEY-----\n","RootCert":"-----BEGIN CERTIFICATE-----\nMIICDjCCAbOgAwIBAgIBDjAKBggqhkjOPQQDAjAwMS4wLAYDVQQDEyVwcmktZ2Fn\nMXhrYS5jb25zdWwuY2EuZmM2YmY5NDYuY29uc3VsMB4XDTI0MDMxMzE3MTQwOVoX\nDTM0MDMxMTE3MTQwOVowMDEuMCwGA1UEAxMlcHJpLWdhZzF4a2EuY29uc3VsLmNh\nLmZjNmJmOTQ2LmNvbnN1bDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH9MltXo\nzJk6Kgm4bUj75V8pUp0vG8SbSQ+n7OFRmIe+euw4xnwXWhHYHn3my7g3Tz5fcQMz\nTooVdvY0m+loXlGjgb0wgbowDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB\nAf8wKQYDVR0OBCIEILHtYgr0Zfai/xwJ6PEXOiNAtlDhn3ZSRkZcQNCGq+RnMCsG\nA1UdIwQkMCKAILHtYgr0Zfai/xwJ6PEXOiNAtlDhn3ZSRkZcQNCGq+RnMD8GA1Ud\nEQQ4MDaGNHNwaWZmZTovL2ZjNmJmOTQ2LTk3MzgtMzNmMi1hYmI2LThlYWI2ZGU1\nNmZiYS5jb25zdWwwCgYIKoZIzj0EAwIDSQAwRgIhAL/pd0eKuR/DoWBCYBV2ATNO\nPXjoamqziYct83HMqfv+AiEAzys8TxOmt6h83TujE+2CFmZxRZ1wTdUHPC4efjOb\nahw=\n-----END CERTIFICATE-----\n","IntermediateCert":"","CreateIndex":13,"ModifyIndex":15},"Type":"ConnectCAProviderState"} +{"Data":{"Provider":"consul","Config":{"IntermediateCertTTL":"8760h","LeafCertTTL":"72h","RootCertTTL":"87600h"},"State":null,"ForceWithoutCrossSigning":false,"CreateIndex":12,"ModifyIndex":16},"Type":"ConnectCAConfig"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"api-gateway","Name":"apigw","Listeners":[{"Name":"tcp","Hostname":"","Port":443,"Protocol":"tcp","TLS":{"Certificates":[{"Kind":"inline-certificate","Name":"blah","SectionName":""}],"MaxVersion":"","MinVersion":"","CipherSuites":null}},{"Name":"http","Hostname":"","Port":8080,"Protocol":"http","TLS":{"Certificates":null,"MaxVersion":"","MinVersion":"","CipherSuites":null}}],"Status":{"Conditions":[{"Type":"Accepted","Status":"True","Reason":"Accepted","Message":"gateway is valid","Resource":{"Kind":"","Name":"","SectionName":""},"LastTransitionTime":"2024-03-13T17:14:16.170758Z"},{"Type":"Conflicted","Status":"False","Reason":"NoConflict","Message":"listener has no route conflicts","Resource":{"Kind":"api-gateway","Name":"apigw","SectionName":"http"},"LastTransitionTime":"2024-03-13T17:14:16.170763Z"},{"Type":"Conflicted","Status":"False","Reason":"NoConflict","Message":"listener has no route conflicts","Resource":{"Kind":"api-gateway","Name":"apigw","SectionName":"tcp"},"LastTransitionTime":"2024-03-13T17:14:16.170763Z"},{"Type":"ResolvedRefs","Status":"True","Reason":"ResolvedRefs","Message":"resolved refs","Resource":{"Kind":"api-gateway","Name":"apigw","SectionName":"http"},"LastTransitionTime":"2024-03-13T17:14:16.170756Z"},{"Type":"ResolvedRefs","Status":"True","Reason":"ResolvedRefs","Message":"resolved refs","Resource":{"Kind":"api-gateway","Name":"apigw","SectionName":"tcp"},"LastTransitionTime":"2024-03-13T17:14:16.170757Z"}]},"Hash":6495004227697965289,"CreateIndex":48,"ModifyIndex":49},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"bound-api-gateway","Name":"apigw","Listeners":[{"Name":"tcp","Routes":[{"Kind":"tcp-route","Name":"fake","SectionName":""}],"Certificates":[{"Kind":"inline-certificate","Name":"blah","SectionName":""}]},{"Name":"http","Routes":null,"Certificates":null}],"Services":{"fake":[{"Kind":"tcp-route","Name":"fake","SectionName":""}]},"CreateIndex":50,"ModifyIndex":55},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"exported-services","Name":"default","Services":[{"Name":"web","Namespace":"default","Consumers":[{"Peer":"other"}]}],"Hash":15272881108129132528,"CreateIndex":46,"ModifyIndex":46},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"http-route","Name":"web","Parents":[{"Kind":"api-gateway","Name":"apigw","SectionName":"http"}],"Rules":[{"Filters":{"Headers":null,"URLRewrite":null,"RetryFilter":null,"TimeoutFilter":null,"JWT":null},"ResponseFilters":{"Headers":null},"Matches":null,"Services":[{"Name":"fake","Weight":1,"Filters":{"Headers":null,"URLRewrite":null,"RetryFilter":null,"TimeoutFilter":null,"JWT":null},"ResponseFilters":{"Headers":null}}]}],"Hostnames":null,"Status":{"Conditions":[{"Type":"Accepted","Status":"False","Reason":"InvalidDiscoveryChain","Message":"route protocol does not match targeted service protocol","Resource":{"Kind":"","Name":"","SectionName":""},"LastTransitionTime":"2024-03-13T17:14:16.417825Z"},{"Type":"Bound","Status":"False","Reason":"FailedToBind","Message":"failed to bind route to gateway apigw: route has not been accepted","Resource":{"Kind":"api-gateway","Name":"apigw","SectionName":"http"},"LastTransitionTime":"2024-03-13T17:14:16.417832Z"}]},"Hash":1173445267586960895,"CreateIndex":56,"ModifyIndex":57},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"ingress-gateway","Name":"api","TLS":{"Enabled":false},"Listeners":null,"Hash":15966540600821199974,"CreateIndex":42,"ModifyIndex":42},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"inline-certificate","Name":"blah","Certificate":"-----BEGIN CERTIFICATE-----\nMIICnjCCAkSgAwIBAgIQAxVHhSG0wSbdZm+3ToYAkDAKBggqhkjOPQQDAjCBuTEL\nMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv\nMRowGAYDVQQJExExMDEgU2Vjb25kIFN0cmVldDEOMAwGA1UEERMFOTQxMDUxFzAV\nBgNVBAoTDkhhc2hpQ29ycCBJbmMuMUAwPgYDVQQDEzdDb25zdWwgQWdlbnQgQ0Eg\nMjgwNzE4MDMxODA1Mjk2OTA1NzQ4MzU3NjI1MTI5ODQ5NDA5NjI3MCAXDTIzMTEw\nMjE1Mjk0NVoYDzIxMjMxMDA5MTUyOTQ1WjAcMRowGAYDVQQDExFjbGllbnQuZGMx\nLmNvbnN1bDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKvl1yhbsI9r7IxJxLrt\nZTNYXkCXuFy8q3gsokMqsl/MUynrIBrd9NrZEQA91ZArUYzF1+QlxM6D4hRJc5CR\n3x6jgccwgcQwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggr\nBgEFBQcDATAMBgNVHRMBAf8EAjAAMCkGA1UdDgQiBCCvXve+zMFSJMXNS3l3YL9k\n2QH8zF74wa+TlwFSaQEjGzArBgNVHSMEJDAigCBGa65jF6Wwq9OmdbgJIRCYv++x\nHG8dRBUpwvSk0Mk1+jAtBgNVHREEJjAkghFjbGllbnQuZGMxLmNvbnN1bIIJbG9j\nYWxob3N0hwR/AAABMAoGCCqGSM49BAMCA0gAMEUCIBLqa1Zh3KUE0RiQzWdoYXkU\nwZo5aBw9ujqzLyAqxToFAiEAihWmc4r6lDYRR35X4QB1nTT92POJRClsfLPOTRG5\nrsU=\n-----END CERTIFICATE-----","PrivateKey":"-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEINE2CQhnu7ipo67FGbEBRXoYRCTM4uJdHgNRTrdkAnHCoAoGCCqGSM49\nAwEHoUQDQgAEq+XXKFuwj2vsjEnEuu1lM1heQJe4XLyreCyiQyqyX8xTKesgGt30\n2tkRAD3VkCtRjMXX5CXEzoPiFElzkJHfHg==\n-----END EC PRIVATE KEY-----","Hash":3420847368935414704,"CreateIndex":47,"ModifyIndex":47},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"jwt-provider","Name":"whocare","JSONWebKeySet":{"Local":{"Filename":"/tmp/jwks.json"}},"ClockSkewSeconds":30,"Hash":11700458008192259302,"CreateIndex":58,"ModifyIndex":58},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"mesh","TransparentProxy":{"MeshDestinationsOnly":false},"AllowEnablingPermissiveMutualTLS":true,"Hash":10541910966466195416,"CreateIndex":45,"ModifyIndex":45},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"proxy-defaults","Name":"global","Config":null,"TransparentProxy":{},"MeshGateway":{},"Expose":{},"AccessLogs":{},"Hash":2982631359577466273,"CreateIndex":36,"ModifyIndex":36},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"sameness-group","Name":"default","DefaultForFailover":true,"IncludeLocal":true,"Members":[{"Peer":"other"}],"Hash":8697701191886031964,"CreateIndex":51,"ModifyIndex":51},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"service-defaults","Name":"foo","Protocol":"http","TransparentProxy":{},"MeshGateway":{},"Expose":{},"Hash":6851507846005072818,"CreateIndex":38,"ModifyIndex":38},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"service-defaults","Name":"web","Protocol":"http","TransparentProxy":{},"MeshGateway":{},"Expose":{},"Hash":7641900064431671148,"CreateIndex":37,"ModifyIndex":37},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"service-intentions","Name":"web","Sources":[{"Name":"api","Action":"allow","Precedence":9,"Type":"consul"}],"Hash":1271129721167983805,"CreateIndex":44,"ModifyIndex":44},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"RequestTimeout":"3s","Kind":"service-resolver","Name":"web","Hash":3307964110661939386,"CreateIndex":41,"ModifyIndex":41},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"service-router","Name":"foo","Routes":[{"Match":{"HTTP":{"PathPrefix":"/foo"}},"Destination":{"Service":"web","Namespace":"default","Partition":"default"}}],"Hash":101247989479106989,"CreateIndex":39,"ModifyIndex":39},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"service-splitter","Name":"web","Splits":[{"Weight":100,"Service":"web"}],"Hash":18208480688038965425,"CreateIndex":40,"ModifyIndex":40},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"tcp-route","Name":"fake","Parents":[{"Kind":"api-gateway","Name":"apigw","SectionName":"tcp"}],"Services":[{"Name":"fake"}],"Status":{"Conditions":[{"Type":"Accepted","Status":"True","Reason":"Accepted","Message":"route is valid","Resource":{"Kind":"","Name":"","SectionName":""},"LastTransitionTime":"2024-03-13T17:14:16.353589Z"},{"Type":"Bound","Status":"True","Reason":"Bound","Message":"successfully bound route","Resource":{"Kind":"api-gateway","Name":"apigw","SectionName":"tcp"},"LastTransitionTime":"2024-03-13T17:14:16.353602Z"}]},"Hash":4006422401340817930,"CreateIndex":52,"ModifyIndex":54},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Op":"","Datacenter":"","Entry":{"Kind":"terminating-gateway","Name":"external","Services":[{"Name":"external"}],"Hash":15903386135938294095,"CreateIndex":43,"ModifyIndex":43},"Token":""},"Type":"ConfigEntry"} +{"Data":{"Datacenter":"","Op":"upsert","State":{"Datacenter":"dc1","UpdatedAt":"2024-03-13T17:14:10.392908Z","PrimaryModifyIndex":23,"CreateIndex":23,"ModifyIndex":23},"Token":""},"Type":"FederationState"} +{"Data":{"Key":"intention-format","Value":"config-entry","CreateIndex":17,"ModifyIndex":17},"Type":"SystemMetadata"} +{"Data":{"Key":"reporting-process-id","Value":"01HRWCX8N4S6GEPX7EMTK17B6F","CreateIndex":20,"ModifyIndex":20},"Type":"SystemMetadata"} +{"Data":{"Key":"server-management-token","Value":"16ccea12-b43d-eb04-d1f6-205124572d70","CreateIndex":8,"ModifyIndex":8},"Type":"SystemMetadata"} +{"Data":{"Key":"virtual-ips","Value":"true","CreateIndex":18,"ModifyIndex":18},"Type":"SystemMetadata"} +{"Data":{"Key":"virtual-ips-term-gateway","Value":"true","CreateIndex":19,"ModifyIndex":19},"Type":"SystemMetadata"} +{"Data":{"Key":"acl-auth-methods","Value":34},"Type":"Index"} +{"Data":{"Key":"acl-binding-rules","Value":35},"Type":"Index"} +{"Data":{"Key":"acl-policies","Value":32},"Type":"Index"} +{"Data":{"Key":"acl-roles","Value":33},"Type":"Index"} +{"Data":{"Key":"acl-token-bootstrap","Value":6},"Type":"Index"} +{"Data":{"Key":"acl-tokens","Value":31},"Type":"Index"} +{"Data":{"Key":"checks","Value":21},"Type":"Index"} +{"Data":{"Key":"config-entries","Value":58},"Type":"Index"} +{"Data":{"Key":"connect-ca-builtin","Value":15},"Type":"Index"} +{"Data":{"Key":"connect-ca-builtin-serial","Value":15},"Type":"Index"} +{"Data":{"Key":"connect-ca-roots","Value":16},"Type":"Index"} +{"Data":{"Key":"connect-intentions","Value":17},"Type":"Index"} +{"Data":{"Key":"federation-states","Value":23},"Type":"Index"} +{"Data":{"Key":"gateway-services","Value":43},"Type":"Index"} +{"Data":{"Key":"kind_service_names.partition.default:namespace.default:typical","Value":21},"Type":"Index"} +{"Data":{"Key":"kind_service_names.partition.default:typical","Value":21},"Type":"Index"} +{"Data":{"Key":"kind_service_names.typical","Value":21},"Type":"Index"} +{"Data":{"Key":"mesh-topology","Value":42},"Type":"Index"} +{"Data":{"Key":"nodes","Value":22},"Type":"Index"} +{"Data":{"Key":"partition","Value":9},"Type":"Index"} +{"Data":{"Key":"partition.default:acl-auth-methods","Value":34},"Type":"Index"} +{"Data":{"Key":"partition.default:acl-binding-rules","Value":35},"Type":"Index"} +{"Data":{"Key":"partition.default:acl-policies","Value":32},"Type":"Index"} +{"Data":{"Key":"partition.default:acl-roles","Value":33},"Type":"Index"} +{"Data":{"Key":"partition.default:acl-tokens","Value":31},"Type":"Index"} +{"Data":{"Key":"partition.default:kvs","Value":28},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace","Value":10},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace.default:acl-auth-methods","Value":34},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace.default:acl-binding-rules","Value":35},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace.default:acl-policies","Value":32},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace.default:acl-roles","Value":33},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace.default:acl-tokens","Value":31},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace.default:kvs","Value":28},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace.default:sessions","Value":29},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace.default:tombstones","Value":28},"Type":"Index"} +{"Data":{"Key":"partition.default:peer.~:checks","Value":21},"Type":"Index"} +{"Data":{"Key":"partition.default:peer.~:namespace.default:checks","Value":21},"Type":"Index"} +{"Data":{"Key":"partition.default:peer.~:namespace.default:service.consul","Value":22},"Type":"Index"} +{"Data":{"Key":"partition.default:peer.~:namespace.default:service_kind.typical","Value":22},"Type":"Index"} +{"Data":{"Key":"partition.default:peer.~:namespace.default:services","Value":21},"Type":"Index"} +{"Data":{"Key":"partition.default:peer.~:node.mkeeler-C02F44FDMD6R","Value":22},"Type":"Index"} +{"Data":{"Key":"partition.default:peer.~:nodes","Value":22},"Type":"Index"} +{"Data":{"Key":"partition.default:peer.~:service_kind.typical","Value":22},"Type":"Index"} +{"Data":{"Key":"partition.default:peer.~:services","Value":21},"Type":"Index"} +{"Data":{"Key":"partition.default:peering","Value":62},"Type":"Index"} +{"Data":{"Key":"partition.default:peering-trust-bundles","Value":62},"Type":"Index"} +{"Data":{"Key":"partition.default:service-virtual-ips","Value":43},"Type":"Index"} +{"Data":{"Key":"partition.default:sessions","Value":29},"Type":"Index"} +{"Data":{"Key":"partition.default:namespace.default:tombstones","Value":28},"Type":"Index"} +{"Data":{"Key":"peering","Value":62},"Type":"Index"} +{"Data":{"Key":"peering-trust-bundles","Value":62},"Type":"Index"} +{"Data":{"Key":"prepared-queries","Value":30},"Type":"Index"} +{"Data":{"Key":"services","Value":21},"Type":"Index"} +{"Data":{"Key":"sessions","Value":29},"Type":"Index"} +{"Data":{"Key":"system-metadata","Value":20},"Type":"Index"} +{"Data":{"ID":"503f605c-6ac3-1bbc-4518-758e07212491","Name":"other","Partition":"default","State":1,"PeerCAPems":["-----BEGIN CERTIFICATE-----\nMIICDzCCAbWgAwIBAgIBCTAKBggqhkjOPQQDAjAxMS8wLQYDVQQDEyZwcmktMWhk\nZG90d2IuY29uc3VsLmNhLjU4NGVjZjgyLmNvbnN1bDAeFw0yNDAzMTMxNzE0MDla\nFw0zNDAzMTExNzE0MDlaMDExLzAtBgNVBAMTJnByaS0xaGRkb3R3Yi5jb25zdWwu\nY2EuNTg0ZWNmODIuY29uc3VsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFC3D\n0+YDsc7BhFLJy5ePs5W86pEGScYI0PWilubR+NrV4o40hqgTbwANieTjd77oQTYr\nXD+uaPj+pIOnuOu5LqOBvTCBujAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw\nAwEB/zApBgNVHQ4EIgQgLAzSlQKEkAhISEfhG1Y6m2uoA/jlY5kAYVGTHgMEbSMw\nKwYDVR0jBCQwIoAgLAzSlQKEkAhISEfhG1Y6m2uoA/jlY5kAYVGTHgMEbSMwPwYD\nVR0RBDgwNoY0c3BpZmZlOi8vNTg0ZWNmODItZmU5YS00NDY0LTVkZWItMjU5ZTRh\nYmExZGVlLmNvbnN1bDAKBggqhkjOPQQDAgNIADBFAiEAzD28+wMMO3RPfYR4kF9G\ncrqWkBCWP7k2fvwX10vLdNwCIBKf0pWS1qTOgJDxX1dn9+vqk1flv7stwwgFgJlH\nT0xb\n-----END CERTIFICATE-----\n"],"CreateIndex":59,"ModifyIndex":62,"Remote":{"Partition":"default","Datacenter":"dc1"}},"Type":"Peering"} +{"Data":{"TrustDomain":"584ecf82-fe9a-4464-5deb-259e4aba1dee.consul","PeerName":"other","Partition":"default","RootPEMs":["-----BEGIN CERTIFICATE-----\nMIICDzCCAbWgAwIBAgIBCTAKBggqhkjOPQQDAjAxMS8wLQYDVQQDEyZwcmktMWhk\nZG90d2IuY29uc3VsLmNhLjU4NGVjZjgyLmNvbnN1bDAeFw0yNDAzMTMxNzE0MDla\nFw0zNDAzMTExNzE0MDlaMDExLzAtBgNVBAMTJnByaS0xaGRkb3R3Yi5jb25zdWwu\nY2EuNTg0ZWNmODIuY29uc3VsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFC3D\n0+YDsc7BhFLJy5ePs5W86pEGScYI0PWilubR+NrV4o40hqgTbwANieTjd77oQTYr\nXD+uaPj+pIOnuOu5LqOBvTCBujAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw\nAwEB/zApBgNVHQ4EIgQgLAzSlQKEkAhISEfhG1Y6m2uoA/jlY5kAYVGTHgMEbSMw\nKwYDVR0jBCQwIoAgLAzSlQKEkAhISEfhG1Y6m2uoA/jlY5kAYVGTHgMEbSMwPwYD\nVR0RBDgwNoY0c3BpZmZlOi8vNTg0ZWNmODItZmU5YS00NDY0LTVkZWItMjU5ZTRh\nYmExZGVlLmNvbnN1bDAKBggqhkjOPQQDAgNIADBFAiEAzD28+wMMO3RPfYR4kF9G\ncrqWkBCWP7k2fvwX10vLdNwCIBKf0pWS1qTOgJDxX1dn9+vqk1flv7stwwgFgJlH\nT0xb\n-----END CERTIFICATE-----\n"],"ExportedPartition":"default","CreateIndex":62,"ModifyIndex":62},"Type":"PeeringTrustBundle"} +{"Data":{"PeerID":"503f605c-6ac3-1bbc-4518-758e07212491","stream":{"ActiveSecretID":"cda5e0b8-be51-5b62-a89d-8546f9c48da9"}},"Type":"PeeringSecret"} +{"Data":{"ChunkMap":{}},"Type":"ChunkingState"} diff --git a/command/snapshot/decode/testdata/TestSnapshotDecodeCommand/no-kv.ce.golden b/command/snapshot/decode/testdata/TestSnapshotDecodeCommand/no-kv.ce.golden new file mode 100644 index 0000000000..99536ad585 --- /dev/null +++ b/command/snapshot/decode/testdata/TestSnapshotDecodeCommand/no-kv.ce.golden @@ -0,0 +1,23 @@ +{"Data":{"Version":1,"ID":"2-13-1602222343947","Index":13,"Term":2,"Peers":"ka4xMjcuMC4wLjE6ODMwMA==","Configuration":{"Servers":[{"Suffrage":0,"ID":"a577b288-b354-770e-e909-da0972eb20e8","Address":"127.0.0.1:8300"}]},"ConfigurationIndex":1,"Size":5141},"Type":"SnapshotHeader"} +{"Data":{"Datacenter":"dc1","ID":"a577b288-b354-770e-e909-da0972eb20e8","Node":"macbook-pro.lan","Address":"127.0.0.1","TaggedAddresses":{"lan":"127.0.0.1","lan_ipv4":"127.0.0.1","wan":"127.0.0.1","wan_ipv4":"127.0.0.1"},"NodeMeta":{"consul-network-segment":""},"Service":null,"Check":null,"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":11,"ModifyIndex":12},"Type":"Register"} +{"Data":{"Datacenter":"dc1","ID":"a577b288-b354-770e-e909-da0972eb20e8","Node":"macbook-pro.lan","Address":"127.0.0.1","TaggedAddresses":{"lan":"127.0.0.1","lan_ipv4":"127.0.0.1","wan":"127.0.0.1","wan_ipv4":"127.0.0.1"},"NodeMeta":{"consul-network-segment":""},"Service":{"ID":"consul","Service":"consul","Tags":null,"Address":"","Meta":{"non_voter":"false","raft_version":"3","serf_protocol_current":"2","serf_protocol_max":"5","serf_protocol_min":"1","version":"1.9.0"},"Port":8300,"Weights":{"Passing":1,"Warning":1},"EnableTagOverride":false,"Proxy":{"Mode":"","MeshGateway":{},"Expose":{}},"Connect":{},"PeerName":"","CreateIndex":11,"ModifyIndex":11},"Check":null,"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":11,"ModifyIndex":12},"Type":"Register"} +{"Data":{"Datacenter":"dc1","ID":"a577b288-b354-770e-e909-da0972eb20e8","Node":"macbook-pro.lan","Address":"127.0.0.1","TaggedAddresses":{"lan":"127.0.0.1","lan_ipv4":"127.0.0.1","wan":"127.0.0.1","wan_ipv4":"127.0.0.1"},"NodeMeta":{"consul-network-segment":""},"Service":null,"Check":{"Node":"macbook-pro.lan","CheckID":"serfHealth","Name":"Serf Health Status","Status":"passing","Notes":"","Output":"Agent alive and reachable","ServiceID":"","ServiceName":"","ServiceTags":null,"Type":"","Interval":"","Timeout":"","ExposedPort":0,"Definition":{},"CreateIndex":11,"ModifyIndex":11},"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":11,"ModifyIndex":12},"Type":"Register"} +{"Data":{"Datacenter":"","Config":{"CleanupDeadServers":false,"LastContactThreshold":0,"MaxTrailingLogs":0,"MinQuorum":0,"ServerStabilizationTime":0,"RedundancyZoneTag":"","DisableUpgradeMigration":false,"UpgradeVersionTag":"","CreateIndex":0,"ModifyIndex":0},"CAS":false,"Token":""},"Type":"Autopilot"} +{"Data":{"Op":"","Datacenter":"","Index":0,"Roots":null,"Config":null,"ProviderState":null,"Token":""},"Type":"ConnectCA"} +{"Data":{"ID":"07:80:c8:de:f6:41:86:29:8f:9c:b8:17:d6:48:c2:d5:c5:5c:7f:0c:03:f7:cf:97:5a:a7:c1:68:aa:23:ae:81","PrivateKey":"-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIGwMuojUj9fSERmBjUjp3AbmkFhwRZZEEcm0XgdnCSyRoAoGCCqGSM49\nAwEHoUQDQgAEBi0AvynqnFMRIsxs1VNKkDBIvlKywpuFIaZY3TDMEvuVV/iLvFOl\n8I/OBkjXVsUPzXpao6Da6oPpbtzVuphD7A==\n-----END EC PRIVATE KEY-----\n","RootCert":"-----BEGIN CERTIFICATE-----\nMIICDjCCAbOgAwIBAgIBBzAKBggqhkjOPQQDAjAwMS4wLAYDVQQDEyVwcmktMXN5\nYzU4Zi5jb25zdWwuY2EuMzMzZDFmYTIuY29uc3VsMB4XDTIwMTAwOTA1NDUyNloX\nDTMwMTAwOTA1NDUyNlowMDEuMCwGA1UEAxMlcHJpLTFzeWM1OGYuY29uc3VsLmNh\nLjMzM2QxZmEyLmNvbnN1bDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAYtAL8p\n6pxTESLMbNVTSpAwSL5SssKbhSGmWN0wzBL7lVf4i7xTpfCPzgZI11bFD816WqOg\n2uqD6W7c1bqYQ+yjgb0wgbowDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB\nAf8wKQYDVR0OBCIEIOZNpB8CrBdX2haue5rcSaauDsPs8S1Ld39j9ne1JP+xMCsG\nA1UdIwQkMCKAIOZNpB8CrBdX2haue5rcSaauDsPs8S1Ld39j9ne1JP+xMD8GA1Ud\nEQQ4MDaGNHNwaWZmZTovLzMzM2QxZmEyLTFjMTItMzgzYS05MDRlLWFmMjc0OTEz\nNmViZS5jb25zdWwwCgYIKoZIzj0EAwIDSQAwRgIhALy+D4SiHnHaEtxj62ncLyus\nxf6XS4amT2P3uc+zsURWAiEAvGAvh5/BwyUg0wzcVGZ40K+tllAVmk4fWL6dkUcT\nJ+o=\n-----END CERTIFICATE-----\n","IntermediateCert":"","CreateIndex":6,"ModifyIndex":8},"Type":"ConnectCAProviderState"} +{"Data":{"Provider":"consul","Config":{"IntermediateCertTTL":"8760h","LeafCertTTL":"72h","RotationPeriod":"2160h"},"State":null,"ForceWithoutCrossSigning":false,"CreateIndex":5,"ModifyIndex":5},"Type":"ConnectCAConfig"} +{"Data":{"Datacenter":"","Op":"upsert","State":{"Datacenter":"dc1","UpdatedAt":"2020-10-09T05:45:26.48447Z","PrimaryModifyIndex":13,"CreateIndex":13,"ModifyIndex":13},"Token":""},"Type":"FederationState"} +{"Data":{"Key":"intention-format","Value":"config-entry","CreateIndex":10,"ModifyIndex":10},"Type":"SystemMetadata"} +{"Data":{"Key":"checks","Value":11},"Type":"Index"} +{"Data":{"Key":"config-entries","Value":10},"Type":"Index"} +{"Data":{"Key":"connect-ca-builtin","Value":8},"Type":"Index"} +{"Data":{"Key":"connect-ca-builtin-serial","Value":7},"Type":"Index"} +{"Data":{"Key":"connect-ca-roots","Value":9},"Type":"Index"} +{"Data":{"Key":"connect-intentions","Value":10},"Type":"Index"} +{"Data":{"Key":"federation-states","Value":13},"Type":"Index"} +{"Data":{"Key":"nodes","Value":12},"Type":"Index"} +{"Data":{"Key":"service.consul","Value":12},"Type":"Index"} +{"Data":{"Key":"service_kind.typical","Value":12},"Type":"Index"} +{"Data":{"Key":"services","Value":11},"Type":"Index"} +{"Data":{"Key":"system-metadata","Value":10},"Type":"Index"} +{"Data":{"ChunkMap":{}},"Type":"ChunkingState"} diff --git a/command/snapshot/decode/testdata/TestSnapshotDecodeCommand/with-kv.ce.golden b/command/snapshot/decode/testdata/TestSnapshotDecodeCommand/with-kv.ce.golden new file mode 100644 index 0000000000..62c95700a4 --- /dev/null +++ b/command/snapshot/decode/testdata/TestSnapshotDecodeCommand/with-kv.ce.golden @@ -0,0 +1,51 @@ +{"Data":{"Version":1,"ID":"2-12426-1604593650375","Index":12426,"Term":2,"Peers":"kbMxOTIuMTY4Ljg2LjIzNjo4MzAw","Configuration":{"Servers":[{"Suffrage":0,"ID":"1047e34e-dc15-fa4b-8e1d-5bf74c2ac239","Address":"192.168.86.236:8300"}]},"ConfigurationIndex":1,"Size":17228},"Type":"SnapshotHeader"} +{"Data":{"Datacenter":"dc1","ID":"1047e34e-dc15-fa4b-8e1d-5bf74c2ac239","Node":"hashicorp.lan","Address":"192.168.86.236","TaggedAddresses":{"lan":"192.168.86.236","lan_ipv4":"192.168.86.236","wan":"192.168.86.236","wan_ipv4":"192.168.86.236"},"NodeMeta":{"consul-network-segment":""},"Service":null,"Check":null,"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":6,"ModifyIndex":7},"Type":"Register"} +{"Data":{"Datacenter":"dc1","ID":"1047e34e-dc15-fa4b-8e1d-5bf74c2ac239","Node":"hashicorp.lan","Address":"192.168.86.236","TaggedAddresses":{"lan":"192.168.86.236","lan_ipv4":"192.168.86.236","wan":"192.168.86.236","wan_ipv4":"192.168.86.236"},"NodeMeta":{"consul-network-segment":""},"Service":{"ID":"consul","Service":"consul","Tags":null,"Address":"","Meta":{"non_voter":"false","raft_version":"3","serf_protocol_current":"2","serf_protocol_max":"5","serf_protocol_min":"1","version":"1.8.5"},"Port":8300,"Weights":{"Passing":1,"Warning":1},"EnableTagOverride":false,"Proxy":{"Mode":"","MeshGateway":{},"Expose":{}},"Connect":{},"PeerName":"","CreateIndex":6,"ModifyIndex":6},"Check":null,"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":6,"ModifyIndex":7},"Type":"Register"} +{"Data":{"Datacenter":"dc1","ID":"1047e34e-dc15-fa4b-8e1d-5bf74c2ac239","Node":"hashicorp.lan","Address":"192.168.86.236","TaggedAddresses":{"lan":"192.168.86.236","lan_ipv4":"192.168.86.236","wan":"192.168.86.236","wan_ipv4":"192.168.86.236"},"NodeMeta":{"consul-network-segment":""},"Service":{"ID":"vault:127.0.0.1:8200","Service":"vault","Tags":["active","initialized"],"Address":"127.0.0.1","TaggedAddresses":{"lan_ipv4":{"Address":"127.0.0.1","Port":8200},"wan_ipv4":{"Address":"127.0.0.1","Port":8200}},"Meta":null,"Port":8200,"Weights":{"Passing":1,"Warning":1},"EnableTagOverride":false,"Proxy":{"Mode":"","MeshGateway":{},"Expose":{}},"Connect":{},"PeerName":"","CreateIndex":3470,"ModifyIndex":3497},"Check":null,"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":6,"ModifyIndex":7},"Type":"Register"} +{"Data":{"Datacenter":"dc1","ID":"1047e34e-dc15-fa4b-8e1d-5bf74c2ac239","Node":"hashicorp.lan","Address":"192.168.86.236","TaggedAddresses":{"lan":"192.168.86.236","lan_ipv4":"192.168.86.236","wan":"192.168.86.236","wan_ipv4":"192.168.86.236"},"NodeMeta":{"consul-network-segment":""},"Service":null,"Check":{"Node":"hashicorp.lan","CheckID":"serfHealth","Name":"Serf Health Status","Status":"passing","Notes":"","Output":"Agent alive and reachable","ServiceID":"","ServiceName":"","ServiceTags":null,"Type":"","Interval":"","Timeout":"","ExposedPort":0,"Definition":{},"CreateIndex":6,"ModifyIndex":6},"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":6,"ModifyIndex":7},"Type":"Register"} +{"Data":{"Datacenter":"dc1","ID":"1047e34e-dc15-fa4b-8e1d-5bf74c2ac239","Node":"hashicorp.lan","Address":"192.168.86.236","TaggedAddresses":{"lan":"192.168.86.236","lan_ipv4":"192.168.86.236","wan":"192.168.86.236","wan_ipv4":"192.168.86.236"},"NodeMeta":{"consul-network-segment":""},"Service":null,"Check":{"Node":"hashicorp.lan","CheckID":"vault:127.0.0.1:8200:vault-sealed-check","Name":"Vault Sealed Status","Status":"passing","Notes":"Vault service is healthy when Vault is in an unsealed status and can become an active Vault server","Output":"Vault Unsealed","ServiceID":"vault:127.0.0.1:8200","ServiceName":"vault","ServiceTags":["active","initialized"],"Type":"ttl","Interval":"","Timeout":"","ExposedPort":0,"Definition":{},"CreateIndex":3471,"ModifyIndex":6836},"Checks":null,"Locality":null,"SkipNodeUpdate":false,"PeerName":"","Token":"","CreateIndex":6,"ModifyIndex":7},"Type":"Register"} +{"Data":[{"Node":"hashicorp.lan","Segment":"","Coord":{"Vec":[0,0,0,0,0,0,0,0],"Error":1.5,"Adjustment":0,"Height":0.00001}}],"Type":"CoordinateBatchUpdate"} +{"Data":{"Datacenter":"","Op":"","Session":{"ID":"","Name":"","Node":"","LockDelay":0,"Behavior":"","TTL":"","NodeChecks":null,"ServiceChecks":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"Session"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","DirEnt":{"LockIndex":0,"Key":"","Flags":0,"Value":null,"CreateIndex":0,"ModifyIndex":0},"Token":""},"Type":"KVS"} +{"Data":{"Datacenter":"","Op":"","ReapIndex":0,"Token":""},"Type":"Tombstone"} +{"Data":{"Datacenter":"","Op":"","ReapIndex":0,"Token":""},"Type":"Tombstone"} +{"Data":{"Datacenter":"","Config":{"CleanupDeadServers":false,"LastContactThreshold":0,"MaxTrailingLogs":0,"MinQuorum":0,"ServerStabilizationTime":0,"RedundancyZoneTag":"","DisableUpgradeMigration":false,"UpgradeVersionTag":"","CreateIndex":0,"ModifyIndex":0},"CAS":false,"Token":""},"Type":"Autopilot"} +{"Data":{"Datacenter":"","Op":"upsert","State":{"Datacenter":"dc1","UpdatedAt":"2020-11-03T23:57:19.636962Z","PrimaryModifyIndex":5,"CreateIndex":5,"ModifyIndex":5},"Token":""},"Type":"FederationState"} +{"Data":{"Key":"checks","Value":6836},"Type":"Index"} +{"Data":{"Key":"coordinates","Value":12424},"Type":"Index"} +{"Data":{"Key":"federation-states","Value":5},"Type":"Index"} +{"Data":{"Key":"kvs","Value":12426},"Type":"Index"} +{"Data":{"Key":"nodes","Value":7},"Type":"Index"} +{"Data":{"Key":"service.consul","Value":7},"Type":"Index"} +{"Data":{"Key":"service.vault","Value":6836},"Type":"Index"} +{"Data":{"Key":"service_kind.typical","Value":6836},"Type":"Index"} +{"Data":{"Key":"services","Value":3497},"Type":"Index"} +{"Data":{"Key":"sessions","Value":3493},"Type":"Index"} +{"Data":{"Key":"tombstones","Value":12426},"Type":"Index"} +{"Data":{"ChunkMap":{}},"Type":"ChunkingState"} diff --git a/command/snapshot/decode/testdata/all.snap b/command/snapshot/decode/testdata/all.snap new file mode 100644 index 0000000000000000000000000000000000000000..8b69dec197bc1ef39fd4161c3044b435b4e0a47b GIT binary patch literal 9179 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 literal 0 HcmV?d00001 diff --git a/command/snapshot/decode/testdata/backup.snap b/command/snapshot/decode/testdata/backup.snap new file mode 100644 index 0000000000000000000000000000000000000000..ddb621c396fb27f2195eb713e811f20b05fe1493 GIT binary patch literal 2842 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
CX7-le$TjKZssV6LF+Z#|0p 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 literal 0 HcmV?d00001 diff --git a/command/snapshot/decode/testdata/populate-all.sh b/command/snapshot/decode/testdata/populate-all.sh new file mode 100755 index 0000000000..dfecec7249 --- /dev/null +++ b/command/snapshot/decode/testdata/populate-all.sh @@ -0,0 +1,296 @@ +#!/bin/bash +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +set -e + +trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT + + +readonly SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" +readonly SCRIPT_DIR="$(dirname ${BASH_SOURCE[0]})" + +# Start a couple dev agents in the background +echo "Starting Dev Agents" +consul agent -dev -hcl 'acl { enabled = true default_policy="allow" tokens { initial_management = "root" } }' >/dev/null 2>&1 & +consul agent -dev -dns-port=9600 -grpc-port=9502 -grpc-tls-port=9503 -http-port=9500 -serf-lan-port=9301 -serf-wan-port=9302 -server-port=9300 >/dev/null 2>&1 & + +# should be long enough for the dev agents to be available +sleep 5 + +# This script expects a consul dev agent with acls enabled in default allow to be running on localhost +# consul agent -dev -hcl 'acl { enabled = true default_policy="allow" tokens { initial_management = "root" } }' +# It also requires another dev agent running on alternative ports to peer with +# consul agent -dev -dns-port=9600 -grpc-port=9502 -grpc-tls-port=9503 -http-port=9500 -serf-lan-port=9301 -serf-wan-port=9302 -server-port=9300 + +# Just running Consul will cause the following data to be in the snapshot: +# Register +# ConnectCA +# ConnectCAProviderState +# ConnectCAConfig +# Autopilot +# Index +# SystemMetadata +# CoordinateBatchUpdate +# FederationState +# ChunkingState +# FreeVirtualIP +# Partition +# Tombstone + +# Ensure a KV entry ends up in the snapshot +echo "Creating KV Entry" +consul kv put foo/bar 1 >/dev/null + +# Ensure a tombstone ends up in the snapshot +echo "Forcing KV Tombstone Creation" +consul kv put foo/baz 2 >/dev/null +consul kv delete foo/baz > /dev/null + + +# Ensure a session ends up in the snapshot +echo "Creating Session" +curl -s -X PUT localhost:8500/v1/session/create >/dev/null + +# Ensure a prepared query ends up in the snapshot +echo "Creating Prepared Query" +curl -s -X POST localhost:8500/v1/query -d '{"Name": "test", "Token": "root", "Service": {"Service": "test"}}' >/dev/null + +# Ensure an ACL token ends up in the snapshot +echo "Creating ACL Token" +consul acl token create -node-identity=localhost:dc1 >/dev/null + +# Ensure an ACL policy ends up in the snapshot +echo "Creating ACL Policy" +consul acl policy create -name=test -rules='node_prefix "" { policy = "write" }' >/dev/null + +# Ensure an ACL role ends up in the snapshot +echo "Creating ACL Role" +consul acl role create -name=test -policy-name=test >/dev/null + +# Ensure an ACL auth method ends up in the snapshot +echo "Creating ACL Auth Method" +consul acl auth-method create -type jwt -name test -config '{"JWTValidationPubKeys": ["-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENRw6ZwlBOx5XZKjcc1HhU00sDehc\n8nqeeSnRZLv89yT7M7qUOFDtR29FR/AFUSAEOFl1iIYLqNMElHs2VkgAZA==\n-----END PUBLIC KEY-----"]}' >/dev/null + +# Ensure an ACL binding rule ends up in the snapshot +echo "Creating ACL Binding Rule" +consul acl binding-rule create -bind-type="service" -bind-name="service" -method="test" >/dev/null + +# Ensure config entries end up in the snapshot +echo "Creating Proxy Default Config Entry" +consul config write - >/dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null </dev/null +if [ $? -eq 0 ]; then +set -e +echo "Creating Sameness Group Config Entry" +consul config write - >/dev/null </dev/null </dev/null </dev/null </dev/null + +echo "Saving Snapshot to all.snap" +sleep 2 +consul snapshot save "${SCRIPT_DIR}/all.snap" >/dev/null \ No newline at end of file diff --git a/command/snapshot/snapshot_command.go b/command/snapshot/snapshot_command.go index 2e96550e19..e5c4805e7f 100644 --- a/command/snapshot/snapshot_command.go +++ b/command/snapshot/snapshot_command.go @@ -45,6 +45,10 @@ Usage: consul snapshot [options] [args] Restore a snapshot: $ consul snapshot restore backup.snap + + Decode a snapshot: + + $ consul snapshot decode backup.snap Inspect a snapshot: diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go index 9e77bba692..7f64f4b5ad 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go @@ -250,7 +250,7 @@ func TestBuildMultiportImplicitDestinations(t *testing.T) { }) actual := protoToJSON(t, proxyTmpl) - expected := JSONToProxyTemplate(t, golden.GetBytes(t, actual, name+"-"+tenancy.Partition+"-"+tenancy.Namespace+".golden")) + expected := JSONToProxyTemplate(t, golden.GetBytes(t, []byte(actual), name+"-"+tenancy.Partition+"-"+tenancy.Namespace+".golden")) // sort routers on listener from golden file expectedRouters := expected.ProxyState.Listeners[0].Routers diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_multiport_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_multiport_test.go index 4a60d0f8b3..e9fcb1fff5 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_multiport_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_multiport_test.go @@ -157,7 +157,7 @@ func TestBuildLocalApp_Multiport(t *testing.T) { }) actual := protoToJSON(t, proxyTmpl) - expected := JSONToProxyTemplate(t, golden.GetBytes(t, actual, name+"-"+tenancy.Partition+"-"+tenancy.Namespace+".golden")) + expected := JSONToProxyTemplate(t, golden.GetBytes(t, []byte(actual), name+"-"+tenancy.Partition+"-"+tenancy.Namespace+".golden")) // sort routers on listener from golden file expectedRouters := expected.ProxyState.Listeners[0].Routers diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go index 2fa095da11..1038cee9a0 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go @@ -115,7 +115,7 @@ func TestBuildLocalApp(t *testing.T) { }) actual := protoToJSON(t, proxyTmpl) - expected := JSONToProxyTemplate(t, golden.GetBytes(t, actual, name+"-"+tenancy.Partition+"-"+tenancy.Namespace+".golden")) + expected := JSONToProxyTemplate(t, golden.GetBytes(t, []byte(actual), name+"-"+tenancy.Partition+"-"+tenancy.Namespace+".golden")) // sort routers on listener from golden file expectedRouters := expected.ProxyState.Listeners[0].Routers @@ -233,7 +233,7 @@ func TestBuildLocalApp_WithProxyConfiguration(t *testing.T) { }) actual := protoToJSON(t, proxyTmpl) - expected := JSONToProxyTemplate(t, golden.GetBytes(t, actual, name+"-"+tenancy.Partition+"-"+tenancy.Namespace+".golden")) + expected := JSONToProxyTemplate(t, golden.GetBytes(t, []byte(actual), name+"-"+tenancy.Partition+"-"+tenancy.Namespace+".golden")) // sort routers on listener from golden file expectedRouters := expected.ProxyState.Listeners[0].Routers diff --git a/internal/testing/golden/golden.go b/internal/testing/golden/golden.go index a4d971d0d0..7146261a7e 100644 --- a/internal/testing/golden/golden.go +++ b/internal/testing/golden/golden.go @@ -22,7 +22,7 @@ var update = flag.Bool("update", false, "update golden files") // to the value of actual. func Get(t *testing.T, actual, filename string) string { t.Helper() - return string(GetBytes(t, actual, filename)) + return string(GetBytes(t, []byte(actual), filename)) } // GetBytes reads the expected value from the file at filename and returns the @@ -30,7 +30,7 @@ func Get(t *testing.T, actual, filename string) string { // // If the `-update` flag is used with `go test`, the golden file will be updated // to the value of actual. -func GetBytes(t *testing.T, actual, filename string) []byte { +func GetBytes(t *testing.T, actual []byte, filename string) []byte { t.Helper() path := filepath.Join("testdata", filename) @@ -38,7 +38,7 @@ func GetBytes(t *testing.T, actual, filename string) []byte { if dir := filepath.Dir(path); dir != "." { require.NoError(t, os.MkdirAll(dir, 0755)) } - err := os.WriteFile(path, []byte(actual), 0644) + err := os.WriteFile(path, actual, 0644) require.NoError(t, err) }