diff --git a/client/status/viewmodel/render.go b/client/status/viewmodel/render.go index aaaff77..aefa86a 100644 --- a/client/status/viewmodel/render.go +++ b/client/status/viewmodel/render.go @@ -273,9 +273,9 @@ func printFilesystemStatus(t *stringbuilder.B, rep *report.FilesystemReport, max attribs = append(attribs, "resumed") } - attribs = append(attribs, fmt.Sprintf("encrypted=%s", nextStep.Info.Encrypted)) - - next += fmt.Sprintf(" (%s)", strings.Join(attribs, ", ")) + if len(attribs) > 0 { + next += fmt.Sprintf(" (%s)", strings.Join(attribs, ", ")) + } } else { next = "" // individual FSes may still be in planning state } diff --git a/daemon/job/active.go b/daemon/job/active.go index 4eb2962..48b42b1 100644 --- a/daemon/job/active.go +++ b/daemon/job/active.go @@ -168,7 +168,6 @@ func modePushFromConfig(g *config.Global, in *config.PushJob, jobID endpoint.Job } m.plannerPolicy = &logic.PlannerPolicy{ - EncryptedSend: logic.TriFromBool(in.Send.Encrypted), ConflictResolution: conflictResolution, ReplicationConfig: replicationConfig, SizeEstimationConcurrency: in.Replication.Concurrency.SizeEstimates, @@ -273,7 +272,6 @@ func modePullFromConfig(g *config.Global, in *config.PullJob, jobID endpoint.Job } m.plannerPolicy = &logic.PlannerPolicy{ - EncryptedSend: logic.DontCare, ConflictResolution: conflictResolution, ReplicationConfig: replicationConfig, SizeEstimationConcurrency: in.Replication.Concurrency.SizeEstimates, diff --git a/docs/changelog.rst b/docs/changelog.rst index edbce5e..3c5b5e2 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -22,6 +22,17 @@ Developers should consult the git commit log or GitHub issue tracker. * `Feature Wishlist on GitHub `_ * |feature| Add ``ZREPL_DESTROY_MAX_BATCH_SIZE`` env var (default 0=unlimited). +* |bugfix| Fix resuming from interrupted replications that use ``send.raw`` on unencrypted datasets. + + * The send options introduced in zrepl 0.4 allow users to specify additional zfs send flags for zrepl to use. + Before this fix, when setting ``send.raw=true`` on a job that replicates unencrypted datasets, + zrepl would not allow an interrupted replication to resume. + The reason were overly cautious checks to support the ``send.encrypted`` option. + * This bugfix removes these checks from the replication planner. + This makes ``send.encrypted`` a sender-side-only concern, much like all other ``send.*`` flags. + * However, this means that the ``zrepl status`` UI no longer indicates whether a replication step uses encrypted sends or not. + The setting is still effective though. + * |break| |feature| convert Prometheus metric ``zrepl_version_daemon`` to ``zrepl_start_time`` metric * The metric still reports the zrepl version in a label. diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index c43d6c7..1166659 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -105,15 +105,10 @@ func (s *Sender) ListFilesystems(ctx context.Context, r *pdu.ListFilesystemReq) } rfss := make([]*pdu.Filesystem, len(fss)) for i := range fss { - encEnabled, err := zfs.ZFSGetEncryptionEnabled(ctx, fss[i].ToString()) - if err != nil { - return nil, errors.Wrap(err, "cannot get filesystem encryption status") - } rfss[i] = &pdu.Filesystem{ Path: fss[i].ToString(), // ResumeToken does not make sense from Sender IsPlaceholder: false, // sender FSs are never placeholders - IsEncrypted: encEnabled, } } res := &pdu.ListFilesystemRes{Filesystems: rfss} @@ -165,23 +160,6 @@ func (s *Sender) sendMakeArgs(ctx context.Context, r *pdu.SendReq) (sendArgs zfs if err != nil { return sendArgs, err } - switch r.Encrypted { - case pdu.Tri_DontCare: - // use s.encrypt setting - // ok, fallthrough outer - case pdu.Tri_False: - if s.config.Encrypt.B { - return sendArgs, errors.New("only encrypted sends allowed (send -w + encryption!= off), but unencrypted send requested") - } - // fallthrough outer - case pdu.Tri_True: - if !s.config.Encrypt.B { - return sendArgs, errors.New("only unencrypted sends allowed, but encrypted send requested") - } - // fallthrough outer - default: - return sendArgs, fmt.Errorf("unknown pdu.Tri variant %q", r.Encrypted) - } sendArgsUnvalidated := zfs.ZFSSendArgsUnvalidated{ FS: r.Filesystem, @@ -658,11 +636,6 @@ func (s *Receiver) ListFilesystems(ctx context.Context, req *pdu.ListFilesystemR l.WithError(err).Error("cannot get receive resume token") return nil, err } - encEnabled, err := zfs.ZFSGetEncryptionEnabled(ctx, a.ToString()) - if err != nil { - l.WithError(err).Error("cannot get encryption enabled status") - return nil, err - } l.WithField("receive_resume_token", token).Debug("receive resume token") a.TrimPrefix(root) @@ -671,7 +644,6 @@ func (s *Receiver) ListFilesystems(ctx context.Context, req *pdu.ListFilesystemR Path: a.ToString(), IsPlaceholder: ph.IsPlaceholder, ResumeToken: token, - IsEncrypted: encEnabled, } fss = append(fss, fs) } diff --git a/platformtest/tests/generated_cases.go b/platformtest/tests/generated_cases.go index 83f9eda..16891aa 100644 --- a/platformtest/tests/generated_cases.go +++ b/platformtest/tests/generated_cases.go @@ -36,6 +36,7 @@ var Cases = []Case{BatchDestroy, ReplicationStepCompletedLostBehavior__GuaranteeResumability, ResumableRecvAndTokenHandling, ResumeTokenParsing, + SendArgsValidationEE_EncryptionAndRaw, SendArgsValidationEncryptedSendOfUnencryptedDatasetForbidden__EncryptionSupported_false, SendArgsValidationEncryptedSendOfUnencryptedDatasetForbidden__EncryptionSupported_true, SendArgsValidationResumeTokenDifferentFilesystemForbidden, diff --git a/platformtest/tests/replication.go b/platformtest/tests/replication.go index 0173b1e..283737b 100644 --- a/platformtest/tests/replication.go +++ b/platformtest/tests/replication.go @@ -35,16 +35,17 @@ import ( // of a new sender and receiver instance and one blocking invocation // of the replication engine without encryption type replicationInvocation struct { - sjid, rjid endpoint.JobID - sfs string - sfilter *filters.DatasetMapFilter - rfsRoot string - interceptSender func(e *endpoint.Sender) logic.Sender - interceptReceiver func(e *endpoint.Receiver) logic.Receiver - guarantee *pdu.ReplicationConfigProtection - senderConfigHook func(*endpoint.SenderConfig) - receiverConfigHook func(*endpoint.ReceiverConfig) - plannerPolicyHook func(*logic.PlannerPolicy) + sjid, rjid endpoint.JobID + sfs string + sfilter *filters.DatasetMapFilter + rfsRoot string + interceptSender func(e *endpoint.Sender) logic.Sender + interceptReceiver func(e *endpoint.Receiver) logic.Receiver + guarantee *pdu.ReplicationConfigProtection + senderConfigHook func(*endpoint.SenderConfig) + receiverConfigHook func(*endpoint.ReceiverConfig) + plannerPolicyHook func(*logic.PlannerPolicy) + skipSendArgsValidation bool } func (i replicationInvocation) Do(ctx *platformtest.Context) *report.Report { @@ -92,7 +93,6 @@ func (i replicationInvocation) Do(ctx *platformtest.Context) *report.Report { sender := i.interceptSender(endpoint.NewSender(senderConfig)) receiver := i.interceptReceiver(endpoint.NewReceiver(receiverConfig)) plannerPolicy := logic.PlannerPolicy{ - EncryptedSend: logic.TriFromBool(false), ReplicationConfig: &pdu.ReplicationConfig{ Protection: i.guarantee, }, @@ -105,8 +105,13 @@ func (i replicationInvocation) Do(ctx *platformtest.Context) *report.Report { i.plannerPolicyHook(&plannerPolicy) } + var doCtx context.Context = ctx + if i.skipSendArgsValidation { + doCtx = zfs.ZFSSendArgsSkipValidation(ctx) + } + report, wait := replication.Do( - ctx, + doCtx, driver.Config{ MaxAttempts: 1, StepQueueConcurrency: 1, diff --git a/platformtest/tests/sendArgsValidation.go b/platformtest/tests/sendArgsValidation.go index c1e96e1..c233318 100644 --- a/platformtest/tests/sendArgsValidation.go +++ b/platformtest/tests/sendArgsValidation.go @@ -2,10 +2,16 @@ package tests import ( "fmt" + "path" + "github.com/kr/pretty" "github.com/stretchr/testify/require" + "github.com/zrepl/zrepl/endpoint" "github.com/zrepl/zrepl/platformtest" + "github.com/zrepl/zrepl/replication/logic" + "github.com/zrepl/zrepl/replication/logic/pdu" + "github.com/zrepl/zrepl/replication/report" "github.com/zrepl/zrepl/util/nodefault" "github.com/zrepl/zrepl/zfs" ) @@ -208,3 +214,225 @@ func SendArgsValidationResumeTokenDifferentFilesystemForbidden(ctx *platformtest require.True(ctx, ok) require.Equal(ctx, mismatchError.What, zfs.ZFSSendArgsResumeTokenMismatchFilesystem) } + +type sendArgsValidationEndToEndTestOutcome string + +const ( + ValidationAccepts sendArgsValidationEndToEndTestOutcome = "accept" + ValidationRejects sendArgsValidationEndToEndTestOutcome = "rejects" +) + +type sendArgsValidationEndToEndTest struct { + encryptedSenderFilesystem bool + senderConfigHook func(config *endpoint.SenderConfig) + expectedOutcome sendArgsValidationEndToEndTestOutcome + outcomeRejectsInspectError func(require.TestingT, *report.FilesystemReport, bool) + inspectReceiverFSAfterSuccessfulCycle func(rfs string) +} + +func implSendArgsValidationEndToEndTest(ctx *platformtest.Context, setup sendArgsValidationEndToEndTest) { + + senderEncrypted := "" + if setup.encryptedSenderFilesystem { + senderEncrypted = "encrypted" + } + + platformtest.Run(ctx, platformtest.PanicErr, ctx.RootDataset, fmt.Sprintf(` + CREATEROOT + + "sender" %s + + "receiver" + R zfs create -p "${ROOTDS}/receiver/${ROOTDS}" + `, senderEncrypted)) + + sjid := endpoint.MustMakeJobID("sender-job") + rjid := endpoint.MustMakeJobID("receiver-job") + + sfs := ctx.RootDataset + "/sender" + rfsRoot := ctx.RootDataset + "/receiver" + + sfsmp, err := zfs.ZFSGetMountpoint(ctx, sfs) + require.NoError(ctx, err) + require.True(ctx, sfsmp.Mounted) + + // Two cycles. one initial replication, one incremental replication. + // Within each cycle: interrupt replication at least once. + // This exercises both the no-resume-token-present and the resume-token-present validation code paths. +initial_then_incremental: + for i := 0; i < 2; i++ { + writeDummyData(path.Join(sfsmp.Mountpoint, "dummy.data"), 2*(1<<20)) + mustSnapshot(ctx, fmt.Sprintf("%s@%d", sfs, i)) + + rep := replicationInvocation{ + sjid: sjid, + rjid: rjid, + sfs: sfs, + rfsRoot: rfsRoot, + senderConfigHook: setup.senderConfigHook, + interceptSender: func(e *endpoint.Sender) logic.Sender { + return &PartialSender{Sender: e, failAfterByteCount: 1 << 20} + }, + guarantee: pdu.ReplicationConfigProtectionWithKind(pdu.ReplicationGuaranteeKind_GuaranteeResumability), + skipSendArgsValidation: false, + } + + rfs := rep.ReceiveSideFilesystem() + + // PartialSender interrupts after 1MiB, and we wrote 2 MiB of data + // => Give it 3 attempts to replicate. after that, we should have a stable outcome + var lastReport *report.Report + lastResumeToken := "" + interrupt_current_step: + for j := 0; j < 3; j++ { + + lastReport = rep.Do(ctx) + ctx.Logf("\nreport=%s", pretty.Sprint(lastReport)) + require.Len(ctx, lastReport.Attempts, 1) + require.Len(ctx, lastReport.Attempts[0].Filesystems, 1) + lastReportFS := lastReport.Attempts[0].Filesystems[0] + + var rfsExists bool + rfsResumeToken, err := zfs.ZFSGetReceiveResumeTokenOrEmptyStringIfNotSupported(ctx, mustDatasetPath(rfs)) + if err != nil { + _, ok := err.(*zfs.DatasetDoesNotExist) // no shadow + require.True(ctx, ok, "no other errors expected") + rfsExists = false + rfsResumeToken = "" + } else { + rfsExists = true + } + + if setup.expectedOutcome == ValidationRejects { + + // When expecting rejection, it should manifest immediately, before sending anything. + // This is tested in the j=0 iteration (for both initial and incremental repl (i=0, i=1)). + // But we also want to assert correct behavior in case zrepl observes resume tokens. + // Specifically, cases where the send parameters encoded in the token conflict with the + // configured encryption policy. + // Hence, for scenarios that are expected to reject, after we validated that they reject + // for the non-resuming case (j==0), fabricate a resuming scenario by temporarily disabling + // send args validation. After fabricating the scenario, proceed into j==1 to exercise + // the resume token validation. + if j == 0 { + if i == 0 { + require.False(ctx, rfsExists, "the sender should not have sent anything") + } else { + // we fabricate a scenario where rfsExists below, hence can't assert non-existence anymore + } + + ctx.Logf("skipping send args validation to test resuming case") + + rep.skipSendArgsValidation = true + setupResumeReport := rep.Do(ctx) + ctx.Logf("setupResumeReport=%s", pretty.Sprint(setupResumeReport)) + rep.skipSendArgsValidation = false + rt, err := zfs.ZFSGetReceiveResumeTokenOrEmptyStringIfNotSupported(ctx, mustDatasetPath(rfs)) + require.NoError(ctx, err) + require.NotEmpty(ctx, rt, "we disabled send args validation, so the .Do above should have resulted in a resume token on rfs") + lastResumeToken = rt + continue interrupt_current_step // next iteration will test resume case with send args validation enabled + } else { // j > 0 + require.Equal(ctx, lastResumeToken, rfsResumeToken, "we expect policy to refuse replication, no progress must happen") + _, err := zfs.ZFSGetFilesystemVersion(ctx, fmt.Sprintf("%s@%d", rfs, i)) + _, ok := err.(*zfs.DatasetDoesNotExist) + require.True(ctx, ok, "another check that no progress is happening") + } + + setup.outcomeRejectsInspectError(ctx, lastReportFS, j == 0) + + // XXX: check rejection cases for incremental replication as well + break initial_then_incremental + + } else { + require.Equal(ctx, ValidationAccepts, setup.expectedOutcome) + _, err := zfs.ZFSGetFilesystemVersion(ctx, fmt.Sprintf("%s@%d", rfs, i)) + _, notExist := err.(*zfs.DatasetDoesNotExist) + if notExist { + require.NotEmpty(ctx, rfsResumeToken) + continue interrupt_current_step // next iteration will resume + } else { + require.NoError(ctx, err) + // version exists + + // make sure all the filesystem versions we created so far were replicated by the replication loop + for j := 0; j <= i; j++ { + _ = fsversion(ctx, rfs, fmt.Sprintf("@%d", j)) + } + + setup.inspectReceiverFSAfterSuccessfulCycle(rfs) + continue initial_then_incremental + } + } + } + + } + +} + +func SendArgsValidationEE_EncryptionAndRaw(ctx *platformtest.Context) { + type TC struct { + // create sender filesystem with encryption enabled yes/no + SFSEnc bool + SndEnc bool // send flag + SndRaw bool // send flag + RFSEnc bool + Outcome sendArgsValidationEndToEndTestOutcome + RejectErrorNoResume string + RejectErrorResume string + } + tcs := []TC{ + // Sender FS is unencrypted + {SFSEnc: false, SndEnc: false, SndRaw: false, RFSEnc: false, Outcome: ValidationAccepts}, + {SFSEnc: false, SndEnc: false, SndRaw: true, RFSEnc: false, Outcome: ValidationAccepts}, // allow unencrypted raw sends (#503) + {SFSEnc: false, SndEnc: true, SndRaw: false, RFSEnc: false, Outcome: ValidationRejects, + RejectErrorNoResume: `encrypted send mandated by policy, but filesystem .* is not encrypted`, + RejectErrorResume: `encrypted send mandated by policy, but filesystem .* is not encrypted`, + }, + {SFSEnc: false, SndEnc: true, SndRaw: true, RFSEnc: false, Outcome: ValidationRejects, + RejectErrorNoResume: `encrypted send mandated by policy, but filesystem .* is not encrypted`, + RejectErrorResume: `encrypted send mandated by policy, but filesystem .* is not encrypted`, + }, + // Sender FS is encrypted + {SFSEnc: true, SndEnc: false, SndRaw: false, RFSEnc: false, Outcome: ValidationAccepts}, // passes because keys are loaded, thus can send plain. + {SFSEnc: true, SndEnc: false, SndRaw: true, RFSEnc: false, Outcome: ValidationRejects, + RejectErrorNoResume: `policy mandates raw\+unencrypted sends, but filesystem .* is encrypted`, + RejectErrorResume: `resume token has rawok=true which would result in encrypted send, but policy mandates unencrypted sends only`, + }, + {SFSEnc: true, SndEnc: true, SndRaw: false, RFSEnc: true, Outcome: ValidationAccepts}, + {SFSEnc: true, SndEnc: true, SndRaw: true, RFSEnc: true, Outcome: ValidationAccepts}, + } + + for _, tc := range tcs { + tc := tc // closure would copy by ref otherwise + ctx.QueueSubtest(fmt.Sprintf("%#v", tc), func(ctx *platformtest.Context) { + implSendArgsValidationEndToEndTest(ctx, sendArgsValidationEndToEndTest{ + encryptedSenderFilesystem: tc.SFSEnc, + senderConfigHook: func(c *endpoint.SenderConfig) { + c.Encrypt = &nodefault.Bool{B: tc.SndEnc} + c.SendRaw = tc.SndRaw + }, + expectedOutcome: tc.Outcome, + outcomeRejectsInspectError: func(ctx require.TestingT, fr *report.FilesystemReport, isResume bool) { + // this callback is only called for ValidationRejects + + // validation should be failing during dry send => planning stage + // XXX mock out ZFS to ensure we never call a zfs send that would send data + // if we're expecting validation to fail + require.Equal(ctx, report.FilesystemPlanningErrored, fr.State) + + if isResume { + require.NotEmpty(ctx, tc.RejectErrorResume) + require.Regexp(ctx, tc.RejectErrorResume, fr.PlanError) + } else { + require.NotEmpty(ctx, tc.RejectErrorNoResume) + require.Regexp(ctx, tc.RejectErrorNoResume, fr.PlanError) + } + }, + inspectReceiverFSAfterSuccessfulCycle: func(rfs string) { + enabled, err := zfs.ZFSGetEncryptionEnabled(ctx, rfs) + require.NoError(ctx, err) + require.Equal(ctx, tc.RFSEnc, enabled, "receiver filesystem encryption settings unexpected") + }, + }) + }) + } +} diff --git a/replication/logic/pdu/pdu.pb.go b/replication/logic/pdu/pdu.pb.go index 534a40b..5b07e56 100644 --- a/replication/logic/pdu/pdu.pb.go +++ b/replication/logic/pdu/pdu.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 -// protoc v3.12.4 +// protoc v3.14.0 // source: pdu.proto package pdu @@ -25,55 +25,6 @@ const ( // of the legacy proto package is being used. const _ = proto.ProtoPackageIsVersion4 -type Tri int32 - -const ( - Tri_DontCare Tri = 0 - Tri_False Tri = 1 - Tri_True Tri = 2 -) - -// Enum value maps for Tri. -var ( - Tri_name = map[int32]string{ - 0: "DontCare", - 1: "False", - 2: "True", - } - Tri_value = map[string]int32{ - "DontCare": 0, - "False": 1, - "True": 2, - } -) - -func (x Tri) Enum() *Tri { - p := new(Tri) - *p = x - return p -} - -func (x Tri) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Tri) Descriptor() protoreflect.EnumDescriptor { - return file_pdu_proto_enumTypes[0].Descriptor() -} - -func (Tri) Type() protoreflect.EnumType { - return &file_pdu_proto_enumTypes[0] -} - -func (x Tri) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Tri.Descriptor instead. -func (Tri) EnumDescriptor() ([]byte, []int) { - return file_pdu_proto_rawDescGZIP(), []int{0} -} - type ReplicationGuaranteeKind int32 const ( @@ -110,11 +61,11 @@ func (x ReplicationGuaranteeKind) String() string { } func (ReplicationGuaranteeKind) Descriptor() protoreflect.EnumDescriptor { - return file_pdu_proto_enumTypes[1].Descriptor() + return file_pdu_proto_enumTypes[0].Descriptor() } func (ReplicationGuaranteeKind) Type() protoreflect.EnumType { - return &file_pdu_proto_enumTypes[1] + return &file_pdu_proto_enumTypes[0] } func (x ReplicationGuaranteeKind) Number() protoreflect.EnumNumber { @@ -123,7 +74,7 @@ func (x ReplicationGuaranteeKind) Number() protoreflect.EnumNumber { // Deprecated: Use ReplicationGuaranteeKind.Descriptor instead. func (ReplicationGuaranteeKind) EnumDescriptor() ([]byte, []int) { - return file_pdu_proto_rawDescGZIP(), []int{1} + return file_pdu_proto_rawDescGZIP(), []int{0} } type FilesystemVersion_VersionType int32 @@ -156,11 +107,11 @@ func (x FilesystemVersion_VersionType) String() string { } func (FilesystemVersion_VersionType) Descriptor() protoreflect.EnumDescriptor { - return file_pdu_proto_enumTypes[2].Descriptor() + return file_pdu_proto_enumTypes[1].Descriptor() } func (FilesystemVersion_VersionType) Type() protoreflect.EnumType { - return &file_pdu_proto_enumTypes[2] + return &file_pdu_proto_enumTypes[1] } func (x FilesystemVersion_VersionType) Number() protoreflect.EnumNumber { @@ -265,7 +216,6 @@ type Filesystem struct { Path string `protobuf:"bytes,1,opt,name=Path,proto3" json:"Path,omitempty"` ResumeToken string `protobuf:"bytes,2,opt,name=ResumeToken,proto3" json:"ResumeToken,omitempty"` IsPlaceholder bool `protobuf:"varint,3,opt,name=IsPlaceholder,proto3" json:"IsPlaceholder,omitempty"` - IsEncrypted bool `protobuf:"varint,4,opt,name=IsEncrypted,proto3" json:"IsEncrypted,omitempty"` } func (x *Filesystem) Reset() { @@ -321,13 +271,6 @@ func (x *Filesystem) GetIsPlaceholder() bool { return false } -func (x *Filesystem) GetIsEncrypted() bool { - if x != nil { - return x.IsEncrypted - } - return false -} - type ListFilesystemVersionsReq struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -517,7 +460,6 @@ type SendReq struct { // ResumeToken is not empty, the GUIDs of From and To MUST correspond to those // encoded in the ResumeToken. Otherwise, the Sender MUST return an error. ResumeToken string `protobuf:"bytes,4,opt,name=ResumeToken,proto3" json:"ResumeToken,omitempty"` - Encrypted Tri `protobuf:"varint,5,opt,name=Encrypted,proto3,enum=Tri" json:"Encrypted,omitempty"` ReplicationConfig *ReplicationConfig `protobuf:"bytes,6,opt,name=ReplicationConfig,proto3" json:"ReplicationConfig,omitempty"` } @@ -581,13 +523,6 @@ func (x *SendReq) GetResumeToken() string { return "" } -func (x *SendReq) GetEncrypted() Tri { - if x != nil { - return x.Encrypted - } - return Tri_DontCare -} - func (x *SendReq) GetReplicationConfig() *ReplicationConfig { if x != nil { return x.ReplicationConfig @@ -1396,162 +1331,155 @@ var file_pdu_proto_rawDesc = []byte{ 0x65, 0x6d, 0x52, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x75, 0x6d, - 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52, 0x65, - 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x49, 0x73, 0x50, - 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0d, 0x49, 0x73, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, - 0x20, 0x0a, 0x0b, 0x49, 0x73, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x49, 0x73, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, - 0x64, 0x22, 0x3b, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x12, 0x1e, - 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x4b, + 0x74, 0x65, 0x6d, 0x73, 0x22, 0x68, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52, 0x65, 0x73, + 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x49, 0x73, 0x50, 0x6c, + 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x49, 0x73, 0x50, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x22, 0x3b, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x08, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xd4, 0x01, 0x0a, 0x11, - 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x32, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1e, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x75, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x47, 0x75, 0x69, 0x64, 0x12, 0x1c, 0x0a, - 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x58, 0x47, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x58, 0x47, 0x12, 0x1a, 0x0a, 0x08, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, - 0x6f, 0x74, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, - 0x10, 0x01, 0x22, 0xfd, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1e, - 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x26, - 0x0a, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x46, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x4b, 0x0a, 0x19, 0x4c, + 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xd4, 0x01, 0x0a, 0x11, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, + 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x04, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x22, 0x0a, 0x02, 0x54, 0x6f, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x02, 0x54, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, - 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x09, - 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x04, 0x2e, 0x54, 0x72, 0x69, 0x52, 0x09, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, - 0x12, 0x40, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x11, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x22, 0x51, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, - 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8f, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x07, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x4b, 0x69, 0x6e, - 0x64, 0x52, 0x07, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0b, 0x49, 0x6e, - 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x19, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x75, 0x61, - 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x0b, 0x49, 0x6e, 0x63, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x22, 0x34, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, - 0x72, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x57, 0x0a, - 0x07, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x64, - 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0f, 0x55, 0x73, 0x65, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x53, 0x69, - 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x3e, 0x0a, 0x10, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x12, 0x2a, 0x0a, 0x0b, 0x4f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x08, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x52, 0x0b, 0x4f, 0x72, 0x69, 0x67, 0x69, - 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x22, 0xbe, 0x01, 0x0a, 0x0a, 0x52, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x46, - 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x22, 0x0a, 0x02, 0x54, 0x6f, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x02, 0x54, 0x6f, 0x12, 0x2a, 0x0a, - 0x10, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x52, 0x65, + 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x47, 0x75, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x47, 0x75, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x54, 0x58, 0x47, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x58, 0x47, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x10, 0x01, 0x22, + 0xd9, 0x01, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x26, 0x0a, 0x04, 0x46, + 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x46, 0x69, 0x6c, 0x65, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x46, + 0x72, 0x6f, 0x6d, 0x12, 0x22, 0x0a, 0x02, 0x54, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x02, 0x54, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x75, 0x6d, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x40, 0x0a, 0x11, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x0c, 0x0a, 0x0a, 0x52, - 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x52, 0x65, 0x73, 0x22, 0x67, 0x0a, 0x13, 0x44, 0x65, 0x73, - 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x12, 0x1e, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x12, 0x30, 0x0a, 0x09, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, - 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x12, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x53, 0x6e, 0x61, 0x70, - 0x73, 0x68, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, - 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x44, - 0x0a, 0x13, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, - 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x52, 0x07, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x22, 0x36, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, - 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x54, 0x0a, 0x14, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x51, 0x0a, 0x11, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x3c, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8f, + 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, + 0x0a, 0x07, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x19, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x75, 0x61, + 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x07, 0x49, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0b, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x4b, + 0x69, 0x6e, 0x64, 0x52, 0x0b, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, + 0x22, 0x34, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x57, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, + 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x55, 0x73, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x45, + 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0c, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x22, + 0x3e, 0x0a, 0x10, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x71, 0x12, 0x2a, 0x0a, 0x0b, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, + 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, + 0x65, 0x71, 0x52, 0x0b, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x22, + 0x12, 0x0a, 0x10, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x22, 0xbe, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x52, + 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x12, 0x22, 0x0a, 0x02, 0x54, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x02, 0x54, 0x6f, 0x12, 0x2a, 0x0a, 0x10, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x52, + 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x10, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x40, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x52, 0x11, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x22, 0x0c, 0x0a, 0x0a, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x52, + 0x65, 0x73, 0x22, 0x67, 0x0a, 0x13, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x30, 0x0a, 0x09, 0x53, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x09, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x12, 0x44, + 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, + 0x73, 0x12, 0x2e, 0x0a, 0x08, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, + 0x74, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x44, 0x0a, 0x13, 0x44, 0x65, 0x73, 0x74, 0x72, + 0x6f, 0x79, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x73, 0x12, 0x2d, + 0x0a, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, + 0x74, 0x52, 0x65, 0x73, 0x52, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x36, 0x0a, + 0x14, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, + 0x6f, 0x72, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x54, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x12, 0x14, 0x0a, + 0x04, 0x47, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x04, 0x47, + 0x75, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x4e, 0x6f, 0x74, 0x65, 0x78, 0x69, 0x73, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x4e, 0x6f, 0x74, 0x65, 0x78, 0x69, 0x73, + 0x74, 0x42, 0x08, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x23, 0x0a, 0x07, 0x50, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x1d, 0x0a, 0x07, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x45, + 0x63, 0x68, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x2a, + 0x86, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, + 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x10, + 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x52, + 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x01, 0x12, 0x23, 0x0a, + 0x1f, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x4e, + 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x10, 0x03, 0x32, 0x8f, 0x03, 0x0a, 0x0b, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, + 0x12, 0x08, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x08, 0x2e, 0x50, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x12, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, + 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x12, + 0x50, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x12, 0x3e, 0x0a, 0x10, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, 0x70, + 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x44, 0x65, + 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x12, 0x41, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x15, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, - 0x72, 0x52, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x04, 0x47, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x04, 0x48, 0x00, 0x52, 0x04, 0x47, 0x75, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x4e, 0x6f, - 0x74, 0x65, 0x78, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, - 0x4e, 0x6f, 0x74, 0x65, 0x78, 0x69, 0x73, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x22, 0x23, 0x0a, 0x07, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, - 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1d, 0x0a, 0x07, 0x50, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x45, 0x63, 0x68, 0x6f, 0x2a, 0x28, 0x0a, 0x03, 0x54, 0x72, 0x69, 0x12, 0x0c, 0x0a, - 0x08, 0x44, 0x6f, 0x6e, 0x74, 0x43, 0x61, 0x72, 0x65, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x46, - 0x61, 0x6c, 0x73, 0x65, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x72, 0x75, 0x65, 0x10, 0x02, - 0x2a, 0x86, 0x01, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x14, 0x0a, - 0x10, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, - 0x52, 0x65, 0x73, 0x75, 0x6d, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x01, 0x12, 0x23, - 0x0a, 0x1f, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x63, 0x72, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x47, 0x75, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65, - 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x10, 0x03, 0x32, 0x8f, 0x03, 0x0a, 0x0b, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x04, 0x50, 0x69, 0x6e, - 0x67, 0x12, 0x08, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x08, 0x2e, 0x50, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x12, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, - 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, - 0x12, 0x50, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x10, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12, 0x14, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, - 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x44, - 0x65, 0x73, 0x74, 0x72, 0x6f, 0x79, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x12, 0x41, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x12, 0x15, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x15, - 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x75, 0x72, 0x73, - 0x6f, 0x72, 0x52, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x44, 0x72, 0x79, - 0x12, 0x08, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x08, 0x2e, 0x53, 0x65, 0x6e, - 0x64, 0x52, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x70, - 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x11, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x70, - 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x42, 0x07, 0x5a, 0x05, 0x2e, - 0x3b, 0x70, 0x64, 0x75, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x52, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x44, 0x72, 0x79, 0x12, + 0x08, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x08, 0x2e, 0x53, 0x65, 0x6e, 0x64, + 0x52, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x0d, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x64, 0x12, 0x11, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x3b, + 0x70, 0x64, 0x75, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1566,71 +1494,69 @@ func file_pdu_proto_rawDescGZIP() []byte { return file_pdu_proto_rawDescData } -var file_pdu_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_pdu_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_pdu_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_pdu_proto_goTypes = []interface{}{ - (Tri)(0), // 0: Tri - (ReplicationGuaranteeKind)(0), // 1: ReplicationGuaranteeKind - (FilesystemVersion_VersionType)(0), // 2: FilesystemVersion.VersionType - (*ListFilesystemReq)(nil), // 3: ListFilesystemReq - (*ListFilesystemRes)(nil), // 4: ListFilesystemRes - (*Filesystem)(nil), // 5: Filesystem - (*ListFilesystemVersionsReq)(nil), // 6: ListFilesystemVersionsReq - (*ListFilesystemVersionsRes)(nil), // 7: ListFilesystemVersionsRes - (*FilesystemVersion)(nil), // 8: FilesystemVersion - (*SendReq)(nil), // 9: SendReq - (*ReplicationConfig)(nil), // 10: ReplicationConfig - (*ReplicationConfigProtection)(nil), // 11: ReplicationConfigProtection - (*Property)(nil), // 12: Property - (*SendRes)(nil), // 13: SendRes - (*SendCompletedReq)(nil), // 14: SendCompletedReq - (*SendCompletedRes)(nil), // 15: SendCompletedRes - (*ReceiveReq)(nil), // 16: ReceiveReq - (*ReceiveRes)(nil), // 17: ReceiveRes - (*DestroySnapshotsReq)(nil), // 18: DestroySnapshotsReq - (*DestroySnapshotRes)(nil), // 19: DestroySnapshotRes - (*DestroySnapshotsRes)(nil), // 20: DestroySnapshotsRes - (*ReplicationCursorReq)(nil), // 21: ReplicationCursorReq - (*ReplicationCursorRes)(nil), // 22: ReplicationCursorRes - (*PingReq)(nil), // 23: PingReq - (*PingRes)(nil), // 24: PingRes + (ReplicationGuaranteeKind)(0), // 0: ReplicationGuaranteeKind + (FilesystemVersion_VersionType)(0), // 1: FilesystemVersion.VersionType + (*ListFilesystemReq)(nil), // 2: ListFilesystemReq + (*ListFilesystemRes)(nil), // 3: ListFilesystemRes + (*Filesystem)(nil), // 4: Filesystem + (*ListFilesystemVersionsReq)(nil), // 5: ListFilesystemVersionsReq + (*ListFilesystemVersionsRes)(nil), // 6: ListFilesystemVersionsRes + (*FilesystemVersion)(nil), // 7: FilesystemVersion + (*SendReq)(nil), // 8: SendReq + (*ReplicationConfig)(nil), // 9: ReplicationConfig + (*ReplicationConfigProtection)(nil), // 10: ReplicationConfigProtection + (*Property)(nil), // 11: Property + (*SendRes)(nil), // 12: SendRes + (*SendCompletedReq)(nil), // 13: SendCompletedReq + (*SendCompletedRes)(nil), // 14: SendCompletedRes + (*ReceiveReq)(nil), // 15: ReceiveReq + (*ReceiveRes)(nil), // 16: ReceiveRes + (*DestroySnapshotsReq)(nil), // 17: DestroySnapshotsReq + (*DestroySnapshotRes)(nil), // 18: DestroySnapshotRes + (*DestroySnapshotsRes)(nil), // 19: DestroySnapshotsRes + (*ReplicationCursorReq)(nil), // 20: ReplicationCursorReq + (*ReplicationCursorRes)(nil), // 21: ReplicationCursorRes + (*PingReq)(nil), // 22: PingReq + (*PingRes)(nil), // 23: PingRes } var file_pdu_proto_depIdxs = []int32{ - 5, // 0: ListFilesystemRes.Filesystems:type_name -> Filesystem - 8, // 1: ListFilesystemVersionsRes.Versions:type_name -> FilesystemVersion - 2, // 2: FilesystemVersion.Type:type_name -> FilesystemVersion.VersionType - 8, // 3: SendReq.From:type_name -> FilesystemVersion - 8, // 4: SendReq.To:type_name -> FilesystemVersion - 0, // 5: SendReq.Encrypted:type_name -> Tri - 10, // 6: SendReq.ReplicationConfig:type_name -> ReplicationConfig - 11, // 7: ReplicationConfig.protection:type_name -> ReplicationConfigProtection - 1, // 8: ReplicationConfigProtection.Initial:type_name -> ReplicationGuaranteeKind - 1, // 9: ReplicationConfigProtection.Incremental:type_name -> ReplicationGuaranteeKind - 9, // 10: SendCompletedReq.OriginalReq:type_name -> SendReq - 8, // 11: ReceiveReq.To:type_name -> FilesystemVersion - 10, // 12: ReceiveReq.ReplicationConfig:type_name -> ReplicationConfig - 8, // 13: DestroySnapshotsReq.Snapshots:type_name -> FilesystemVersion - 8, // 14: DestroySnapshotRes.Snapshot:type_name -> FilesystemVersion - 19, // 15: DestroySnapshotsRes.Results:type_name -> DestroySnapshotRes - 23, // 16: Replication.Ping:input_type -> PingReq - 3, // 17: Replication.ListFilesystems:input_type -> ListFilesystemReq - 6, // 18: Replication.ListFilesystemVersions:input_type -> ListFilesystemVersionsReq - 18, // 19: Replication.DestroySnapshots:input_type -> DestroySnapshotsReq - 21, // 20: Replication.ReplicationCursor:input_type -> ReplicationCursorReq - 9, // 21: Replication.SendDry:input_type -> SendReq - 14, // 22: Replication.SendCompleted:input_type -> SendCompletedReq - 24, // 23: Replication.Ping:output_type -> PingRes - 4, // 24: Replication.ListFilesystems:output_type -> ListFilesystemRes - 7, // 25: Replication.ListFilesystemVersions:output_type -> ListFilesystemVersionsRes - 20, // 26: Replication.DestroySnapshots:output_type -> DestroySnapshotsRes - 22, // 27: Replication.ReplicationCursor:output_type -> ReplicationCursorRes - 13, // 28: Replication.SendDry:output_type -> SendRes - 15, // 29: Replication.SendCompleted:output_type -> SendCompletedRes - 23, // [23:30] is the sub-list for method output_type - 16, // [16:23] is the sub-list for method input_type - 16, // [16:16] is the sub-list for extension type_name - 16, // [16:16] is the sub-list for extension extendee - 0, // [0:16] is the sub-list for field type_name + 4, // 0: ListFilesystemRes.Filesystems:type_name -> Filesystem + 7, // 1: ListFilesystemVersionsRes.Versions:type_name -> FilesystemVersion + 1, // 2: FilesystemVersion.Type:type_name -> FilesystemVersion.VersionType + 7, // 3: SendReq.From:type_name -> FilesystemVersion + 7, // 4: SendReq.To:type_name -> FilesystemVersion + 9, // 5: SendReq.ReplicationConfig:type_name -> ReplicationConfig + 10, // 6: ReplicationConfig.protection:type_name -> ReplicationConfigProtection + 0, // 7: ReplicationConfigProtection.Initial:type_name -> ReplicationGuaranteeKind + 0, // 8: ReplicationConfigProtection.Incremental:type_name -> ReplicationGuaranteeKind + 8, // 9: SendCompletedReq.OriginalReq:type_name -> SendReq + 7, // 10: ReceiveReq.To:type_name -> FilesystemVersion + 9, // 11: ReceiveReq.ReplicationConfig:type_name -> ReplicationConfig + 7, // 12: DestroySnapshotsReq.Snapshots:type_name -> FilesystemVersion + 7, // 13: DestroySnapshotRes.Snapshot:type_name -> FilesystemVersion + 18, // 14: DestroySnapshotsRes.Results:type_name -> DestroySnapshotRes + 22, // 15: Replication.Ping:input_type -> PingReq + 2, // 16: Replication.ListFilesystems:input_type -> ListFilesystemReq + 5, // 17: Replication.ListFilesystemVersions:input_type -> ListFilesystemVersionsReq + 17, // 18: Replication.DestroySnapshots:input_type -> DestroySnapshotsReq + 20, // 19: Replication.ReplicationCursor:input_type -> ReplicationCursorReq + 8, // 20: Replication.SendDry:input_type -> SendReq + 13, // 21: Replication.SendCompleted:input_type -> SendCompletedReq + 23, // 22: Replication.Ping:output_type -> PingRes + 3, // 23: Replication.ListFilesystems:output_type -> ListFilesystemRes + 6, // 24: Replication.ListFilesystemVersions:output_type -> ListFilesystemVersionsRes + 19, // 25: Replication.DestroySnapshots:output_type -> DestroySnapshotsRes + 21, // 26: Replication.ReplicationCursor:output_type -> ReplicationCursorRes + 12, // 27: Replication.SendDry:output_type -> SendRes + 14, // 28: Replication.SendCompleted:output_type -> SendCompletedRes + 22, // [22:29] is the sub-list for method output_type + 15, // [15:22] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_pdu_proto_init() } @@ -1913,7 +1839,7 @@ func file_pdu_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pdu_proto_rawDesc, - NumEnums: 3, + NumEnums: 2, NumMessages: 22, NumExtensions: 0, NumServices: 1, diff --git a/replication/logic/pdu/pdu.proto b/replication/logic/pdu/pdu.proto index 6eb8cd6..77c2ff4 100644 --- a/replication/logic/pdu/pdu.proto +++ b/replication/logic/pdu/pdu.proto @@ -21,7 +21,6 @@ message Filesystem { string Path = 1; string ResumeToken = 2; bool IsPlaceholder = 3; - bool IsEncrypted = 4; } message ListFilesystemVersionsReq { string Filesystem = 1; } @@ -40,12 +39,6 @@ message FilesystemVersion { string Creation = 5; // RFC 3339 } -enum Tri { - DontCare = 0; - False = 1; - True = 2; -} - message SendReq { string Filesystem = 1; // May be empty / null to request a full transfer of To @@ -59,7 +52,6 @@ message SendReq { // ResumeToken is not empty, the GUIDs of From and To MUST correspond to those // encoded in the ResumeToken. Otherwise, the Sender MUST return an error. string ResumeToken = 4; - Tri Encrypted = 5; ReplicationConfig ReplicationConfig = 6; } diff --git a/replication/logic/replication_logic.go b/replication/logic/replication_logic.go index 36fedb3..9d187a9 100644 --- a/replication/logic/replication_logic.go +++ b/replication/logic/replication_logic.go @@ -156,8 +156,7 @@ type Step struct { parent *Filesystem from, to *pdu.FilesystemVersion // from may be nil, indicating full send - encrypt tri - resumeToken string // empty means no resume token shall be used + resumeToken string // empty means no resume token shall be used expectedSize uint64 // 0 means no size estimate present / possible @@ -201,22 +200,10 @@ func (s *Step) ReportInfo() *report.StepInfo { if s.from != nil { from = s.from.RelName() } - var encrypted report.EncryptedEnum - switch s.encrypt { - case DontCare: - encrypted = report.EncryptedSenderDependent - case True: - encrypted = report.EncryptedTrue - case False: - encrypted = report.EncryptedFalse - default: - panic(fmt.Sprintf("unknown variant %s", s.encrypt)) - } return &report.StepInfo{ From: from, To: s.to.RelName(), Resumed: s.resumeToken != "", - Encrypted: encrypted, BytesExpected: s.expectedSize, BytesReplicated: byteCounter, } @@ -346,10 +333,6 @@ func (fs *Filesystem) doPlanning(ctx context.Context) ([]*Step, error) { log(ctx).Debug("assessing filesystem") - if fs.policy.EncryptedSend == True && !fs.senderFS.GetIsEncrypted() { - return nil, fmt.Errorf("sender filesystem is not encrypted but policy mandates encrypted send") - } - sfsvsres, err := fs.sender.ListFilesystemVersions(ctx, &pdu.ListFilesystemVersionsReq{Filesystem: fs.Path}) if err != nil { log(ctx).WithError(err).Error("cannot get remote filesystem versions") @@ -423,24 +406,7 @@ func (fs *Filesystem) doPlanning(ctx context.Context) ([]*Step, error) { } } - encryptionMatches := false - switch fs.policy.EncryptedSend { - case True: - encryptionMatches = resumeToken.RawOK && resumeToken.CompressOK - case False: - encryptionMatches = !resumeToken.RawOK && !resumeToken.CompressOK - case DontCare: - encryptionMatches = true - } - - log(ctx).WithField("fromVersion", fromVersion). - WithField("toVersion", toVersion). - WithField("encryptionMatches", encryptionMatches). - Debug("result of resume-token-matching to sender's versions") - - if !encryptionMatches { - return nil, fmt.Errorf("resume token `rawok`=%v and `compressok`=%v are incompatible with encryption policy=%v", resumeToken.RawOK, resumeToken.CompressOK, fs.policy.EncryptedSend) - } else if toVersion == nil { + if toVersion == nil { return nil, fmt.Errorf("resume token `toguid` = %v not found on sender (`toname` = %q)", resumeToken.ToGUID, resumeToken.ToName) } else if fromVersion == toVersion { return nil, fmt.Errorf("resume token `fromguid` and `toguid` match same version on sener") @@ -452,9 +418,8 @@ func (fs *Filesystem) doPlanning(ctx context.Context) ([]*Step, error) { sender: fs.sender, receiver: fs.receiver, - from: fromVersion, - to: toVersion, - encrypt: fs.policy.EncryptedSend, + from: fromVersion, + to: toVersion, resumeToken: resumeTokenRaw, } @@ -480,7 +445,6 @@ func (fs *Filesystem) doPlanning(ctx context.Context) ([]*Step, error) { receiver: fs.receiver, from: remainingSFSVs[i], to: remainingSFSVs[i+1], - encrypt: fs.policy.EncryptedSend, }) } } else { // resumeToken == nil @@ -510,9 +474,8 @@ func (fs *Filesystem) doPlanning(ctx context.Context) ([]*Step, error) { sender: fs.sender, receiver: fs.receiver, - from: path[i], // nil in case of initial repl - to: path[i+1], - encrypt: fs.policy.EncryptedSend, + from: path[i], // nil in case of initial repl + to: path[i+1], }) } } @@ -592,7 +555,6 @@ func (s *Step) buildSendRequest() (sr *pdu.SendReq) { Filesystem: fs, From: s.from, // may be nil To: s.to, - Encrypted: s.encrypt.ToPDU(), ResumeToken: s.resumeToken, ReplicationConfig: s.parent.policy.ReplicationConfig, } diff --git a/replication/logic/replication_logic_policy.go b/replication/logic/replication_logic_policy.go index 8084399..9042e93 100644 --- a/replication/logic/replication_logic_policy.go +++ b/replication/logic/replication_logic_policy.go @@ -63,7 +63,6 @@ func ConflictResolutionFromConfig(in *config.ConflictResolution) (*ConflictResol } type PlannerPolicy struct { - EncryptedSend tri // all sends must be encrypted (send -w, and encryption!=off) ConflictResolution *ConflictResolution `validate:"ne=nil"` ReplicationConfig *pdu.ReplicationConfig `validate:"ne=nil"` SizeEstimationConcurrency int `validate:"gte=1"` diff --git a/replication/logic/replication_logic_tri.go b/replication/logic/replication_logic_tri.go deleted file mode 100644 index a17fad8..0000000 --- a/replication/logic/replication_logic_tri.go +++ /dev/null @@ -1,46 +0,0 @@ -package logic - -import ( - "fmt" - - "github.com/zrepl/zrepl/replication/logic/pdu" -) - -type tri int - -const ( - DontCare = 0x0 - False = 0x1 - True = 0x2 -) - -func (t tri) String() string { - switch t { - case DontCare: - return "dontcare" - case False: - return "false" - case True: - return "true" - } - panic(fmt.Sprintf("unknown variant %v", int(t))) -} - -func (t tri) ToPDU() pdu.Tri { - switch t { - case DontCare: - return pdu.Tri_DontCare - case False: - return pdu.Tri_False - case True: - return pdu.Tri_True - } - panic(fmt.Sprintf("unknown variant %v", int(t))) -} - -func TriFromBool(b bool) tri { - if b { - return True - } - return False -} diff --git a/replication/report/replication_report.go b/replication/report/replication_report.go index 767c69e..44a981a 100644 --- a/replication/report/replication_report.go +++ b/replication/report/replication_report.go @@ -97,18 +97,9 @@ type StepReport struct { Info *StepInfo } -type EncryptedEnum string - -const ( - EncryptedTrue EncryptedEnum = "yes" - EncryptedFalse EncryptedEnum = "no" - EncryptedSenderDependent EncryptedEnum = "sender-dependent" -) - type StepInfo struct { From, To string Resumed bool - Encrypted EncryptedEnum BytesExpected uint64 BytesReplicated uint64 } diff --git a/rpc/grpcclientidentity/example/pdu/grpcauth.pb.go b/rpc/grpcclientidentity/example/pdu/grpcauth.pb.go index bbf5f63..d101eba 100644 --- a/rpc/grpcclientidentity/example/pdu/grpcauth.pb.go +++ b/rpc/grpcclientidentity/example/pdu/grpcauth.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.25.0 -// protoc v3.12.4 +// protoc v3.14.0 // source: grpcauth.proto package pdu diff --git a/rpc/versionhandshake/versionhandshake.go b/rpc/versionhandshake/versionhandshake.go index 341b5cc..8dcb467 100644 --- a/rpc/versionhandshake/versionhandshake.go +++ b/rpc/versionhandshake/versionhandshake.go @@ -152,7 +152,7 @@ func (m *HandshakeMessage) DecodeReader(r io.Reader, maxLen int) error { func DoHandshakeCurrentVersion(conn net.Conn, deadline time.Time) *HandshakeError { // current protocol version is hardcoded here - return DoHandshakeVersion(conn, deadline, 6) + return DoHandshakeVersion(conn, deadline, 7) } const HandshakeMessageMaxLen = 16 * 4096 diff --git a/zfs/zfs.go b/zfs/zfs.go index 4d9e4c2..922d28f 100644 --- a/zfs/zfs.go +++ b/zfs/zfs.go @@ -632,6 +632,14 @@ func (e ZFSSendArgsValidationError) Error() string { return e.Msg.Error() } +type zfsSendArgsSkipValidationKeyType struct{} + +var zfsSendArgsSkipValidationKey = zfsSendArgsSkipValidationKeyType{} + +func ZFSSendArgsSkipValidation(ctx context.Context) context.Context { + return context.WithValue(ctx, zfsSendArgsSkipValidationKey, true) +} + // - Recursively call Validate on each field. // - Make sure that if ResumeToken != "", it reflects the same operation as the other parameters would. // @@ -659,6 +667,16 @@ func (a ZFSSendArgsUnvalidated) Validate(ctx context.Context) (v ZFSSendArgsVali // fallthrough } + validated := ZFSSendArgsValidated{ + ZFSSendArgsUnvalidated: a, + FromVersion: fromVersion, + ToVersion: toVersion, + } + + if ctx.Value(zfsSendArgsSkipValidationKey) != nil { + return validated, nil + } + if err := a.ZFSSendFlags.Validate(); err != nil { return v, newGenericValidationError(a, errors.Wrap(err, "send flags invalid")) } @@ -673,18 +691,19 @@ func (a ZFSSendArgsUnvalidated) Validate(ctx context.Context) (v ZFSSendArgsVali if a.Encrypted.B && !fsEncrypted { return v, newValidationError(a, ZFSSendArgsEncryptedSendRequestedButFSUnencrypted, - errors.Errorf("encrypted send requested, but filesystem %q is not encrypted", a.FS)) + errors.Errorf("encrypted send mandated by policy, but filesystem %q is not encrypted", a.FS)) + } + + if a.Raw && fsEncrypted && !a.Encrypted.B { + return v, newValidationError(a, ZFSSendArgsGenericValidationError, + errors.Errorf("policy mandates raw+unencrypted sends, but filesystem %q is encrypted", a.FS)) } if err := a.validateEncryptionFlagsCorrespondToResumeToken(ctx, valCtx); err != nil { return v, newValidationError(a, ZFSSendArgsResumeTokenMismatch, err) } - return ZFSSendArgsValidated{ - ZFSSendArgsUnvalidated: a, - FromVersion: fromVersion, - ToVersion: toVersion, - }, nil + return validated, nil } func (f ZFSSendFlags) Validate() error { @@ -852,21 +871,34 @@ func (a ZFSSendArgsUnvalidated) validateEncryptionFlagsCorrespondToResumeToken(c return gen.fmt("resume token `toguid` != expected: %v != %v", t.ToGUID, a.To.GUID) } - if a.Encrypted.B { - if !(t.RawOK && t.CompressOK) { - return ZFSSendArgsResumeTokenMismatchEncryptionNotSet.fmt( - "resume token must have `rawok` and `compressok` = true but got %v %v", t.RawOK, t.CompressOK) - } - // fallthrough - } else { - if t.RawOK || t.CompressOK { - return ZFSSendArgsResumeTokenMismatchEncryptionSet.fmt( - "resume token must not have `rawok` or `compressok` set but got %v %v", t.RawOK, t.CompressOK) - } - // fallthrough + // ensure resume stream will be encrypted/unencrypted as specified in policy + if err := valCtx.encEnabled.ValidateNoDefault(); err != nil { + panic(valCtx) + } + wouldSendEncryptedIfFilesystemIsEncrypted := t.RawOK + filesystemIsEncrypted := valCtx.encEnabled.B + resumeWillBeEncryptedSend := filesystemIsEncrypted && wouldSendEncryptedIfFilesystemIsEncrypted + if a.Encrypted.B { + if resumeWillBeEncryptedSend { + return nil // encrypted send in policy, and that's what's going to happen + } else { + if !filesystemIsEncrypted { + // NB: a.Encrypted.B && !valCtx.encEnabled.B + // is handled in the caller, because it doesn't concern the resume token (different kind of error) + panic("caller should have already raised an error") + } + // XXX we have no test coverage for this case. We'd need to forge a resume token for that. + return ZFSSendArgsResumeTokenMismatchEncryptionNotSet.fmt( + "resume token does not have rawok=true which would result in an unencrypted send, but policy mandates encrypted sends only") + } + } else { + if resumeWillBeEncryptedSend { + return ZFSSendArgsResumeTokenMismatchEncryptionSet.fmt( + "resume token has rawok=true which would result in encrypted send, but policy mandates unencrypted sends only") + } else { + return nil // unencrypted send in policy, and that's what's going to happen + } } - - return nil } var zfsSendStderrCaptureMaxSize = envconst.Int("ZREPL_ZFS_SEND_STDERR_MAX_CAPTURE_SIZE", 1<<15)