From 83d73eb19aa0098041bcaf211adb86487fa8931c Mon Sep 17 00:00:00 2001 From: Paul Lorenz Date: Wed, 20 Nov 2024 11:08:51 -0500 Subject: [PATCH 1/2] Add router data model chaos test. Fixes #2550 --- common/pb/edge_ctrl_pb/edge_ctrl.pb.go | 943 ++++++++++++------ common/pb/edge_ctrl_pb/edge_ctrl.proto | 20 + common/pb/edge_ctrl_pb/impl.go | 16 + common/router_data_model.go | 152 +++ controller/env/broker.go | 6 + controller/env/sync.go | 2 + controller/handler_mgmt/bind.go | 6 +- .../validate_router_data_model.go | 47 +- controller/sync_strats/sync_instant.go | 4 + router/state/manager.go | 2 + router/state/validate.go | 77 ++ zititest/models/links-test/validation.go | 2 +- .../configs/ctrl.yml.tmpl | 201 ++++ .../configs/router.yml.tmpl | 81 ++ .../models/router-data-model-test/main.go | 398 ++++++++ .../router-data-model-test/validation.go | 468 +++++++++ .../models/sdk-hosting-test/validation.go | 2 +- zititest/models/sdk-status-test/validation.go | 2 +- zititest/zitilab/chaos/chaos.go | 12 +- zititest/zitilab/models/api.go | 213 ++++ 20 files changed, 2313 insertions(+), 341 deletions(-) create mode 100644 router/state/validate.go create mode 100644 zititest/models/router-data-model-test/configs/ctrl.yml.tmpl create mode 100644 zititest/models/router-data-model-test/configs/router.yml.tmpl create mode 100644 zititest/models/router-data-model-test/main.go create mode 100644 zititest/models/router-data-model-test/validation.go create mode 100644 zititest/zitilab/models/api.go diff --git a/common/pb/edge_ctrl_pb/edge_ctrl.pb.go b/common/pb/edge_ctrl_pb/edge_ctrl.pb.go index b97284919..4dfb65f73 100644 --- a/common/pb/edge_ctrl_pb/edge_ctrl.pb.go +++ b/common/pb/edge_ctrl_pb/edge_ctrl.pb.go @@ -75,6 +75,8 @@ const ( ContentType_DataStateType ContentType = 20500 ContentType_DataStateChangeSetType ContentType = 20501 ContentType_UpdateTokenType ContentType = 20502 + ContentType_ValidateDataStateRequestType ContentType = 20503 + ContentType_ValidateDataStateResponseType ContentType = 20504 ) // Enum value maps for ContentType. @@ -129,6 +131,8 @@ var ( 20500: "DataStateType", 20501: "DataStateChangeSetType", 20502: "UpdateTokenType", + 20503: "ValidateDataStateRequestType", + 20504: "ValidateDataStateResponseType", } ContentType_value = map[string]int32{ "Zero": 0, @@ -180,6 +184,8 @@ var ( "DataStateType": 20500, "DataStateChangeSetType": 20501, "UpdateTokenType": 20502, + "ValidateDataStateRequestType": 20503, + "ValidateDataStateResponseType": 20504, } ) @@ -3651,6 +3657,195 @@ func (x *ConnectEvents) GetFullState() bool { return false } +type RouterDataModelValidateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + State *DataState `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` + Fix bool `protobuf:"varint,2,opt,name=fix,proto3" json:"fix,omitempty"` +} + +func (x *RouterDataModelValidateRequest) Reset() { + *x = RouterDataModelValidateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_edge_ctrl_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RouterDataModelValidateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RouterDataModelValidateRequest) ProtoMessage() {} + +func (x *RouterDataModelValidateRequest) ProtoReflect() protoreflect.Message { + mi := &file_edge_ctrl_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RouterDataModelValidateRequest.ProtoReflect.Descriptor instead. +func (*RouterDataModelValidateRequest) Descriptor() ([]byte, []int) { + return file_edge_ctrl_proto_rawDescGZIP(), []int{42} +} + +func (x *RouterDataModelValidateRequest) GetState() *DataState { + if x != nil { + return x.State + } + return nil +} + +func (x *RouterDataModelValidateRequest) GetFix() bool { + if x != nil { + return x.Fix + } + return false +} + +type RouterDataModelDiff struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EntityType string `protobuf:"bytes,1,opt,name=entityType,proto3" json:"entityType,omitempty"` + EntityId string `protobuf:"bytes,2,opt,name=entityId,proto3" json:"entityId,omitempty"` + DiffType string `protobuf:"bytes,3,opt,name=diffType,proto3" json:"diffType,omitempty"` + Detail string `protobuf:"bytes,4,opt,name=detail,proto3" json:"detail,omitempty"` +} + +func (x *RouterDataModelDiff) Reset() { + *x = RouterDataModelDiff{} + if protoimpl.UnsafeEnabled { + mi := &file_edge_ctrl_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RouterDataModelDiff) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RouterDataModelDiff) ProtoMessage() {} + +func (x *RouterDataModelDiff) ProtoReflect() protoreflect.Message { + mi := &file_edge_ctrl_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RouterDataModelDiff.ProtoReflect.Descriptor instead. +func (*RouterDataModelDiff) Descriptor() ([]byte, []int) { + return file_edge_ctrl_proto_rawDescGZIP(), []int{43} +} + +func (x *RouterDataModelDiff) GetEntityType() string { + if x != nil { + return x.EntityType + } + return "" +} + +func (x *RouterDataModelDiff) GetEntityId() string { + if x != nil { + return x.EntityId + } + return "" +} + +func (x *RouterDataModelDiff) GetDiffType() string { + if x != nil { + return x.DiffType + } + return "" +} + +func (x *RouterDataModelDiff) GetDetail() string { + if x != nil { + return x.Detail + } + return "" +} + +type RouterDataModelValidateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrigEntityCounts map[string]uint32 `protobuf:"bytes,1,rep,name=origEntityCounts,proto3" json:"origEntityCounts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + CopyEntityCounts map[string]uint32 `protobuf:"bytes,2,rep,name=copyEntityCounts,proto3" json:"copyEntityCounts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Diffs []*RouterDataModelDiff `protobuf:"bytes,3,rep,name=diffs,proto3" json:"diffs,omitempty"` +} + +func (x *RouterDataModelValidateResponse) Reset() { + *x = RouterDataModelValidateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_edge_ctrl_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RouterDataModelValidateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RouterDataModelValidateResponse) ProtoMessage() {} + +func (x *RouterDataModelValidateResponse) ProtoReflect() protoreflect.Message { + mi := &file_edge_ctrl_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RouterDataModelValidateResponse.ProtoReflect.Descriptor instead. +func (*RouterDataModelValidateResponse) Descriptor() ([]byte, []int) { + return file_edge_ctrl_proto_rawDescGZIP(), []int{44} +} + +func (x *RouterDataModelValidateResponse) GetOrigEntityCounts() map[string]uint32 { + if x != nil { + return x.OrigEntityCounts + } + return nil +} + +func (x *RouterDataModelValidateResponse) GetCopyEntityCounts() map[string]uint32 { + if x != nil { + return x.CopyEntityCounts + } + return nil +} + +func (x *RouterDataModelValidateResponse) GetDiffs() []*RouterDataModelDiff { + if x != nil { + return x.Diffs + } + return nil +} + type DataState_ConfigType struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3663,7 +3858,7 @@ type DataState_ConfigType struct { func (x *DataState_ConfigType) Reset() { *x = DataState_ConfigType{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[45] + mi := &file_edge_ctrl_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3676,7 +3871,7 @@ func (x *DataState_ConfigType) String() string { func (*DataState_ConfigType) ProtoMessage() {} func (x *DataState_ConfigType) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[45] + mi := &file_edge_ctrl_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3720,7 +3915,7 @@ type DataState_Config struct { func (x *DataState_Config) Reset() { *x = DataState_Config{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[46] + mi := &file_edge_ctrl_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3733,7 +3928,7 @@ func (x *DataState_Config) String() string { func (*DataState_Config) ProtoMessage() {} func (x *DataState_Config) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[46] + mi := &file_edge_ctrl_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3788,7 +3983,7 @@ type DataState_ServiceConfigs struct { func (x *DataState_ServiceConfigs) Reset() { *x = DataState_ServiceConfigs{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[47] + mi := &file_edge_ctrl_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3801,7 +3996,7 @@ func (x *DataState_ServiceConfigs) String() string { func (*DataState_ServiceConfigs) ProtoMessage() {} func (x *DataState_ServiceConfigs) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[47] + mi := &file_edge_ctrl_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3843,7 +4038,7 @@ type DataState_Identity struct { func (x *DataState_Identity) Reset() { *x = DataState_Identity{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[48] + mi := &file_edge_ctrl_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3856,7 +4051,7 @@ func (x *DataState_Identity) String() string { func (*DataState_Identity) ProtoMessage() {} func (x *DataState_Identity) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[48] + mi := &file_edge_ctrl_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3949,7 +4144,7 @@ type DataState_Service struct { func (x *DataState_Service) Reset() { *x = DataState_Service{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[49] + mi := &file_edge_ctrl_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3962,7 +4157,7 @@ func (x *DataState_Service) String() string { func (*DataState_Service) ProtoMessage() {} func (x *DataState_Service) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[49] + mi := &file_edge_ctrl_proto_msgTypes[52] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4019,7 +4214,7 @@ type DataState_ServicePolicy struct { func (x *DataState_ServicePolicy) Reset() { *x = DataState_ServicePolicy{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[50] + mi := &file_edge_ctrl_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4032,7 +4227,7 @@ func (x *DataState_ServicePolicy) String() string { func (*DataState_ServicePolicy) ProtoMessage() {} func (x *DataState_ServicePolicy) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[50] + mi := &file_edge_ctrl_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4081,7 +4276,7 @@ type DataState_Revocation struct { func (x *DataState_Revocation) Reset() { *x = DataState_Revocation{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[51] + mi := &file_edge_ctrl_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4094,7 +4289,7 @@ func (x *DataState_Revocation) String() string { func (*DataState_Revocation) ProtoMessage() {} func (x *DataState_Revocation) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[51] + mi := &file_edge_ctrl_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4138,7 +4333,7 @@ type DataState_ServicePolicyChange struct { func (x *DataState_ServicePolicyChange) Reset() { *x = DataState_ServicePolicyChange{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[52] + mi := &file_edge_ctrl_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4151,7 +4346,7 @@ func (x *DataState_ServicePolicyChange) String() string { func (*DataState_ServicePolicyChange) ProtoMessage() {} func (x *DataState_ServicePolicyChange) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[52] + mi := &file_edge_ctrl_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4208,7 +4403,7 @@ type DataState_ChangeSet struct { func (x *DataState_ChangeSet) Reset() { *x = DataState_ChangeSet{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[53] + mi := &file_edge_ctrl_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4221,7 +4416,7 @@ func (x *DataState_ChangeSet) String() string { func (*DataState_ChangeSet) ProtoMessage() {} func (x *DataState_ChangeSet) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[53] + mi := &file_edge_ctrl_proto_msgTypes[56] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4283,7 +4478,7 @@ type DataState_Event struct { func (x *DataState_Event) Reset() { *x = DataState_Event{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[54] + mi := &file_edge_ctrl_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4296,7 +4491,7 @@ func (x *DataState_Event) String() string { func (*DataState_Event) ProtoMessage() {} func (x *DataState_Event) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[54] + mi := &file_edge_ctrl_proto_msgTypes[57] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4468,7 +4663,7 @@ type DataState_PublicKey struct { func (x *DataState_PublicKey) Reset() { *x = DataState_PublicKey{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[55] + mi := &file_edge_ctrl_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4481,7 +4676,7 @@ func (x *DataState_PublicKey) String() string { func (*DataState_PublicKey) ProtoMessage() {} func (x *DataState_PublicKey) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[55] + mi := &file_edge_ctrl_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4547,7 +4742,7 @@ type DataState_PostureCheck struct { func (x *DataState_PostureCheck) Reset() { *x = DataState_PostureCheck{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[56] + mi := &file_edge_ctrl_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4560,7 +4755,7 @@ func (x *DataState_PostureCheck) String() string { func (*DataState_PostureCheck) ProtoMessage() {} func (x *DataState_PostureCheck) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[56] + mi := &file_edge_ctrl_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4697,7 +4892,7 @@ type DataState_PostureCheck_Mac struct { func (x *DataState_PostureCheck_Mac) Reset() { *x = DataState_PostureCheck_Mac{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[61] + mi := &file_edge_ctrl_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4710,7 +4905,7 @@ func (x *DataState_PostureCheck_Mac) String() string { func (*DataState_PostureCheck_Mac) ProtoMessage() {} func (x *DataState_PostureCheck_Mac) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[61] + mi := &file_edge_ctrl_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4747,7 +4942,7 @@ type DataState_PostureCheck_Mfa struct { func (x *DataState_PostureCheck_Mfa) Reset() { *x = DataState_PostureCheck_Mfa{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[62] + mi := &file_edge_ctrl_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4760,7 +4955,7 @@ func (x *DataState_PostureCheck_Mfa) String() string { func (*DataState_PostureCheck_Mfa) ProtoMessage() {} func (x *DataState_PostureCheck_Mfa) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[62] + mi := &file_edge_ctrl_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4816,7 +5011,7 @@ type DataState_PostureCheck_Os struct { func (x *DataState_PostureCheck_Os) Reset() { *x = DataState_PostureCheck_Os{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[63] + mi := &file_edge_ctrl_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4829,7 +5024,7 @@ func (x *DataState_PostureCheck_Os) String() string { func (*DataState_PostureCheck_Os) ProtoMessage() {} func (x *DataState_PostureCheck_Os) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[63] + mi := &file_edge_ctrl_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4870,7 +5065,7 @@ type DataState_PostureCheck_OsList struct { func (x *DataState_PostureCheck_OsList) Reset() { *x = DataState_PostureCheck_OsList{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[64] + mi := &file_edge_ctrl_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4883,7 +5078,7 @@ func (x *DataState_PostureCheck_OsList) String() string { func (*DataState_PostureCheck_OsList) ProtoMessage() {} func (x *DataState_PostureCheck_OsList) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[64] + mi := &file_edge_ctrl_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4920,7 +5115,7 @@ type DataState_PostureCheck_Process struct { func (x *DataState_PostureCheck_Process) Reset() { *x = DataState_PostureCheck_Process{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[65] + mi := &file_edge_ctrl_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4933,7 +5128,7 @@ func (x *DataState_PostureCheck_Process) String() string { func (*DataState_PostureCheck_Process) ProtoMessage() {} func (x *DataState_PostureCheck_Process) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[65] + mi := &file_edge_ctrl_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4989,7 +5184,7 @@ type DataState_PostureCheck_ProcessMulti struct { func (x *DataState_PostureCheck_ProcessMulti) Reset() { *x = DataState_PostureCheck_ProcessMulti{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[66] + mi := &file_edge_ctrl_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5002,7 +5197,7 @@ func (x *DataState_PostureCheck_ProcessMulti) String() string { func (*DataState_PostureCheck_ProcessMulti) ProtoMessage() {} func (x *DataState_PostureCheck_ProcessMulti) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[66] + mi := &file_edge_ctrl_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5043,7 +5238,7 @@ type DataState_PostureCheck_Domains struct { func (x *DataState_PostureCheck_Domains) Reset() { *x = DataState_PostureCheck_Domains{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[67] + mi := &file_edge_ctrl_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5056,7 +5251,7 @@ func (x *DataState_PostureCheck_Domains) String() string { func (*DataState_PostureCheck_Domains) ProtoMessage() {} func (x *DataState_PostureCheck_Domains) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[67] + mi := &file_edge_ctrl_proto_msgTypes[70] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5092,7 +5287,7 @@ type ConnectEvents_ConnectDetails struct { func (x *ConnectEvents_ConnectDetails) Reset() { *x = ConnectEvents_ConnectDetails{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[83] + mi := &file_edge_ctrl_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5105,7 +5300,7 @@ func (x *ConnectEvents_ConnectDetails) String() string { func (*ConnectEvents_ConnectDetails) ProtoMessage() {} func (x *ConnectEvents_ConnectDetails) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[83] + mi := &file_edge_ctrl_proto_msgTypes[86] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5155,7 +5350,7 @@ type ConnectEvents_IdentityConnectEvents struct { func (x *ConnectEvents_IdentityConnectEvents) Reset() { *x = ConnectEvents_IdentityConnectEvents{} if protoimpl.UnsafeEnabled { - mi := &file_edge_ctrl_proto_msgTypes[84] + mi := &file_edge_ctrl_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5168,7 +5363,7 @@ func (x *ConnectEvents_IdentityConnectEvents) String() string { func (*ConnectEvents_IdentityConnectEvents) ProtoMessage() {} func (x *ConnectEvents_IdentityConnectEvents) ProtoReflect() protoreflect.Message { - mi := &file_edge_ctrl_proto_msgTypes[84] + mi := &file_edge_ctrl_proto_msgTypes[87] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6072,146 +6267,195 @@ var file_edge_ctrl_proto_rawDesc = []byte{ 0x2f, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x2a, 0xe4, - 0x0c, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, - 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x10, 0xa0, 0x9c, 0x01, 0x12, - 0x15, 0x0a, 0x0f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xa1, 0x9c, 0x01, 0x12, 0x0f, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xa2, 0x9c, 0x01, 0x12, 0x18, 0x0a, 0x12, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0x86, 0x9d, - 0x01, 0x12, 0x19, 0x0a, 0x13, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x41, - 0x64, 0x64, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe8, 0x9d, 0x01, 0x12, 0x1b, 0x0a, 0x15, - 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe9, 0x9d, 0x01, 0x12, 0x1b, 0x0a, 0x15, 0x41, 0x70, 0x69, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xea, 0x9d, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xeb, 0x9d, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xec, 0x9d, 0x01, 0x12, 0x1e, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x69, - 0x72, 0x63, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xed, 0x9d, 0x01, 0x12, 0x1f, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x69, - 0x72, 0x63, 0x75, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xee, 0x9d, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, - 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x10, 0xef, 0x9d, 0x01, 0x12, 0x22, 0x0a, 0x1c, 0x43, 0x72, 0x65, 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, 0xf0, 0x9d, 0x01, 0x12, 0x21, 0x0a, 0x1b, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf1, 0x9d, 0x01, 0x12, - 0x22, 0x0a, 0x1c, 0x55, 0x70, 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, - 0xf2, 0x9d, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x72, - 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x10, 0xf3, 0x9d, 0x01, 0x12, 0x22, 0x0a, 0x1c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf4, 0x9d, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf5, 0x9d, 0x01, 0x12, 0x15, 0x0a, - 0x0f, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xf6, 0x9d, 0x01, 0x12, 0x23, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf8, 0x9d, 0x01, 0x12, 0x24, 0x0a, 0x1e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x56, 0x32, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf9, 0x9d, 0x01, 0x12, - 0x20, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, - 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfa, 0x9d, - 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, - 0x69, 0x74, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xfb, 0x9d, 0x01, 0x12, 0x26, 0x0a, 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, - 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x56, 0x32, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfc, 0x9d, 0x01, 0x12, 0x27, 0x0a, 0x21, + 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x22, 0x66, + 0x0a, 0x1e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, + 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x03, 0x66, 0x69, 0x78, 0x22, 0x85, 0x01, 0x0a, 0x13, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x44, 0x69, 0x66, 0x66, 0x12, 0x1e, + 0x0a, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, + 0x66, 0x66, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, + 0x66, 0x66, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x22, 0xd5, + 0x03, 0x0a, 0x1f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x74, 0x0a, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x7a, + 0x69, 0x74, 0x69, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, + 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x69, + 0x74, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x74, 0x0a, 0x10, 0x63, 0x6f, 0x70, 0x79, + 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, + 0x74, 0x72, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, + 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x70, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x63, 0x6f, + 0x70, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x3c, + 0x0a, 0x05, 0x64, 0x69, 0x66, 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x7a, 0x69, 0x74, 0x69, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x2e, 0x70, + 0x62, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x44, 0x69, 0x66, 0x66, 0x52, 0x05, 0x64, 0x69, 0x66, 0x66, 0x73, 0x1a, 0x43, 0x0a, 0x15, + 0x4f, 0x72, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x1a, 0x43, 0x0a, 0x15, 0x43, 0x6f, 0x70, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0xad, 0x0d, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x5a, 0x65, 0x72, 0x6f, 0x10, 0x00, + 0x12, 0x15, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, + 0x79, 0x70, 0x65, 0x10, 0xa0, 0x9c, 0x01, 0x12, 0x15, 0x0a, 0x0f, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x10, 0xa1, 0x9c, 0x01, 0x12, 0x0f, + 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x10, 0xa2, 0x9c, 0x01, 0x12, + 0x18, 0x0a, 0x12, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0x86, 0x9d, 0x01, 0x12, 0x19, 0x0a, 0x13, 0x41, 0x70, 0x69, + 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, + 0x10, 0xe8, 0x9d, 0x01, 0x12, 0x1b, 0x0a, 0x15, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0xe9, 0x9d, + 0x01, 0x12, 0x1b, 0x0a, 0x15, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x10, 0xea, 0x9d, 0x01, 0x12, 0x1d, + 0x0a, 0x17, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x65, 0x61, 0x72, + 0x74, 0x62, 0x65, 0x61, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xeb, 0x9d, 0x01, 0x12, 0x1d, 0x0a, + 0x17, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x53, 0x79, 0x6e, 0x63, 0x54, 0x79, 0x70, 0x65, 0x10, 0xec, 0x9d, 0x01, 0x12, 0x1e, 0x0a, 0x18, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xed, 0x9d, 0x01, 0x12, 0x1f, 0x0a, 0x19, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xee, 0x9d, 0x01, 0x12, 0x21, 0x0a, + 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xef, 0x9d, 0x01, + 0x12, 0x22, 0x0a, 0x1c, 0x43, 0x72, 0x65, 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, 0xf0, 0x9d, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, + 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x10, 0xf1, 0x9d, 0x01, 0x12, 0x22, 0x0a, 0x1c, 0x55, 0x70, 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, 0xf2, 0x9d, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf3, 0x9d, 0x01, 0x12, 0x22, + 0x0a, 0x1c, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf4, + 0x9d, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xf5, 0x9d, 0x01, 0x12, 0x15, 0x0a, 0x0f, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf6, 0x9d, 0x01, 0x12, 0x23, 0x0a, 0x1d, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, + 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xf8, 0x9d, + 0x01, 0x12, 0x24, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x10, 0xf9, 0x9d, 0x01, 0x12, 0x20, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfa, 0x9d, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfb, 0x9d, 0x01, 0x12, 0x26, 0x0a, 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x69, 0x72, 0x63, - 0x75, 0x69, 0x74, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xfd, 0x9d, 0x01, 0x12, 0x10, 0x0a, 0x0a, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xcc, 0x9e, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xcd, 0x9e, 0x01, 0x12, 0x27, 0x0a, 0x21, 0x45, 0x6e, - 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xce, 0x9e, 0x01, 0x12, 0x2d, 0x0a, 0x27, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, - 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xcf, - 0x9e, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xb0, 0x9f, 0x01, 0x12, 0x22, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, - 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb1, 0x9f, 0x01, 0x12, 0x28, 0x0a, 0x22, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xb2, 0x9f, 0x01, 0x12, 0x29, 0x0a, 0x23, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x69, 0x72, - 0x63, 0x75, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb3, 0x9f, 0x01, 0x12, 0x1d, - 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb4, 0x9f, 0x01, 0x12, 0x15, 0x0a, - 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x10, 0xb5, 0x9f, 0x01, 0x12, 0x27, 0x0a, 0x21, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, - 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb6, 0x9f, 0x01, 0x12, 0x28, 0x0a, - 0x22, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, - 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x10, 0xb7, 0x9f, 0x01, 0x12, 0x27, 0x0a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb8, 0x9f, 0x01, - 0x12, 0x28, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, - 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb9, 0x9f, 0x01, 0x12, 0x27, 0x0a, 0x21, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, - 0xba, 0x9f, 0x01, 0x12, 0x28, 0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x75, 0x6e, - 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbb, 0x9f, 0x01, 0x12, 0x1b, 0x0a, - 0x15, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbc, 0x9f, 0x01, 0x12, 0x29, 0x0a, 0x23, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x32, 0x54, 0x79, 0x70, - 0x65, 0x10, 0xbd, 0x9f, 0x01, 0x12, 0x2a, 0x0a, 0x24, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x75, 0x69, 0x74, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x10, 0xfc, 0x9d, 0x01, 0x12, 0x27, 0x0a, 0x21, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x56, 0x32, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xfd, 0x9d, 0x01, 0x12, 0x10, 0x0a, + 0x0a, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x10, 0xcc, 0x9e, 0x01, 0x12, + 0x21, 0x0a, 0x1b, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xcd, + 0x9e, 0x01, 0x12, 0x27, 0x0a, 0x21, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xce, 0x9e, 0x01, 0x12, 0x2d, 0x0a, 0x27, 0x45, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x6d, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x72, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xcf, 0x9e, 0x01, 0x12, 0x21, 0x0a, 0x1b, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb0, 0x9f, 0x01, 0x12, 0x22, 0x0a, + 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x69, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb1, 0x9f, + 0x01, 0x12, 0x28, 0x0a, 0x22, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, + 0x69, 0x74, 0x46, 0x6f, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb2, 0x9f, 0x01, 0x12, 0x29, 0x0a, 0x23, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x10, 0xb3, 0x9f, 0x01, 0x12, 0x1d, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xb4, 0x9f, 0x01, 0x12, 0x15, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb5, 0x9f, 0x01, 0x12, 0x27, 0x0a, 0x21, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xb6, 0x9f, 0x01, 0x12, 0x28, 0x0a, 0x22, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbe, 0x9f, - 0x01, 0x12, 0x18, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x73, 0x10, 0xbf, 0x9f, 0x01, 0x12, 0x13, 0x0a, 0x0d, 0x44, - 0x61, 0x74, 0x61, 0x53, 0x74, 0x61, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x94, 0xa0, 0x01, - 0x12, 0x1c, 0x0a, 0x16, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x95, 0xa0, 0x01, 0x12, 0x15, - 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x54, 0x79, 0x70, - 0x65, 0x10, 0x96, 0xa0, 0x01, 0x2a, 0x21, 0x0a, 0x0b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x69, 0x61, 0x6c, 0x10, 0x00, 0x12, 0x08, - 0x0a, 0x04, 0x42, 0x69, 0x6e, 0x64, 0x10, 0x01, 0x2a, 0x6e, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5a, 0x65, 0x72, 0x6f, - 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, - 0x49, 0x64, 0x10, 0xfe, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, 0x61, - 0x73, 0x73, 0x65, 0x64, 0x10, 0xff, 0x07, 0x12, 0x14, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x10, 0x80, 0x08, 0x12, 0x19, 0x0a, - 0x14, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, - 0x49, 0x6e, 0x64, 0x65, 0x78, 0x10, 0x81, 0x08, 0x2a, 0x3f, 0x0a, 0x0a, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x69, 0x61, - 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x42, 0x69, 0x6e, - 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x10, 0x02, 0x2a, 0x7a, 0x0a, 0x1e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, - 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x49, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, - 0x65, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, 0x74, - 0x65, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, - 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x10, 0x03, 0x2a, 0x3d, 0x0a, 0x14, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, - 0x74, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x63, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0b, 0x0a, - 0x07, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, 0x6c, - 0x65, 0x64, 0x10, 0x02, 0x2a, 0x76, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, - 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0b, - 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x46, - 0x61, 0x69, 0x6c, 0x65, 0x64, 0x49, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x10, - 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x74, 0x68, 0x65, 0x72, - 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x42, 0x75, 0x73, 0x79, - 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x10, 0x04, 0x42, 0x31, 0x5a, 0x2f, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, - 0x69, 0x74, 0x69, 0x2f, 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, - 0x70, 0x62, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x5f, 0x70, 0x62, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb7, 0x9f, 0x01, 0x12, + 0x27, 0x0a, 0x21, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x10, 0xb8, 0x9f, 0x01, 0x12, 0x28, 0x0a, 0x22, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0xb9, + 0x9f, 0x01, 0x12, 0x27, 0x0a, 0x21, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x75, 0x6e, 0x6e, + 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xba, 0x9f, 0x01, 0x12, 0x28, 0x0a, 0x22, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x10, 0xbb, 0x9f, 0x01, 0x12, 0x1b, 0x0a, 0x15, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbc, + 0x9f, 0x01, 0x12, 0x29, 0x0a, 0x23, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, + 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x56, 0x32, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbd, 0x9f, 0x01, 0x12, 0x2a, 0x0a, + 0x24, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, + 0x32, 0x54, 0x79, 0x70, 0x65, 0x10, 0xbe, 0x9f, 0x01, 0x12, 0x18, 0x0a, 0x12, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x54, 0x79, 0x70, 0x65, 0x73, 0x10, + 0xbf, 0x9f, 0x01, 0x12, 0x13, 0x0a, 0x0d, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x10, 0x94, 0xa0, 0x01, 0x12, 0x1c, 0x0a, 0x16, 0x44, 0x61, 0x74, 0x61, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x10, 0x95, 0xa0, 0x01, 0x12, 0x15, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x10, 0x96, 0xa0, 0x01, 0x12, 0x22, 0x0a, + 0x1c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x10, 0x97, 0xa0, + 0x01, 0x12, 0x23, 0x0a, 0x1d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, + 0x61, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x10, 0x98, 0xa0, 0x01, 0x2a, 0x21, 0x0a, 0x0b, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x69, 0x61, 0x6c, 0x10, 0x00, 0x12, + 0x08, 0x0a, 0x04, 0x42, 0x69, 0x6e, 0x64, 0x10, 0x01, 0x2a, 0x6e, 0x0a, 0x06, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5a, 0x65, 0x72, + 0x6f, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, + 0x72, 0x49, 0x64, 0x10, 0xfe, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x50, + 0x61, 0x73, 0x73, 0x65, 0x64, 0x10, 0xff, 0x07, 0x12, 0x14, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x10, 0x80, 0x08, 0x12, 0x19, + 0x0a, 0x14, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x10, 0x81, 0x08, 0x2a, 0x3f, 0x0a, 0x0a, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x6e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x69, + 0x61, 0x6c, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x42, 0x69, + 0x6e, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x10, 0x02, 0x2a, 0x7a, 0x0a, 0x1e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x12, + 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x54, 0x79, + 0x70, 0x65, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x61, + 0x74, 0x65, 0x64, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x10, 0x02, 0x12, 0x17, 0x0a, + 0x13, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x73, 0x74, 0x75, 0x72, 0x65, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x10, 0x03, 0x2a, 0x3d, 0x0a, 0x14, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x63, 0x65, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x0b, + 0x0a, 0x07, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x61, 0x69, + 0x6c, 0x65, 0x64, 0x10, 0x02, 0x2a, 0x76, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, + 0x0b, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, + 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x49, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, + 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4f, 0x74, 0x68, 0x65, + 0x72, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x42, 0x75, 0x73, + 0x79, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x49, 0x6e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x10, 0x04, 0x42, 0x31, 0x5a, + 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, + 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2f, 0x70, 0x62, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x5f, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -6227,7 +6471,7 @@ func file_edge_ctrl_proto_rawDescGZIP() []byte { } var file_edge_ctrl_proto_enumTypes = make([]protoimpl.EnumInfo, 10) -var file_edge_ctrl_proto_msgTypes = make([]protoimpl.MessageInfo, 85) +var file_edge_ctrl_proto_msgTypes = make([]protoimpl.MessageInfo, 90) var file_edge_ctrl_proto_goTypes = []interface{}{ (ContentType)(0), // 0: ziti.edge_ctrl.pb.ContentType (SessionType)(0), // 1: ziti.edge_ctrl.pb.SessionType @@ -6281,130 +6525,139 @@ var file_edge_ctrl_proto_goTypes = []interface{}{ (*EnrollmentCertsResponse)(nil), // 49: ziti.edge_ctrl.pb.EnrollmentCertsResponse (*EnrollmentExtendRouterVerifyRequest)(nil), // 50: ziti.edge_ctrl.pb.EnrollmentExtendRouterVerifyRequest (*ConnectEvents)(nil), // 51: ziti.edge_ctrl.pb.ConnectEvents - nil, // 52: ziti.edge_ctrl.pb.ServerHello.DataEntry - nil, // 53: ziti.edge_ctrl.pb.ServerHello.ByteDataEntry - nil, // 54: ziti.edge_ctrl.pb.ClientHello.DataEntry - (*DataState_ConfigType)(nil), // 55: ziti.edge_ctrl.pb.DataState.ConfigType - (*DataState_Config)(nil), // 56: ziti.edge_ctrl.pb.DataState.Config - (*DataState_ServiceConfigs)(nil), // 57: ziti.edge_ctrl.pb.DataState.ServiceConfigs - (*DataState_Identity)(nil), // 58: ziti.edge_ctrl.pb.DataState.Identity - (*DataState_Service)(nil), // 59: ziti.edge_ctrl.pb.DataState.Service - (*DataState_ServicePolicy)(nil), // 60: ziti.edge_ctrl.pb.DataState.ServicePolicy - (*DataState_Revocation)(nil), // 61: ziti.edge_ctrl.pb.DataState.Revocation - (*DataState_ServicePolicyChange)(nil), // 62: ziti.edge_ctrl.pb.DataState.ServicePolicyChange - (*DataState_ChangeSet)(nil), // 63: ziti.edge_ctrl.pb.DataState.ChangeSet - (*DataState_Event)(nil), // 64: ziti.edge_ctrl.pb.DataState.Event - (*DataState_PublicKey)(nil), // 65: ziti.edge_ctrl.pb.DataState.PublicKey - (*DataState_PostureCheck)(nil), // 66: ziti.edge_ctrl.pb.DataState.PostureCheck - nil, // 67: ziti.edge_ctrl.pb.DataState.ServiceConfigs.ConfigsEntry - nil, // 68: ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingPrecedencesEntry - nil, // 69: ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingCostsEntry - nil, // 70: ziti.edge_ctrl.pb.DataState.Identity.ServiceConfigsEntry - (*DataState_PostureCheck_Mac)(nil), // 71: ziti.edge_ctrl.pb.DataState.PostureCheck.Mac - (*DataState_PostureCheck_Mfa)(nil), // 72: ziti.edge_ctrl.pb.DataState.PostureCheck.Mfa - (*DataState_PostureCheck_Os)(nil), // 73: ziti.edge_ctrl.pb.DataState.PostureCheck.Os - (*DataState_PostureCheck_OsList)(nil), // 74: ziti.edge_ctrl.pb.DataState.PostureCheck.OsList - (*DataState_PostureCheck_Process)(nil), // 75: ziti.edge_ctrl.pb.DataState.PostureCheck.Process - (*DataState_PostureCheck_ProcessMulti)(nil), // 76: ziti.edge_ctrl.pb.DataState.PostureCheck.ProcessMulti - (*DataState_PostureCheck_Domains)(nil), // 77: ziti.edge_ctrl.pb.DataState.PostureCheck.Domains - nil, // 78: ziti.edge_ctrl.pb.CreateCircuitRequest.PeerDataEntry - nil, // 79: ziti.edge_ctrl.pb.CreateCircuitResponse.PeerDataEntry - nil, // 80: ziti.edge_ctrl.pb.CreateCircuitResponse.TagsEntry - nil, // 81: ziti.edge_ctrl.pb.CreateTerminatorRequest.PeerDataEntry - nil, // 82: ziti.edge_ctrl.pb.CreateTerminatorV2Request.PeerDataEntry - nil, // 83: ziti.edge_ctrl.pb.CreateApiSessionResponse.ServicePrecedencesEntry - nil, // 84: ziti.edge_ctrl.pb.CreateApiSessionResponse.ServiceCostsEntry - nil, // 85: ziti.edge_ctrl.pb.CreateCircuitForServiceRequest.PeerDataEntry - nil, // 86: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.PeerDataEntry - nil, // 87: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.TagsEntry - nil, // 88: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Request.PeerDataEntry - nil, // 89: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.PeerDataEntry - nil, // 90: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.TagsEntry - nil, // 91: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequest.PeerDataEntry - nil, // 92: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequestV2.PeerDataEntry - (*ConnectEvents_ConnectDetails)(nil), // 93: ziti.edge_ctrl.pb.ConnectEvents.ConnectDetails - (*ConnectEvents_IdentityConnectEvents)(nil), // 94: ziti.edge_ctrl.pb.ConnectEvents.IdentityConnectEvents - (*timestamppb.Timestamp)(nil), // 95: google.protobuf.Timestamp + (*RouterDataModelValidateRequest)(nil), // 52: ziti.edge_ctrl.pb.RouterDataModelValidateRequest + (*RouterDataModelDiff)(nil), // 53: ziti.edge_ctrl.pb.RouterDataModelDiff + (*RouterDataModelValidateResponse)(nil), // 54: ziti.edge_ctrl.pb.RouterDataModelValidateResponse + nil, // 55: ziti.edge_ctrl.pb.ServerHello.DataEntry + nil, // 56: ziti.edge_ctrl.pb.ServerHello.ByteDataEntry + nil, // 57: ziti.edge_ctrl.pb.ClientHello.DataEntry + (*DataState_ConfigType)(nil), // 58: ziti.edge_ctrl.pb.DataState.ConfigType + (*DataState_Config)(nil), // 59: ziti.edge_ctrl.pb.DataState.Config + (*DataState_ServiceConfigs)(nil), // 60: ziti.edge_ctrl.pb.DataState.ServiceConfigs + (*DataState_Identity)(nil), // 61: ziti.edge_ctrl.pb.DataState.Identity + (*DataState_Service)(nil), // 62: ziti.edge_ctrl.pb.DataState.Service + (*DataState_ServicePolicy)(nil), // 63: ziti.edge_ctrl.pb.DataState.ServicePolicy + (*DataState_Revocation)(nil), // 64: ziti.edge_ctrl.pb.DataState.Revocation + (*DataState_ServicePolicyChange)(nil), // 65: ziti.edge_ctrl.pb.DataState.ServicePolicyChange + (*DataState_ChangeSet)(nil), // 66: ziti.edge_ctrl.pb.DataState.ChangeSet + (*DataState_Event)(nil), // 67: ziti.edge_ctrl.pb.DataState.Event + (*DataState_PublicKey)(nil), // 68: ziti.edge_ctrl.pb.DataState.PublicKey + (*DataState_PostureCheck)(nil), // 69: ziti.edge_ctrl.pb.DataState.PostureCheck + nil, // 70: ziti.edge_ctrl.pb.DataState.ServiceConfigs.ConfigsEntry + nil, // 71: ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingPrecedencesEntry + nil, // 72: ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingCostsEntry + nil, // 73: ziti.edge_ctrl.pb.DataState.Identity.ServiceConfigsEntry + (*DataState_PostureCheck_Mac)(nil), // 74: ziti.edge_ctrl.pb.DataState.PostureCheck.Mac + (*DataState_PostureCheck_Mfa)(nil), // 75: ziti.edge_ctrl.pb.DataState.PostureCheck.Mfa + (*DataState_PostureCheck_Os)(nil), // 76: ziti.edge_ctrl.pb.DataState.PostureCheck.Os + (*DataState_PostureCheck_OsList)(nil), // 77: ziti.edge_ctrl.pb.DataState.PostureCheck.OsList + (*DataState_PostureCheck_Process)(nil), // 78: ziti.edge_ctrl.pb.DataState.PostureCheck.Process + (*DataState_PostureCheck_ProcessMulti)(nil), // 79: ziti.edge_ctrl.pb.DataState.PostureCheck.ProcessMulti + (*DataState_PostureCheck_Domains)(nil), // 80: ziti.edge_ctrl.pb.DataState.PostureCheck.Domains + nil, // 81: ziti.edge_ctrl.pb.CreateCircuitRequest.PeerDataEntry + nil, // 82: ziti.edge_ctrl.pb.CreateCircuitResponse.PeerDataEntry + nil, // 83: ziti.edge_ctrl.pb.CreateCircuitResponse.TagsEntry + nil, // 84: ziti.edge_ctrl.pb.CreateTerminatorRequest.PeerDataEntry + nil, // 85: ziti.edge_ctrl.pb.CreateTerminatorV2Request.PeerDataEntry + nil, // 86: ziti.edge_ctrl.pb.CreateApiSessionResponse.ServicePrecedencesEntry + nil, // 87: ziti.edge_ctrl.pb.CreateApiSessionResponse.ServiceCostsEntry + nil, // 88: ziti.edge_ctrl.pb.CreateCircuitForServiceRequest.PeerDataEntry + nil, // 89: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.PeerDataEntry + nil, // 90: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.TagsEntry + nil, // 91: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Request.PeerDataEntry + nil, // 92: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.PeerDataEntry + nil, // 93: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.TagsEntry + nil, // 94: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequest.PeerDataEntry + nil, // 95: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequestV2.PeerDataEntry + (*ConnectEvents_ConnectDetails)(nil), // 96: ziti.edge_ctrl.pb.ConnectEvents.ConnectDetails + (*ConnectEvents_IdentityConnectEvents)(nil), // 97: ziti.edge_ctrl.pb.ConnectEvents.IdentityConnectEvents + nil, // 98: ziti.edge_ctrl.pb.RouterDataModelValidateResponse.OrigEntityCountsEntry + nil, // 99: ziti.edge_ctrl.pb.RouterDataModelValidateResponse.CopyEntityCountsEntry + (*timestamppb.Timestamp)(nil), // 100: google.protobuf.Timestamp } var file_edge_ctrl_proto_depIdxs = []int32{ - 52, // 0: ziti.edge_ctrl.pb.ServerHello.data:type_name -> ziti.edge_ctrl.pb.ServerHello.DataEntry - 53, // 1: ziti.edge_ctrl.pb.ServerHello.byteData:type_name -> ziti.edge_ctrl.pb.ServerHello.ByteDataEntry - 11, // 2: ziti.edge_ctrl.pb.Listener.address:type_name -> ziti.edge_ctrl.pb.Address - 11, // 3: ziti.edge_ctrl.pb.Listener.advertise:type_name -> ziti.edge_ctrl.pb.Address - 54, // 4: ziti.edge_ctrl.pb.ClientHello.data:type_name -> ziti.edge_ctrl.pb.ClientHello.DataEntry - 12, // 5: ziti.edge_ctrl.pb.ClientHello.listeners:type_name -> ziti.edge_ctrl.pb.Listener - 64, // 6: ziti.edge_ctrl.pb.DataState.events:type_name -> ziti.edge_ctrl.pb.DataState.Event - 16, // 7: ziti.edge_ctrl.pb.ApiSessionAdded.apiSessions:type_name -> ziti.edge_ctrl.pb.ApiSession - 16, // 8: ziti.edge_ctrl.pb.ApiSessionUpdated.apiSessions:type_name -> ziti.edge_ctrl.pb.ApiSession - 78, // 9: ziti.edge_ctrl.pb.CreateCircuitRequest.peerData:type_name -> ziti.edge_ctrl.pb.CreateCircuitRequest.PeerDataEntry - 79, // 10: ziti.edge_ctrl.pb.CreateCircuitResponse.peerData:type_name -> ziti.edge_ctrl.pb.CreateCircuitResponse.PeerDataEntry - 80, // 11: ziti.edge_ctrl.pb.CreateCircuitResponse.tags:type_name -> ziti.edge_ctrl.pb.CreateCircuitResponse.TagsEntry - 81, // 12: ziti.edge_ctrl.pb.CreateTerminatorRequest.peerData:type_name -> ziti.edge_ctrl.pb.CreateTerminatorRequest.PeerDataEntry - 5, // 13: ziti.edge_ctrl.pb.CreateTerminatorRequest.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 82, // 14: ziti.edge_ctrl.pb.CreateTerminatorV2Request.peerData:type_name -> ziti.edge_ctrl.pb.CreateTerminatorV2Request.PeerDataEntry - 5, // 15: ziti.edge_ctrl.pb.CreateTerminatorV2Request.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 6, // 16: ziti.edge_ctrl.pb.CreateTerminatorV2Response.result:type_name -> ziti.edge_ctrl.pb.CreateTerminatorResult - 5, // 17: ziti.edge_ctrl.pb.UpdateTerminatorRequest.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 32, // 18: ziti.edge_ctrl.pb.CreateApiSessionRequest.envInfo:type_name -> ziti.edge_ctrl.pb.EnvInfo - 33, // 19: ziti.edge_ctrl.pb.CreateApiSessionRequest.sdkInfo:type_name -> ziti.edge_ctrl.pb.SdkInfo - 5, // 20: ziti.edge_ctrl.pb.CreateApiSessionResponse.defaultHostingPrecedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 83, // 21: ziti.edge_ctrl.pb.CreateApiSessionResponse.servicePrecedences:type_name -> ziti.edge_ctrl.pb.CreateApiSessionResponse.ServicePrecedencesEntry - 84, // 22: ziti.edge_ctrl.pb.CreateApiSessionResponse.serviceCosts:type_name -> ziti.edge_ctrl.pb.CreateApiSessionResponse.ServiceCostsEntry - 85, // 23: ziti.edge_ctrl.pb.CreateCircuitForServiceRequest.peerData:type_name -> ziti.edge_ctrl.pb.CreateCircuitForServiceRequest.PeerDataEntry - 35, // 24: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.apiSession:type_name -> ziti.edge_ctrl.pb.CreateApiSessionResponse - 37, // 25: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.session:type_name -> ziti.edge_ctrl.pb.CreateSessionResponse - 86, // 26: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.peerData:type_name -> ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.PeerDataEntry - 87, // 27: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.tags:type_name -> ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.TagsEntry - 88, // 28: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Request.peerData:type_name -> ziti.edge_ctrl.pb.CreateTunnelCircuitV2Request.PeerDataEntry - 89, // 29: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.peerData:type_name -> ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.PeerDataEntry - 90, // 30: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.tags:type_name -> ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.TagsEntry - 42, // 31: ziti.edge_ctrl.pb.ServicesList.services:type_name -> ziti.edge_ctrl.pb.TunnelService - 91, // 32: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequest.peerData:type_name -> ziti.edge_ctrl.pb.CreateTunnelTerminatorRequest.PeerDataEntry - 5, // 33: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequest.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 35, // 34: ziti.edge_ctrl.pb.CreateTunnelTerminatorResponse.apiSession:type_name -> ziti.edge_ctrl.pb.CreateApiSessionResponse - 37, // 35: ziti.edge_ctrl.pb.CreateTunnelTerminatorResponse.session:type_name -> ziti.edge_ctrl.pb.CreateSessionResponse - 92, // 36: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequestV2.peerData:type_name -> ziti.edge_ctrl.pb.CreateTunnelTerminatorRequestV2.PeerDataEntry - 5, // 37: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequestV2.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 5, // 38: ziti.edge_ctrl.pb.UpdateTunnelTerminatorRequest.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 94, // 39: ziti.edge_ctrl.pb.ConnectEvents.events:type_name -> ziti.edge_ctrl.pb.ConnectEvents.IdentityConnectEvents - 67, // 40: ziti.edge_ctrl.pb.DataState.ServiceConfigs.configs:type_name -> ziti.edge_ctrl.pb.DataState.ServiceConfigs.ConfigsEntry - 5, // 41: ziti.edge_ctrl.pb.DataState.Identity.defaultHostingPrecedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 68, // 42: ziti.edge_ctrl.pb.DataState.Identity.serviceHostingPrecedences:type_name -> ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingPrecedencesEntry - 69, // 43: ziti.edge_ctrl.pb.DataState.Identity.serviceHostingCosts:type_name -> ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingCostsEntry - 70, // 44: ziti.edge_ctrl.pb.DataState.Identity.serviceConfigs:type_name -> ziti.edge_ctrl.pb.DataState.Identity.ServiceConfigsEntry - 3, // 45: ziti.edge_ctrl.pb.DataState.ServicePolicy.policyType:type_name -> ziti.edge_ctrl.pb.PolicyType - 95, // 46: ziti.edge_ctrl.pb.DataState.Revocation.ExpiresAt:type_name -> google.protobuf.Timestamp - 4, // 47: ziti.edge_ctrl.pb.DataState.ServicePolicyChange.relatedEntityType:type_name -> ziti.edge_ctrl.pb.ServicePolicyRelatedEntityType - 64, // 48: ziti.edge_ctrl.pb.DataState.ChangeSet.changes:type_name -> ziti.edge_ctrl.pb.DataState.Event - 7, // 49: ziti.edge_ctrl.pb.DataState.Event.action:type_name -> ziti.edge_ctrl.pb.DataState.Action - 58, // 50: ziti.edge_ctrl.pb.DataState.Event.identity:type_name -> ziti.edge_ctrl.pb.DataState.Identity - 59, // 51: ziti.edge_ctrl.pb.DataState.Event.service:type_name -> ziti.edge_ctrl.pb.DataState.Service - 60, // 52: ziti.edge_ctrl.pb.DataState.Event.servicePolicy:type_name -> ziti.edge_ctrl.pb.DataState.ServicePolicy - 66, // 53: ziti.edge_ctrl.pb.DataState.Event.postureCheck:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck - 65, // 54: ziti.edge_ctrl.pb.DataState.Event.publicKey:type_name -> ziti.edge_ctrl.pb.DataState.PublicKey - 61, // 55: ziti.edge_ctrl.pb.DataState.Event.revocation:type_name -> ziti.edge_ctrl.pb.DataState.Revocation - 62, // 56: ziti.edge_ctrl.pb.DataState.Event.servicePolicyChange:type_name -> ziti.edge_ctrl.pb.DataState.ServicePolicyChange - 55, // 57: ziti.edge_ctrl.pb.DataState.Event.configType:type_name -> ziti.edge_ctrl.pb.DataState.ConfigType - 56, // 58: ziti.edge_ctrl.pb.DataState.Event.config:type_name -> ziti.edge_ctrl.pb.DataState.Config - 8, // 59: ziti.edge_ctrl.pb.DataState.PublicKey.usages:type_name -> ziti.edge_ctrl.pb.DataState.PublicKey.Usage - 9, // 60: ziti.edge_ctrl.pb.DataState.PublicKey.format:type_name -> ziti.edge_ctrl.pb.DataState.PublicKey.Format - 71, // 61: ziti.edge_ctrl.pb.DataState.PostureCheck.mac:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Mac - 72, // 62: ziti.edge_ctrl.pb.DataState.PostureCheck.mfa:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Mfa - 74, // 63: ziti.edge_ctrl.pb.DataState.PostureCheck.osList:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.OsList - 75, // 64: ziti.edge_ctrl.pb.DataState.PostureCheck.process:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Process - 76, // 65: ziti.edge_ctrl.pb.DataState.PostureCheck.processMulti:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.ProcessMulti - 77, // 66: ziti.edge_ctrl.pb.DataState.PostureCheck.domains:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Domains - 5, // 67: ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingPrecedencesEntry.value:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 57, // 68: ziti.edge_ctrl.pb.DataState.Identity.ServiceConfigsEntry.value:type_name -> ziti.edge_ctrl.pb.DataState.ServiceConfigs - 73, // 69: ziti.edge_ctrl.pb.DataState.PostureCheck.OsList.osList:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Os - 75, // 70: ziti.edge_ctrl.pb.DataState.PostureCheck.ProcessMulti.processes:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Process - 5, // 71: ziti.edge_ctrl.pb.CreateApiSessionResponse.ServicePrecedencesEntry.value:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence - 93, // 72: ziti.edge_ctrl.pb.ConnectEvents.IdentityConnectEvents.connectTimes:type_name -> ziti.edge_ctrl.pb.ConnectEvents.ConnectDetails - 73, // [73:73] is the sub-list for method output_type - 73, // [73:73] is the sub-list for method input_type - 73, // [73:73] is the sub-list for extension type_name - 73, // [73:73] is the sub-list for extension extendee - 0, // [0:73] is the sub-list for field type_name + 55, // 0: ziti.edge_ctrl.pb.ServerHello.data:type_name -> ziti.edge_ctrl.pb.ServerHello.DataEntry + 56, // 1: ziti.edge_ctrl.pb.ServerHello.byteData:type_name -> ziti.edge_ctrl.pb.ServerHello.ByteDataEntry + 11, // 2: ziti.edge_ctrl.pb.Listener.address:type_name -> ziti.edge_ctrl.pb.Address + 11, // 3: ziti.edge_ctrl.pb.Listener.advertise:type_name -> ziti.edge_ctrl.pb.Address + 57, // 4: ziti.edge_ctrl.pb.ClientHello.data:type_name -> ziti.edge_ctrl.pb.ClientHello.DataEntry + 12, // 5: ziti.edge_ctrl.pb.ClientHello.listeners:type_name -> ziti.edge_ctrl.pb.Listener + 67, // 6: ziti.edge_ctrl.pb.DataState.events:type_name -> ziti.edge_ctrl.pb.DataState.Event + 16, // 7: ziti.edge_ctrl.pb.ApiSessionAdded.apiSessions:type_name -> ziti.edge_ctrl.pb.ApiSession + 16, // 8: ziti.edge_ctrl.pb.ApiSessionUpdated.apiSessions:type_name -> ziti.edge_ctrl.pb.ApiSession + 81, // 9: ziti.edge_ctrl.pb.CreateCircuitRequest.peerData:type_name -> ziti.edge_ctrl.pb.CreateCircuitRequest.PeerDataEntry + 82, // 10: ziti.edge_ctrl.pb.CreateCircuitResponse.peerData:type_name -> ziti.edge_ctrl.pb.CreateCircuitResponse.PeerDataEntry + 83, // 11: ziti.edge_ctrl.pb.CreateCircuitResponse.tags:type_name -> ziti.edge_ctrl.pb.CreateCircuitResponse.TagsEntry + 84, // 12: ziti.edge_ctrl.pb.CreateTerminatorRequest.peerData:type_name -> ziti.edge_ctrl.pb.CreateTerminatorRequest.PeerDataEntry + 5, // 13: ziti.edge_ctrl.pb.CreateTerminatorRequest.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 85, // 14: ziti.edge_ctrl.pb.CreateTerminatorV2Request.peerData:type_name -> ziti.edge_ctrl.pb.CreateTerminatorV2Request.PeerDataEntry + 5, // 15: ziti.edge_ctrl.pb.CreateTerminatorV2Request.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 6, // 16: ziti.edge_ctrl.pb.CreateTerminatorV2Response.result:type_name -> ziti.edge_ctrl.pb.CreateTerminatorResult + 5, // 17: ziti.edge_ctrl.pb.UpdateTerminatorRequest.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 32, // 18: ziti.edge_ctrl.pb.CreateApiSessionRequest.envInfo:type_name -> ziti.edge_ctrl.pb.EnvInfo + 33, // 19: ziti.edge_ctrl.pb.CreateApiSessionRequest.sdkInfo:type_name -> ziti.edge_ctrl.pb.SdkInfo + 5, // 20: ziti.edge_ctrl.pb.CreateApiSessionResponse.defaultHostingPrecedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 86, // 21: ziti.edge_ctrl.pb.CreateApiSessionResponse.servicePrecedences:type_name -> ziti.edge_ctrl.pb.CreateApiSessionResponse.ServicePrecedencesEntry + 87, // 22: ziti.edge_ctrl.pb.CreateApiSessionResponse.serviceCosts:type_name -> ziti.edge_ctrl.pb.CreateApiSessionResponse.ServiceCostsEntry + 88, // 23: ziti.edge_ctrl.pb.CreateCircuitForServiceRequest.peerData:type_name -> ziti.edge_ctrl.pb.CreateCircuitForServiceRequest.PeerDataEntry + 35, // 24: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.apiSession:type_name -> ziti.edge_ctrl.pb.CreateApiSessionResponse + 37, // 25: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.session:type_name -> ziti.edge_ctrl.pb.CreateSessionResponse + 89, // 26: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.peerData:type_name -> ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.PeerDataEntry + 90, // 27: ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.tags:type_name -> ziti.edge_ctrl.pb.CreateCircuitForServiceResponse.TagsEntry + 91, // 28: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Request.peerData:type_name -> ziti.edge_ctrl.pb.CreateTunnelCircuitV2Request.PeerDataEntry + 92, // 29: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.peerData:type_name -> ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.PeerDataEntry + 93, // 30: ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.tags:type_name -> ziti.edge_ctrl.pb.CreateTunnelCircuitV2Response.TagsEntry + 42, // 31: ziti.edge_ctrl.pb.ServicesList.services:type_name -> ziti.edge_ctrl.pb.TunnelService + 94, // 32: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequest.peerData:type_name -> ziti.edge_ctrl.pb.CreateTunnelTerminatorRequest.PeerDataEntry + 5, // 33: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequest.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 35, // 34: ziti.edge_ctrl.pb.CreateTunnelTerminatorResponse.apiSession:type_name -> ziti.edge_ctrl.pb.CreateApiSessionResponse + 37, // 35: ziti.edge_ctrl.pb.CreateTunnelTerminatorResponse.session:type_name -> ziti.edge_ctrl.pb.CreateSessionResponse + 95, // 36: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequestV2.peerData:type_name -> ziti.edge_ctrl.pb.CreateTunnelTerminatorRequestV2.PeerDataEntry + 5, // 37: ziti.edge_ctrl.pb.CreateTunnelTerminatorRequestV2.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 5, // 38: ziti.edge_ctrl.pb.UpdateTunnelTerminatorRequest.precedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 97, // 39: ziti.edge_ctrl.pb.ConnectEvents.events:type_name -> ziti.edge_ctrl.pb.ConnectEvents.IdentityConnectEvents + 15, // 40: ziti.edge_ctrl.pb.RouterDataModelValidateRequest.state:type_name -> ziti.edge_ctrl.pb.DataState + 98, // 41: ziti.edge_ctrl.pb.RouterDataModelValidateResponse.origEntityCounts:type_name -> ziti.edge_ctrl.pb.RouterDataModelValidateResponse.OrigEntityCountsEntry + 99, // 42: ziti.edge_ctrl.pb.RouterDataModelValidateResponse.copyEntityCounts:type_name -> ziti.edge_ctrl.pb.RouterDataModelValidateResponse.CopyEntityCountsEntry + 53, // 43: ziti.edge_ctrl.pb.RouterDataModelValidateResponse.diffs:type_name -> ziti.edge_ctrl.pb.RouterDataModelDiff + 70, // 44: ziti.edge_ctrl.pb.DataState.ServiceConfigs.configs:type_name -> ziti.edge_ctrl.pb.DataState.ServiceConfigs.ConfigsEntry + 5, // 45: ziti.edge_ctrl.pb.DataState.Identity.defaultHostingPrecedence:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 71, // 46: ziti.edge_ctrl.pb.DataState.Identity.serviceHostingPrecedences:type_name -> ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingPrecedencesEntry + 72, // 47: ziti.edge_ctrl.pb.DataState.Identity.serviceHostingCosts:type_name -> ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingCostsEntry + 73, // 48: ziti.edge_ctrl.pb.DataState.Identity.serviceConfigs:type_name -> ziti.edge_ctrl.pb.DataState.Identity.ServiceConfigsEntry + 3, // 49: ziti.edge_ctrl.pb.DataState.ServicePolicy.policyType:type_name -> ziti.edge_ctrl.pb.PolicyType + 100, // 50: ziti.edge_ctrl.pb.DataState.Revocation.ExpiresAt:type_name -> google.protobuf.Timestamp + 4, // 51: ziti.edge_ctrl.pb.DataState.ServicePolicyChange.relatedEntityType:type_name -> ziti.edge_ctrl.pb.ServicePolicyRelatedEntityType + 67, // 52: ziti.edge_ctrl.pb.DataState.ChangeSet.changes:type_name -> ziti.edge_ctrl.pb.DataState.Event + 7, // 53: ziti.edge_ctrl.pb.DataState.Event.action:type_name -> ziti.edge_ctrl.pb.DataState.Action + 61, // 54: ziti.edge_ctrl.pb.DataState.Event.identity:type_name -> ziti.edge_ctrl.pb.DataState.Identity + 62, // 55: ziti.edge_ctrl.pb.DataState.Event.service:type_name -> ziti.edge_ctrl.pb.DataState.Service + 63, // 56: ziti.edge_ctrl.pb.DataState.Event.servicePolicy:type_name -> ziti.edge_ctrl.pb.DataState.ServicePolicy + 69, // 57: ziti.edge_ctrl.pb.DataState.Event.postureCheck:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck + 68, // 58: ziti.edge_ctrl.pb.DataState.Event.publicKey:type_name -> ziti.edge_ctrl.pb.DataState.PublicKey + 64, // 59: ziti.edge_ctrl.pb.DataState.Event.revocation:type_name -> ziti.edge_ctrl.pb.DataState.Revocation + 65, // 60: ziti.edge_ctrl.pb.DataState.Event.servicePolicyChange:type_name -> ziti.edge_ctrl.pb.DataState.ServicePolicyChange + 58, // 61: ziti.edge_ctrl.pb.DataState.Event.configType:type_name -> ziti.edge_ctrl.pb.DataState.ConfigType + 59, // 62: ziti.edge_ctrl.pb.DataState.Event.config:type_name -> ziti.edge_ctrl.pb.DataState.Config + 8, // 63: ziti.edge_ctrl.pb.DataState.PublicKey.usages:type_name -> ziti.edge_ctrl.pb.DataState.PublicKey.Usage + 9, // 64: ziti.edge_ctrl.pb.DataState.PublicKey.format:type_name -> ziti.edge_ctrl.pb.DataState.PublicKey.Format + 74, // 65: ziti.edge_ctrl.pb.DataState.PostureCheck.mac:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Mac + 75, // 66: ziti.edge_ctrl.pb.DataState.PostureCheck.mfa:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Mfa + 77, // 67: ziti.edge_ctrl.pb.DataState.PostureCheck.osList:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.OsList + 78, // 68: ziti.edge_ctrl.pb.DataState.PostureCheck.process:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Process + 79, // 69: ziti.edge_ctrl.pb.DataState.PostureCheck.processMulti:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.ProcessMulti + 80, // 70: ziti.edge_ctrl.pb.DataState.PostureCheck.domains:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Domains + 5, // 71: ziti.edge_ctrl.pb.DataState.Identity.ServiceHostingPrecedencesEntry.value:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 60, // 72: ziti.edge_ctrl.pb.DataState.Identity.ServiceConfigsEntry.value:type_name -> ziti.edge_ctrl.pb.DataState.ServiceConfigs + 76, // 73: ziti.edge_ctrl.pb.DataState.PostureCheck.OsList.osList:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Os + 78, // 74: ziti.edge_ctrl.pb.DataState.PostureCheck.ProcessMulti.processes:type_name -> ziti.edge_ctrl.pb.DataState.PostureCheck.Process + 5, // 75: ziti.edge_ctrl.pb.CreateApiSessionResponse.ServicePrecedencesEntry.value:type_name -> ziti.edge_ctrl.pb.TerminatorPrecedence + 96, // 76: ziti.edge_ctrl.pb.ConnectEvents.IdentityConnectEvents.connectTimes:type_name -> ziti.edge_ctrl.pb.ConnectEvents.ConnectDetails + 77, // [77:77] is the sub-list for method output_type + 77, // [77:77] is the sub-list for method input_type + 77, // [77:77] is the sub-list for extension type_name + 77, // [77:77] is the sub-list for extension extendee + 0, // [0:77] is the sub-list for field type_name } func init() { file_edge_ctrl_proto_init() } @@ -6917,7 +7170,43 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RouterDataModelValidateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_edge_ctrl_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RouterDataModelDiff); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_edge_ctrl_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RouterDataModelValidateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_edge_ctrl_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_ConfigType); i { case 0: return &v.state @@ -6929,7 +7218,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_Config); i { case 0: return &v.state @@ -6941,7 +7230,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_ServiceConfigs); i { case 0: return &v.state @@ -6953,7 +7242,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_Identity); i { case 0: return &v.state @@ -6965,7 +7254,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_Service); i { case 0: return &v.state @@ -6977,7 +7266,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_ServicePolicy); i { case 0: return &v.state @@ -6989,7 +7278,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_Revocation); i { case 0: return &v.state @@ -7001,7 +7290,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_ServicePolicyChange); i { case 0: return &v.state @@ -7013,7 +7302,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_ChangeSet); i { case 0: return &v.state @@ -7025,7 +7314,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_Event); i { case 0: return &v.state @@ -7037,7 +7326,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_PublicKey); i { case 0: return &v.state @@ -7049,7 +7338,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_PostureCheck); i { case 0: return &v.state @@ -7061,7 +7350,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_PostureCheck_Mac); i { case 0: return &v.state @@ -7073,7 +7362,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_PostureCheck_Mfa); i { case 0: return &v.state @@ -7085,7 +7374,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_PostureCheck_Os); i { case 0: return &v.state @@ -7097,7 +7386,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_PostureCheck_OsList); i { case 0: return &v.state @@ -7109,7 +7398,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_PostureCheck_Process); i { case 0: return &v.state @@ -7121,7 +7410,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_PostureCheck_ProcessMulti); i { case 0: return &v.state @@ -7133,7 +7422,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DataState_PostureCheck_Domains); i { case 0: return &v.state @@ -7145,7 +7434,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[86].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ConnectEvents_ConnectDetails); i { case 0: return &v.state @@ -7157,7 +7446,7 @@ func file_edge_ctrl_proto_init() { return nil } } - file_edge_ctrl_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} { + file_edge_ctrl_proto_msgTypes[87].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ConnectEvents_IdentityConnectEvents); i { case 0: return &v.state @@ -7170,7 +7459,7 @@ func file_edge_ctrl_proto_init() { } } } - file_edge_ctrl_proto_msgTypes[54].OneofWrappers = []interface{}{ + file_edge_ctrl_proto_msgTypes[57].OneofWrappers = []interface{}{ (*DataState_Event_Identity)(nil), (*DataState_Event_Service)(nil), (*DataState_Event_ServicePolicy)(nil), @@ -7181,7 +7470,7 @@ func file_edge_ctrl_proto_init() { (*DataState_Event_ConfigType)(nil), (*DataState_Event_Config)(nil), } - file_edge_ctrl_proto_msgTypes[56].OneofWrappers = []interface{}{ + file_edge_ctrl_proto_msgTypes[59].OneofWrappers = []interface{}{ (*DataState_PostureCheck_Mac_)(nil), (*DataState_PostureCheck_Mfa_)(nil), (*DataState_PostureCheck_OsList_)(nil), @@ -7195,7 +7484,7 @@ func file_edge_ctrl_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_edge_ctrl_proto_rawDesc, NumEnums: 10, - NumMessages: 85, + NumMessages: 90, NumExtensions: 0, NumServices: 0, }, diff --git a/common/pb/edge_ctrl_pb/edge_ctrl.proto b/common/pb/edge_ctrl_pb/edge_ctrl.proto index 0228524fa..ebc79e55c 100644 --- a/common/pb/edge_ctrl_pb/edge_ctrl.proto +++ b/common/pb/edge_ctrl_pb/edge_ctrl.proto @@ -65,6 +65,8 @@ enum ContentType { DataStateType = 20500; DataStateChangeSetType = 20501; UpdateTokenType = 20502; + ValidateDataStateRequestType = 20503; + ValidateDataStateResponseType = 20504; } enum SessionType { @@ -572,4 +574,22 @@ message ConnectEvents { repeated IdentityConnectEvents events = 1; bool fullState = 2; +} + +message RouterDataModelValidateRequest { + DataState state = 1; + bool fix = 2; +} + +message RouterDataModelDiff { + string entityType = 1; + string entityId = 2; + string diffType = 3; + string detail = 4; +} + +message RouterDataModelValidateResponse { + map origEntityCounts = 1; + map copyEntityCounts = 2; + repeated RouterDataModelDiff diffs = 3; } \ No newline at end of file diff --git a/common/pb/edge_ctrl_pb/impl.go b/common/pb/edge_ctrl_pb/impl.go index c02c48e03..5e3d52fce 100644 --- a/common/pb/edge_ctrl_pb/impl.go +++ b/common/pb/edge_ctrl_pb/impl.go @@ -16,6 +16,10 @@ package edge_ctrl_pb +import ( + "fmt" +) + func (x *DataState_Identity) GetServiceConfigsAsMap() map[string]map[string]string { if x.ServiceConfigs == nil { return nil @@ -32,3 +36,15 @@ func (x *DataState_Identity) GetServiceConfigsAsMap() map[string]map[string]stri return result } + +func (request *RouterDataModelValidateRequest) GetContentType() int32 { + return int32(ContentType_ValidateDataStateRequestType) +} + +func (request *RouterDataModelValidateResponse) GetContentType() int32 { + return int32(ContentType_ValidateDataStateResponseType) +} + +func (diff *RouterDataModelDiff) ToDetail() string { + return fmt.Sprintf("%s id: %s %s: %s", diff.EntityType, diff.EntityId, diff.DiffType, diff.Detail) +} diff --git a/common/router_data_model.go b/common/router_data_model.go index 280e3f55c..7d449b366 100644 --- a/common/router_data_model.go +++ b/common/router_data_model.go @@ -17,11 +17,13 @@ package common import ( + "bytes" "compress/gzip" "crypto" "crypto/x509" "encoding/json" "fmt" + "github.com/google/go-cmp/cmp" "github.com/michaelquigley/pfxlog" "github.com/openziti/foundation/v2/concurrenz" "github.com/openziti/ziti/common/pb/edge_ctrl_pb" @@ -116,6 +118,21 @@ type RouterDataModel struct { stopped atomic.Bool } +// NewBareRouterDataModel creates a new RouterDataModel that is expected to have no buffers, listeners or subscriptions +func NewBareRouterDataModel() *RouterDataModel { + return &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](), + } +} + // NewSenderRouterDataModel creates a new RouterDataModel that will store events in a circular buffer of // logSize. listenerBufferSize affects the buffer size of channels returned to listeners of the data model. func NewSenderRouterDataModel(logSize uint64, listenerBufferSize uint) *RouterDataModel { @@ -156,6 +173,30 @@ func NewReceiverRouterDataModel(listenerBufferSize uint, closeNotify <-chan stru 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 { + result := &RouterDataModel{ + EventCache: NewForgetfulEventCache(), + ConfigTypes: existing.ConfigTypes, + Configs: existing.Configs, + Identities: existing.Identities, + Services: existing.Services, + ServicePolicies: existing.ServicePolicies, + PostureChecks: existing.PostureChecks, + PublicKeys: existing.PublicKeys, + CachedPublicKeys: existing.CachedPublicKeys, + Revocations: existing.Revocations, + listenerBufferSize: listenerBufferSize, + subscriptions: cmap.New[*IdentitySubscription](), + events: make(chan subscriberEvent), + closeNotify: closeNotify, + stopNotify: make(chan struct{}), + } + go result.processSubscriberEvents() + return result +} + // NewReceiverRouterDataModelFromFile creates a new RouterDataModel that does not store events and is initialized from // a file backup. listenerBufferSize affects the buffer size of channels returned to listeners of the data model. func NewReceiverRouterDataModelFromFile(path string, listenerBufferSize uint, closeNotify <-chan struct{}) (*RouterDataModel, error) { @@ -516,6 +557,14 @@ func (rdm *RouterDataModel) GetPublicKeys() map[string]crypto.PublicKey { return rdm.CachedPublicKeys.Load() } +func (rdm *RouterDataModel) getPublicKeysAsCmap() cmap.ConcurrentMap[string, crypto.PublicKey] { + m := cmap.New[crypto.PublicKey]() + for k, v := range rdm.CachedPublicKeys.Load() { + m.Set(k, v) + } + return m +} + func (rdm *RouterDataModel) recalculateCachedPublicKeys() { publicKeys := map[string]crypto.PublicKey{} rdm.PublicKeys.IterCb(func(kid string, pubKey *edge_ctrl_pb.DataState_PublicKey) { @@ -924,3 +973,106 @@ func (rdm *RouterDataModel) loadIdentityConfig(configId string, log *logrus.Entr ConfigType: configType, } } + +func (rdm *RouterDataModel) GetEntityCounts() map[string]uint32 { + result := map[string]uint32{ + "configType": uint32(rdm.ConfigTypes.Count()), + "configs": uint32(rdm.Configs.Count()), + "identities": uint32(rdm.Identities.Count()), + "services": uint32(rdm.Services.Count()), + "service-policies": uint32(rdm.ServicePolicies.Count()), + "posture-checks": uint32(rdm.PostureChecks.Count()), + "public-keys": uint32(rdm.PublicKeys.Count()), + "revocations": uint32(rdm.Revocations.Count()), + "cached-public-keys": uint32(rdm.getPublicKeysAsCmap().Count()), + } + return result +} + +type DiffType string + +const ( + DiffTypeAdd = "added" + DiffTypeMod = "modified" + DiffTypeSub = "removed" +) + +type DiffSink func(entityType string, id string, diffType DiffType, detail string) + +func (rdm *RouterDataModel) Diff(o *RouterDataModel, sink DiffSink) { + if o == nil { + sink("router-data-model", "root", DiffTypeSub, "router data model not present") + return + } + + diffType("configType", rdm.ConfigTypes, o.ConfigTypes, sink) + diffType("config", rdm.Configs, o.Configs, sink) + diffType("identity", rdm.Identities, o.Identities, sink) + diffType("service", rdm.Services, o.Services, sink) + diffType("service-policy", rdm.ServicePolicies, o.ServicePolicies, sink) + diffType("posture-check", rdm.PostureChecks, o.PostureChecks, sink) + diffType("public-keys", rdm.PublicKeys, o.PublicKeys, sink) + diffType("revocations", rdm.Revocations, o.Revocations, sink) + diffType("cached-public-keys", rdm.getPublicKeysAsCmap(), o.getPublicKeysAsCmap(), sink) +} + +func diffType[T any](entityType string, m1 cmap.ConcurrentMap[string, T], m2 cmap.ConcurrentMap[string, T], sink DiffSink) { + diffReporter := &compareReporter{ + f: func(key string, detail string) { + sink(entityType, key, DiffTypeMod, detail) + }, + } + + hasMissing := false + adapter := cmp.Reporter(diffReporter) + m1.IterCb(func(key string, v T) { + v2, exists := m2.Get(key) + if !exists { + sink(entityType, key, DiffTypeSub, "entity missing") + hasMissing = true + } else { + diffReporter.key = key + cmp.Diff(v, v2, adapter) + } + }) + + if m1.Count() != m2.Count() || hasMissing { + m2.IterCb(func(key string, v2 T) { + if _, exists := m1.Get(key); !exists { + sink(entityType, key, DiffTypeAdd, "entity unexpected") + } + }) + } +} + +type compareReporter struct { + steps []cmp.PathStep + key string + f func(key string, detail string) +} + +func (self *compareReporter) PushStep(step cmp.PathStep) { + self.steps = append(self.steps, step) +} + +func (self *compareReporter) Report(result cmp.Result) { + if !result.Equal() { + var step cmp.PathStep + path := &bytes.Buffer{} + for _, v := range self.steps { + path.Write([]byte(v.String())) + step = v + } + if step != nil { + vx, vy := step.Values() + err := fmt.Sprintf("%s mismatch. orig: %s, copy: %s", path.String(), vx.String(), vy.String()) + self.f(self.key, err) + } else { + self.f(self.key, "programming error, empty path stack") + } + } +} + +func (self *compareReporter) PopStep() { + self.steps = self.steps[:len(self.steps)-1] +} diff --git a/controller/env/broker.go b/controller/env/broker.go index 6673ebe5e..8b6edb451 100644 --- a/controller/env/broker.go +++ b/controller/env/broker.go @@ -21,6 +21,7 @@ import ( "github.com/michaelquigley/pfxlog" "github.com/openziti/channel/v3" "github.com/openziti/storage/boltz" + "github.com/openziti/ziti/common" "github.com/openziti/ziti/common/pb/edge_ctrl_pb" "github.com/openziti/ziti/controller/db" "github.com/openziti/ziti/controller/event" @@ -37,6 +38,7 @@ const ( ApiSessionUpdatedType = int32(edge_ctrl_pb.ContentType_ApiSessionUpdatedType) RequestClientReSyncType = int32(edge_ctrl_pb.ContentType_RequestClientReSyncType) DataStateType = int32(edge_ctrl_pb.ContentType_DataStateType) + ValidateDataStateType = int32(edge_ctrl_pb.ContentType_ValidateDataStateRequestType) DataStateChangeSetType = int32(edge_ctrl_pb.ContentType_DataStateChangeSetType) ServerHelloType = int32(edge_ctrl_pb.ContentType_ServerHelloType) @@ -87,6 +89,10 @@ func (broker *Broker) ValidateRouterDataModel() []error { return broker.routerSyncStrategy.Validate() } +func (broker *Broker) GetRouterDataModel() *common.RouterDataModel { + return broker.routerSyncStrategy.GetRouterDataModel() +} + func (broker *Broker) AcceptClusterEvent(clusterEvent *event.ClusterEvent) { if clusterEvent.EventType == event.ClusterLeadershipGained { broker.ae.Managers.Controller.PeersConnected(clusterEvent.Peers, false) diff --git a/controller/env/sync.go b/controller/env/sync.go index d40707860..bcf69f175 100644 --- a/controller/env/sync.go +++ b/controller/env/sync.go @@ -20,6 +20,7 @@ import ( "crypto" "github.com/openziti/channel/v3" "github.com/openziti/foundation/v2/versions" + "github.com/openziti/ziti/common" "github.com/openziti/ziti/controller/db" "github.com/openziti/ziti/controller/model" "sync" @@ -62,6 +63,7 @@ type RouterSyncStrategy interface { RouterConnectionHandler RouterSynchronizerEventHandler Validate() []error + GetRouterDataModel() *common.RouterDataModel } // RouterConnectionHandler is responsible for handling router connect/disconnect for synchronizing state. diff --git a/controller/handler_mgmt/bind.go b/controller/handler_mgmt/bind.go index a71057577..2bffdb177 100644 --- a/controller/handler_mgmt/bind.go +++ b/controller/handler_mgmt/bind.go @@ -32,7 +32,11 @@ type BindHandler struct { } func NewBindHandler(env *env.AppEnv, network *network.Network, xmgmts *concurrenz.CopyOnWriteSlice[xmgmt.Xmgmt]) channel.BindHandler { - return &BindHandler{network: network, xmgmts: xmgmts} + return &BindHandler{ + env: env, + network: network, + xmgmts: xmgmts, + } } func (bindHandler *BindHandler) BindChannel(binding channel.Binding) error { diff --git a/controller/handler_mgmt/validate_router_data_model.go b/controller/handler_mgmt/validate_router_data_model.go index 5202d89a5..f3f1f7b8d 100644 --- a/controller/handler_mgmt/validate_router_data_model.go +++ b/controller/handler_mgmt/validate_router_data_model.go @@ -22,8 +22,10 @@ import ( "github.com/openziti/channel/v3" "github.com/openziti/channel/v3/protobufs" "github.com/openziti/foundation/v2/concurrenz" + "github.com/openziti/ziti/common/pb/edge_ctrl_pb" "github.com/openziti/ziti/common/pb/mgmt_pb" "github.com/openziti/ziti/controller/env" + "github.com/openziti/ziti/controller/model" "github.com/openziti/ziti/controller/network" "google.golang.org/protobuf/proto" "time" @@ -128,21 +130,18 @@ func (handler *validateRouterDataModelHandler) ValidateRouterDataModel(includeCt cb(details) }() } + + var dataState *edge_ctrl_pb.DataState for _, router := range result.Entities { connectedRouter := handler.appEnv.GetHostController().GetNetwork().GetConnectedRouter(router.Id) if connectedRouter != nil { + if dataState == nil { + dataState = handler.appEnv.Broker.GetRouterDataModel().GetDataState() + } sem.Acquire() go func() { defer sem.Release() - - details := &mgmt_pb.RouterDataModelDetails{ - ComponentType: "router", - ComponentId: router.Id, - ComponentName: router.Name, - ValidateSuccess: false, - Errors: []string{"not yet implemented"}, - } - cb(details) + handler.ValidateRouterDataModelOnRouter(connectedRouter, dataState, cb) }() } else { details := &mgmt_pb.RouterDataModelDetails{ @@ -164,3 +163,33 @@ func (handler *validateRouterDataModelHandler) ValidateRouterDataModel(includeCt return count, evalF, nil } + +func (handler *validateRouterDataModelHandler) ValidateRouterDataModelOnRouter(router *model.Router, dataState *edge_ctrl_pb.DataState, cb RouterDataModelValidationCallback) { + details := &mgmt_pb.RouterDataModelDetails{ + ComponentType: "router", + ComponentId: router.Id, + ComponentName: router.Name, + } + + request := &edge_ctrl_pb.RouterDataModelValidateRequest{ + State: dataState, + } + 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 { + details.Errors = []string{fmt.Sprintf("unable to validate router data (%s)", err.Error())} + cb(details) + return + } + + if len(resp.Diffs) == 0 { + details.ValidateSuccess = true + cb(details) + } else { + details.ValidateSuccess = false + for _, diff := range resp.Diffs { + details.Errors = append(details.Errors, diff.ToDetail()) + } + cb(details) + } +} diff --git a/controller/sync_strats/sync_instant.go b/controller/sync_strats/sync_instant.go index ecabe53da..886761576 100644 --- a/controller/sync_strats/sync_instant.go +++ b/controller/sync_strats/sync_instant.go @@ -1337,6 +1337,10 @@ func (strategy *InstantStrategy) BuildPostureChecks(index uint64, tx *bbolt.Tx, return nil } +func (strategy *InstantStrategy) GetRouterDataModel() *common.RouterDataModel { + return strategy.RouterDataModel +} + func (strategy *InstantStrategy) Validate() []error { return strategy.ValidateAll(strategy.RouterDataModel) } diff --git a/router/state/manager.go b/router/state/manager.go index 7922eac47..9cee83ff2 100644 --- a/router/state/manager.go +++ b/router/state/manager.go @@ -60,6 +60,7 @@ type DisconnectCB func(token string) type Env interface { IsHaEnabled() bool GetCloseNotify() <-chan struct{} + DefaultRequestTimeout() time.Duration } type Manager interface { @@ -876,6 +877,7 @@ func (sm *ManagerImpl) BindChannel(binding channel.Binding) error { binding.AddTypedReceiveHandler(NewApiSessionUpdatedHandler(sm)) binding.AddTypedReceiveHandler(NewDataStateHandler(sm)) binding.AddTypedReceiveHandler(NewDataStateEventHandler(sm)) + binding.AddTypedReceiveHandler(NewValidateDataStateRequestHandler(sm, sm.env)) return nil } diff --git a/router/state/validate.go b/router/state/validate.go new file mode 100644 index 000000000..f5ea0de8a --- /dev/null +++ b/router/state/validate.go @@ -0,0 +1,77 @@ +package state + +import ( + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel/v3" + "github.com/openziti/channel/v3/protobufs" + "github.com/openziti/ziti/common" + "github.com/openziti/ziti/common/pb/edge_ctrl_pb" + controllerEnv "github.com/openziti/ziti/controller/env" + log "github.com/sirupsen/logrus" + "google.golang.org/protobuf/proto" +) + +type ValidateDataStateRequestHandler struct { + state Manager + env Env +} + +func NewValidateDataStateRequestHandler(state Manager, env Env) *ValidateDataStateRequestHandler { + return &ValidateDataStateRequestHandler{ + state: state, + env: env, + } +} + +func (*ValidateDataStateRequestHandler) ContentType() int32 { + return controllerEnv.ValidateDataStateType +} + +func (self *ValidateDataStateRequestHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { + request := &edge_ctrl_pb.RouterDataModelValidateRequest{} + + if err := proto.Unmarshal(msg.Body, request); err != nil { + pfxlog.Logger().WithError(err).Errorf("could not unmarshal validate data state request") + return + } + + newState := request.State + model := common.NewBareRouterDataModel() + + for _, event := range newState.Events { + model.Handle(newState.EndIndex, event) + } + + model.SetCurrentIndex(newState.EndIndex) + current := self.state.RouterDataModel() + + response := &edge_ctrl_pb.RouterDataModelValidateResponse{ + OrigEntityCounts: model.GetEntityCounts(), + CopyEntityCounts: current.GetEntityCounts(), + } + + model.Diff(current, func(entityType string, id string, diffType common.DiffType, detail string) { + response.Diffs = append(response.Diffs, &edge_ctrl_pb.RouterDataModelDiff{ + EntityType: entityType, + EntityId: id, + DiffType: string(diffType), + Detail: detail, + }) + }) + + if len(response.Diffs) > 0 && request.Fix { + model = common.NewReceiverRouterDataModelFromExisting(model, RouterDataModelListerBufferSize, self.state.GetEnv().GetCloseNotify()) + self.state.SetRouterDataModel(model) + } + + go func() { + err := protobufs.MarshalTyped(response). + ReplyTo(msg). + WithTimeout(self.env.DefaultRequestTimeout()). + SendAndWaitForWire(ch) + + if err != nil { + log.WithError(err).Error("failed to send validate router data model response") + } + }() +} diff --git a/zititest/models/links-test/validation.go b/zititest/models/links-test/validation.go index 135664fa8..bc3c43940 100644 --- a/zititest/models/links-test/validation.go +++ b/zititest/models/links-test/validation.go @@ -44,7 +44,7 @@ func sowChaos(run model.Run) error { } toRestart := append(routers, controllers...) fmt.Printf("restarting %v controllers and %v routers\n", len(controllers), len(routers)) - return chaos.RestartSelected(run, toRestart, 100) + return chaos.RestartSelected(run, 100, toRestart...) } func validateLinks(run model.Run) error { diff --git a/zititest/models/router-data-model-test/configs/ctrl.yml.tmpl b/zititest/models/router-data-model-test/configs/ctrl.yml.tmpl new file mode 100644 index 000000000..4e9464ee9 --- /dev/null +++ b/zititest/models/router-data-model-test/configs/ctrl.yml.tmpl @@ -0,0 +1,201 @@ +v: 3 + +{{if .Component.GetFlag "ha"}} +raft: + minClusterSize: 3 + dataDir: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/fablab/ctrldata +{{else}} +db: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/ctrl.db +{{end}} + +identity: + cert: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/fablab/pki/{{ .Component.Id }}/certs/{{ .Component.Id }}-server.chain.pem + key: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/fablab/pki/{{ .Component.Id }}/keys/{{ .Component.Id }}-server.key + ca: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/fablab/pki/{{ .Component.Id }}/certs/{{ .Component.Id }}.chain.pem + +trustDomain: sdk-hosting-test + +commandRateLimiter: + enabled: true + maxQueued: 25 + +# the endpoint that routers will connect to the controller over. +ctrl: + listener: tls:0.0.0.0:6262 + options: + advertiseAddress: tls:{{ .Host.PublicIp }}:6262 + # (optional) settings + # set the maximum number of connect requests that are buffered and waiting to be acknowledged (1 to 5000, default 1000) + #maxQueuedConnects: 50 + + # the maximum number of connects that have begun hello synchronization (1 to 1000, default 16) + #maxOutstandingConnects: 100 + + # the number of milliseconds to wait before a hello synchronization fails and closes the connection (30ms to 60000ms, default: 1000ms) + #connectTimeoutMs: 3000 + + # Sets the control channel write timeout. A write timeout will close the control channel, so the router will reconnect + #writeTimeout: 15s + + # A listener address which will be sent to connecting routers in order to change their configured controller + # address. If defined, routers will update address configuration to immediately use the new address for future + # connections. The value of newListener must be resolvable both via DNS and validate via certificates + #newListener: tls:localhost:6262 + +events: + jsonLogger: + subscriptions: + - type: entityChange + - type: edge.apiSessions + - type: edge.entityCounts + interval: 15s + - type: edge.sessions + - type: fabric.routers + - type: fabric.terminators +# - type: metrics +# sourceFilter: .* +# metricFilter: .*egress.*m1_rate* +# - type: fabric.circuits +# include: +# - created +# include: +# - created +# - type: fabric.usage +# - type: services +# - type: fabric.usage + handler: + type: file + format: json + path: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/logs/event.log + +healthChecks: + boltCheck: + # How often to try entering a bolt read tx. Defaults to 30 seconds + interval: 30s + # When to timeout the check. Defaults to 15 seconds + timeout: 15s + # How long to wait before starting the check. Defaults to 15 seconds + initialDelay: 15s + +# By having an 'edge' section defined, the ziti-controller will attempt to parse the edge configuration. Removing this +# section, commenting out, or altering the name of the section will cause the edge to not run. +edge: + # This section represents the configuration of the Edge API that is served over HTTPS + api: + #(optional, default 90s) Alters how frequently heartbeat and last activity values are persisted + # activityUpdateInterval: 90s + #(optional, default 250) The number of API Sessions updated for last activity per transaction + # activityUpdateBatchSize: 250 + # sessionTimeout - optional, default 10m + # The number of minutes before an Edge API session will timeout. Timeouts are reset by + # API requests and connections that are maintained to Edge Routers + sessionTimeout: 30m + # address - required + # The default address (host:port) to use for enrollment for the Client API. This value must match one of the addresses + # defined in a bind point's address field for the `edge-client` API in the web section. + address: {{ .Host.PublicIp }}:1280 + # enrollment - required + # A section containing settings pertaining to enrollment. + enrollment: + # signingCert - required + # A Ziti Identity configuration section that specifically makes use of the cert and key fields to define + # a signing certificate from the PKI that the Ziti environment is using to sign certificates. The signingCert.cert + # will be added to the /.well-known CA store that is used to bootstrap trust with the Ziti Controller. + signingCert: + cert: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/fablab/pki/{{ .Component.Id }}/certs/{{ .Component.Id }}.cert + key: /home/{{ .Model.MustVariable "credentials.ssh.username" }}/fablab/pki/{{ .Component.Id }}/keys/{{ .Component.Id }}.key + + # edgeIdentity - optional + # A section for identity enrollment specific settings + edgeIdentity: + # duration - optional, default 5m + # The length of time that a Ziti Edge Identity enrollment should remain valid. After + # this duration, the enrollment will expire and not longer be usable. + duration: 1h + # edgeRouter - Optional + # A section for edge router enrollment specific settings. + edgeRouter: + # duration - optional, default 5m + # The length of time that a Ziti Edge Router enrollment should remain valid. After + # this duration, the enrollment will expire and not longer be usable. + duration: 1h + + +# web - optional +# Defines webListeners that will be hosted by the controller. Each webListener can host many APIs and be bound to many +# bind points. +web: + # name - required + # Provides a name for this listener, used for logging output. Not required to be unique, but is highly suggested. + - name: all-apis-localhost + # bindPoints - required + # One or more bind points are required. A bind point specifies an interface (interface:port string) that defines + # where on the host machine the webListener will listen and the address (host:port) that should be used to + # publicly address the webListener(i.e. mydomain.com, localhost, 127.0.0.1). This public address may be used for + # incoming address resolution as well as used in responses in the API. + bindPoints: + #interface - required + # A host:port string on which network interface to listen on. 0.0.0.0 will listen on all interfaces + - interface: 0.0.0.0:1280 + + # address - required + # The public address that external incoming requests will be able to resolve. Used in request processing and + # response content that requires full host:port/path addresses. + address: {{ .Host.PublicIp }}:1280 + + # newAddress - optional + # A host:port string which will be sent out as an HTTP header "ziti-new-address" if specified. If the header + # is present, clients should update location configuration to immediately use the new address for future + # connections. The value of newAddress must be resolvable both via DNS and validate via certificates + #newAddress: localhost:1280 + # identity - optional + # Allows the webListener to have a specific identity instead of defaulting to the root `identity` section. + # identity: + # cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-client.cert.pem + # server_cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-server.cert.pem + # key: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/private/ctrl.key.pem + # ca: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ca-chain.cert.pem + # options - optional + # Allows the specification of webListener level options - mainly dealing with HTTP/TLS settings. These options are + # used for all http servers started by the current webListener. + options: + # idleTimeout - optional, default 5000ms + # The maximum amount of idle time in milliseconds allowed for pipelined HTTP requests. Setting this too high + # can cause resources on the host to be consumed as clients remain connected and idle. Lowering this value + # will cause clients to reconnect on subsequent HTTPs requests. + idleTimeout: 5000ms #http timeouts, new + + # readTimeout - optional, default 5000ms + # The maximum amount of time in milliseconds http servers will wait to read the first incoming requests. A higher + # value risks consuming resources on the host with clients that are acting bad faith or suffering from high latency + # or packet loss. A lower value can risk losing connections to high latency/packet loss clients. + + readTimeout: 5000ms + # writeTimeout - optional, default 10000ms + # The total maximum time in milliseconds that the http server will wait for a single requests to be received and + # responded too. A higher value can allow long running requests to consume resources on the host. A lower value + # can risk ending requests before the server has a chance to respond. + + writeTimeout: 100000ms + # minTLSVersion - optional, default TSL1.2 + # The minimum version of TSL to support + + minTLSVersion: TLS1.2 + # maxTLSVersion - optional, default TSL1.3 + # The maximum version of TSL to support + + maxTLSVersion: TLS1.3 + # apis - required + # Allows one or more APIs to be bound to this webListener + apis: + # binding - required + # Specifies an API to bind to this webListener. Built-in APIs are + # - health-checks + # - edge-management + # - edge-client + # - fabric-management + - binding: health-checks + - binding: fabric + - binding: edge-management + - binding: edge-client + - binding: edge-oidc \ No newline at end of file diff --git a/zititest/models/router-data-model-test/configs/router.yml.tmpl b/zititest/models/router-data-model-test/configs/router.yml.tmpl new file mode 100644 index 000000000..8e42c4598 --- /dev/null +++ b/zititest/models/router-data-model-test/configs/router.yml.tmpl @@ -0,0 +1,81 @@ +{{$ssh_username := .Model.MustVariable "credentials.ssh.username"}} +{{$identity := .Component.Id}} +{{$router_ip := .Host.PublicIp}} + +v: 3 + +enableDebugOps: true + +{{if .Component.GetFlag "ha"}} +ha: + enabled: true +{{end}} + +identity: + cert: /home/{{$ssh_username}}/fablab/cfg/{{$identity}}-client.cert + server_cert: /home/{{$ssh_username}}/fablab/cfg/{{$identity}}-server.cert + key: /home/{{$ssh_username}}/fablab/cfg/{{$identity}}.key + ca: /home/{{$ssh_username}}/fablab/cfg/{{$identity}}-server.chain.pem + +tls: + handshakeTimeout: 30s + +ctrl: + endpoints: {{ range $host := .Model.MustSelectHosts "component.ctrl" 1 }} + - tls:{{ $host.PublicIp }}:6262{{end}} + startupTimeout: 5m + +healthChecks: + ctrlPingCheck: + # How often to ping the controller over the control channel. Defaults to 30 seconds + interval: 30s + # When to timeout the ping. Defaults to 15 seconds + timeout: 15s + # How long to wait before pinging the controller. Defaults to 15 seconds + initialDelay: 15s + +metrics: + reportInterval: 15s + messageQueueSize: 10 + +link: + listeners: + - binding: transport + bind: tls:0.0.0.0:6000 + advertise: tls:{{$router_ip}}:6000 + dialers: + - binding: transport + options: + connectTimeout: 30s + +listeners: +{{if .Component.HasTag "tunneler"}} + - binding: tunnel + options: + mode: host +{{end}} + - binding: edge + address: tls:0.0.0.0:6262 + options: + # (required) The public hostname and port combination that Ziti SDKs should connect on. Previously this was in the chanIngress section. + advertise: {{ .Host.PublicIp }}:6262 + +# By having an 'edge' section defined, the ziti router will attempt to parse the edge configuration. Removing this +# section, commenting out, or altering the name of the section will cause the router to no longer operate as an Edge +# Router. +edge: + # (required) Information used to generate the initial registration CSR. For documentation on these fields please + # refer to the openssl documentation. These values MUST be supplied and have no defaults. + csr: + country: US + province: NC + locality: Charlotte + organization: NetFoundry + organizationalUnit: Ziti + + # (required) SANs that this Gateways certs should contain. At least one IP or DNS SAN should be defined that matches + # the edge listeners "advertise" value from the "listeners" section. + sans: + ip: + - {{ .Host.PublicIp }} + diff --git a/zititest/models/router-data-model-test/main.go b/zititest/models/router-data-model-test/main.go new file mode 100644 index 000000000..86e387fcc --- /dev/null +++ b/zititest/models/router-data-model-test/main.go @@ -0,0 +1,398 @@ +package main + +import ( + "embed" + _ "embed" + "fmt" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/fablab" + "github.com/openziti/fablab/kernel/lib/actions" + "github.com/openziti/fablab/kernel/lib/actions/component" + "github.com/openziti/fablab/kernel/lib/actions/host" + "github.com/openziti/fablab/kernel/lib/actions/semaphore" + "github.com/openziti/fablab/kernel/lib/binding" + "github.com/openziti/fablab/kernel/lib/parallel" + "github.com/openziti/fablab/kernel/lib/runlevel/0_infrastructure/aws_ssh_key" + "github.com/openziti/fablab/kernel/lib/runlevel/0_infrastructure/semaphore" + "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" + awsSshKeyDispose "github.com/openziti/fablab/kernel/lib/runlevel/6_disposal/aws_ssh_key" + "github.com/openziti/fablab/kernel/lib/runlevel/6_disposal/terraform" + "github.com/openziti/fablab/kernel/model" + "github.com/openziti/fablab/resources" + "github.com/openziti/ziti/zititest/models/test_resources" + "github.com/openziti/ziti/zititest/zitilab" + zitilibActions "github.com/openziti/ziti/zititest/zitilab/actions" + "github.com/openziti/ziti/zititest/zitilab/actions/edge" + "github.com/openziti/ziti/zititest/zitilab/chaos" + "github.com/openziti/ziti/zititest/zitilab/models" + "os" + "path" + "time" +) + +const TargetZitiVersion = "" + +//go:embed configs +var configResource embed.FS + +type scaleStrategy struct{} + +func (self scaleStrategy) IsScaled(entity model.Entity) bool { + if entity.GetType() == model.EntityTypeHost { + return entity.GetScope().HasTag("router") || entity.GetScope().HasTag("host") + } + return entity.GetType() == model.EntityTypeComponent && entity.GetScope().HasTag("host") +} + +func (self scaleStrategy) GetEntityCount(entity model.Entity) uint32 { + if entity.GetType() == model.EntityTypeHost { + if entity.GetScope().HasTag("router") { + return 2 + } + if entity.GetScope().HasTag("host") { + h := entity.(*model.Host) + if h.Region.Id == "us-east-1" { + return 8 + } + return 6 + } + } + if entity.GetType() == model.EntityTypeComponent { + return 10 + } + return 1 +} + +var m = &model.Model{ + Id: "sdk-hosting-test", + Scope: model.Scope{ + Defaults: model.Variables{ + "environment": "sdk-hosting-test", + "credentials": model.Variables{ + "aws": model.Variables{ + "managed_key": true, + }, + "ssh": model.Variables{ + "username": "ubuntu", + }, + "edge": model.Variables{ + "username": "admin", + "password": "admin", + }, + }, + "metrics": model.Variables{ + "influxdb": model.Variables{ + "url": "http://localhost:8086", + "db": "ziti", + }, + }, + }, + }, + StructureFactories: []model.Factory{ + model.FactoryFunc(func(m *model.Model) error { + err := m.ForEachHost("component.ctrl", 1, func(host *model.Host) error { + host.InstanceType = "c5.xlarge" + return nil + }) + + if err != nil { + return err + } + + err = m.ForEachHost("component.router", 1, func(host *model.Host) error { + host.InstanceType = "c5.xlarge" + return nil + }) + + if err != nil { + return err + } + + return m.ForEachComponent(".host", 1, func(c *model.Component) error { + c.Type.(*zitilab.ZitiTunnelType).Mode = zitilab.ZitiTunnelModeHost + return nil + }) + }), + model.FactoryFunc(func(m *model.Model) error { + if val, _ := m.GetBoolVariable("ha"); !val { + for _, host := range m.SelectHosts("component.ha") { + delete(host.Region.Hosts, host.Id) + } + } else { + for _, component := range m.SelectComponents("*") { + if ztType, ok := component.Type.(*zitilab.ZitiTunnelType); ok { + ztType.HA = true + } + } + } + return nil + }), + model.NewScaleFactoryWithDefaultEntityFactory(&scaleStrategy{}), + }, + Resources: model.Resources{ + resources.Configs: resources.SubFolder(configResource, "configs"), + resources.Binaries: os.DirFS(path.Join(os.Getenv("GOPATH"), "bin")), + resources.Terraform: test_resources.TerraformResources(), + }, + Regions: model.Regions{ + "us-east-1": { + Region: "us-east-1", + Site: "us-east-1a", + Hosts: model.Hosts{ + "ctrl1": { + Components: model.Components{ + "ctrl1": { + Scope: model.Scope{Tags: model.Tags{"ctrl"}}, + Type: &zitilab.ControllerType{ + Version: TargetZitiVersion, + }, + }, + }, + }, + "router-us-{{.ScaleIndex}}": { + Scope: model.Scope{Tags: model.Tags{"router"}}, + Components: model.Components{ + "router-us-{{.Host.ScaleIndex}}": { + Scope: model.Scope{Tags: model.Tags{"router"}}, + Type: &zitilab.RouterType{ + Version: TargetZitiVersion, + }, + }, + }, + }, + }, + }, + "eu-west-2": { + Region: "eu-west-2", + Site: "eu-west-2a", + Hosts: model.Hosts{ + "ctrl2": { + Components: model.Components{ + "ctrl2": { + Scope: model.Scope{Tags: model.Tags{"ctrl", "ha"}}, + Type: &zitilab.ControllerType{ + Version: TargetZitiVersion, + }, + }, + }, + }, + "router-eu-{{.ScaleIndex}}": { + Scope: model.Scope{Tags: model.Tags{"router"}}, + Components: model.Components{ + "router-eu-{{.Host.ScaleIndex}}": { + Scope: model.Scope{Tags: model.Tags{"router"}}, + Type: &zitilab.RouterType{ + Version: TargetZitiVersion, + }, + }, + }, + }, + }, + }, + "ap-southeast-2": { + Region: "ap-southeast-2", + Site: "ap-southeast-2a", + Hosts: model.Hosts{ + "ctrl3": { + Components: model.Components{ + "ctrl3": { + Scope: model.Scope{Tags: model.Tags{"ctrl", "ha"}}, + Type: &zitilab.ControllerType{ + Version: TargetZitiVersion, + }, + }, + }, + }, + "router-ap-{{.ScaleIndex}}": { + Scope: model.Scope{Tags: model.Tags{"router", "scaled"}}, + Components: model.Components{ + "router-ap-{{.Host.ScaleIndex}}": { + Scope: model.Scope{Tags: model.Tags{"router"}}, + Type: &zitilab.RouterType{ + Version: TargetZitiVersion, + }, + }, + }, + }, + }, + }, + }, + + Actions: model.ActionBinders{ + "bootstrap": model.ActionBinder(func(m *model.Model) model.Action { + workflow := actions.Workflow() + + isHA := len(m.SelectComponents(".ctrl")) > 1 + + workflow.AddAction(component.StopInParallel("*", 300)) + workflow.AddAction(host.GroupExec("*", 25, "rm -f logs/* ctrl.db")) + workflow.AddAction(host.GroupExec("component.ctrl", 5, "rm -rf ./fablab/ctrldata")) + + if !isHA { + workflow.AddAction(component.Exec("#ctrl1", zitilab.ControllerActionInitStandalone)) + } + + workflow.AddAction(component.Start(".ctrl")) + + if isHA { + workflow.AddAction(semaphore.Sleep(2 * time.Second)) + workflow.AddAction(edge.InitRaftController("#ctrl1")) + } + + workflow.AddAction(edge.ControllerAvailable("#ctrl1", 30*time.Second)) + workflow.AddAction(edge.Login("#ctrl1")) + workflow.AddAction(edge.InitEdgeRouters(models.RouterTag, 25)) + + workflow.AddAction(zitilibActions.Edge("create", "edge-router-policy", "all", "--edge-router-roles", "#all", "--identity-roles", "#all")) + workflow.AddAction(zitilibActions.Edge("create", "service-edge-router-policy", "all", "--service-roles", "#all", "--edge-router-roles", "#all")) + + workflow.AddAction(zitilibActions.Edge("create", "config", "host-config", "host.v1", ` + { + "address" : "localhost", + "port" : 8080, + "protocol" : "tcp" + }`)) + + workflow.AddAction(model.ActionFunc(func(run model.Run) error { + ctrls := &CtrlClients{} + if err := ctrls.init(run, "#ctrl1"); err != nil { + return err + } + + var tasks []parallel.LabeledTask + for range 100 { + task := createNewService(ctrls.getCtrl("ctrl1")) + tasks = append(tasks, task) + } + return parallel.ExecuteLabeled(tasks, 2) + })) + + workflow.AddAction(model.ActionFunc(func(run model.Run) error { + ctrls := &CtrlClients{} + if err := ctrls.init(run, "#ctrl1"); err != nil { + return err + } + + var tasks []parallel.LabeledTask + for range 100 { + task := createNewIdentity(ctrls.getCtrl("ctrl1")) + tasks = append(tasks, task) + } + return parallel.ExecuteLabeled(tasks, 2) + })) + + workflow.AddAction(model.ActionFunc(func(run model.Run) error { + ctrls := &CtrlClients{} + if err := ctrls.init(run, "#ctrl1"); err != nil { + return err + } + + var tasks []parallel.LabeledTask + for range 100 { + task := createNewService(ctrls.getCtrl("ctrl1")) + tasks = append(tasks, task) + } + return parallel.ExecuteLabeled(tasks, 2) + })) + + workflow.AddAction(semaphore.Sleep(2 * time.Second)) + workflow.AddAction(edge.RaftJoin("ctrl1", ".ctrl")) + workflow.AddAction(semaphore.Sleep(5 * time.Second)) + + workflow.AddAction(component.StartInParallel(".router", 10)) + workflow.AddAction(semaphore.Sleep(2 * time.Second)) + + return workflow + }), + "stop": model.Bind(component.StopInParallelHostExclusive("*", 15)), + "clean": model.Bind(actions.Workflow( + component.StopInParallelHostExclusive("*", 15), + host.GroupExec("*", 25, "rm -f logs/*"), + )), + "login": model.Bind(edge.Login("#ctrl1")), + "login2": model.Bind(edge.Login("#ctrl2")), + "login3": model.Bind(edge.Login("#ctrl3")), + "restart": model.ActionBinder(func(run *model.Model) model.Action { + workflow := actions.Workflow() + workflow.AddAction(component.StopInParallel("*", 100)) + workflow.AddAction(host.GroupExec("*", 25, "rm -f logs/*")) + workflow.AddAction(component.Start(".ctrl")) + workflow.AddAction(semaphore.Sleep(2 * time.Second)) + workflow.AddAction(component.StartInParallel(".router", 10)) + workflow.AddAction(semaphore.Sleep(2 * time.Second)) + workflow.AddAction(component.StartInParallel(".host", 50)) + return workflow + }), + "sowChaos": model.Bind(model.ActionFunc(sowChaos)), + "validateUp": model.Bind(model.ActionFunc(func(run model.Run) error { + if err := chaos.ValidateUp(run, ".ctrl", 3, 15*time.Second); err != nil { + return err + } + err := run.GetModel().ForEachComponent(".ctrl", 3, func(c *model.Component) error { + return edge.ControllerAvailable(c.Id, 30*time.Second).Execute(run) + }) + if err != nil { + return err + } + if err := chaos.ValidateUp(run, ".router", 100, time.Minute); err != nil { + pfxlog.Logger().WithError(err).Error("validate up failed, trying to start all routers again") + return component.StartInParallel(".router", 100).Execute(run) + } + return nil + })), + "validate": model.Bind(model.ActionFunc(validateRouterDataModel)), + "testIteration": model.Bind(model.ActionFunc(func(run model.Run) error { + return run.GetModel().Exec(run, + "sowChaos", + "validateUp", + "validate", + ) + })), + }, + + Infrastructure: model.Stages{ + aws_ssh_key.Express(), + &terraform_0.Terraform{ + Retries: 3, + ReadyCheck: &semaphore_0.ReadyStage{ + MaxWait: 90 * time.Second, + }, + }, + }, + + Distribution: model.Stages{ + distribution.DistributeSshKey("*"), + rsync.RsyncStaged(), + }, + + Disposal: model.Stages{ + terraform.Dispose(), + awsSshKeyDispose.Dispose(), + }, +} + +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") + + model.AddBootstrapExtension(binding.AwsCredentialsLoader) + model.AddBootstrapExtension(aws_ssh_key.KeyManager) + + fablab.InitModel(m) + fablab.Run() +} diff --git a/zititest/models/router-data-model-test/validation.go b/zititest/models/router-data-model-test/validation.go new file mode 100644 index 000000000..accd82040 --- /dev/null +++ b/zititest/models/router-data-model-test/validation.go @@ -0,0 +1,468 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package main + +import ( + "errors" + "fmt" + "github.com/google/uuid" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel/v3" + "github.com/openziti/channel/v3/protobufs" + "github.com/openziti/edge-api/rest_model" + "github.com/openziti/fablab/kernel/lib/parallel" + "github.com/openziti/fablab/kernel/model" + "github.com/openziti/ziti/common/pb/mgmt_pb" + "github.com/openziti/ziti/zitirest" + "github.com/openziti/ziti/zititest/zitilab/chaos" + "github.com/openziti/ziti/zititest/zitilab/models" + "google.golang.org/protobuf/proto" + "math/rand" + "sync" + "time" +) + +type CtrlClients struct { + ctrls []*zitirest.Clients + ctrlMap map[string]*zitirest.Clients + sync.Mutex +} + +func (self *CtrlClients) init(run model.Run, selector string) error { + self.ctrlMap = map[string]*zitirest.Clients{} + ctrls := run.GetModel().SelectComponents(selector) + resultC := make(chan struct { + err error + id string + clients *zitirest.Clients + }, len(ctrls)) + + for _, ctrl := range ctrls { + go func() { + clients, err := chaos.EnsureLoggedIntoCtrl(run, ctrl, time.Minute) + resultC <- struct { + err error + id string + clients *zitirest.Clients + }{ + err: err, + id: ctrl.Id, + clients: clients, + } + }() + } + + for i := 0; i < len(ctrls); i++ { + result := <-resultC + if result.err != nil { + return result.err + } + self.ctrls = append(self.ctrls, result.clients) + self.ctrlMap[result.id] = result.clients + } + return nil +} + +func (self *CtrlClients) getRandomCtrl() *zitirest.Clients { + return self.ctrls[rand.Intn(len(self.ctrls))] +} + +func (self *CtrlClients) getCtrl(id string) *zitirest.Clients { + return self.ctrlMap[id] +} + +// start with a random scenario then cycle through them +var scenarioCounter = rand.Intn(7) + +func sowChaos(run model.Run) error { + ctrls := &CtrlClients{} + if err := ctrls.init(run, ".ctrl"); err != nil { + return err + } + + var tasks []parallel.LabeledTask + var err error + + applyTasks := func(f func(run model.Run, ctrls *CtrlClients) ([]parallel.LabeledTask, error)) { + var t []parallel.LabeledTask + if err == nil { + t, err = f(run, ctrls) + if err == nil { + tasks = append(tasks, t...) + } + } + } + + applyTasks(getRestartTasks) + applyTasks(getServiceChaosTasks) + applyTasks(getIdentityChaosTasks) + applyTasks(getServicePolicyChaosTasks) + + if err != nil { + return err + } + + chaos.Randomize(tasks) + return parallel.ExecuteLabeled(tasks, 2) +} + +func getRestartTasks(run model.Run, _ *CtrlClients) ([]parallel.LabeledTask, error) { + var controllers []*model.Component + var err error + + scenarioCounter = (scenarioCounter + 1) % 7 + scenario := scenarioCounter + 1 + + var result []parallel.LabeledTask + + if scenario&0b001 > 0 { + controllers, err = chaos.SelectRandom(run, ".ctrl", chaos.RandomOfTotal()) + if err != nil { + return nil, err + } + for _, controller := range controllers { + result = append(result, parallel.TaskWithLabel(fmt.Sprintf("restart controller %s", controller.Id), func() error { + return chaos.RestartSelected(run, 1, controller) + })) + } + } + + var routers []*model.Component + if scenario&0b010 > 0 { + routers, err = chaos.SelectRandom(run, ".router", chaos.PercentageRange(10, 75)) + if err != nil { + return nil, err + } + for _, router := range routers { + result = append(result, parallel.TaskWithLabel(fmt.Sprintf("restart router %s", router.Id), func() error { + return chaos.RestartSelected(run, 1, router) + })) + } + } + + return result, nil +} + +func getRoles(n int) []string { + roles := getRoleAttributes(n) + for i, role := range roles { + roles[i] = "#" + role + } + return roles +} + +func getRoleAttributes(n int) []string { + attr := map[string]struct{}{} + count := rand.Intn(n) + 1 + for i := 0; i < count; i++ { + attr[fmt.Sprintf("role-%v", rand.Intn(10))] = struct{}{} + } + + var result []string + for k := range attr { + result = append(result, k) + } + return result +} + +func getRoleAttributesAsAttrPtr(n int) *rest_model.Attributes { + result := getRoleAttributes(n) + return (*rest_model.Attributes)(&result) +} + +func newId() *string { + id := uuid.NewString() + return &id +} + +func newBoolPtr() *bool { + b := rand.Int()%2 == 0 + return &b +} + +func getServiceChaosTasks(_ model.Run, ctrls *CtrlClients) ([]parallel.LabeledTask, error) { + svcs, err := models.ListServices(ctrls.getRandomCtrl(), "limit none", 15*time.Second) + if err != nil { + return nil, err + } + chaos.Randomize(svcs) + + var result []parallel.LabeledTask + + for i := 0; i < 5; i++ { + result = append(result, parallel.TaskWithLabel(fmt.Sprintf("delete service %s", *svcs[i].ID), func() error { + return models.DeleteService(ctrls.getRandomCtrl(), *svcs[i].ID, 15*time.Second) + })) + } + + for i := 5; i < 10; i++ { + result = append(result, parallel.TaskWithLabel(fmt.Sprintf("modify service %s", *svcs[i].ID), func() error { + svc := svcs[i] + svc.RoleAttributes = getRoleAttributesAsAttrPtr(3) + svc.Name = newId() + return models.UpdateServiceFromDetail(ctrls.getRandomCtrl(), svc, 15*time.Second) + })) + } + + for i := 0; i < 5; i++ { + result = append(result, createNewService(ctrls.getRandomCtrl())) + } + + return result, nil +} + +func getIdentityChaosTasks(_ model.Run, ctrls *CtrlClients) ([]parallel.LabeledTask, error) { + entities, err := models.ListIdentities(ctrls.getRandomCtrl(), "limit none", 15*time.Second) + if err != nil { + return nil, err + } + chaos.Randomize(entities) + + var result []parallel.LabeledTask + + for i := 0; i < 5; i++ { + result = append(result, parallel.TaskWithLabel(fmt.Sprintf("delete identity %s", *entities[i].ID), func() error { + return models.DeleteIdentity(ctrls.getRandomCtrl(), *entities[i].ID, 15*time.Second) + })) + } + + for i := 5; i < 10; i++ { + result = append(result, parallel.TaskWithLabel(fmt.Sprintf("modify identity %s", *entities[i].ID), func() error { + entity := entities[i] + entity.RoleAttributes = getRoleAttributesAsAttrPtr(3) + entity.Name = newId() + return models.UpdateIdentityFromDetail(ctrls.getRandomCtrl(), entity, 15*time.Second) + })) + } + + for i := 0; i < 5; i++ { + result = append(result, createNewIdentity(ctrls.getRandomCtrl())) + } + + return result, nil +} + +func getServicePolicyChaosTasks(_ model.Run, ctrls *CtrlClients) ([]parallel.LabeledTask, error) { + entities, err := models.ListServicePolicies(ctrls.getRandomCtrl(), "limit none", 15*time.Second) + if err != nil { + return nil, err + } + chaos.Randomize(entities) + + var result []parallel.LabeledTask + + for i := 0; i < 5; i++ { + result = append(result, parallel.TaskWithLabel(fmt.Sprintf("delete service policy %s", *entities[i].ID), func() error { + return models.DeleteServicePolicy(ctrls.getRandomCtrl(), *entities[i].ID, 15*time.Second) + })) + } + + for i := 5; i < 10; i++ { + result = append(result, parallel.TaskWithLabel(fmt.Sprintf("modify service policy %s", *entities[i].ID), func() error { + entity := entities[i] + entity.IdentityRoles = getRoles(3) + entity.ServiceRoles = getRoles(3) + entity.PostureCheckRoles = getRoles(3) + entity.Name = newId() + return models.UpdateServicePolicyFromDetail(ctrls.getRandomCtrl(), entity, 15*time.Second) + })) + } + + for i := 0; i < 5; i++ { + result = append(result, createNewServicePolicy(ctrls.getRandomCtrl())) + } + + return result, nil +} + +func createNewService(ctrl *zitirest.Clients) parallel.LabeledTask { + return parallel.TaskWithLabel("create new service", func() error { + svc := &rest_model.ServiceCreate{ + Configs: nil, + EncryptionRequired: newBoolPtr(), + Name: newId(), + RoleAttributes: getRoleAttributes(3), + TerminatorStrategy: "smartrouting", + } + return models.CreateService(ctrl, svc, 15*time.Second) + }) +} + +func createNewIdentity(ctrl *zitirest.Clients) parallel.LabeledTask { + isAdmin := false + identityType := rest_model.IdentityTypeDefault + return parallel.TaskWithLabel("create new identity", func() error { + svc := &rest_model.IdentityCreate{ + DefaultHostingCost: nil, + DefaultHostingPrecedence: "", + IsAdmin: &isAdmin, + Name: newId(), + RoleAttributes: getRoleAttributesAsAttrPtr(3), + ServiceHostingCosts: nil, + ServiceHostingPrecedences: nil, + Tags: nil, + Type: &identityType, + } + return models.CreateIdentity(ctrl, svc, 15*time.Second) + }) +} + +func createNewServicePolicy(ctrl *zitirest.Clients) parallel.LabeledTask { + return parallel.TaskWithLabel("create new service policy", func() error { + anyOf := rest_model.SemanticAnyOf + policyType := rest_model.DialBindDial + if rand.Int()%2 == 0 { + policyType = rest_model.DialBindBind + } + entity := &rest_model.ServicePolicyCreate{ + Name: newId(), + IdentityRoles: getRoles(3), + PostureCheckRoles: getRoles(3), + Semantic: &anyOf, + ServiceRoles: getRoles(3), + Type: &policyType, + } + return models.CreateServicePolicy(ctrl, entity, 15*time.Second) + }) +} + +func validateRouterDataModel(run model.Run) error { + ctrls := run.GetModel().SelectComponents(".ctrl") + errC := make(chan error, len(ctrls)) + deadline := time.Now().Add(15 * time.Minute) + for _, ctrl := range ctrls { + ctrlComponent := ctrl + go validateRouterDataModelForCtrlWithChan(run, ctrlComponent, deadline, errC) + } + + for i := 0; i < len(ctrls); i++ { + err := <-errC + if err != nil { + return err + } + } + + return nil +} + +func validateRouterDataModelForCtrlWithChan(run model.Run, c *model.Component, deadline time.Time, errC chan<- error) { + errC <- validateRouterDataModelForCtrl(run, c, deadline) +} + +func validateRouterDataModelForCtrl(run model.Run, c *model.Component, deadline time.Time) error { + clients, err := chaos.EnsureLoggedIntoCtrl(run, c, time.Minute) + if err != nil { + return err + } + + start := time.Now() + + logger := pfxlog.Logger().WithField("ctrl", c.Id) + + for { + count, err := validateRouterDataModelForCtrlOnce(c.Id, clients) + if err == nil { + return nil + } + + if time.Now().After(deadline) { + return err + } + + logger.Infof("current count of router data model errors: %v, elapsed time: %v", count, time.Since(start)) + time.Sleep(15 * time.Second) + + clients, err = chaos.EnsureLoggedIntoCtrl(run, c, time.Minute) + if err != nil { + return err + } + } +} + +func validateRouterDataModelForCtrlOnce(id string, clients *zitirest.Clients) (int, error) { + logger := pfxlog.Logger().WithField("ctrl", id) + + closeNotify := make(chan struct{}) + eventNotify := make(chan *mgmt_pb.RouterDataModelDetails, 1) + + handleSdkTerminatorResults := func(msg *channel.Message, _ channel.Channel) { + detail := &mgmt_pb.RouterDataModelDetails{} + if err := proto.Unmarshal(msg.Body, detail); err != nil { + pfxlog.Logger().WithError(err).Error("unable to unmarshal router data model details") + return + } + eventNotify <- detail + } + + bindHandler := func(binding channel.Binding) error { + binding.AddReceiveHandlerF(int32(mgmt_pb.ContentType_ValidateRouterDataModelResultType), handleSdkTerminatorResults) + binding.AddCloseHandler(channel.CloseHandlerF(func(ch channel.Channel) { + close(closeNotify) + })) + return nil + } + + ch, err := clients.NewWsMgmtChannel(channel.BindHandlerF(bindHandler)) + if err != nil { + return 0, err + } + + defer func() { + _ = ch.Close() + }() + + request := &mgmt_pb.ValidateRouterDataModelRequest{ + RouterFilter: "limit none", + ValidateCtrl: true, + } + responseMsg, err := protobufs.MarshalTyped(request).WithTimeout(10 * time.Second).SendForReply(ch) + + response := &mgmt_pb.ValidateRouterDataModelResponse{} + if err = protobufs.TypedResponse(response).Unmarshall(responseMsg, err); err != nil { + return 0, err + } + + if !response.Success { + return 0, fmt.Errorf("failed to start router data model validation: %s", response.Message) + } + + logger.Infof("started validation of %v components", response.ComponentCount) + + expected := response.ComponentCount + + invalid := 0 + for expected > 0 { + select { + case <-closeNotify: + fmt.Printf("channel closed, exiting") + return 0, errors.New("unexpected close of mgmt channel") + case detail := <-eventNotify: + if !detail.ValidateSuccess { + invalid++ + } + for _, errorDetails := range detail.Errors { + fmt.Printf("\tdetail: %s\n", errorDetails) + } + expected-- + } + } + if invalid == 0 { + logger.Infof("router data model validation of %v components successful", response.ComponentCount) + return invalid, nil + } + return invalid, errors.New("errors found") +} diff --git a/zititest/models/sdk-hosting-test/validation.go b/zititest/models/sdk-hosting-test/validation.go index 010be59d2..7585df984 100644 --- a/zititest/models/sdk-hosting-test/validation.go +++ b/zititest/models/sdk-hosting-test/validation.go @@ -71,7 +71,7 @@ func sowChaos(run model.Run) error { toRestart = append(toRestart, routers...) toRestart = append(toRestart, hosts...) fmt.Printf("restarting %d controllers, %d routers and %d hosts\n", len(controllers), len(routers), len(hosts)) - return chaos.RestartSelected(run, toRestart, 100) + return chaos.RestartSelected(run, 100, toRestart...) } func validateTerminators(run model.Run) error { diff --git a/zititest/models/sdk-status-test/validation.go b/zititest/models/sdk-status-test/validation.go index 30076bd52..304126209 100644 --- a/zititest/models/sdk-status-test/validation.go +++ b/zititest/models/sdk-status-test/validation.go @@ -66,7 +66,7 @@ func sowChaos(run model.Run) error { } fmt.Printf("stopping %d controllers, %d routers and %d hosts\n", len(controllers), len(routers), len(hosts)) - if err = chaos.RestartSelected(run, controllers, 3); err != nil { + if err = chaos.RestartSelected(run, 3, controllers...); err != nil { return err } var toStop []*model.Component diff --git a/zititest/zitilab/chaos/chaos.go b/zititest/zitilab/chaos/chaos.go index 5e5f05bf4..68b4c12d9 100644 --- a/zititest/zitilab/chaos/chaos.go +++ b/zititest/zitilab/chaos/chaos.go @@ -119,7 +119,7 @@ func StopSelected(run model.Run, list []*model.Component, concurrency int) error }) } -func RestartSelected(run model.Run, list []*model.Component, concurrency int) error { +func RestartSelected(run model.Run, concurrency int, list ...*model.Component) error { if len(list) == 0 { return nil } @@ -224,3 +224,13 @@ func EnsureRunning(c *model.Component, run model.Run) error { } return fmt.Errorf("component %v isn't of ServerComponent type, is of type %T", c, c.Type) } + +func Randomize[T any](s []T) { + for i := 0; i < len(s); i++ { + idx := rand.Intn(len(s)) + e1 := s[i] + e2 := s[idx] + s[i] = e2 + s[idx] = e1 + } +} diff --git a/zititest/zitilab/models/api.go b/zititest/zitilab/models/api.go new file mode 100644 index 000000000..5db9411f6 --- /dev/null +++ b/zititest/zitilab/models/api.go @@ -0,0 +1,213 @@ +package models + +import ( + "context" + "github.com/openziti/edge-api/rest_management_api_client/identity" + "github.com/openziti/edge-api/rest_management_api_client/service" + "github.com/openziti/edge-api/rest_management_api_client/service_policy" + "github.com/openziti/edge-api/rest_model" + "github.com/openziti/ziti/ziti/util" + "github.com/openziti/ziti/zitirest" + "time" +) + +func ListServices(clients *zitirest.Clients, filter string, timeout time.Duration) ([]*rest_model.ServiceDetail, error) { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + result, err := clients.Edge.Service.ListServices(&service.ListServicesParams{ + Filter: &filter, + Context: ctx, + }, nil) + + if err != nil { + return nil, err + } + return result.Payload.Data, nil +} + +func CreateService(clients *zitirest.Clients, svc *rest_model.ServiceCreate, timeout time.Duration) error { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + _, err := clients.Edge.Service.CreateService(&service.CreateServiceParams{ + Context: ctx, + Service: svc, + }, nil) + + return err +} + +func DeleteService(clients *zitirest.Clients, id string, timeout time.Duration) error { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + _, err := clients.Edge.Service.DeleteService(&service.DeleteServiceParams{ + Context: ctx, + ID: id, + }, nil) + + return err +} + +func UpdateServiceFromDetail(clients *zitirest.Clients, svc *rest_model.ServiceDetail, timeout time.Duration) error { + svcUpdate := &rest_model.ServiceUpdate{ + Configs: svc.Configs, + EncryptionRequired: *svc.EncryptionRequired, + MaxIdleTimeMillis: *svc.MaxIdleTimeMillis, + Name: svc.Name, + RoleAttributes: *svc.RoleAttributes, + Tags: svc.Tags, + TerminatorStrategy: *svc.TerminatorStrategy, + } + return UpdateService(clients, *svc.ID, svcUpdate, timeout) +} + +func UpdateService(clients *zitirest.Clients, id string, svc *rest_model.ServiceUpdate, timeout time.Duration) error { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + _, err := clients.Edge.Service.UpdateService(&service.UpdateServiceParams{ + Context: ctx, + ID: id, + Service: svc, + }, nil) + + return err +} + +func ListIdentities(clients *zitirest.Clients, filter string, timeout time.Duration) ([]*rest_model.IdentityDetail, error) { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + result, err := clients.Edge.Identity.ListIdentities(&identity.ListIdentitiesParams{ + Filter: &filter, + Context: ctx, + }, nil) + + if err != nil { + return nil, err + } + return result.Payload.Data, nil +} + +func CreateIdentity(clients *zitirest.Clients, entity *rest_model.IdentityCreate, timeout time.Duration) error { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + _, err := clients.Edge.Identity.CreateIdentity(&identity.CreateIdentityParams{ + Context: ctx, + Identity: entity, + }, nil) + + return util.WrapIfApiError(err) +} + +func DeleteIdentity(clients *zitirest.Clients, id string, timeout time.Duration) error { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + _, err := clients.Edge.Identity.DeleteIdentity(&identity.DeleteIdentityParams{ + Context: ctx, + ID: id, + }, nil) + + return err +} + +func UpdateIdentityFromDetail(clients *zitirest.Clients, entity *rest_model.IdentityDetail, timeout time.Duration) error { + typeId := rest_model.IdentityType(entity.Type.ID) + identityUpdate := &rest_model.IdentityUpdate{ + AppData: entity.AppData, + AuthPolicyID: entity.AuthPolicyID, + DefaultHostingCost: entity.DefaultHostingCost, + DefaultHostingPrecedence: entity.DefaultHostingPrecedence, + ExternalID: entity.ExternalID, + IsAdmin: entity.IsAdmin, + Name: entity.Name, + RoleAttributes: entity.RoleAttributes, + ServiceHostingCosts: entity.ServiceHostingCosts, + ServiceHostingPrecedences: entity.ServiceHostingPrecedences, + Tags: entity.Tags, + Type: &typeId, + } + return UpdateIdentity(clients, *entity.ID, identityUpdate, timeout) +} + +func UpdateIdentity(clients *zitirest.Clients, id string, entity *rest_model.IdentityUpdate, timeout time.Duration) error { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + _, err := clients.Edge.Identity.UpdateIdentity(&identity.UpdateIdentityParams{ + Context: ctx, + ID: id, + Identity: entity, + }, nil) + + return err +} + +func ListServicePolicies(clients *zitirest.Clients, filter string, timeout time.Duration) ([]*rest_model.ServicePolicyDetail, error) { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + result, err := clients.Edge.ServicePolicy.ListServicePolicies(&service_policy.ListServicePoliciesParams{ + Filter: &filter, + Context: ctx, + }, nil) + + if err != nil { + return nil, err + } + return result.Payload.Data, nil +} + +func CreateServicePolicy(clients *zitirest.Clients, entity *rest_model.ServicePolicyCreate, timeout time.Duration) error { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + _, err := clients.Edge.ServicePolicy.CreateServicePolicy(&service_policy.CreateServicePolicyParams{ + Context: ctx, + Policy: entity, + }, nil) + + return err +} + +func DeleteServicePolicy(clients *zitirest.Clients, id string, timeout time.Duration) error { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + _, err := clients.Edge.ServicePolicy.DeleteServicePolicy(&service_policy.DeleteServicePolicyParams{ + Context: ctx, + ID: id, + }, nil) + + return err +} + +func UpdateServicePolicyFromDetail(clients *zitirest.Clients, entity *rest_model.ServicePolicyDetail, timeout time.Duration) error { + servicePolicyUpdate := &rest_model.ServicePolicyUpdate{ + Name: entity.Name, + IdentityRoles: entity.IdentityRoles, + PostureCheckRoles: entity.PostureCheckRoles, + Semantic: entity.Semantic, + ServiceRoles: entity.ServiceRoles, + Tags: entity.Tags, + Type: entity.Type, + } + return UpdateServicePolicy(clients, *entity.ID, servicePolicyUpdate, timeout) +} + +func UpdateServicePolicy(clients *zitirest.Clients, id string, entity *rest_model.ServicePolicyUpdate, timeout time.Duration) error { + ctx, cancelF := context.WithTimeout(context.Background(), timeout) + defer cancelF() + + _, err := clients.Edge.ServicePolicy.UpdateServicePolicy(&service_policy.UpdateServicePolicyParams{ + Context: ctx, + ID: id, + Policy: entity, + }, nil) + + return err +} From 950d615b066cfad7499704d40d233acf86d314e9 Mon Sep 17 00:00:00 2001 From: Paul Lorenz Date: Mon, 2 Dec 2024 21:32:38 -0500 Subject: [PATCH 2/2] Remove HA config from router. Fixes #2566 --- common/config/value.go | 91 ++++++++ common/router_data_model.go | 112 +++++++--- common/subscriber.go | 17 +- controller/model/controller_manager.go | 7 +- controller/sync_strats/sync_instant.go | 30 ++- router/config.go | 17 -- router/env/env.go | 2 + router/env/xrctrl.go | 1 - router/handler_ctrl/bind.go | 6 + router/handler_ctrl/inspect.go | 4 + router/handler_edge_ctrl/hello.go | 11 +- router/router.go | 81 +++---- router/state/manager.go | 4 +- router/xgress_edge/factory.go | 12 +- router/xgress_edge/hosted.go | 2 +- router/xgress_edge/listener.go | 8 +- router/xgress_edge_tunnel/fabric.go | 2 +- router/xgress_edge_tunnel/factory.go | 7 +- router/xgress_edge_tunnel/factory_wrapper.go | 202 ++++++++++++++++++ router/xgress_edge_tunnel_v2/factory.go | 25 +-- tests/context.go | 4 +- ziti/cmd/fabric/inspect.go | 1 + .../configs/router.yml.tmpl | 2 - .../models/router-data-model-test/main.go | 8 +- .../router-data-model-test/validation.go | 46 ++-- 25 files changed, 531 insertions(+), 171 deletions(-) create mode 100644 common/config/value.go create mode 100644 router/xgress_edge_tunnel/factory_wrapper.go diff --git a/common/config/value.go b/common/config/value.go new file mode 100644 index 000000000..1869fd6c0 --- /dev/null +++ b/common/config/value.go @@ -0,0 +1,91 @@ +/* + Copyright NetFoundry Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package config + +import ( + "github.com/openziti/foundation/v2/concurrenz" + "sync" +) + +type Listener[T any] interface { + NotifyChanged(init bool, old T, new T) +} + +type ListenerFunc[T any] func(init bool, old T, new T) + +func (f ListenerFunc[T]) NotifyChanged(init bool, old T, new T) { + f(init, old, new) +} + +func NewConfigValue[T comparable]() *Value[T] { + return &Value[T]{ + notifyInitialized: make(chan struct{}), + } +} + +type Value[T comparable] struct { + lock sync.Mutex + initialized bool + notifyInitialized chan struct{} + value concurrenz.AtomicValue[T] + listeners concurrenz.CopyOnWriteSlice[Listener[T]] +} + +func (self *Value[T]) Store(value T) { + self.lock.Lock() + defer self.lock.Unlock() + + first := !self.initialized + old := self.value.Swap(value) + + if first || old != value { + for _, l := range self.listeners.Value() { + l.NotifyChanged(first, old, value) + } + } + + if first { + self.initialized = true + close(self.notifyInitialized) + } +} + +func (self *Value[T]) Load() T { + return self.value.Load() +} + +func (self *Value[T]) AddListener(listener Listener[T]) { + self.lock.Lock() + defer self.lock.Unlock() + + self.listeners.Append(listener) + + if self.initialized { + listener.NotifyChanged(true, self.Load(), self.Load()) + } +} + +func (self *Value[T]) RemoveListener(listener Listener[T]) { + self.lock.Lock() + defer self.lock.Unlock() + + self.listeners.Delete(listener) +} + +func (self *Value[T]) GetInitNotifyChannel() <-chan struct{} { + return self.notifyInitialized +} diff --git a/common/router_data_model.go b/common/router_data_model.go index 7d449b366..6537193b5 100644 --- a/common/router_data_model.go +++ b/common/router_data_model.go @@ -24,6 +24,7 @@ import ( "encoding/json" "fmt" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/michaelquigley/pfxlog" "github.com/openziti/foundation/v2/concurrenz" "github.com/openziti/ziti/common/pb/edge_ctrl_pb" @@ -49,36 +50,36 @@ type DataStateIdentity = edge_ctrl_pb.DataState_Identity type Identity struct { *DataStateIdentity ServicePolicies map[string]struct{} `json:"servicePolicies"` - IdentityIndex uint64 - ServiceSetIndex uint64 + identityIndex uint64 + serviceSetIndex uint64 } type DataStateConfigType = edge_ctrl_pb.DataState_ConfigType type ConfigType struct { *DataStateConfigType - Index uint64 + index uint64 } type DataStateConfig = edge_ctrl_pb.DataState_Config type Config struct { *DataStateConfig - Index uint64 + index uint64 } type DataStateService = edge_ctrl_pb.DataState_Service type Service struct { *DataStateService - Index uint64 + index uint64 } type DataStatePostureCheck = edge_ctrl_pb.DataState_PostureCheck type PostureCheck struct { *DataStatePostureCheck - Index uint64 + index uint64 } type DataStateServicePolicy = edge_ctrl_pb.DataState_ServicePolicy @@ -354,14 +355,14 @@ func (rdm *RouterDataModel) HandleIdentityEvent(index uint64, event *edge_ctrl_p identity = &Identity{ DataStateIdentity: model.Identity, ServicePolicies: map[string]struct{}{}, - IdentityIndex: index, + identityIndex: index, } } else { identity = &Identity{ DataStateIdentity: model.Identity, ServicePolicies: valueInMap.ServicePolicies, - IdentityIndex: index, - ServiceSetIndex: valueInMap.ServiceSetIndex, + identityIndex: index, + serviceSetIndex: valueInMap.serviceSetIndex, } } return identity @@ -381,10 +382,13 @@ func (rdm *RouterDataModel) HandleIdentityEvent(index uint64, event *edge_ctrl_p func (rdm *RouterDataModel) HandleServiceEvent(index uint64, event *edge_ctrl_pb.DataState_Event, model *edge_ctrl_pb.DataState_Event_Service) { if event.Action == edge_ctrl_pb.DataState_Delete { rdm.Services.Remove(model.Service.Id) + rdm.ServicePolicies.IterCb(func(key string, v *ServicePolicy) { + delete(v.Services, model.Service.Id) + }) } else { rdm.Services.Set(model.Service.Id, &Service{ DataStateService: model.Service, - Index: index, + index: index, }) } } @@ -398,7 +402,7 @@ func (rdm *RouterDataModel) HandleConfigTypeEvent(index uint64, event *edge_ctrl } else { rdm.ConfigTypes.Set(model.ConfigType.Id, &ConfigType{ DataStateConfigType: model.ConfigType, - Index: index, + index: index, }) } } @@ -412,12 +416,12 @@ func (rdm *RouterDataModel) HandleConfigEvent(index uint64, event *edge_ctrl_pb. } else { rdm.Configs.Set(model.Config.Id, &Config{ DataStateConfig: model.Config, - Index: index, + index: index, }) } } -func (rdm *RouterDataModel) applyUpdateServicePolicyEvent(event *edge_ctrl_pb.DataState_Event, model *edge_ctrl_pb.DataState_Event_ServicePolicy) { +func (rdm *RouterDataModel) applyUpdateServicePolicyEvent(model *edge_ctrl_pb.DataState_Event_ServicePolicy) { servicePolicy := model.ServicePolicy rdm.ServicePolicies.Upsert(servicePolicy.Id, nil, func(exist bool, valueInMap *ServicePolicy, newValue *ServicePolicy) *ServicePolicy { if valueInMap == nil { @@ -436,7 +440,7 @@ func (rdm *RouterDataModel) applyUpdateServicePolicyEvent(event *edge_ctrl_pb.Da }) } -func (rdm *RouterDataModel) applyDeleteServicePolicyEvent(_ *edge_ctrl_pb.DataState_Event, model *edge_ctrl_pb.DataState_Event_ServicePolicy) { +func (rdm *RouterDataModel) applyDeleteServicePolicyEvent(model *edge_ctrl_pb.DataState_Event_ServicePolicy) { rdm.ServicePolicies.Remove(model.ServicePolicy.Id) } @@ -447,11 +451,11 @@ func (rdm *RouterDataModel) HandleServicePolicyEvent(event *edge_ctrl_pb.DataSta pfxlog.Logger().WithField("policyId", model.ServicePolicy.Id).WithField("action", event.Action).Debug("applying service policy event") switch event.Action { case edge_ctrl_pb.DataState_Create: - rdm.applyUpdateServicePolicyEvent(event, model) + rdm.applyUpdateServicePolicyEvent(model) case edge_ctrl_pb.DataState_Update: - rdm.applyUpdateServicePolicyEvent(event, model) + rdm.applyUpdateServicePolicyEvent(model) case edge_ctrl_pb.DataState_Delete: - rdm.applyDeleteServicePolicyEvent(event, model) + rdm.applyDeleteServicePolicyEvent(model) } } @@ -464,7 +468,7 @@ func (rdm *RouterDataModel) HandlePostureCheckEvent(index uint64, event *edge_ct } else { rdm.PostureChecks.Set(model.PostureCheck.Id, &PostureCheck{ DataStatePostureCheck: model.PostureCheck, - Index: index, + index: index, }) } } @@ -509,7 +513,7 @@ func (rdm *RouterDataModel) HandleServicePolicyChange(index uint64, model *edge_ } else { delete(valueInMap.ServicePolicies, model.PolicyId) } - valueInMap.ServiceSetIndex = index + valueInMap.serviceSetIndex = index } return valueInMap }) @@ -593,7 +597,9 @@ func (rdm *RouterDataModel) recalculateCachedPublicKeys() { func (rdm *RouterDataModel) GetDataState() *edge_ctrl_pb.DataState { var events []*edge_ctrl_pb.DataState_Event - rdm.EventCache.WhileLocked(func(_ uint64, _ bool) { + 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, @@ -717,7 +723,8 @@ func (rdm *RouterDataModel) GetDataState() *edge_ctrl_pb.DataState { }) return &edge_ctrl_pb.DataState{ - Events: events, + Events: events, + EndIndex: index, } } @@ -1005,18 +1012,48 @@ func (rdm *RouterDataModel) Diff(o *RouterDataModel, sink DiffSink) { return } - diffType("configType", rdm.ConfigTypes, o.ConfigTypes, sink) - diffType("config", rdm.Configs, o.Configs, sink) - diffType("identity", rdm.Identities, o.Identities, sink) - diffType("service", rdm.Services, o.Services, sink) - diffType("service-policy", rdm.ServicePolicies, o.ServicePolicies, sink) - diffType("posture-check", rdm.PostureChecks, o.PostureChecks, sink) - diffType("public-keys", rdm.PublicKeys, o.PublicKeys, sink) - diffType("revocations", rdm.Revocations, o.Revocations, sink) - diffType("cached-public-keys", rdm.getPublicKeysAsCmap(), o.getPublicKeysAsCmap(), sink) + diffType("configType", rdm.ConfigTypes, o.ConfigTypes, sink, ConfigType{}, DataStateConfigType{}) + diffType("config", rdm.Configs, o.Configs, sink, Config{}, DataStateConfig{}) + diffType("identity", rdm.Identities, o.Identities, sink, Identity{}, DataStateIdentity{}) + diffType("service", rdm.Services, o.Services, sink, Service{}, DataStateService{}) + diffType("service-policy", rdm.ServicePolicies, o.ServicePolicies, sink, ServicePolicy{}, DataStateServicePolicy{}) + diffType("posture-check", rdm.PostureChecks, o.PostureChecks, sink, PostureCheck{}, DataStatePostureCheck{}) + diffType("public-keys", rdm.PublicKeys, o.PublicKeys, sink, edge_ctrl_pb.DataState_PublicKey{}) + diffType("revocations", rdm.Revocations, o.Revocations, sink, edge_ctrl_pb.DataState_Revocation{}) + diffMaps("cached-public-keys", rdm.getPublicKeysAsCmap(), o.getPublicKeysAsCmap(), sink, func(a, b crypto.PublicKey) []string { + if a == nil || b == nil { + return []string{fmt.Sprintf("cached public key is nil: orig: %v, dest: %v", a, a)} + } + return nil + }) +} + +type diffF[T any] func(a, b T) []string + +func diffMaps[T any](entityType string, m1, m2 cmap.ConcurrentMap[string, T], sink DiffSink, differ diffF[T]) { + hasMissing := false + m1.IterCb(func(key string, v T) { + v2, exists := m2.Get(key) + if !exists { + sink(entityType, key, DiffTypeSub, "entity missing") + hasMissing = true + } else { + for _, diff := range differ(v, v2) { + sink(entityType, key, DiffTypeMod, diff) + } + } + }) + + if m1.Count() != m2.Count() || hasMissing { + m2.IterCb(func(key string, v2 T) { + if _, exists := m1.Get(key); !exists { + sink(entityType, key, DiffTypeAdd, "entity unexpected") + } + }) + } } -func diffType[T any](entityType string, m1 cmap.ConcurrentMap[string, T], m2 cmap.ConcurrentMap[string, T], sink DiffSink) { +func diffType[P any, T *P](entityType string, m1 cmap.ConcurrentMap[string, T], m2 cmap.ConcurrentMap[string, T], sink DiffSink, ignoreTypes ...any) { diffReporter := &compareReporter{ f: func(key string, detail string) { sink(entityType, key, DiffTypeMod, detail) @@ -1032,7 +1069,7 @@ func diffType[T any](entityType string, m1 cmap.ConcurrentMap[string, T], m2 cma hasMissing = true } else { diffReporter.key = key - cmp.Diff(v, v2, adapter) + cmp.Diff(v, v2, cmpopts.IgnoreUnexported(ignoreTypes...), adapter) } }) @@ -1065,7 +1102,16 @@ func (self *compareReporter) Report(result cmp.Result) { } if step != nil { vx, vy := step.Values() - err := fmt.Sprintf("%s mismatch. orig: %s, copy: %s", path.String(), vx.String(), vy.String()) + var x any + var y any + + if vx.IsValid() { + x = vx.Interface() + } + if vy.IsValid() { + y = vy.Interface() + } + err := fmt.Sprintf("%s mismatch. orig: %v, copy: %v", path.String(), x, y) self.f(self.key, err) } else { self.f(self.key, "programming error, empty path stack") diff --git a/common/subscriber.go b/common/subscriber.go index 31a0bc11a..091babaf8 100644 --- a/common/subscriber.go +++ b/common/subscriber.go @@ -36,7 +36,7 @@ type IdentityService struct { } func (self *IdentityService) Equals(other *IdentityService) bool { - if self.Service.Index != other.Service.Index { + if self.Service.index != other.Service.index { return false } @@ -67,10 +67,10 @@ func (self *IdentityService) Equals(other *IdentityService) bool { if !ok { return false } - if config.Config.Index != otherConfig.Config.Index { + if config.Config.index != otherConfig.Config.index { return false } - if config.ConfigType.Index != otherConfig.ConfigType.Index { + if config.ConfigType.index != otherConfig.ConfigType.index { return false } } @@ -102,7 +102,7 @@ func (self *IdentitySubscription) identityUpdated(rdm *RouterDataModel, identity var state *IdentityState self.Lock() if self.Identity != nil { - if identity.IdentityIndex > self.Identity.IdentityIndex { + if identity.identityIndex > self.Identity.identityIndex { self.Identity = identity notify = true } @@ -198,7 +198,7 @@ func (self *IdentitySubscription) checkForChanges(rdm *RouterDataModel) { return } - if oldIdentity.IdentityIndex < newIdentity.IdentityIndex { + if oldIdentity.identityIndex < newIdentity.identityIndex { for _, subscriber := range self.Listeners.Value() { subscriber.NotifyIdentityEvent(state, EventIdentityUpdated) } @@ -235,7 +235,7 @@ func (self *IdentitySubscription) checkForChanges(rdm *RouterDataModel) { checksChanged = true break } - if check.Index != newCheck.Index { + if check.index != newCheck.index { checksChanged = true break } @@ -294,7 +294,10 @@ type identityCreatedEvent struct { } func (self identityCreatedEvent) process(rdm *RouterDataModel) { - pfxlog.Logger().WithField("subs", rdm.subscriptions.Count()).WithField("identityId", self.identity.Id).Info("handling identity created event") + pfxlog.Logger(). + WithField("subs", rdm.subscriptions.Count()). + WithField("identityId", self.identity.Id). + Debug("handling identity created event") if sub, found := rdm.subscriptions.Get(self.identity.Id); found { state := sub.initialize(rdm, self.identity) diff --git a/controller/model/controller_manager.go b/controller/model/controller_manager.go index 78aa94b1d..6c4671642 100644 --- a/controller/model/controller_manager.go +++ b/controller/model/controller_manager.go @@ -126,6 +126,11 @@ func (self *ControllerManager) Unmarshall(bytes []byte) (*Controller, error) { return nil, err } + lastJoinedAt := time.Time{} + if msg.LastJoinedAt != nil { + lastJoinedAt = *pbTimeToTimePtr(msg.LastJoinedAt) + } + controller := &Controller{ BaseEntity: models.BaseEntity{ Id: msg.Id, @@ -136,7 +141,7 @@ func (self *ControllerManager) Unmarshall(bytes []byte) (*Controller, error) { CertPem: msg.CertPem, Fingerprint: msg.Fingerprint, IsOnline: msg.IsOnline, - LastJoinedAt: *pbTimeToTimePtr(msg.LastJoinedAt), + LastJoinedAt: lastJoinedAt, ApiAddresses: map[string][]ApiAddress{}, } diff --git a/controller/sync_strats/sync_instant.go b/controller/sync_strats/sync_instant.go index 886761576..2be42a631 100644 --- a/controller/sync_strats/sync_instant.go +++ b/controller/sync_strats/sync_instant.go @@ -612,11 +612,13 @@ func (strategy *InstantStrategy) ReceiveClientHello(routerId string, msg *channe WithField("os", rtx.Router.VersionInfo.OS). WithField("arch", rtx.Router.VersionInfo.Arch) + var routerDataModelIndex uint64 if supported, ok := msg.Headers.GetBoolHeader(int32(edge_ctrl_pb.Header_RouterDataModel)); ok && supported { rtx.SupportsRouterModel = true if index, ok := msg.Headers.GetUint64Header(int32(edge_ctrl_pb.Header_RouterDataModelIndex)); ok { rtx.RouterModelIndex = &index + routerDataModelIndex = index } } @@ -641,7 +643,13 @@ func (strategy *InstantStrategy) ReceiveClientHello(routerId string, msg *channe rtx.SetVersionInfo(*rtx.Router.VersionInfo) serverVersion := build.GetBuildInfo().Version() - logger.Infof("edge router sent hello with version [%s] to controller with version [%s]", respHello.Version, serverVersion) + + currentIndex, _ := strategy.CurrentIndex() + logger.WithField("routerIndex", routerDataModelIndex). + WithField("dataModelIndex", currentIndex). + WithField("routerVersion", respHello.Version). + WithField("serverVersion", serverVersion). + Info("edge router sent hello") strategy.queueClientHello(rtx) } @@ -721,6 +729,8 @@ func (strategy *InstantStrategy) synchronize(rtx *RouterSender) { rtx.RouterModelIndex = nil events, ok := strategy.RouterDataModel.ReplayFrom(*replayFrom) + logger.WithError(err).Infof("replaying %d router data model events to router", len(events)) + if ok { var err error for _, curEvent := range events { @@ -762,12 +772,12 @@ func (strategy *InstantStrategy) synchronize(rtx *RouterSender) { Error("could not send data state event for peers") } } - } - // no error sync is done, if err try full state - if err == nil { - rtx.SetSyncStatus(env.RouterSyncDone) - return + // no error sync is done, if err try full state + if err == nil { + rtx.SetSyncStatus(env.RouterSyncDone) + return + } } pfxlog.Logger().WithError(err).Error("could not send events for router sync, attempting full state") @@ -779,9 +789,8 @@ func (strategy *InstantStrategy) synchronize(rtx *RouterSender) { if dataState == nil { return } - dataState.EndIndex = strategy.indexProvider.CurrentIndex() - if err := strategy.sendDataState(rtx, dataState); err != nil { + if err = strategy.sendDataState(rtx, dataState); err != nil { logger.WithError(err).Error("failure sending full data state") rtx.SetSyncStatus(env.RouterSyncError) return @@ -1915,6 +1924,11 @@ func (strategy *InstantStrategy) inspect(val string) (bool, *string, error) { result := string(js) return true, &result, nil } + if val == "router-data-model-index" { + idx, _ := strategy.RouterDataModel.CurrentIndex() + strVal := fmt.Sprintf("%d", idx) + return true, &strVal, nil + } return false, nil, nil } diff --git a/router/config.go b/router/config.go index 1adeeb755..fbb7f4317 100644 --- a/router/config.go +++ b/router/config.go @@ -179,9 +179,6 @@ type Config struct { InitialDelay time.Duration } } - Ha struct { - Enabled bool - } ConnectEvents env.ConnectEventsConfig Proxy *transport.ProxyConfiguration Plugins []string @@ -201,10 +198,6 @@ func (config *Config) SetFlags(flags map[string]*pflag.Flag) { SetConfigMapFlags(config.src, flags) } -func (config *Config) IsHaEnabled() bool { - return config.Ha.Enabled -} - const ( TimeFormatYear = "2006" TimeFormatMonth = "01" @@ -818,16 +811,6 @@ func LoadConfig(path string) (*Config, error) { } } - if value, found := cfgmap[CtrlHaMapKey]; found { - if haMap, ok := value.(map[interface{}]interface{}); ok { - if enabledValue, found := haMap["enabled"]; found { - if enabled, ok := enabledValue.(bool); ok { - cfg.Ha.Enabled = enabled - } - } - } - } - cfg.ConnectEvents.Enabled = DefaultConnectEventsEnabled cfg.ConnectEvents.BatchInterval = DefaultConnectEventsBatchInterval cfg.ConnectEvents.FullSyncInterval = DefaultConnectEventsFullSyncInterval diff --git a/router/env/env.go b/router/env/env.go index b55fc90d7..9570c910a 100644 --- a/router/env/env.go +++ b/router/env/env.go @@ -24,6 +24,7 @@ import ( "github.com/openziti/identity" "github.com/openziti/metrics" "github.com/openziti/ziti/common" + "github.com/openziti/ziti/common/config" "github.com/openziti/ziti/router/xgress" "github.com/openziti/ziti/router/xlink" "time" @@ -46,6 +47,7 @@ type RouterEnv interface { GetVersionInfo() versions.VersionProvider GetRouterDataModel() *common.RouterDataModel GetConnectEventsConfig() *ConnectEventsConfig + GetRouterDataModelEnabledConfig() *config.Value[bool] } type ConnectEventsConfig struct { diff --git a/router/env/xrctrl.go b/router/env/xrctrl.go index 86b017f1a..72ab0d120 100644 --- a/router/env/xrctrl.go +++ b/router/env/xrctrl.go @@ -33,5 +33,4 @@ type Xrctrl interface { Enabled() bool Run(env RouterEnv) error NotifyOfReconnect(ch channel.Channel) - GetTraceDecoders() []channel.TraceMessageDecoder } diff --git a/router/handler_ctrl/bind.go b/router/handler_ctrl/bind.go index 46e758096..51766d2c1 100644 --- a/router/handler_ctrl/bind.go +++ b/router/handler_ctrl/bind.go @@ -117,5 +117,11 @@ func (self *bindHandler) BindChannel(binding channel.Binding) error { } } + if ok, _ := ctrl.GetVersion().HasMinimumVersion("1.3.0"); ok { + self.env.GetRouterDataModelEnabledConfig().Store(true) + } else { + self.env.GetRouterDataModelEnabledConfig().Store(false) + } + return nil } diff --git a/router/handler_ctrl/inspect.go b/router/handler_ctrl/inspect.go index 3eeab4134..2f2a86c32 100644 --- a/router/handler_ctrl/inspect.go +++ b/router/handler_ctrl/inspect.go @@ -131,6 +131,10 @@ func (context *inspectRequestContext) processLocal() { } else if lc == "router-data-model" { result := context.handler.env.GetRouterDataModel() context.handleJsonResponse(requested, result) + } else if lc == "router-data-model-index" { + idx, _ := context.handler.env.GetRouterDataModel().CurrentIndex() + strVal := fmt.Sprintf("%d", idx) + context.appendValue(requested, strVal) } else if lc == "router-controllers" { result := context.handler.env.GetNetworkControllers().Inspect() context.handleJsonResponse(requested, result) diff --git a/router/handler_edge_ctrl/hello.go b/router/handler_edge_ctrl/hello.go index 686c4da5d..484e89cd5 100644 --- a/router/handler_edge_ctrl/hello.go +++ b/router/handler_edge_ctrl/hello.go @@ -92,14 +92,11 @@ func (h *helloHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { outMsg := protobufs.MarshalTyped(clientHello).ToSendable().Msg() - if h.stateManager.GetEnv().IsHaEnabled() { - if supported, ok := msg.Headers.GetBoolHeader(int32(edge_ctrl_pb.Header_RouterDataModel)); ok && supported { + if supported, ok := msg.Headers.GetBoolHeader(int32(edge_ctrl_pb.Header_RouterDataModel)); ok && supported { + outMsg.Headers.PutBoolHeader(int32(edge_ctrl_pb.Header_RouterDataModel), true) - outMsg.Headers.PutBoolHeader(int32(edge_ctrl_pb.Header_RouterDataModel), true) - - if index, ok := h.stateManager.RouterDataModel().CurrentIndex(); ok { - outMsg.Headers.PutUint64Header(int32(edge_ctrl_pb.Header_RouterDataModelIndex), index) - } + if index, ok := h.stateManager.RouterDataModel().CurrentIndex(); ok { + outMsg.Headers.PutUint64Header(int32(edge_ctrl_pb.Header_RouterDataModelIndex), index) } } diff --git a/router/router.go b/router/router.go index 07af30597..b4855da31 100644 --- a/router/router.go +++ b/router/router.go @@ -73,29 +73,29 @@ import ( ) type Router struct { - config *Config - ctrls env.NetworkControllers - ctrlBindhandler channel.BindHandler - faulter *forwarder.Faulter - forwarder *forwarder.Forwarder - xrctrls []env.Xrctrl - xlinkFactories map[string]xlink.Factory - xlinkListeners []xlink.Listener - xlinkDialers []xlink.Dialer - xlinkRegistry xlink.Registry - xgressListeners []xgress.Listener - linkDialerPool goroutines.Pool - rateLimiterPool goroutines.Pool - ctrlRateLimiter rate.AdaptiveRateLimitTracker - metricsRegistry metrics.UsageRegistry - shutdownC chan struct{} - shutdownDoneC chan struct{} - isShutdown atomic.Bool - metricsReporter metrics.Handler - versionProvider versions.VersionProvider - debugOperations map[byte]func(c *bufio.ReadWriter) error - stateManager state.Manager - + config *Config + ctrls env.NetworkControllers + ctrlBindhandler channel.BindHandler + faulter *forwarder.Faulter + forwarder *forwarder.Forwarder + xrctrls []env.Xrctrl + xlinkFactories map[string]xlink.Factory + xlinkListeners []xlink.Listener + xlinkDialers []xlink.Dialer + xlinkRegistry xlink.Registry + xgressListeners []xgress.Listener + linkDialerPool goroutines.Pool + rateLimiterPool goroutines.Pool + ctrlRateLimiter rate.AdaptiveRateLimitTracker + metricsRegistry metrics.UsageRegistry + shutdownC chan struct{} + shutdownDoneC chan struct{} + isShutdown atomic.Bool + metricsReporter metrics.Handler + versionProvider versions.VersionProvider + debugOperations map[byte]func(c *bufio.ReadWriter) error + stateManager state.Manager + rdmEnabled *config.Value[bool] xwebs []xweb.Instance xwebFactoryRegistry xweb.Registry agentBindHandlers []channel.BindHandler @@ -167,29 +167,33 @@ func (self *Router) GetRouterDataModel() *common.RouterDataModel { return self.stateManager.RouterDataModel() } -func (self *Router) IsHaEnabled() bool { - return self.config.Ha.Enabled +func (self *Router) IsRouterDataModelEnabled() bool { + return self.rdmEnabled.Load() +} + +func (self *Router) GetRouterDataModelEnabledConfig() *config.Value[bool] { + return self.rdmEnabled } func (self *Router) GetConnectEventsConfig() *env.ConnectEventsConfig { return &self.config.ConnectEvents } -func Create(config *Config, versionProvider versions.VersionProvider) *Router { +func Create(cfg *Config, versionProvider versions.VersionProvider) *Router { closeNotify := make(chan struct{}) - if config.Metrics.IntervalAgeThreshold != 0 { - metrics.SetIntervalAgeThreshold(config.Metrics.IntervalAgeThreshold) - logrus.Infof("set interval age threshold to '%v'", config.Metrics.IntervalAgeThreshold) + if cfg.Metrics.IntervalAgeThreshold != 0 { + metrics.SetIntervalAgeThreshold(cfg.Metrics.IntervalAgeThreshold) + logrus.Infof("set interval age threshold to '%v'", cfg.Metrics.IntervalAgeThreshold) } - env.IntervalSize = config.Metrics.ReportInterval - metricsRegistry := metrics.NewUsageRegistry(config.Id.Token, map[string]string{}, closeNotify) + env.IntervalSize = cfg.Metrics.ReportInterval + metricsRegistry := metrics.NewUsageRegistry(cfg.Id.Token, map[string]string{}, closeNotify) xgress.InitMetrics(metricsRegistry) linkDialerPoolConfig := goroutines.PoolConfig{ - QueueSize: uint32(config.Forwarder.LinkDial.QueueLength), + QueueSize: uint32(cfg.Forwarder.LinkDial.QueueLength), MinWorkers: 0, - MaxWorkers: uint32(config.Forwarder.LinkDial.WorkerCount), + MaxWorkers: uint32(cfg.Forwarder.LinkDial.WorkerCount), IdleTime: 30 * time.Second, CloseNotify: closeNotify, PanicHandler: func(err interface{}) { @@ -205,7 +209,7 @@ func Create(config *Config, versionProvider versions.VersionProvider) *Router { } router := &Router{ - config: config, + config: cfg, metricsRegistry: metricsRegistry, shutdownC: closeNotify, shutdownDoneC: make(chan struct{}), @@ -213,15 +217,16 @@ func Create(config *Config, versionProvider versions.VersionProvider) *Router { debugOperations: map[byte]func(c *bufio.ReadWriter) error{}, xwebFactoryRegistry: xweb.NewRegistryMap(), linkDialerPool: linkDialerPool, - ctrlRateLimiter: command.NewAdaptiveRateLimitTracker(config.Ctrl.RateLimit, metricsRegistry, closeNotify), + ctrlRateLimiter: command.NewAdaptiveRateLimitTracker(cfg.Ctrl.RateLimit, metricsRegistry, closeNotify), + rdmEnabled: config.NewConfigValue[bool](), } router.stateManager = state.NewManager(router) - router.ctrls = env.NewNetworkControllers(config.Ctrl.DefaultRequestTimeout, router.connectToController, &config.Ctrl.Heartbeats) + router.ctrls = env.NewNetworkControllers(cfg.Ctrl.DefaultRequestTimeout, router.connectToController, &cfg.Ctrl.Heartbeats) router.xlinkRegistry = link.NewLinkRegistry(router) - router.faulter = forwarder.NewFaulter(router.ctrls, config.Forwarder.FaultTxInterval, closeNotify) - router.forwarder = forwarder.NewForwarder(metricsRegistry, router.faulter, config.Forwarder, closeNotify) + router.faulter = forwarder.NewFaulter(router.ctrls, cfg.Forwarder.FaultTxInterval, closeNotify) + router.forwarder = forwarder.NewForwarder(metricsRegistry, router.faulter, cfg.Forwarder, closeNotify) router.forwarder.StartScanner(router.ctrls) xgress.InitPayloadIngester(closeNotify) diff --git a/router/state/manager.go b/router/state/manager.go index 9cee83ff2..bc8ba845c 100644 --- a/router/state/manager.go +++ b/router/state/manager.go @@ -58,7 +58,7 @@ type RemoveListener func() type DisconnectCB func(token string) type Env interface { - IsHaEnabled() bool + IsRouterDataModelEnabled() bool GetCloseNotify() <-chan struct{} DefaultRequestTimeout() time.Duration } @@ -503,7 +503,7 @@ func NewApiSessionFromToken(jwtToken *jwt.Token, accessClaims *common.AccessClai } func (sm *ManagerImpl) GetApiSession(token string) *ApiSession { - if sm.env.IsHaEnabled() && strings.HasPrefix(token, oidc_auth.JwtTokenPrefix) { + if strings.HasPrefix(token, oidc_auth.JwtTokenPrefix) { jwtToken, accessClaims, err := sm.ParseJwt(token) if err == nil { diff --git a/router/xgress_edge/factory.go b/router/xgress_edge/factory.go index 000085378..261c700e0 100644 --- a/router/xgress_edge/factory.go +++ b/router/xgress_edge/factory.go @@ -25,7 +25,6 @@ import ( "github.com/openziti/metrics" "github.com/openziti/sdk-golang/ziti/edge" "github.com/openziti/transport/v2" - "github.com/openziti/ziti/common" "github.com/openziti/ziti/common/inspect" "github.com/openziti/ziti/common/pb/edge_ctrl_pb" "github.com/openziti/ziti/router" @@ -103,10 +102,6 @@ func (factory *Factory) addReconnectionHandler(h reconnectionHandler) { factory.reconnectionHandlers.Append(h) } -func (factory *Factory) GetTraceDecoders() []channel.TraceMessageDecoder { - return nil -} - func (factory *Factory) Run(env env.RouterEnv) error { factory.stateManager.StartHeartbeat(env, factory.edgeRouterConfig.HeartbeatIntervalSeconds, env.GetCloseNotify()) @@ -141,12 +136,7 @@ func (factory *Factory) LoadConfig(configMap map[interface{}]interface{}) error edgeConfig.Tcfg["protocol"] = append(edgeConfig.Tcfg.Protocols(), "ziti-edge", "") factory.edgeRouterConfig = edgeConfig - - if factory.routerConfig.Ha.Enabled { - factory.stateManager.LoadRouterModel(factory.edgeRouterConfig.Db) - } else { - factory.stateManager.SetRouterDataModel(common.NewReceiverRouterDataModel(state.RouterDataModelListerBufferSize, factory.env.GetCloseNotify())) - } + factory.stateManager.LoadRouterModel(factory.edgeRouterConfig.Db) go apiproxy.Start(edgeConfig) diff --git a/router/xgress_edge/hosted.go b/router/xgress_edge/hosted.go index 17a5b418c..d1c6884bc 100644 --- a/router/xgress_edge/hosted.go +++ b/router/xgress_edge/hosted.go @@ -550,7 +550,7 @@ func (self *hostedServiceRegistry) establishTerminator(terminator *edgeTerminato InstanceSecret: terminator.instanceSecret, } - if self.stateManager.GetEnv().IsHaEnabled() && xgress_common.IsBearerToken(request.SessionToken) { + if xgress_common.IsBearerToken(request.SessionToken) { apiSession := self.stateManager.GetApiSessionFromCh(terminator.Channel) if apiSession == nil { diff --git a/router/xgress_edge/listener.go b/router/xgress_edge/listener.go index 3e81baee8..8045778a3 100644 --- a/router/xgress_edge/listener.go +++ b/router/xgress_edge/listener.go @@ -183,7 +183,7 @@ func (self *edgeClientConn) processConnect(manager state.Manager, req *channel.M PeerData: peerData, } - if manager.GetEnv().IsHaEnabled() && xgress_common.IsBearerToken(sessionToken) { + if xgress_common.IsBearerToken(sessionToken) { apiSession := manager.GetApiSessionFromCh(ch) if apiSession == nil { @@ -369,7 +369,7 @@ func (self *edgeClientConn) processBindV1(manager state.Manager, req *channel.Me InstanceSecret: terminatorIdentitySecret, } - if manager.GetEnv().IsHaEnabled() && xgress_common.IsBearerToken(sessionToken) { + if xgress_common.IsBearerToken(sessionToken) { apiSession := manager.GetApiSessionFromCh(ch) if apiSession == nil { @@ -596,7 +596,7 @@ func (self *edgeClientConn) processUpdateBind(manager state.Manager, req *channe TerminatorId: terminator.terminatorId, } - if manager.GetEnv().IsHaEnabled() && xgress_common.IsBearerToken(sessionToken) { + if xgress_common.IsBearerToken(sessionToken) { apiSession := manager.GetApiSessionFromCh(ch) request.ApiSessionToken = apiSession.Token } @@ -663,7 +663,7 @@ func (self *edgeClientConn) processHealthEvent(manager state.Manager, req *chann log = log.WithField("terminator", terminator.terminatorId).WithField("checkPassed", checkPassed) - if manager.GetEnv().IsHaEnabled() && xgress_common.IsBearerToken(sessionToken) { + if xgress_common.IsBearerToken(sessionToken) { apiSession := manager.GetApiSessionFromCh(ch) request.ApiSessionToken = apiSession.Token } diff --git a/router/xgress_edge_tunnel/fabric.go b/router/xgress_edge_tunnel/fabric.go index 4ad7b5aed..ea66db69a 100644 --- a/router/xgress_edge_tunnel/fabric.go +++ b/router/xgress_edge_tunnel/fabric.go @@ -235,7 +235,7 @@ func (self *fabricProvider) TunnelService(service tunnel.Service, terminatorInst return errors.New(errStr) } - if self.factory.routerConfig.Ha.Enabled { + if self.factory.stateManager.GetEnv().IsRouterDataModelEnabled() { return self.tunnelServiceV2(service, terminatorInstanceId, conn, halfClose, ctrlCh, peerData, keyPair) } diff --git a/router/xgress_edge_tunnel/factory.go b/router/xgress_edge_tunnel/factory.go index 617446e08..54bcf2019 100644 --- a/router/xgress_edge_tunnel/factory.go +++ b/router/xgress_edge_tunnel/factory.go @@ -29,7 +29,6 @@ import ( "github.com/openziti/ziti/router/handler_edge_ctrl" "github.com/openziti/ziti/router/state" "github.com/openziti/ziti/router/xgress" - "github.com/openziti/ziti/router/xgress_edge_tunnel_v2" "github.com/pkg/errors" "strings" "time" @@ -96,10 +95,10 @@ type XrctrlFactory interface { // NewFactory constructs a new Edge Xgress Tunnel Factory instance func NewFactory(env env.RouterEnv, routerConfig *router.Config, stateManager state.Manager) XrctrlFactory { - if routerConfig.Ha.Enabled { - return xgress_edge_tunnel_v2.NewFactory(env, routerConfig, stateManager) - } + return NewFactoryWrapper(env, routerConfig, stateManager) +} +func NewV1Factory(env env.RouterEnv, routerConfig *router.Config, stateManager state.Manager) XrctrlFactory { factory := &Factory{ id: env.GetRouterId(), routerConfig: routerConfig, diff --git a/router/xgress_edge_tunnel/factory_wrapper.go b/router/xgress_edge_tunnel/factory_wrapper.go new file mode 100644 index 000000000..3a7ed073a --- /dev/null +++ b/router/xgress_edge_tunnel/factory_wrapper.go @@ -0,0 +1,202 @@ +package xgress_edge_tunnel + +import ( + "errors" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel/v3" + "github.com/openziti/foundation/v2/concurrenz" + "github.com/openziti/ziti/common" + "github.com/openziti/ziti/common/config" + "github.com/openziti/ziti/common/pb/edge_ctrl_pb" + "github.com/openziti/ziti/router" + "github.com/openziti/ziti/router/env" + "github.com/openziti/ziti/router/state" + "github.com/openziti/ziti/router/xgress" + "github.com/openziti/ziti/router/xgress_edge_tunnel_v2" + "time" +) + +type FactoryWrapper struct { + env env.RouterEnv + routerConfig *router.Config + stateManager state.Manager + initDone chan struct{} + delegate concurrenz.AtomicValue[XrctrlFactory] + + listenerOptions chan xgress.OptionsData + listenerArgs chan listenArgs +} + +func (self *FactoryWrapper) LoadConfig(map[interface{}]interface{}) error { + // both v1/v2 currently have empty LoadConfig methods. Will need to update this if that changes. + return nil +} + +func (self *FactoryWrapper) BindChannel(binding channel.Binding) error { + // v1 bindings + binding.AddReceiveHandlerF(int32(edge_ctrl_pb.ContentType_ServiceListType), self.handleV1ServiceListType) + binding.AddReceiveHandlerF(int32(edge_ctrl_pb.ContentType_CreateTunnelTerminatorResponseType), self.handleV1CreateTunnelTerminatorResponse) + + // v2 bindings + binding.AddReceiveHandlerF(int32(edge_ctrl_pb.ContentType_CreateTunnelTerminatorResponseV2Type), self.handleV2CreateTunnelTerminatorResponse) + + return nil +} + +func (self *FactoryWrapper) handleV1ServiceListType(msg *channel.Message, ch channel.Channel) { + if delegate := self.delegate.Load(); delegate != nil { + if v1, ok := delegate.(*Factory); ok { + v1.serviceListHandler.HandleReceive(msg, ch) + } + } +} + +func (self *FactoryWrapper) handleV1CreateTunnelTerminatorResponse(msg *channel.Message, ch channel.Channel) { + if delegate := self.delegate.Load(); delegate != nil { + if v1, ok := delegate.(*Factory); ok { + v1.tunneler.fabricProvider.HandleTunnelResponse(msg, ch) + } + } +} + +func (self *FactoryWrapper) handleV2CreateTunnelTerminatorResponse(msg *channel.Message, ch channel.Channel) { + if delegate := self.delegate.Load(); delegate != nil { + if v2, ok := delegate.(*xgress_edge_tunnel_v2.Factory); ok { + v2.HandleCreateTunnelTerminatorResponse(msg, ch) + } + } +} + +func (self *FactoryWrapper) Enabled() bool { + return true +} + +func (self *FactoryWrapper) Run(env.RouterEnv) error { + // we'll call run when initialization is complete + return nil +} + +func (self *FactoryWrapper) NotifyOfReconnect(ch channel.Channel) { + if delegate := self.delegate.Load(); delegate != nil { + delegate.NotifyOfReconnect(ch) + } +} + +func NewFactoryWrapper(env env.RouterEnv, routerConfig *router.Config, stateManager state.Manager) XrctrlFactory { + wrapper := &FactoryWrapper{ + env: env, + routerConfig: routerConfig, + stateManager: stateManager, + initDone: make(chan struct{}), + listenerOptions: make(chan xgress.OptionsData, 5), + listenerArgs: make(chan listenArgs, 5), + } + + env.GetRouterDataModelEnabledConfig().AddListener(config.ListenerFunc[bool](func(init bool, old bool, new bool) { + if !init && old != new { + pfxlog.Logger() + } + })) + + go func() { + defer close(wrapper.initDone) + + log := pfxlog.Logger() + + select { + case <-env.GetRouterDataModelEnabledConfig().GetInitNotifyChannel(): + case <-env.GetCloseNotify(): + return + } + + var factory XrctrlFactory + if env.GetRouterDataModelEnabledConfig().Load() { + log.Info("router data model enabled, using xgress_edge_tunnel_v2") + factory = xgress_edge_tunnel_v2.NewFactory(env, routerConfig, stateManager) + } else { + log.Info("router data model NOT enabled, using xgress_edge_tunnel") + factory = NewV1Factory(env, routerConfig, stateManager) + } + + wrapper.delegate.Store(factory) + + done := false + for !done { + select { + case options := <-wrapper.listenerOptions: + listener, err := factory.CreateListener(options) + if err != nil { + log.WithField("binding", common.TunnelBinding).WithError(err).Fatal("error creating listener") + return + } + + select { + case args := <-wrapper.listenerArgs: + args.delegate.delegate.Store(listener) + err = listener.Listen(args.address, args.bindHandler) + if err != nil { + log.WithField("binding", common.TunnelBinding).WithError(err).Fatal("error starting listener") + return + } + case <-time.After(time.Second * 5): + log.WithField("binding", common.TunnelBinding).WithError(err).Fatal("timeout waiting for start to be called on listener") + return + } + default: + done = true + } + + } + + _ = env.GetNetworkControllers().AnyValidCtrlChannel() + if err := factory.Run(env); err != nil { + log.WithError(err).Fatal("error starting") + } + }() + + return wrapper +} + +func (self *FactoryWrapper) CreateListener(optionsData xgress.OptionsData) (xgress.Listener, error) { + self.listenerOptions <- optionsData + return &delegatingListener{ + factory: self, + options: optionsData, + }, nil +} + +func (self *FactoryWrapper) CreateDialer(optionsData xgress.OptionsData) (xgress.Dialer, error) { + if delegate := self.delegate.Load(); delegate != nil { + return delegate.CreateDialer(optionsData) + } + + return nil, errors.New("initialization incomplete, unable to create dialer") +} + +type delegatingListener struct { + factory *FactoryWrapper + options xgress.OptionsData + delegate concurrenz.AtomicValue[xgress.Listener] +} + +type listenArgs struct { + address string + bindHandler xgress.BindHandler + delegate *delegatingListener +} + +func (self *delegatingListener) Listen(address string, bindHandler xgress.BindHandler) error { + self.factory.listenerArgs <- listenArgs{ + address: address, + bindHandler: bindHandler, + delegate: self, + } + return nil +} + +func (self *delegatingListener) Close() error { + if listener := self.delegate.Load(); listener != nil { + return listener.Close() + } + return nil +} diff --git a/router/xgress_edge_tunnel_v2/factory.go b/router/xgress_edge_tunnel_v2/factory.go index 6cb7a4247..6319a2f8d 100644 --- a/router/xgress_edge_tunnel_v2/factory.go +++ b/router/xgress_edge_tunnel_v2/factory.go @@ -26,7 +26,6 @@ import ( "github.com/openziti/ziti/common/pb/edge_ctrl_pb" "github.com/openziti/ziti/router" "github.com/openziti/ziti/router/env" - "github.com/openziti/ziti/router/handler_edge_ctrl" "github.com/openziti/ziti/router/state" "github.com/openziti/ziti/router/xgress" "github.com/pkg/errors" @@ -42,14 +41,13 @@ const ( ) type Factory struct { - id *identity.TokenId - ctrls env.NetworkControllers - routerConfig *router.Config - stateManager state.Manager - serviceListHandler *handler_edge_ctrl.ServiceListHandler - tunneler *tunneler - metricsRegistry metrics.UsageRegistry - env env.RouterEnv + id *identity.TokenId + ctrls env.NetworkControllers + routerConfig *router.Config + stateManager state.Manager + tunneler *tunneler + metricsRegistry metrics.UsageRegistry + env env.RouterEnv } func (self *Factory) NotifyOfReconnect(channel.Channel) { @@ -57,20 +55,19 @@ func (self *Factory) NotifyOfReconnect(channel.Channel) { self.tunneler.HandleReconnect() } -func (self *Factory) GetTraceDecoders() []channel.TraceMessageDecoder { - return nil -} - func (self *Factory) Enabled() bool { return true } func (self *Factory) BindChannel(binding channel.Binding) error { - binding.AddTypedReceiveHandler(self.serviceListHandler) binding.AddReceiveHandlerF(int32(edge_ctrl_pb.ContentType_CreateTunnelTerminatorResponseV2Type), self.tunneler.fabricProvider.HandleTunnelResponse) return nil } +func (self *Factory) HandleCreateTunnelTerminatorResponse(msg *channel.Message, ch channel.Channel) { + self.tunneler.fabricProvider.HandleTunnelResponse(msg, ch) +} + func (self *Factory) Run(env env.RouterEnv) error { self.ctrls = env.GetNetworkControllers() if self.tunneler.listenOptions != nil { diff --git a/tests/context.go b/tests/context.go index d08cde88e..6a4872c3f 100644 --- a/tests/context.go +++ b/tests/context.go @@ -530,9 +530,7 @@ func (ctx *TestContext) CreateEnrollAndStartEdgeRouter(roleAttributes ...string) func (ctx *TestContext) CreateEnrollAndStartHAEdgeRouter(roleAttributes ...string) *router.Router { ctx.shutdownRouters() ctx.createAndEnrollEdgeRouter(false, roleAttributes...) - return ctx.startEdgeRouter(func(r *router.Config) { - r.Ha.Enabled = true - }) + return ctx.startEdgeRouter(nil) } func (ctx *TestContext) startEdgeRouter(cfgTweaks func(*router.Config)) *router.Router { diff --git a/ziti/cmd/fabric/inspect.go b/ziti/cmd/fabric/inspect.go index 72961ccf1..a6406516d 100644 --- a/ziti/cmd/fabric/inspect.go +++ b/ziti/cmd/fabric/inspect.go @@ -35,6 +35,7 @@ func newInspectCmd(p common.OptionsProvider) *cobra.Command { cmd.AddCommand(action.newInspectSubCmd(p, "sdk-terminators", "gets information from routers about their view of sdk terminators")) cmd.AddCommand(action.newInspectSubCmd(p, "router-messaging", "gets information about pending router peer updates and terminator validations")) cmd.AddCommand(action.newInspectSubCmd(p, "router-data-model", "gets information about the router data model")) + cmd.AddCommand(action.newInspectSubCmd(p, "router-data-model-index", "gets current index of the router data model")) cmd.AddCommand(action.newInspectSubCmd(p, "router-controllers", "gets information about the state of a router's connections to its controllers")) cmd.AddCommand(action.newInspectSubCmd(p, "terminator-costs", "gets information about terminator dynamic costs")) cmd.AddCommand(action.newInspectSubCmd(p, inspectCommon.RouterIdentityConnectionStatusesKey, "gets information about controller identity state")) diff --git a/zititest/models/router-data-model-test/configs/router.yml.tmpl b/zititest/models/router-data-model-test/configs/router.yml.tmpl index 8e42c4598..a652ee6df 100644 --- a/zititest/models/router-data-model-test/configs/router.yml.tmpl +++ b/zititest/models/router-data-model-test/configs/router.yml.tmpl @@ -6,10 +6,8 @@ v: 3 enableDebugOps: true -{{if .Component.GetFlag "ha"}} ha: enabled: true -{{end}} identity: cert: /home/{{$ssh_username}}/fablab/cfg/{{$identity}}-client.cert diff --git a/zititest/models/router-data-model-test/main.go b/zititest/models/router-data-model-test/main.go index 86e387fcc..eaf8c6695 100644 --- a/zititest/models/router-data-model-test/main.go +++ b/zititest/models/router-data-model-test/main.go @@ -266,7 +266,7 @@ var m = &model.Model{ task := createNewService(ctrls.getCtrl("ctrl1")) tasks = append(tasks, task) } - return parallel.ExecuteLabeled(tasks, 2) + return parallel.ExecuteLabeled(tasks, 2, nil) })) workflow.AddAction(model.ActionFunc(func(run model.Run) error { @@ -280,7 +280,7 @@ var m = &model.Model{ task := createNewIdentity(ctrls.getCtrl("ctrl1")) tasks = append(tasks, task) } - return parallel.ExecuteLabeled(tasks, 2) + return parallel.ExecuteLabeled(tasks, 2, nil) })) workflow.AddAction(model.ActionFunc(func(run model.Run) error { @@ -291,10 +291,10 @@ var m = &model.Model{ var tasks []parallel.LabeledTask for range 100 { - task := createNewService(ctrls.getCtrl("ctrl1")) + task := createNewServicePolicy(ctrls.getCtrl("ctrl1")) tasks = append(tasks, task) } - return parallel.ExecuteLabeled(tasks, 2) + return parallel.ExecuteLabeled(tasks, 2, nil) })) workflow.AddAction(semaphore.Sleep(2 * time.Second)) diff --git a/zititest/models/router-data-model-test/validation.go b/zititest/models/router-data-model-test/validation.go index accd82040..c72961a56 100644 --- a/zititest/models/router-data-model-test/validation.go +++ b/zititest/models/router-data-model-test/validation.go @@ -26,12 +26,15 @@ import ( "github.com/openziti/edge-api/rest_model" "github.com/openziti/fablab/kernel/lib/parallel" "github.com/openziti/fablab/kernel/model" + "github.com/openziti/foundation/v2/errorz" "github.com/openziti/ziti/common/pb/mgmt_pb" + "github.com/openziti/ziti/ziti/util" "github.com/openziti/ziti/zitirest" "github.com/openziti/ziti/zititest/zitilab/chaos" "github.com/openziti/ziti/zititest/zitilab/models" "google.golang.org/protobuf/proto" "math/rand" + "strings" "sync" "time" ) @@ -117,7 +120,24 @@ func sowChaos(run model.Run) error { } chaos.Randomize(tasks) - return parallel.ExecuteLabeled(tasks, 2) + + retryPolicy := func(task parallel.LabeledTask, attempt int, err error) parallel.ErrorAction { + if strings.HasPrefix(task.Type(), "delete.") { + var apiErr util.ApiErrorPayload + if errors.As(err, &apiErr) { + if apiErr.GetPayload().Error.Code == errorz.NotFoundCode { + return parallel.ErrActionIgnore + } + } + } + if attempt > 3 { + return parallel.ErrActionReport + } + pfxlog.Logger().WithField("attempt", attempt).WithError(err).WithField("task", task.Label()).Error("action failed, retrying") + time.Sleep(time.Second) + return parallel.ErrActionRetry + } + return parallel.ExecuteLabeled(tasks, 2, retryPolicy) } func getRestartTasks(run model.Run, _ *CtrlClients) ([]parallel.LabeledTask, error) { @@ -135,7 +155,7 @@ func getRestartTasks(run model.Run, _ *CtrlClients) ([]parallel.LabeledTask, err return nil, err } for _, controller := range controllers { - result = append(result, parallel.TaskWithLabel(fmt.Sprintf("restart controller %s", controller.Id), func() error { + result = append(result, parallel.TaskWithLabel("restart.ctrl", fmt.Sprintf("restart controller %s", controller.Id), func() error { return chaos.RestartSelected(run, 1, controller) })) } @@ -148,7 +168,7 @@ func getRestartTasks(run model.Run, _ *CtrlClients) ([]parallel.LabeledTask, err return nil, err } for _, router := range routers { - result = append(result, parallel.TaskWithLabel(fmt.Sprintf("restart router %s", router.Id), func() error { + result = append(result, parallel.TaskWithLabel("restart.router", fmt.Sprintf("restart router %s", router.Id), func() error { return chaos.RestartSelected(run, 1, router) })) } @@ -204,13 +224,13 @@ func getServiceChaosTasks(_ model.Run, ctrls *CtrlClients) ([]parallel.LabeledTa var result []parallel.LabeledTask for i := 0; i < 5; i++ { - result = append(result, parallel.TaskWithLabel(fmt.Sprintf("delete service %s", *svcs[i].ID), func() error { + result = append(result, parallel.TaskWithLabel("delete.service", fmt.Sprintf("delete service %s", *svcs[i].ID), func() error { return models.DeleteService(ctrls.getRandomCtrl(), *svcs[i].ID, 15*time.Second) })) } for i := 5; i < 10; i++ { - result = append(result, parallel.TaskWithLabel(fmt.Sprintf("modify service %s", *svcs[i].ID), func() error { + result = append(result, parallel.TaskWithLabel("modify.service", fmt.Sprintf("modify service %s", *svcs[i].ID), func() error { svc := svcs[i] svc.RoleAttributes = getRoleAttributesAsAttrPtr(3) svc.Name = newId() @@ -226,7 +246,7 @@ func getServiceChaosTasks(_ model.Run, ctrls *CtrlClients) ([]parallel.LabeledTa } func getIdentityChaosTasks(_ model.Run, ctrls *CtrlClients) ([]parallel.LabeledTask, error) { - entities, err := models.ListIdentities(ctrls.getRandomCtrl(), "limit none", 15*time.Second) + entities, err := models.ListIdentities(ctrls.getRandomCtrl(), "not isAdmin limit none", 15*time.Second) if err != nil { return nil, err } @@ -235,13 +255,13 @@ func getIdentityChaosTasks(_ model.Run, ctrls *CtrlClients) ([]parallel.LabeledT var result []parallel.LabeledTask for i := 0; i < 5; i++ { - result = append(result, parallel.TaskWithLabel(fmt.Sprintf("delete identity %s", *entities[i].ID), func() error { + result = append(result, parallel.TaskWithLabel("delete.identity", fmt.Sprintf("delete identity %s", *entities[i].ID), func() error { return models.DeleteIdentity(ctrls.getRandomCtrl(), *entities[i].ID, 15*time.Second) })) } for i := 5; i < 10; i++ { - result = append(result, parallel.TaskWithLabel(fmt.Sprintf("modify identity %s", *entities[i].ID), func() error { + result = append(result, parallel.TaskWithLabel("modify.identity", fmt.Sprintf("modify identity %s", *entities[i].ID), func() error { entity := entities[i] entity.RoleAttributes = getRoleAttributesAsAttrPtr(3) entity.Name = newId() @@ -266,13 +286,13 @@ func getServicePolicyChaosTasks(_ model.Run, ctrls *CtrlClients) ([]parallel.Lab var result []parallel.LabeledTask for i := 0; i < 5; i++ { - result = append(result, parallel.TaskWithLabel(fmt.Sprintf("delete service policy %s", *entities[i].ID), func() error { + result = append(result, parallel.TaskWithLabel("delete.service-policy", fmt.Sprintf("delete service policy %s", *entities[i].ID), func() error { return models.DeleteServicePolicy(ctrls.getRandomCtrl(), *entities[i].ID, 15*time.Second) })) } for i := 5; i < 10; i++ { - result = append(result, parallel.TaskWithLabel(fmt.Sprintf("modify service policy %s", *entities[i].ID), func() error { + result = append(result, parallel.TaskWithLabel("modify.service-policy", fmt.Sprintf("modify service policy %s", *entities[i].ID), func() error { entity := entities[i] entity.IdentityRoles = getRoles(3) entity.ServiceRoles = getRoles(3) @@ -290,7 +310,7 @@ func getServicePolicyChaosTasks(_ model.Run, ctrls *CtrlClients) ([]parallel.Lab } func createNewService(ctrl *zitirest.Clients) parallel.LabeledTask { - return parallel.TaskWithLabel("create new service", func() error { + return parallel.TaskWithLabel("create.service", "create new service", func() error { svc := &rest_model.ServiceCreate{ Configs: nil, EncryptionRequired: newBoolPtr(), @@ -305,7 +325,7 @@ func createNewService(ctrl *zitirest.Clients) parallel.LabeledTask { func createNewIdentity(ctrl *zitirest.Clients) parallel.LabeledTask { isAdmin := false identityType := rest_model.IdentityTypeDefault - return parallel.TaskWithLabel("create new identity", func() error { + return parallel.TaskWithLabel("create.identity", "create new identity", func() error { svc := &rest_model.IdentityCreate{ DefaultHostingCost: nil, DefaultHostingPrecedence: "", @@ -322,7 +342,7 @@ func createNewIdentity(ctrl *zitirest.Clients) parallel.LabeledTask { } func createNewServicePolicy(ctrl *zitirest.Clients) parallel.LabeledTask { - return parallel.TaskWithLabel("create new service policy", func() error { + return parallel.TaskWithLabel("create.service-policy", "create new service policy", func() error { anyOf := rest_model.SemanticAnyOf policyType := rest_model.DialBindDial if rand.Int()%2 == 0 {