From 2f27817ba36131027cb47d31c3d5b36b80e9cdd1 Mon Sep 17 00:00:00 2001 From: Paul Lorenz Date: Fri, 3 Jan 2025 15:02:29 -0500 Subject: [PATCH] Switch router storage to serialized protobuf, rather than json --- common/pb/mgmt_pb/mgmt.pb.go | 365 +++++++++--------- common/pb/mgmt_pb/mgmt.proto | 1 + common/router_data_model.go | 332 ++++++++-------- common/subscriber.go | 5 +- .../validate_router_data_model.go | 21 +- controller/sync_strats/rtx.go | 7 +- controller/sync_strats/sync_instant.go | 12 +- router/env/ctrl.go | 10 + router/env/ctrls.go | 12 +- router/internal/edgerouter/config.go | 4 +- router/posture/access.go | 2 +- router/state/dataState.go | 14 +- router/state/dataStateChangeSetEvent.go | 21 +- router/state/manager.go | 62 ++- router/state/validate.go | 2 +- router/xgress_edge_tunnel/factory.go | 2 +- ziti/cmd/fabric/validate_router_data_model.go | 3 + zititest/go.mod | 4 +- zititest/go.sum | 23 +- .../models/router-data-model-test/main.go | 15 - .../router-data-model-test/validation.go | 2 +- zititest/models/smoke/actions/bootstrap.go | 6 +- zititest/models/smoke/configs/ctrl.yml.tmpl | 3 + zititest/models/smoke/smoketest.go | 37 +- 24 files changed, 541 insertions(+), 424 deletions(-) diff --git a/common/pb/mgmt_pb/mgmt.pb.go b/common/pb/mgmt_pb/mgmt.pb.go index 67fdf64da..654f6fab4 100644 --- a/common/pb/mgmt_pb/mgmt.pb.go +++ b/common/pb/mgmt_pb/mgmt.pb.go @@ -1958,6 +1958,7 @@ type ValidateRouterDataModelRequest struct { RouterFilter string `protobuf:"bytes,1,opt,name=routerFilter,proto3" json:"routerFilter,omitempty"` ValidateCtrl bool `protobuf:"varint,2,opt,name=validateCtrl,proto3" json:"validateCtrl,omitempty"` + Fix bool `protobuf:"varint,3,opt,name=fix,proto3" json:"fix,omitempty"` } func (x *ValidateRouterDataModelRequest) Reset() { @@ -2006,6 +2007,13 @@ func (x *ValidateRouterDataModelRequest) GetValidateCtrl() bool { return false } +func (x *ValidateRouterDataModelRequest) GetFix() bool { + if x != nil { + return x.Fix + } + return false +} + type ValidateRouterDataModelResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2878,192 +2886,193 @@ var file_mgmt_proto_rawDesc = []byte{ 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, - 0x61, 0x73, 0x74, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x22, 0x68, 0x0a, 0x1e, 0x56, 0x61, + 0x61, 0x73, 0x74, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x22, 0x7a, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x43, 0x74, 0x72, 0x6c, 0x22, 0x7d, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x22, 0xc8, 0x01, 0x0a, 0x16, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, - 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x24, - 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, - 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x4f, - 0x0a, 0x29, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x72, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, - 0x88, 0x01, 0x0a, 0x2a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, + 0x43, 0x74, 0x72, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x03, 0x66, 0x69, 0x78, 0x22, 0x7d, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, + 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xc8, 0x01, 0x0a, 0x16, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, + 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, + 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, + 0x22, 0x4f, 0x0a, 0x29, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, - 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd9, 0x01, 0x0a, 0x27, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x44, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x24, - 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x16, - 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x59, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x2a, 0xc5, 0x0b, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x17, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb8, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xb9, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x50, - 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xbc, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x54, 0x6f, 0x67, 0x67, 0x6c, - 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbd, 0x4e, 0x12, 0x1c, 0x0a, 0x17, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbe, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xbf, 0x4e, 0x12, 0x17, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc0, 0x4e, 0x12, - 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc1, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x53, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x44, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xd6, 0x4e, 0x12, 0x25, 0x0a, 0x20, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, - 0x65, 0x62, 0x75, 0x67, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd7, 0x4e, 0x12, 0x2c, 0x0a, 0x27, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x54, 0x6f, 0x67, 0x67, 0x6c, - 0x65, 0x43, 0x74, 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd8, 0x4e, 0x12, 0x26, 0x0a, 0x21, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xd9, 0x4e, 0x12, 0x2e, 0x0a, 0x29, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, - 0x67, 0x44, 0x75, 0x6d, 0x70, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xda, 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, - 0x67, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdb, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x6e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdc, 0x4e, 0x12, 0x1d, 0x0a, 0x18, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x51, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdd, 0x4e, 0x12, 0x1f, 0x0a, 0x1a, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x71, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xde, 0x4e, 0x12, 0x22, 0x0a, 0x1d, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdf, 0x4e, - 0x12, 0x1f, 0x0a, 0x1a, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe0, - 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xe1, 0x4e, 0x12, 0x1b, 0x0a, 0x16, 0x52, 0x61, 0x66, 0x74, 0x41, 0x64, 0x64, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe2, 0x4e, - 0x12, 0x1e, 0x0a, 0x19, 0x52, 0x61, 0x66, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x65, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe3, 0x4e, - 0x12, 0x26, 0x0a, 0x21, 0x52, 0x61, 0x66, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, - 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe4, 0x4e, 0x12, 0x13, 0x0a, 0x0e, 0x52, 0x61, 0x66, 0x74, - 0x49, 0x6e, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x44, 0x62, 0x10, 0xe5, 0x4e, 0x12, 0x0d, 0x0a, - 0x08, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x10, 0xe6, 0x4e, 0x12, 0x23, 0x0a, 0x1e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, - 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf4, - 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, - 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xf5, 0x4e, 0x12, 0x21, 0x0a, 0x1c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf7, 0x4e, 0x12, 0x24, - 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, - 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xf8, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, 0x4e, 0x12, 0x2c, 0x0a, 0x27, 0x56, 0x61, 0x6c, 0x69, + 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, + 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x22, 0x88, 0x01, 0x0a, 0x2a, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x63, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xd9, 0x01, 0x0a, + 0x27, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, + 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x49, 0x64, + 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x59, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x2a, 0xc5, 0x0b, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x1c, 0x0a, + 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb8, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xb9, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x54, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x50, 0x69, 0x70, 0x65, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbc, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x54, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbd, 0x4e, 0x12, 0x1c, + 0x0a, 0x17, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbe, 0x4e, 0x12, 0x1a, 0x0a, 0x15, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x73, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbf, 0x4e, 0x12, 0x17, 0x0a, 0x12, 0x49, 0x6e, 0x73, 0x70, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc0, + 0x4e, 0x12, 0x18, 0x0a, 0x13, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xc1, 0x4e, 0x12, 0x1a, 0x0a, 0x15, 0x53, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x44, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xd6, 0x4e, 0x12, 0x25, 0x0a, 0x20, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x46, 0x6f, 0x72, 0x67, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd7, 0x4e, 0x12, 0x2c, + 0x0a, 0x27, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x54, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x43, 0x74, 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xd8, 0x4e, 0x12, 0x26, 0x0a, 0x21, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xd9, 0x4e, 0x12, 0x2e, 0x0a, 0x29, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, + 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x72, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xda, 0x4e, 0x12, 0x24, 0x0a, 0x1f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, + 0x62, 0x75, 0x67, 0x44, 0x75, 0x6d, 0x70, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdb, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x62, 0x75, 0x67, 0x55, 0x6e, 0x72, 0x6f, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdc, 0x4e, 0x12, 0x1d, + 0x0a, 0x18, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x51, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xdd, 0x4e, 0x12, 0x1f, 0x0a, + 0x1a, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x71, 0x75, 0x69, 0x65, 0x73, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xde, 0x4e, 0x12, 0x22, + 0x0a, 0x1d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xdf, 0x4e, 0x12, 0x1f, 0x0a, 0x1a, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x10, 0xe0, 0x4e, 0x12, 0x20, 0x0a, 0x1b, 0x52, 0x61, 0x66, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x10, 0xe1, 0x4e, 0x12, 0x1b, 0x0a, 0x16, 0x52, 0x61, 0x66, 0x74, 0x41, 0x64, 0x64, + 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xe2, 0x4e, 0x12, 0x1e, 0x0a, 0x19, 0x52, 0x61, 0x66, 0x74, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, + 0xe3, 0x4e, 0x12, 0x26, 0x0a, 0x21, 0x52, 0x61, 0x66, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x65, 0x72, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe4, 0x4e, 0x12, 0x13, 0x0a, 0x0e, 0x52, 0x61, + 0x66, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x44, 0x62, 0x10, 0xe5, 0x4e, 0x12, + 0x0d, 0x0a, 0x08, 0x52, 0x61, 0x66, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x10, 0xe6, 0x4e, 0x12, 0x23, + 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x10, 0xf4, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf5, 0x4e, 0x12, 0x21, 0x0a, 0x1c, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x4e, 0x12, 0x23, 0x0a, 0x1e, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, + 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf7, 0x4e, + 0x12, 0x24, 0x0a, 0x1f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x10, 0xf8, 0x4e, 0x12, 0x22, 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, 0x4e, 0x12, 0x2c, 0x0a, 0x27, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfa, 0x4e, 0x12, 0x2d, 0x0a, 0x28, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, - 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xfa, 0x4e, 0x12, 0x2d, 0x0a, 0x28, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, - 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xfb, 0x4e, 0x12, 0x2b, 0x0a, 0x26, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xfc, 0x4e, 0x12, 0x27, 0x0a, 0x22, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfd, 0x4e, 0x12, 0x28, 0x0a, 0x23, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, - 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xfe, 0x4e, 0x12, 0x26, 0x0a, 0x21, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xff, 0x4e, 0x12, 0x32, 0x0a, - 0x2d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, - 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x80, - 0x4f, 0x12, 0x33, 0x0a, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x10, 0x81, 0x4f, 0x12, 0x31, 0x0a, 0x2c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x82, 0x4f, 0x2a, 0x53, 0x0a, 0x06, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x6f, 0x6e, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, - 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x74, 0x72, 0x6c, - 0x43, 0x68, 0x61, 0x6e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x10, 0x0c, 0x2a, 0x78, - 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, - 0x75, 0x69, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, - 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x10, 0x01, - 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x50, 0x72, 0x65, 0x73, 0x65, - 0x6e, 0x74, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x61, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, - 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x04, 0x2a, 0x2b, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x63, - 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x45, - 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x43, 0x4c, - 0x55, 0x44, 0x45, 0x10, 0x01, 0x2a, 0x77, 0x0a, 0x0f, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, - 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x01, - 0x12, 0x19, 0x0a, 0x15, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, - 0x77, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x49, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x65, 0x72, - 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x04, 0x2a, 0x53, - 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, - 0x69, 0x6e, 0x6b, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, - 0x4c, 0x69, 0x6e, 0x6b, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x10, - 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x69, 0x61, 0x6c, 0x69, 0x6e, - 0x67, 0x10, 0x03, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x66, 0x61, 0x62, 0x72, 0x69, - 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xfb, 0x4e, 0x12, 0x2b, 0x0a, 0x26, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x53, 0x64, 0x6b, 0x54, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xfc, 0x4e, 0x12, 0x27, 0x0a, 0x22, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfd, 0x4e, 0x12, 0x28, 0x0a, + 0x23, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, + 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xfe, 0x4e, 0x12, 0x26, 0x0a, 0x21, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xff, 0x4e, 0x12, + 0x32, 0x0a, 0x2d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x10, 0x80, 0x4f, 0x12, 0x33, 0x0a, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x81, 0x4f, 0x12, 0x31, 0x0a, 0x2c, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x82, 0x4f, 0x2a, 0x53, 0x0a, 0x06, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x6f, 0x6e, 0x65, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x74, + 0x72, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x10, 0x0b, 0x12, 0x10, + 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x10, 0x0c, + 0x2a, 0x78, 0x0a, 0x16, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, + 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, + 0x72, 0x63, 0x75, 0x69, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x10, 0x00, 0x12, 0x12, + 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x50, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x61, 0x74, 0x68, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x69, 0x72, 0x63, 0x75, + 0x69, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x04, 0x2a, 0x2b, 0x0a, 0x0f, 0x54, 0x72, + 0x61, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, + 0x07, 0x45, 0x58, 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, + 0x43, 0x4c, 0x55, 0x44, 0x45, 0x10, 0x01, 0x2a, 0x77, 0x0a, 0x0f, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x1c, 0x0a, + 0x18, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x49, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x10, 0x04, + 0x2a, 0x53, 0x0a, 0x09, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0f, 0x0a, + 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x13, + 0x0a, 0x0f, 0x4c, 0x69, 0x6e, 0x6b, 0x45, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, + 0x64, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x44, 0x69, 0x61, 0x6c, + 0x69, 0x6e, 0x67, 0x10, 0x03, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x66, 0x61, 0x62, + 0x72, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x67, 0x6d, 0x74, 0x5f, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/common/pb/mgmt_pb/mgmt.proto b/common/pb/mgmt_pb/mgmt.proto index b7e75b02c..efc02a6a4 100644 --- a/common/pb/mgmt_pb/mgmt.proto +++ b/common/pb/mgmt_pb/mgmt.proto @@ -282,6 +282,7 @@ message RouterSdkTerminatorDetail { message ValidateRouterDataModelRequest { string routerFilter = 1; bool validateCtrl = 2; + bool fix = 3; } message ValidateRouterDataModelResponse { diff --git a/common/router_data_model.go b/common/router_data_model.go index 7055faa53..c3ad62119 100644 --- a/common/router_data_model.go +++ b/common/router_data_model.go @@ -21,7 +21,6 @@ import ( "compress/gzip" "crypto" "crypto/x509" - "encoding/json" "fmt" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" @@ -30,6 +29,7 @@ import ( "github.com/openziti/ziti/common/pb/edge_ctrl_pb" cmap "github.com/orcaman/concurrent-map/v2" "github.com/sirupsen/logrus" + "google.golang.org/protobuf/proto" "io" "os" "sort" @@ -57,7 +57,7 @@ type DataStateIdentity = edge_ctrl_pb.DataState_Identity type Identity struct { *DataStateIdentity - ServicePolicies *concurrenz.SyncSet[string] `json:"servicePolicies"` + ServicePolicies cmap.ConcurrentMap[string, struct{}] `json:"servicePolicies"` identityIndex uint64 serviceSetIndex uint64 } @@ -94,8 +94,8 @@ type DataStateServicePolicy = edge_ctrl_pb.DataState_ServicePolicy type ServicePolicy struct { *DataStateServicePolicy - Services *concurrenz.SyncSet[string] `json:"services"` - PostureChecks *concurrenz.SyncSet[string] `json:"postureChecks"` + Services cmap.ConcurrentMap[string, struct{}] `json:"services"` + PostureChecks cmap.ConcurrentMap[string, struct{}] `json:"postureChecks"` } // RouterDataModel represents a sub-set of a controller's data model. Enough to validate an identities access to dial/bind @@ -182,6 +182,38 @@ func NewReceiverRouterDataModel(listenerBufferSize uint, closeNotify <-chan stru return result } +// NewReceiverRouterDataModelFromDataState creates a new RouterDataModel that does not store events. listenerBufferSize affects the +// buffer size of channels returned to listeners of the data model. +func NewReceiverRouterDataModelFromDataState(dataState *edge_ctrl_pb.DataState, listenerBufferSize uint, closeNotify <-chan struct{}) *RouterDataModel { + result := &RouterDataModel{ + EventCache: NewForgetfulEventCache(), + ConfigTypes: cmap.New[*ConfigType](), + Configs: cmap.New[*Config](), + Identities: cmap.New[*Identity](), + Services: cmap.New[*Service](), + ServicePolicies: cmap.New[*ServicePolicy](), + PostureChecks: cmap.New[*PostureCheck](), + PublicKeys: cmap.New[*edge_ctrl_pb.DataState_PublicKey](), + Revocations: cmap.New[*edge_ctrl_pb.DataState_Revocation](), + listenerBufferSize: listenerBufferSize, + subscriptions: cmap.New[*IdentitySubscription](), + events: make(chan subscriberEvent), + closeNotify: closeNotify, + stopNotify: make(chan struct{}), + } + + go result.processSubscriberEvents() + + result.WhileLocked(func(u uint64, b bool) { + for _, event := range dataState.Events { + result.Handle(dataState.EndIndex, event) + } + result.SetCurrentIndex(dataState.EndIndex) + }) + + return result +} + // NewReceiverRouterDataModel creates a new RouterDataModel that does not store events. listenerBufferSize affects the // buffer size of channels returned to listeners of the data model. func NewReceiverRouterDataModelFromExisting(existing *RouterDataModel, listenerBufferSize uint, closeNotify <-chan struct{}) *RouterDataModel { @@ -228,19 +260,15 @@ func NewReceiverRouterDataModelFromFile(path string, listenerBufferSize uint, cl return nil, err } - rdmContents := &rdmDb{ - RouterDataModel: NewReceiverRouterDataModel(listenerBufferSize, closeNotify), - } - - err = json.Unmarshal(data, rdmContents) - if err != nil { - rdmContents.RouterDataModel.Stop() + state := &edge_ctrl_pb.DataState{} + if err = proto.Unmarshal(data, state); err != nil { return nil, err } - rdmContents.RouterDataModel.lastSaveIndex = &rdmContents.Index + rdm := NewReceiverRouterDataModelFromDataState(state, listenerBufferSize, closeNotify) + rdm.lastSaveIndex = &state.EndIndex - return rdmContents.RouterDataModel, nil + return rdm, nil } func (rdm *RouterDataModel) processSubscriberEvents() { @@ -374,7 +402,7 @@ func (rdm *RouterDataModel) HandleIdentityEvent(index uint64, event *edge_ctrl_p if valueInMap == nil { identity = &Identity{ DataStateIdentity: model.Identity, - ServicePolicies: concurrenz.NewSyncSet[string](), + ServicePolicies: cmap.New[struct{}](), identityIndex: index, } } else { @@ -447,8 +475,8 @@ func (rdm *RouterDataModel) applyUpdateServicePolicyEvent(model *edge_ctrl_pb.Da if valueInMap == nil { return &ServicePolicy{ DataStateServicePolicy: servicePolicy, - Services: concurrenz.NewSyncSet[string](), - PostureChecks: concurrenz.NewSyncSet[string](), + Services: cmap.New[struct{}](), + PostureChecks: cmap.New[struct{}](), } } else { return &ServicePolicy{ @@ -529,7 +557,7 @@ func (rdm *RouterDataModel) HandleServicePolicyChange(index uint64, model *edge_ rdm.Identities.Upsert(identityId, nil, func(exist bool, valueInMap *Identity, newValue *Identity) *Identity { if valueInMap != nil { if model.Add { - valueInMap.ServicePolicies.Add(model.PolicyId) + valueInMap.ServicePolicies.Set(model.PolicyId, struct{}{}) } else { valueInMap.ServicePolicies.Remove(model.PolicyId) } @@ -554,7 +582,7 @@ func (rdm *RouterDataModel) HandleServicePolicyChange(index uint64, model *edge_ case edge_ctrl_pb.ServicePolicyRelatedEntityType_RelatedService: if model.Add { for _, serviceId := range model.RelatedEntityIds { - valueInMap.Services.Add(serviceId) + valueInMap.Services.Set(serviceId, struct{}{}) } } else { for _, serviceId := range model.RelatedEntityIds { @@ -564,7 +592,7 @@ func (rdm *RouterDataModel) HandleServicePolicyChange(index uint64, model *edge_ case edge_ctrl_pb.ServicePolicyRelatedEntityType_RelatedPostureCheck: if model.Add { for _, postureCheckId := range model.RelatedEntityIds { - valueInMap.PostureChecks.Add(postureCheckId) + valueInMap.PostureChecks.Set(postureCheckId, struct{}{}) } } else { for _, postureCheckId := range model.RelatedEntityIds { @@ -615,131 +643,135 @@ func (rdm *RouterDataModel) recalculateCachedPublicKeys() { } func (rdm *RouterDataModel) GetDataState() *edge_ctrl_pb.DataState { + var result *edge_ctrl_pb.DataState + rdm.EventCache.WhileLocked(func(currentIndex uint64, _ bool) { + result = rdm.getDataStateAlreadyLocked(currentIndex) + }) + return result +} + +func (rdm *RouterDataModel) getDataStateAlreadyLocked(index uint64) *edge_ctrl_pb.DataState { var events []*edge_ctrl_pb.DataState_Event - var index uint64 - rdm.EventCache.WhileLocked(func(currentIndex uint64, _ bool) { - index = currentIndex - rdm.ConfigTypes.IterCb(func(key string, v *ConfigType) { - newEvent := &edge_ctrl_pb.DataState_Event{ - Action: edge_ctrl_pb.DataState_Create, - Model: &edge_ctrl_pb.DataState_Event_ConfigType{ - ConfigType: v.DataStateConfigType, - }, - } - events = append(events, newEvent) - }) + rdm.ConfigTypes.IterCb(func(key string, v *ConfigType) { + newEvent := &edge_ctrl_pb.DataState_Event{ + Action: edge_ctrl_pb.DataState_Create, + Model: &edge_ctrl_pb.DataState_Event_ConfigType{ + ConfigType: v.DataStateConfigType, + }, + } + events = append(events, newEvent) + }) - rdm.Configs.IterCb(func(key string, v *Config) { - newEvent := &edge_ctrl_pb.DataState_Event{ - Action: edge_ctrl_pb.DataState_Create, - Model: &edge_ctrl_pb.DataState_Event_Config{ - Config: v.DataStateConfig, - }, - } - events = append(events, newEvent) - }) + rdm.Configs.IterCb(func(key string, v *Config) { + newEvent := &edge_ctrl_pb.DataState_Event{ + Action: edge_ctrl_pb.DataState_Create, + Model: &edge_ctrl_pb.DataState_Event_Config{ + Config: v.DataStateConfig, + }, + } + events = append(events, newEvent) + }) - servicePolicyIdentities := map[string]*edge_ctrl_pb.DataState_ServicePolicyChange{} + servicePolicyIdentities := map[string]*edge_ctrl_pb.DataState_ServicePolicyChange{} - rdm.Identities.IterCb(func(key string, v *Identity) { - newEvent := &edge_ctrl_pb.DataState_Event{ - Action: edge_ctrl_pb.DataState_Create, - Model: &edge_ctrl_pb.DataState_Event_Identity{ - Identity: v.DataStateIdentity, - }, - } - events = append(events, newEvent) - - v.ServicePolicies.RangeAll(func(policyId string) { - change := servicePolicyIdentities[policyId] - if change == nil { - change = &edge_ctrl_pb.DataState_ServicePolicyChange{ - PolicyId: policyId, - RelatedEntityType: edge_ctrl_pb.ServicePolicyRelatedEntityType_RelatedIdentity, - Add: true, - } - servicePolicyIdentities[policyId] = change + rdm.Identities.IterCb(func(key string, v *Identity) { + newEvent := &edge_ctrl_pb.DataState_Event{ + Action: edge_ctrl_pb.DataState_Create, + Model: &edge_ctrl_pb.DataState_Event_Identity{ + Identity: v.DataStateIdentity, + }, + } + events = append(events, newEvent) + + v.ServicePolicies.IterCb(func(policyId string, _ struct{}) { + change := servicePolicyIdentities[policyId] + if change == nil { + change = &edge_ctrl_pb.DataState_ServicePolicyChange{ + PolicyId: policyId, + RelatedEntityType: edge_ctrl_pb.ServicePolicyRelatedEntityType_RelatedIdentity, + Add: true, } - change.RelatedEntityIds = append(change.RelatedEntityIds, v.Id) - }) - }) - - rdm.Services.IterCb(func(key string, v *Service) { - newEvent := &edge_ctrl_pb.DataState_Event{ - Action: edge_ctrl_pb.DataState_Create, - Model: &edge_ctrl_pb.DataState_Event_Service{ - Service: v.DataStateService, - }, + servicePolicyIdentities[policyId] = change } - events = append(events, newEvent) + change.RelatedEntityIds = append(change.RelatedEntityIds, v.Id) }) + }) - rdm.PostureChecks.IterCb(func(key string, v *PostureCheck) { - newEvent := &edge_ctrl_pb.DataState_Event{ - Action: edge_ctrl_pb.DataState_Create, - Model: &edge_ctrl_pb.DataState_Event_PostureCheck{ - PostureCheck: v.DataStatePostureCheck, - }, - } - events = append(events, newEvent) - }) + rdm.Services.IterCb(func(key string, v *Service) { + newEvent := &edge_ctrl_pb.DataState_Event{ + Action: edge_ctrl_pb.DataState_Create, + Model: &edge_ctrl_pb.DataState_Event_Service{ + Service: v.DataStateService, + }, + } + events = append(events, newEvent) + }) - rdm.ServicePolicies.IterCb(func(key string, v *ServicePolicy) { - newEvent := &edge_ctrl_pb.DataState_Event{ - Action: edge_ctrl_pb.DataState_Create, - Model: &edge_ctrl_pb.DataState_Event_ServicePolicy{ - ServicePolicy: v.DataStateServicePolicy, - }, - } - events = append(events, newEvent) + rdm.PostureChecks.IterCb(func(key string, v *PostureCheck) { + newEvent := &edge_ctrl_pb.DataState_Event{ + Action: edge_ctrl_pb.DataState_Create, + Model: &edge_ctrl_pb.DataState_Event_PostureCheck{ + PostureCheck: v.DataStatePostureCheck, + }, + } + events = append(events, newEvent) + }) - addServicesChange := &edge_ctrl_pb.DataState_ServicePolicyChange{ - PolicyId: v.Id, - RelatedEntityType: edge_ctrl_pb.ServicePolicyRelatedEntityType_RelatedService, - Add: true, - } - v.Services.RangeAll(func(serviceId string) { - addServicesChange.RelatedEntityIds = append(addServicesChange.RelatedEntityIds, serviceId) - }) - events = append(events, &edge_ctrl_pb.DataState_Event{ - Model: &edge_ctrl_pb.DataState_Event_ServicePolicyChange{ - ServicePolicyChange: addServicesChange, - }, - }) + rdm.ServicePolicies.IterCb(func(key string, v *ServicePolicy) { + newEvent := &edge_ctrl_pb.DataState_Event{ + Action: edge_ctrl_pb.DataState_Create, + Model: &edge_ctrl_pb.DataState_Event_ServicePolicy{ + ServicePolicy: v.DataStateServicePolicy, + }, + } + events = append(events, newEvent) - addPostureCheckChanges := &edge_ctrl_pb.DataState_ServicePolicyChange{ - PolicyId: v.Id, - RelatedEntityType: edge_ctrl_pb.ServicePolicyRelatedEntityType_RelatedPostureCheck, - Add: true, - } - v.PostureChecks.RangeAll(func(postureCheckId string) { - addPostureCheckChanges.RelatedEntityIds = append(addPostureCheckChanges.RelatedEntityIds, postureCheckId) - }) + addServicesChange := &edge_ctrl_pb.DataState_ServicePolicyChange{ + PolicyId: v.Id, + RelatedEntityType: edge_ctrl_pb.ServicePolicyRelatedEntityType_RelatedService, + Add: true, + } + v.Services.IterCb(func(serviceId string, _ struct{}) { + addServicesChange.RelatedEntityIds = append(addServicesChange.RelatedEntityIds, serviceId) + }) + events = append(events, &edge_ctrl_pb.DataState_Event{ + Model: &edge_ctrl_pb.DataState_Event_ServicePolicyChange{ + ServicePolicyChange: addServicesChange, + }, + }) + + addPostureCheckChanges := &edge_ctrl_pb.DataState_ServicePolicyChange{ + PolicyId: v.Id, + RelatedEntityType: edge_ctrl_pb.ServicePolicyRelatedEntityType_RelatedPostureCheck, + Add: true, + } + v.PostureChecks.IterCb(func(postureCheckId string, _ struct{}) { + addPostureCheckChanges.RelatedEntityIds = append(addPostureCheckChanges.RelatedEntityIds, postureCheckId) + }) + events = append(events, &edge_ctrl_pb.DataState_Event{ + Model: &edge_ctrl_pb.DataState_Event_ServicePolicyChange{ + ServicePolicyChange: addPostureCheckChanges, + }, + }) + + if addIdentityChanges, found := servicePolicyIdentities[v.Id]; found { events = append(events, &edge_ctrl_pb.DataState_Event{ Model: &edge_ctrl_pb.DataState_Event_ServicePolicyChange{ - ServicePolicyChange: addPostureCheckChanges, + ServicePolicyChange: addIdentityChanges, }, }) + } + }) - if addIdentityChanges, found := servicePolicyIdentities[v.Id]; found { - events = append(events, &edge_ctrl_pb.DataState_Event{ - Model: &edge_ctrl_pb.DataState_Event_ServicePolicyChange{ - ServicePolicyChange: addIdentityChanges, - }, - }) - } - }) - - rdm.PublicKeys.IterCb(func(key string, v *edge_ctrl_pb.DataState_PublicKey) { - newEvent := &edge_ctrl_pb.DataState_Event{ - Action: edge_ctrl_pb.DataState_Create, - Model: &edge_ctrl_pb.DataState_Event_PublicKey{ - PublicKey: v, - }, - } - events = append(events, newEvent) - }) + rdm.PublicKeys.IterCb(func(key string, v *edge_ctrl_pb.DataState_PublicKey) { + newEvent := &edge_ctrl_pb.DataState_Event{ + Action: edge_ctrl_pb.DataState_Create, + Model: &edge_ctrl_pb.DataState_Event_PublicKey{ + PublicKey: v, + }, + } + events = append(events, newEvent) }) return &edge_ctrl_pb.DataState{ @@ -748,12 +780,6 @@ func (rdm *RouterDataModel) GetDataState() *edge_ctrl_pb.DataState { } } -// rdmDb is a helper structure of serializing router data models to JSON gzipped files. -type rdmDb struct { - RouterDataModel *RouterDataModel `json:"model"` - Index uint64 `json:"index"` -} - func (rdm *RouterDataModel) Save(path string) { rdm.EventCache.WhileLocked(func(index uint64, indexInitialized bool) { if !indexInitialized { @@ -761,20 +787,14 @@ func (rdm *RouterDataModel) Save(path string) { return } - //nothing to save + // nothing to save if rdm.lastSaveIndex != nil && *rdm.lastSaveIndex == index { pfxlog.Logger().Debug("no changes to router model, nothing to save") return } - rdm.lastSaveIndex = &index - - rdmFile := rdmDb{ - RouterDataModel: rdm, - Index: index, - } - - jsonBytes, err := json.Marshal(rdmFile) + state := rdm.getDataStateAlreadyLocked(index) + stateBytes, err := proto.Marshal(state) if err != nil { pfxlog.Logger().WithError(err).Error("could not marshal router data model") @@ -793,13 +813,15 @@ func (rdm *RouterDataModel) Save(path string) { gz := gzip.NewWriter(file) defer func() { _ = gz.Close() }() - // Write the gzipped JSON data to the file - _, err = gz.Write(jsonBytes) + // Write the gzipped protobuf data to the file + _, err = gz.Write(stateBytes) if err != nil { pfxlog.Logger().WithError(err).Error("could not marshal router data model, could not compress and write") return } + + rdm.lastSaveIndex = &index }) } @@ -821,13 +843,13 @@ func (rdm *RouterDataModel) GetServiceAccessPolicies(identityId string, serviceI postureChecks := map[string]*edge_ctrl_pb.DataState_PostureCheck{} - identity.ServicePolicies.RangeAll(func(servicePolicyId string) { + identity.ServicePolicies.IterCb(func(servicePolicyId string, _ struct{}) { servicePolicy, ok := rdm.ServicePolicies.Get(servicePolicyId) if ok && servicePolicy.PolicyType != policyType { policies = append(policies, servicePolicy) - servicePolicy.PostureChecks.RangeAll(func(postureCheckId string) { + servicePolicy.PostureChecks.IterCb(func(postureCheckId string, _ struct{}) { if _, ok := postureChecks[postureCheckId]; !ok { //ignore ok, if !ok postureCheck == nil which will trigger //failure during evaluation @@ -892,14 +914,14 @@ func (rdm *RouterDataModel) buildServiceList(sub *IdentitySubscription) (map[str services := map[string]*IdentityService{} postureChecks := map[string]*PostureCheck{} - sub.Identity.ServicePolicies.RangeAll(func(policyId string) { + sub.Identity.ServicePolicies.IterCb(func(policyId string, _ struct{}) { policy, ok := rdm.ServicePolicies.Get(policyId) if !ok { log.WithField("policyId", policyId).Error("could not find service policy") return } - policy.Services.RangeAll(func(serviceId string) { + policy.Services.IterCb(func(serviceId string, _ struct{}) { service, ok := rdm.Services.Get(serviceId) if !ok { log.WithField("policyId", policyId). @@ -937,7 +959,7 @@ func (rdm *RouterDataModel) loadServicePostureChecks(identity *Identity, policy WithField("serviceId", svc.Service.Id). WithField("policyId", policy.Id) - policy.PostureChecks.RangeAll(func(postureCheckId string) { + policy.PostureChecks.IterCb(func(postureCheckId string, _ struct{}) { check, ok := rdm.PostureChecks.Get(postureCheckId) if !ok { log.WithField("postureCheckId", postureCheckId).Error("could not find posture check") @@ -1102,8 +1124,8 @@ func diffType[P any, T *P](entityType string, m1 cmap.ConcurrentMap[string, T], hasMissing := false adapter := cmp.Reporter(diffReporter) - syncSetT := cmp.Transformer("syncSetToMap", func(s *concurrenz.SyncSet[string]) map[string]struct{} { - return s.ToMap() + syncSetT := cmp.Transformer("syncSetToMap", func(s cmap.ConcurrentMap[string, struct{}]) map[string]struct{} { + return CMapToMap(s) }) m1.IterCb(func(key string, v T) { v2, exists := m2.Get(key) @@ -1125,6 +1147,14 @@ func diffType[P any, T *P](entityType string, m1 cmap.ConcurrentMap[string, T], } } +func CMapToMap[T any](m cmap.ConcurrentMap[string, T]) map[string]T { + result := map[string]T{} + m.IterCb(func(key string, val T) { + result[key] = val + }) + return result +} + type compareReporter struct { steps []cmp.PathStep key string diff --git a/common/subscriber.go b/common/subscriber.go index b0a7a79c0..bc3be9322 100644 --- a/common/subscriber.go +++ b/common/subscriber.go @@ -22,6 +22,7 @@ import ( "github.com/michaelquigley/pfxlog" "github.com/openziti/foundation/v2/concurrenz" "github.com/openziti/ziti/common/pb/edge_ctrl_pb" + cmap "github.com/orcaman/concurrent-map/v2" "sync" ) @@ -107,8 +108,8 @@ func (self *IdentitySubscription) Diff(rdm *RouterDataModel, sink DiffSink) { } adapter := cmp.Reporter(diffReporter) - syncSetT := cmp.Transformer("syncSetToMap", func(s *concurrenz.SyncSet[string]) map[string]struct{} { - return s.ToMap() + syncSetT := cmp.Transformer("syncSetToMap", func(s cmap.ConcurrentMap[string, struct{}]) map[string]struct{} { + return CMapToMap(s) }) cmp.Diff(currentState, self, syncSetT, cmpopts.IgnoreUnexported( sync.Mutex{}, IdentitySubscription{}, IdentityService{}, diff --git a/controller/handler_mgmt/validate_router_data_model.go b/controller/handler_mgmt/validate_router_data_model.go index f3f1f7b8d..0a6f8ca2d 100644 --- a/controller/handler_mgmt/validate_router_data_model.go +++ b/controller/handler_mgmt/validate_router_data_model.go @@ -56,7 +56,7 @@ func (handler *validateRouterDataModelHandler) HandleReceive(msg *channel.Messag var count int64 var evalF func() if err = proto.Unmarshal(msg.Body, request); err == nil { - count, evalF, err = handler.ValidateRouterDataModel(request.ValidateCtrl, request.RouterFilter, func(detail *mgmt_pb.RouterDataModelDetails) { + count, evalF, err = handler.ValidateRouterDataModel(request, func(detail *mgmt_pb.RouterDataModelDetails) { if !ch.IsClosed() { if sendErr := protobufs.MarshalTyped(detail).WithTimeout(15 * time.Second).SendAndWaitForWire(ch); sendErr != nil { log.WithError(sendErr).Error("send of router data model detail failed, closing channel") @@ -100,8 +100,8 @@ func (handler *validateRouterDataModelHandler) HandleReceive(msg *channel.Messag type RouterDataModelValidationCallback func(detail *mgmt_pb.RouterDataModelDetails) -func (handler *validateRouterDataModelHandler) ValidateRouterDataModel(includeCtrl bool, filter string, cb RouterDataModelValidationCallback) (int64, func(), error) { - result, err := handler.appEnv.Managers.Router.BaseList(filter) +func (handler *validateRouterDataModelHandler) ValidateRouterDataModel(req *mgmt_pb.ValidateRouterDataModelRequest, cb RouterDataModelValidationCallback) (int64, func(), error) { + result, err := handler.appEnv.Managers.Router.BaseList(req.RouterFilter) if err != nil { return 0, nil, err } @@ -109,7 +109,7 @@ func (handler *validateRouterDataModelHandler) ValidateRouterDataModel(includeCt sem := concurrenz.NewSemaphore(10) evalF := func() { - if includeCtrl { + if req.ValidateCtrl { sem.Acquire() go func() { defer sem.Release() @@ -141,7 +141,7 @@ func (handler *validateRouterDataModelHandler) ValidateRouterDataModel(includeCt sem.Acquire() go func() { defer sem.Release() - handler.ValidateRouterDataModelOnRouter(connectedRouter, dataState, cb) + handler.ValidateRouterDataModelOnRouter(connectedRouter, dataState, req.Fix, cb) }() } else { details := &mgmt_pb.RouterDataModelDetails{ @@ -157,14 +157,19 @@ func (handler *validateRouterDataModelHandler) ValidateRouterDataModel(includeCt } count := int64(len(result.Entities)) - if includeCtrl { + if req.ValidateCtrl { count++ } return count, evalF, nil } -func (handler *validateRouterDataModelHandler) ValidateRouterDataModelOnRouter(router *model.Router, dataState *edge_ctrl_pb.DataState, cb RouterDataModelValidationCallback) { +func (handler *validateRouterDataModelHandler) ValidateRouterDataModelOnRouter( + router *model.Router, + dataState *edge_ctrl_pb.DataState, + fix bool, + cb RouterDataModelValidationCallback) { + details := &mgmt_pb.RouterDataModelDetails{ ComponentType: "router", ComponentId: router.Id, @@ -173,7 +178,9 @@ func (handler *validateRouterDataModelHandler) ValidateRouterDataModelOnRouter(r request := &edge_ctrl_pb.RouterDataModelValidateRequest{ State: dataState, + Fix: fix, } + resp := &edge_ctrl_pb.RouterDataModelValidateResponse{} respMsg, err := protobufs.MarshalTyped(request).WithTimeout(time.Minute).SendForReply(router.Control) if err = protobufs.TypedResponse(resp).Unmarshall(respMsg, err); err != nil { diff --git a/controller/sync_strats/rtx.go b/controller/sync_strats/rtx.go index 4799dacad..5ffc5a919 100644 --- a/controller/sync_strats/rtx.go +++ b/controller/sync_strats/rtx.go @@ -175,7 +175,10 @@ func (rtx *RouterSender) handleSyncRequest(req *edge_ctrl_pb.SubscribeToDataMode rtx.syncRdmUntil = time.Now().Add(time.Duration(req.SubscriptionDurationSeconds) * time.Second) pfxlog.Logger().WithField("routerId", rtx.Router.Id). + WithField("routerName", rtx.Router.Name). + WithField("requestedIndex", req.CurrentIndex). WithField("currentIndex", rtx.currentIndex). + WithField("renew", req.Renew). WithField("subscriptionDuration", rtx.syncRdmUntil.String()). Info("data model subscription started") @@ -197,9 +200,9 @@ func (rtx *RouterSender) handleModelChange() { var err error - if ok { - logger.Infof("event retrieval ok? %v, event count: %d for replay to router", ok, len(events)) + logger.Infof("event retrieval ok? %v, event count: %d for replay to router", ok, len(events)) + if ok { for _, curEvent := range events { if err = protobufs.MarshalTyped(curEvent).Send(rtx.Router.Control); err != nil { logger.WithError(err). diff --git a/controller/sync_strats/sync_instant.go b/controller/sync_strats/sync_instant.go index 93e1fecae..1f293b058 100644 --- a/controller/sync_strats/sync_instant.go +++ b/controller/sync_strats/sync_instant.go @@ -1059,9 +1059,7 @@ func (strategy *InstantStrategy) ValidateIdentities(tx *bbolt.Tx, rdm *common.Ro policyList := strategy.ae.GetStores().Identity.GetRelatedEntitiesIdList(tx, t.Id, db.EntityTypeServicePolicies) policySet := genext.SliceToSet(policyList) - v.ServicePolicies.WithReadLock(func(m map[string]struct{}) { - result = diffSets("identity", t.Id, "service policy", policySet, m, result) - }) + result = diffSets("identity", t.Id, "service policy", policySet, common.CMapToMap(v.ServicePolicies), result) return result }) @@ -1161,16 +1159,12 @@ func (strategy *InstantStrategy) ValidateServicePolicies(tx *bbolt.Tx, rdm *comm policyList := strategy.ae.GetStores().ServicePolicy.GetRelatedEntitiesIdList(tx, t.Id, db.EntityTypeServices) policySet := genext.SliceToSet(policyList) - v.Services.WithReadLock(func(m map[string]struct{}) { - result = diffSets("service policy", t.Id, "service", policySet, m, result) - }) + result = diffSets("service policy", t.Id, "service", policySet, common.CMapToMap(v.Services), result) policyList = strategy.ae.GetStores().ServicePolicy.GetRelatedEntitiesIdList(tx, t.Id, db.EntityTypePostureChecks) policySet = genext.SliceToSet(policyList) - v.PostureChecks.WithReadLock(func(m map[string]struct{}) { - result = diffSets("service policy", t.Id, "posture check", policySet, m, result) - }) + result = diffSets("service policy", t.Id, "posture check", policySet, common.CMapToMap(v.PostureChecks), result) return result }) diff --git a/router/env/ctrl.go b/router/env/ctrl.go index acd308c4d..b52b73ff3 100644 --- a/router/env/ctrl.go +++ b/router/env/ctrl.go @@ -38,6 +38,16 @@ type NetworkController interface { updateDataModelIndex(index uint64) } +func newNetworkCtrl(ch channel.Channel, address string, heartbeatOptions *HeartbeatOptions) *networkCtrl { + result := &networkCtrl{ + ch: ch, + address: address, + heartbeatOptions: heartbeatOptions, + } + result.lastContact.Store(time.Now().UnixMilli()) + return result +} + type networkCtrl struct { ch channel.Channel address string diff --git a/router/env/ctrls.go b/router/env/ctrls.go index c5045b03c..954bab509 100644 --- a/router/env/ctrls.go +++ b/router/env/ctrls.go @@ -47,9 +47,9 @@ func (self CtrlEventListenerFunc) NotifyOfCtrlEvent(event CtrlEvent) { type CtrlEventType string const ( - ControllerAdded CtrlEventType = "ADDED" - ControllerReconnected CtrlEventType = "ADDED" - ControllerRemoved CtrlEventType = "ADDED" + ControllerAdded CtrlEventType = "Added" + ControllerReconnected CtrlEventType = "Reconnected" + ControllerRemoved CtrlEventType = "Removed" ) type CtrlEvent struct { @@ -191,11 +191,7 @@ func (self *networkControllers) connectToControllerWithBackoff(endpoint string) } func (self *networkControllers) Add(address string, ch channel.Channel) error { - ctrl := &networkCtrl{ - ch: ch, - address: address, - heartbeatOptions: self.heartbeatOptions, - } + ctrl := newNetworkCtrl(ch, address, self.heartbeatOptions) if versionValue, found := ch.Underlay().Headers()[channel.HelloVersionHeader]; found { if versionInfo, err := versions.StdVersionEncDec.Decode(versionValue); err == nil { diff --git a/router/internal/edgerouter/config.go b/router/internal/edgerouter/config.go index cf24c1b48..b6ed2364a 100644 --- a/router/internal/edgerouter/config.go +++ b/router/internal/edgerouter/config.go @@ -117,12 +117,12 @@ func (config *Config) LoadConfigFromMap(configMap map[interface{}]interface{}) e } if config.Db == "" { - config.Db = "./db.json.gzip" + config.Db = "./db.proto.gzip" if value, found := configMap[router.PathMapKey]; found { configPath := value.(string) configPath = strings.TrimSpace(configPath) - config.Db = configPath + ".json.gzip" + config.Db = configPath + ".proto.gzip" } else { pfxlog.Logger().Warnf("the db property was not set, using default for cached data model: %s", config.Db) } diff --git a/router/posture/access.go b/router/posture/access.go index 58b087344..8ee78d9db 100644 --- a/router/posture/access.go +++ b/router/posture/access.go @@ -43,7 +43,7 @@ func IsPassing(accessPolicies *common.AccessPolicies, cache *Cache) (*common.Ser Errors: []error{}, } - policy.PostureChecks.RangeAll(func(postureCheckId string) { + policy.PostureChecks.IterCb(func(postureCheckId string, _ struct{}) { postureCheck, ok := accessPolicies.PostureChecks[postureCheckId] if !ok || postureCheck == nil { diff --git a/router/state/dataState.go b/router/state/dataState.go index 7f9177bcb..3dec09f19 100644 --- a/router/state/dataState.go +++ b/router/state/dataState.go @@ -40,17 +40,11 @@ func (self *DataStateHandler) HandleReceive(msg *channel.Message, ch channel.Cha return } - model := common.NewReceiverRouterDataModel(RouterDataModelListerBufferSize, self.state.GetEnv().GetCloseNotify()) - logger.WithField("index", newState.EndIndex).Info("received full router data model state") - model.WhileLocked(func(u uint64, b bool) { - for _, event := range newState.Events { - model.Handle(newState.EndIndex, event) - } - model.SetCurrentIndex(newState.EndIndex) - }) - - self.state.SetRouterDataModel(model) + + model := common.NewReceiverRouterDataModelFromDataState(newState, RouterDataModelListerBufferSize, self.state.GetEnv().GetCloseNotify()) + self.state.SetRouterDataModel(model, false) + logger.WithField("index", newState.EndIndex).Info("finished processing full router data model state") }) diff --git a/router/state/dataStateChangeSetEvent.go b/router/state/dataStateChangeSetEvent.go index 12cda7a25..450eb7528 100644 --- a/router/state/dataStateChangeSetEvent.go +++ b/router/state/dataStateChangeSetEvent.go @@ -19,9 +19,18 @@ func NewDataStateEventHandler(state Manager) channel.TypedReceiveHandler { } func (eventHandler *dataStateChangeSetHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { - logger := pfxlog.Logger().WithField("ctrlId", ch.Id()) currentCtrlId := eventHandler.state.GetCurrentDataModelSource() + logger := pfxlog.Logger().WithField("ctrlId", ch.Id()) + + newEvent := &edge_ctrl_pb.DataState_ChangeSet{} + if err := proto.Unmarshal(msg.Body, newEvent); err != nil { + logger.WithError(err).Errorf("could not unmarshal data state change set message") + return + } + + logger = logger.WithField("index", newEvent.Index).WithField("synthetic", newEvent.IsSynthetic) + // ignore state from controllers we are not currently subscribed to if currentCtrlId != ch.Id() { logger.WithField("dataModelSrcId", currentCtrlId).Info("data state received from ctrl other than the one currently subscribed to") @@ -29,19 +38,13 @@ func (eventHandler *dataStateChangeSetHandler) HandleReceive(msg *channel.Messag } err := eventHandler.state.GetRouterDataModelPool().Queue(func() { - newEvent := &edge_ctrl_pb.DataState_ChangeSet{} - if err := proto.Unmarshal(msg.Body, newEvent); err != nil { - pfxlog.Logger().WithError(err).Errorf("could not marshal data state change set message") - return - } - model := eventHandler.state.RouterDataModel() - pfxlog.Logger().WithField("index", newEvent.Index).Info("received data state change set") + logger.Info("received data state change set") model.ApplyChangeSet(newEvent) }) if err != nil { - pfxlog.Logger().WithError(err).Errorf("could not queue processing data state change set message") + logger.WithError(err).Errorf("could not queue processing data state change set message") } } diff --git a/router/state/manager.go b/router/state/manager.go index af78626e8..c755072c6 100644 --- a/router/state/manager.go +++ b/router/state/manager.go @@ -96,7 +96,7 @@ type Manager interface { ParseJwt(jwtStr string) (*jwt.Token, *common.AccessClaims, error) RouterDataModel() *common.RouterDataModel - SetRouterDataModel(model *common.RouterDataModel) + SetRouterDataModel(model *common.RouterDataModel, resetSubscription bool) GetRouterDataModelPool() goroutines.Pool StartHeartbeat(env env.RouterEnv, seconds int, closeNotify <-chan struct{}) @@ -158,6 +158,7 @@ func NewManager(stateEnv Env) Manager { env: stateEnv, routerDataModelPool: routerDataModelPool, endpointsChanged: make(chan env.CtrlEvent, 10), + modelChanged: make(chan struct{}, 1), } stateEnv.GetNetworkControllers().AddChangeListener(env.CtrlEventListenerFunc(func(event env.CtrlEvent) { @@ -197,6 +198,7 @@ type ManagerImpl struct { routerDataModelPool goroutines.Pool endpointsChanged chan env.CtrlEvent + modelChanged chan struct{} dataModelSubCtrlId concurrenz.AtomicValue[string] dataModelSubTimeout time.Time } @@ -221,10 +223,29 @@ func (self *ManagerImpl) manageRouterDataModelSubscription() { case event := <-self.endpointsChanged: // if the controller we're subscribed to has changed, resubscribe if event.Controller.Channel().Id() == self.GetCurrentDataModelSource() { + pfxlog.Logger().WithField("ctrlId", event.Controller.Channel().Id()).WithField("change", event.Type). + Info("currently subscribed controller has changed, resubscribing") self.dataModelSubCtrlId.Store("") } case <-ticker.C: + case <-self.modelChanged: } + + allEndpointChangesProcessed := false + for !allEndpointChangesProcessed { + select { + case event := <-self.endpointsChanged: + // if the controller we're subscribed to has changed, resubscribe + if event.Controller.Channel().Id() == self.GetCurrentDataModelSource() { + pfxlog.Logger().WithField("ctrlId", event.Controller.Channel().Id()).WithField("change", event.Type). + Info("currently subscribed controller has changed, resubscribing") + self.dataModelSubCtrlId.Store("") + } + default: + allEndpointChangesProcessed = true + } + } + self.checkRouterDataModelSubscription() } } @@ -233,17 +254,28 @@ func (self *ManagerImpl) checkRouterDataModelSubscription() { ctrl := self.env.GetNetworkControllers().GetNetworkController(self.dataModelSubCtrlId.Load()) if ctrl == nil || time.Now().After(self.dataModelSubTimeout) { if bestCtrl := self.env.GetNetworkControllers().AnyCtrlChannel(); bestCtrl != nil { + logger := pfxlog.Logger().WithField("ctrlId", bestCtrl.Id()).WithField("prevCtrlId", self.dataModelSubCtrlId.Load()) + if ctrl == nil { + logger.Info("no current data model subscription active, subscribing") + } else { + logger.Info("current data model subscription expired, resubscribing") + } self.subscribeToDataModelUpdates(bestCtrl) } } else if !ctrl.IsConnected() || ctrl.TimeSinceLastContact() > 30*time.Second { bestCtrl := self.env.GetNetworkControllers().AnyCtrlChannel() if bestCtrl != nil && bestCtrl.Id() != ctrl.Channel().Id() { + pfxlog.Logger().WithField("ctrlId", bestCtrl.Id()). + WithField("prevCtrlId", self.dataModelSubCtrlId.Load()). + Info("current data model subscription source unreliable, changing subscription") self.subscribeToDataModelUpdates(bestCtrl) } } } func (self *ManagerImpl) subscribeToDataModelUpdates(ch channel.Channel) { + renew := self.dataModelSubCtrlId.Load() == ch.Id() + // if we store after success, we may miss an update because the ids don't match yet self.dataModelSubCtrlId.Store(ch.Id()) @@ -256,9 +288,14 @@ func (self *ManagerImpl) subscribeToDataModelUpdates(ch channel.Channel) { req := &edge_ctrl_pb.SubscribeToDataModelRequest{ CurrentIndex: currentIndex, SubscriptionDurationSeconds: uint32(DefaultSubscriptionTimeout.Seconds()), - Renew: self.dataModelSubCtrlId.Load() == ch.Id(), + Renew: renew, } - logger := pfxlog.Logger().WithField("ctrlId", ch.Id()) + + logger := pfxlog.Logger(). + WithField("ctrlId", ch.Id()). + WithField("currentIndex", req.CurrentIndex). + WithField("renew", req.Renew) + if err := protobufs.MarshalTyped(req).WithTimeout(self.env.GetNetworkControllers().DefaultRequestTimeout()).SendAndWaitForWire(ch); err != nil { self.dataModelSubCtrlId.Store("") logger.WithError(err).Error("error to subscribing to router data model changes") @@ -341,9 +378,12 @@ func (sm *ManagerImpl) LoadRouterModel(filePath string) { pfxlog.Logger().Infof("router data model file does not exist [%s]", filePath) } model = common.NewReceiverRouterDataModel(RouterDataModelListerBufferSize, sm.env.GetCloseNotify()) + } else { + index, _ := model.CurrentIndex() + pfxlog.Logger().WithField("path", filePath).WithField("index", index).Info("loaded router model from file") } - sm.SetRouterDataModel(model) + sm.SetRouterDataModel(model, false) } func contains[T comparable](values []T, element T) bool { @@ -454,13 +494,16 @@ func (sm *ManagerImpl) RouterDataModel() *common.RouterDataModel { return sm.routerDataModel.Load() } -func (sm *ManagerImpl) SetRouterDataModel(model *common.RouterDataModel) { +func (sm *ManagerImpl) SetRouterDataModel(model *common.RouterDataModel, resetSubscription bool) { index, _ := model.CurrentIndex() logger := pfxlog.Logger().WithField("index", index) publicKeys := model.PublicKeys.Items() logger.Debugf("number of public keys in rdm: %d", len(publicKeys)) + if resetSubscription { + sm.dataModelSubCtrlId.Store("") + } logger.Info("replacing router data model") existing := sm.routerDataModel.Swap(model) if existing != nil { @@ -470,6 +513,15 @@ func (sm *ManagerImpl) SetRouterDataModel(model *common.RouterDataModel) { logger = logger.WithField("existingIndex", existingIndex) } model.SyncAllSubscribers() + + if resetSubscription { + // notify subscription manager code to resubscribe with updated model and index + select { + case sm.modelChanged <- struct{}{}: + default: + } + } + logger.Infof("router data model replacement complete, old: %p, new: %p", existing, model) } diff --git a/router/state/validate.go b/router/state/validate.go index 7a4f10185..4ab6cd533 100644 --- a/router/state/validate.go +++ b/router/state/validate.go @@ -64,7 +64,7 @@ func (self *ValidateDataStateRequestHandler) HandleReceive(msg *channel.Message, if len(response.Diffs) > 0 && request.Fix { model = common.NewReceiverRouterDataModelFromExisting(model, RouterDataModelListerBufferSize, self.state.GetEnv().GetCloseNotify()) - self.state.SetRouterDataModel(model) + self.state.SetRouterDataModel(model, true) } go func() { diff --git a/router/xgress_edge_tunnel/factory.go b/router/xgress_edge_tunnel/factory.go index 54bcf2019..d5017e71f 100644 --- a/router/xgress_edge_tunnel/factory.go +++ b/router/xgress_edge_tunnel/factory.go @@ -66,7 +66,6 @@ func (self *Factory) Enabled() bool { } func (self *Factory) BindChannel(binding channel.Binding) error { - self.serviceListHandler = handler_edge_ctrl.NewServiceListHandler(self.tunneler.servicePoller.handleServiceListUpdate) binding.AddTypedReceiveHandler(self.serviceListHandler) binding.AddReceiveHandlerF(int32(edge_ctrl_pb.ContentType_CreateTunnelTerminatorResponseType), self.tunneler.fabricProvider.HandleTunnelResponse) return nil @@ -107,6 +106,7 @@ func NewV1Factory(env env.RouterEnv, routerConfig *router.Config, stateManager s env: env, } factory.tunneler = newTunneler(factory, stateManager) + factory.serviceListHandler = handler_edge_ctrl.NewServiceListHandler(factory.tunneler.servicePoller.handleServiceListUpdate) return factory } diff --git a/ziti/cmd/fabric/validate_router_data_model.go b/ziti/cmd/fabric/validate_router_data_model.go index c7e375d44..671313f72 100644 --- a/ziti/cmd/fabric/validate_router_data_model.go +++ b/ziti/cmd/fabric/validate_router_data_model.go @@ -34,6 +34,7 @@ type validateRouterDataModelAction struct { api.Options validateController bool includeValidRouters bool + fixInvalid bool eventNotify chan *mgmt_pb.RouterDataModelDetails } @@ -56,6 +57,7 @@ func NewValidateRouterDataModelCmd(p common.OptionsProvider) *cobra.Command { action.AddCommonFlags(validateLinksCmd) validateLinksCmd.Flags().BoolVar(&action.validateController, "validate-controller", true, "Validate the router data model in the controller as well") validateLinksCmd.Flags().BoolVar(&action.includeValidRouters, "include-successes", false, "Don't hide results for successes") + validateLinksCmd.Flags().BoolVar(&action.fixInvalid, "fix", false, "Reset the data models on routers if errors are found") return validateLinksCmd } @@ -84,6 +86,7 @@ func (self *validateRouterDataModelAction) validateRouterDataModel(_ *cobra.Comm request := &mgmt_pb.ValidateRouterDataModelRequest{ RouterFilter: filter, ValidateCtrl: self.validateController, + Fix: self.fixInvalid, } responseMsg, err := protobufs.MarshalTyped(request).WithTimeout(time.Duration(self.Timeout) * time.Second).SendForReply(ch) diff --git a/zititest/go.mod b/zititest/go.mod index 78aa9d214..a0c0450c2 100644 --- a/zititest/go.mod +++ b/zititest/go.mod @@ -14,7 +14,7 @@ require ( github.com/openziti/agent v1.0.23 github.com/openziti/channel/v3 v3.0.23 github.com/openziti/edge-api v0.26.36 - github.com/openziti/fablab v0.5.72 + github.com/openziti/fablab v0.5.83 github.com/openziti/foundation/v2 v2.0.56 github.com/openziti/identity v1.0.94 github.com/openziti/sdk-golang v0.23.44 @@ -150,7 +150,7 @@ require ( github.com/openziti/ziti-db-explorer v1.1.3 // indirect github.com/parallaxsecond/parsec-client-go v0.0.0-20221025095442-f0a77d263cf9 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pkg/sftp v1.13.6 // indirect + github.com/pkg/sftp v1.13.7 // indirect github.com/pkg/term v1.2.0-beta.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect diff --git a/zititest/go.sum b/zititest/go.sum index 99e921f74..5708acbef 100644 --- a/zititest/go.sum +++ b/zititest/go.sum @@ -601,8 +601,8 @@ github.com/openziti/dilithium v0.3.5 h1:+envGNzxc3OyVPiuvtxivQmCsOjdZjtOMLpQBeMz github.com/openziti/dilithium v0.3.5/go.mod h1:XONq1iK6te/WwNzkgZHfIDHordMPqb0hMwJ8bs9EfSk= github.com/openziti/edge-api v0.26.36 h1:zy2DjmIz/B+WxPpIzhFOAxi/LhM/yeKa8s1Vz2h8cQk= github.com/openziti/edge-api v0.26.36/go.mod h1:sYHVpm26Jr1u7VooNJzTb2b2nGSlmCHMnbGC8XfWSng= -github.com/openziti/fablab v0.5.72 h1:omcV1vS8C7FS1gnEFItczq7irf/8pMnvZNg/L7M/N2Q= -github.com/openziti/fablab v0.5.72/go.mod h1:qETYWQwY7QClVPQMpB5mS7izh2Bnk3LzbhbCrprbAR0= +github.com/openziti/fablab v0.5.83 h1:O0GHGtYV56oziaPg0hPgbXcNfE+fyoKA+mmdb4xZ5/s= +github.com/openziti/fablab v0.5.83/go.mod h1:r1tz45RA2u8x1iF/tgKN+B6hSR5FBR61kaq/bCne4zc= github.com/openziti/foundation/v2 v2.0.56 h1:YXqBmkrN0fYr3TqIlWZSZGluE2QpJxlA29Z6okZyQ5I= github.com/openziti/foundation/v2 v2.0.56/go.mod h1:f12R1pwEod348qONZr6esZgackX1ScLGDcEyPF2G5/w= github.com/openziti/identity v1.0.94 h1:nF4etu/5LmOlbT24lpSKq9p+90A9jeyLr5U23LemgD4= @@ -644,8 +644,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= -github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/pkg/sftp v1.13.7 h1:uv+I3nNJvlKZIQGSr8JVQLNHFU9YhhNpvC14Y6KgmSM= +github.com/pkg/sftp v1.13.7/go.mod h1:KMKI0t3T6hfA+lTR/ssZdunHo+uwq7ghoN09/FSu3DY= github.com/pkg/term v1.2.0-beta.2 h1:L3y/h2jkuBVFdWiJvNfYfKmzcCnILw7mJWm2JQuMppw= github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -893,6 +893,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -938,6 +939,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -989,6 +991,8 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1020,6 +1024,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1095,12 +1100,18 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1112,6 +1123,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1176,6 +1190,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/zititest/models/router-data-model-test/main.go b/zititest/models/router-data-model-test/main.go index c3005255c..265df23ae 100644 --- a/zititest/models/router-data-model-test/main.go +++ b/zititest/models/router-data-model-test/main.go @@ -3,7 +3,6 @@ package main import ( "embed" _ "embed" - "fmt" "github.com/michaelquigley/pfxlog" "github.com/openziti/fablab" "github.com/openziti/fablab/kernel/lib/actions" @@ -358,20 +357,6 @@ var m = &model.Model{ }, } -func getHostNames() []string { - var result []string - for i := 0; i < 8; i++ { - for j := 0; j < 10; j++ { - result = append(result, fmt.Sprintf("host-us-%d-%d", i, j)) - if i < 6 { - result = append(result, fmt.Sprintf("host-eu-%d-%d", i, j)) - result = append(result, fmt.Sprintf("host-ap-%d-%d", i, j)) - } - } - } - return result -} - func main() { m.AddActivationActions("stop", "bootstrap") diff --git a/zititest/models/router-data-model-test/validation.go b/zititest/models/router-data-model-test/validation.go index fce2aae5f..b3f685248 100644 --- a/zititest/models/router-data-model-test/validation.go +++ b/zititest/models/router-data-model-test/validation.go @@ -164,7 +164,7 @@ func sowChaos(run model.Run) error { log = log.WithField("msg", msg) } log.Error("action failed, retrying") - time.Sleep(time.Duration(attempt*3) * time.Second) + time.Sleep(time.Duration(attempt*10) * time.Second) return parallel.ErrActionRetry } return parallel.ExecuteLabeled(tasks, 2, retryPolicy) diff --git a/zititest/models/smoke/actions/bootstrap.go b/zititest/models/smoke/actions/bootstrap.go index b29ba4af3..298e66fc3 100644 --- a/zititest/models/smoke/actions/bootstrap.go +++ b/zititest/models/smoke/actions/bootstrap.go @@ -54,8 +54,6 @@ func (a *bootstrapAction) bind(m *model.Model) model.Action { workflow.AddAction(component.Start(".ctrl")) if isHA { - workflow.AddAction(semaphore.Sleep(10 * time.Second)) - workflow.AddAction(edge.RaftJoin("ctrl1", ".ctrl")) workflow.AddAction(semaphore.Sleep(2 * time.Second)) workflow.AddAction(edge.InitRaftController("#ctrl1")) } @@ -182,7 +180,9 @@ func (a *bootstrapAction) bind(m *model.Model) model.Action { workflow.AddAction(zitilib_actions.Edge("create", "edge-router-policy", "client-routers", "--edge-router-roles", "#client", "--identity-roles", "#client")) workflow.AddAction(zitilib_actions.Edge("create", "edge-router-policy", "host-routers", "--edge-router-roles", "#host", "--identity-roles", "#host")) - workflow.AddAction(component.Stop(models.ControllerTag)) + if isHA { + workflow.AddAction(edge.RaftJoin("ctrl1", ".ctrl")) + } return workflow } diff --git a/zititest/models/smoke/configs/ctrl.yml.tmpl b/zititest/models/smoke/configs/ctrl.yml.tmpl index 5ccfb98d0..3b6f83aec 100644 --- a/zititest/models/smoke/configs/ctrl.yml.tmpl +++ b/zititest/models/smoke/configs/ctrl.yml.tmpl @@ -6,6 +6,9 @@ raft: dataDir: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/fablab/ctrldata {{else}} db: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/fablab/ctrl.db +routerDataModel: + enabled: false + {{end}} identity: diff --git a/zititest/models/smoke/smoketest.go b/zititest/models/smoke/smoketest.go index acb28e40f..5138adc14 100644 --- a/zititest/models/smoke/smoketest.go +++ b/zititest/models/smoke/smoketest.go @@ -22,7 +22,7 @@ import ( "github.com/openziti/fablab/kernel/lib/actions/component" "github.com/openziti/fablab/kernel/lib/binding" "github.com/openziti/fablab/kernel/lib/runlevel/0_infrastructure/aws_ssh_key" - semaphore0 "github.com/openziti/fablab/kernel/lib/runlevel/0_infrastructure/semaphore" + semaphore "github.com/openziti/fablab/kernel/lib/runlevel/0_infrastructure/semaphore" terraform_0 "github.com/openziti/fablab/kernel/lib/runlevel/0_infrastructure/terraform" distribution "github.com/openziti/fablab/kernel/lib/runlevel/3_distribution" "github.com/openziti/fablab/kernel/lib/runlevel/3_distribution/rsync" @@ -39,6 +39,8 @@ import ( ) const ZitiEdgeTunnelVersion = "v1.2.9" +const ZitiCtrlVersion = "1.1.15" +const ZitiRouterVersion = "1.1.15" //go:embed configs var configResource embed.FS @@ -138,7 +140,9 @@ var Model = &model.Model{ Components: model.Components{ "ctrl1": { Scope: model.Scope{Tags: model.Tags{"ctrl"}}, - Type: &zitilab.ControllerType{}, + Type: &zitilab.ControllerType{ + Version: ZitiCtrlVersion, + }, }, }, }, @@ -146,7 +150,9 @@ var Model = &model.Model{ Components: model.Components{ "ctrl2": { Scope: model.Scope{Tags: model.Tags{"ctrl", "ha"}}, - Type: &zitilab.ControllerType{}, + Type: &zitilab.ControllerType{ + Version: ZitiCtrlVersion, + }, }, }, }, @@ -156,7 +162,8 @@ var Model = &model.Model{ "router-east-1": { Scope: model.Scope{Tags: model.Tags{"edge-router", "terminator", "tunneler", "client"}}, Type: &zitilab.RouterType{ - Debug: false, + Debug: false, + Version: ZitiRouterVersion, }, }, "zcat": { @@ -170,7 +177,8 @@ var Model = &model.Model{ "router-east-2": { Scope: model.Scope{Tags: model.Tags{"edge-router", "initiator"}}, Type: &zitilab.RouterType{ - Debug: false, + Debug: false, + Version: ZitiRouterVersion, }, }, }, @@ -179,10 +187,10 @@ var Model = &model.Model{ Scope: model.Scope{Tags: model.Tags{"zet-client"}}, Components: model.Components{ "ziti-edge-tunnel-client": { - Scope: model.Scope{Tags: model.Tags{"sdk-app", "client"}}, + Scope: model.Scope{Tags: model.Tags{"sdk-app", "client", "zet"}}, Type: &zitilab.ZitiEdgeTunnelType{ Version: ZitiEdgeTunnelVersion, - VerbosityLevel: 6, + VerbosityLevel: 3, }, }, }, @@ -206,7 +214,9 @@ var Model = &model.Model{ Components: model.Components{ "ctrl3": { Scope: model.Scope{Tags: model.Tags{"ctrl", "ha"}}, - Type: &zitilab.ControllerType{}, + Type: &zitilab.ControllerType{ + Version: ZitiCtrlVersion, + }, }, }, }, @@ -216,7 +226,8 @@ var Model = &model.Model{ "router-west": { Scope: model.Scope{Tags: model.Tags{"edge-router", "tunneler", "host", "ert-host"}}, Type: &zitilab.RouterType{ - Debug: false, + Debug: false, + Version: ZitiRouterVersion, }, }, "echo-server": { @@ -240,14 +251,14 @@ var Model = &model.Model{ "ziti-edge-tunnel-host": { Components: model.Components{ "ziti-edge-tunnel-host": { - Scope: model.Scope{Tags: model.Tags{"sdk-app", "host", "zet-host"}}, + Scope: model.Scope{Tags: model.Tags{"sdk-app", "host", "zet-host", "zet"}}, Type: &zitilab.ZitiEdgeTunnelType{ Version: ZitiEdgeTunnelVersion, - VerbosityLevel: 6, + VerbosityLevel: 3, }, }, "iperf-server-zet": { - Scope: model.Scope{Tags: model.Tags{"iperf", "service", "zet"}}, + Scope: model.Scope{Tags: model.Tags{"iperf", "service"}}, Type: &zitilab.IPerfServerType{}, }, "caddy-zet": { @@ -310,7 +321,7 @@ var Model = &model.Model{ aws_ssh_key.Express(), &terraform_0.Terraform{ Retries: 3, - ReadyCheck: &semaphore0.ReadyStage{ + ReadyCheck: &semaphore.ReadyStage{ MaxWait: 90 * time.Second, }, },