diff --git a/CHANGELOG.md b/CHANGELOG.md index c65621db..692fd914 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -363,4 +363,11 @@ Release 1.9.0 Breaking Changes: #### resource/coralogix_webhook * All webhook types changed from `TypeList` to `SingleNestedAttribute` e.g. - `slack { }` => `slack = { }`. -* Linkage between webhook and alert was changed from webhook's `id` to webhook's `external_id`. e.g.- `integration_id = coralogix_webhook.slack_webhook.id` => `integration_id = coralogix_webhook.slack_webhook.external_id` \ No newline at end of file +* Linkage between webhook and alert was changed from webhook's `id` to webhook's `external_id`. e.g.- `integration_id = coralogix_webhook.slack_webhook.id` => `integration_id = coralogix_webhook.slack_webhook.external_id` + +Release 1.10.0 +Breaking Changes: +#### resource/coralogix_recording_rules_groups_set +* `group` was changed to `groups` and from `TypeSet` to `SetNestedAttribute`. e.g. - `group { }` => `groups = [{ }]`. +* `group.rule` was changed to `groups.rules` and from `TypeList` to `ListNestedAttribute`. e.g. - `rule { }` => `rules = [{ }]`. +* this version contains a [State Upgrader](https://developer.hashicorp.com/terraform/plugin/framework/migrating/resources/state-upgrade#framework). It will upgrade the state to the new schema. Please make sure to back up your state before upgrading. \ No newline at end of file diff --git a/coralogix/clientset/grpc/recording-rules-groups-sets/v1/groups.pb.go b/coralogix/clientset/grpc/recording-rules-groups-sets/v1/groups.pb.go index 42411fee..df94fcfc 100644 --- a/coralogix/clientset/grpc/recording-rules-groups-sets/v1/groups.pb.go +++ b/coralogix/clientset/grpc/recording-rules-groups-sets/v1/groups.pb.go @@ -2,7 +2,7 @@ // versions: // protoc-gen-go v1.28.1 // protoc v3.21.8 -// source: groups.proto +// source: proto/groups.proto package __ @@ -42,7 +42,7 @@ type InRuleGroup struct { func (x *InRuleGroup) Reset() { *x = InRuleGroup{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[0] + mi := &file_proto_groups_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -55,7 +55,7 @@ func (x *InRuleGroup) String() string { func (*InRuleGroup) ProtoMessage() {} func (x *InRuleGroup) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[0] + mi := &file_proto_groups_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -68,7 +68,7 @@ func (x *InRuleGroup) ProtoReflect() protoreflect.Message { // Deprecated: Use InRuleGroup.ProtoReflect.Descriptor instead. func (*InRuleGroup) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{0} + return file_proto_groups_proto_rawDescGZIP(), []int{0} } func (x *InRuleGroup) GetName() string { @@ -118,7 +118,7 @@ type InRule struct { func (x *InRule) Reset() { *x = InRule{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[1] + mi := &file_proto_groups_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -131,7 +131,7 @@ func (x *InRule) String() string { func (*InRule) ProtoMessage() {} func (x *InRule) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[1] + mi := &file_proto_groups_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -144,7 +144,7 @@ func (x *InRule) ProtoReflect() protoreflect.Message { // Deprecated: Use InRule.ProtoReflect.Descriptor instead. func (*InRule) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{1} + return file_proto_groups_proto_rawDescGZIP(), []int{1} } func (x *InRule) GetRecord() string { @@ -183,7 +183,7 @@ type OutRuleGroup struct { func (x *OutRuleGroup) Reset() { *x = OutRuleGroup{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[2] + mi := &file_proto_groups_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -196,7 +196,7 @@ func (x *OutRuleGroup) String() string { func (*OutRuleGroup) ProtoMessage() {} func (x *OutRuleGroup) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[2] + mi := &file_proto_groups_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -209,7 +209,7 @@ func (x *OutRuleGroup) ProtoReflect() protoreflect.Message { // Deprecated: Use OutRuleGroup.ProtoReflect.Descriptor instead. func (*OutRuleGroup) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{2} + return file_proto_groups_proto_rawDescGZIP(), []int{2} } func (x *OutRuleGroup) GetName() string { @@ -261,7 +261,7 @@ type OutRule struct { func (x *OutRule) Reset() { *x = OutRule{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[3] + mi := &file_proto_groups_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -274,7 +274,7 @@ func (x *OutRule) String() string { func (*OutRule) ProtoMessage() {} func (x *OutRule) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[3] + mi := &file_proto_groups_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -287,7 +287,7 @@ func (x *OutRule) ProtoReflect() protoreflect.Message { // Deprecated: Use OutRule.ProtoReflect.Descriptor instead. func (*OutRule) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{3} + return file_proto_groups_proto_rawDescGZIP(), []int{3} } func (x *OutRule) GetRecord() string { @@ -331,7 +331,7 @@ type DeleteRuleGroup struct { func (x *DeleteRuleGroup) Reset() { *x = DeleteRuleGroup{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[4] + mi := &file_proto_groups_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -344,7 +344,7 @@ func (x *DeleteRuleGroup) String() string { func (*DeleteRuleGroup) ProtoMessage() {} func (x *DeleteRuleGroup) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[4] + mi := &file_proto_groups_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -357,7 +357,7 @@ func (x *DeleteRuleGroup) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteRuleGroup.ProtoReflect.Descriptor instead. func (*DeleteRuleGroup) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{4} + return file_proto_groups_proto_rawDescGZIP(), []int{4} } func (x *DeleteRuleGroup) GetName() string { @@ -380,7 +380,7 @@ type RuleGroupListing struct { func (x *RuleGroupListing) Reset() { *x = RuleGroupListing{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[5] + mi := &file_proto_groups_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -393,7 +393,7 @@ func (x *RuleGroupListing) String() string { func (*RuleGroupListing) ProtoMessage() {} func (x *RuleGroupListing) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[5] + mi := &file_proto_groups_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -406,7 +406,7 @@ func (x *RuleGroupListing) ProtoReflect() protoreflect.Message { // Deprecated: Use RuleGroupListing.ProtoReflect.Descriptor instead. func (*RuleGroupListing) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{5} + return file_proto_groups_proto_rawDescGZIP(), []int{5} } func (x *RuleGroupListing) GetRuleGroups() []*OutRuleGroup { @@ -429,7 +429,7 @@ type FetchRuleGroup struct { func (x *FetchRuleGroup) Reset() { *x = FetchRuleGroup{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[6] + mi := &file_proto_groups_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -442,7 +442,7 @@ func (x *FetchRuleGroup) String() string { func (*FetchRuleGroup) ProtoMessage() {} func (x *FetchRuleGroup) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[6] + mi := &file_proto_groups_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -455,7 +455,7 @@ func (x *FetchRuleGroup) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchRuleGroup.ProtoReflect.Descriptor instead. func (*FetchRuleGroup) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{6} + return file_proto_groups_proto_rawDescGZIP(), []int{6} } func (x *FetchRuleGroup) GetName() string { @@ -478,7 +478,7 @@ type FetchRuleGroupResult struct { func (x *FetchRuleGroupResult) Reset() { *x = FetchRuleGroupResult{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[7] + mi := &file_proto_groups_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -491,7 +491,7 @@ func (x *FetchRuleGroupResult) String() string { func (*FetchRuleGroupResult) ProtoMessage() {} func (x *FetchRuleGroupResult) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[7] + mi := &file_proto_groups_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -504,7 +504,7 @@ func (x *FetchRuleGroupResult) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchRuleGroupResult.ProtoReflect.Descriptor instead. func (*FetchRuleGroupResult) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{7} + return file_proto_groups_proto_rawDescGZIP(), []int{7} } func (x *FetchRuleGroupResult) GetRuleGroup() *OutRuleGroup { @@ -526,7 +526,7 @@ type CreateRuleGroupSet struct { func (x *CreateRuleGroupSet) Reset() { *x = CreateRuleGroupSet{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[8] + mi := &file_proto_groups_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -539,7 +539,7 @@ func (x *CreateRuleGroupSet) String() string { func (*CreateRuleGroupSet) ProtoMessage() {} func (x *CreateRuleGroupSet) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[8] + mi := &file_proto_groups_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -552,7 +552,7 @@ func (x *CreateRuleGroupSet) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateRuleGroupSet.ProtoReflect.Descriptor instead. func (*CreateRuleGroupSet) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{8} + return file_proto_groups_proto_rawDescGZIP(), []int{8} } func (x *CreateRuleGroupSet) GetGroups() []*InRuleGroup { @@ -580,7 +580,7 @@ type CreateRuleGroupSetResult struct { func (x *CreateRuleGroupSetResult) Reset() { *x = CreateRuleGroupSetResult{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[9] + mi := &file_proto_groups_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -593,7 +593,7 @@ func (x *CreateRuleGroupSetResult) String() string { func (*CreateRuleGroupSetResult) ProtoMessage() {} func (x *CreateRuleGroupSetResult) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[9] + mi := &file_proto_groups_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -606,7 +606,7 @@ func (x *CreateRuleGroupSetResult) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateRuleGroupSetResult.ProtoReflect.Descriptor instead. func (*CreateRuleGroupSetResult) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{9} + return file_proto_groups_proto_rawDescGZIP(), []int{9} } func (x *CreateRuleGroupSetResult) GetId() string { @@ -623,12 +623,13 @@ type UpdateRuleGroupSet struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Groups []*InRuleGroup `protobuf:"bytes,2,rep,name=groups,proto3" json:"groups,omitempty"` + Name *string `protobuf:"bytes,3,opt,name=name,proto3,oneof" json:"name,omitempty"` } func (x *UpdateRuleGroupSet) Reset() { *x = UpdateRuleGroupSet{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[10] + mi := &file_proto_groups_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -641,7 +642,7 @@ func (x *UpdateRuleGroupSet) String() string { func (*UpdateRuleGroupSet) ProtoMessage() {} func (x *UpdateRuleGroupSet) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[10] + mi := &file_proto_groups_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -654,7 +655,7 @@ func (x *UpdateRuleGroupSet) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateRuleGroupSet.ProtoReflect.Descriptor instead. func (*UpdateRuleGroupSet) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{10} + return file_proto_groups_proto_rawDescGZIP(), []int{10} } func (x *UpdateRuleGroupSet) GetId() string { @@ -671,6 +672,13 @@ func (x *UpdateRuleGroupSet) GetGroups() []*InRuleGroup { return nil } +func (x *UpdateRuleGroupSet) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + type RuleGroupSetListing struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -682,7 +690,7 @@ type RuleGroupSetListing struct { func (x *RuleGroupSetListing) Reset() { *x = RuleGroupSetListing{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[11] + mi := &file_proto_groups_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -695,7 +703,7 @@ func (x *RuleGroupSetListing) String() string { func (*RuleGroupSetListing) ProtoMessage() {} func (x *RuleGroupSetListing) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[11] + mi := &file_proto_groups_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -708,7 +716,7 @@ func (x *RuleGroupSetListing) ProtoReflect() protoreflect.Message { // Deprecated: Use RuleGroupSetListing.ProtoReflect.Descriptor instead. func (*RuleGroupSetListing) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{11} + return file_proto_groups_proto_rawDescGZIP(), []int{11} } func (x *RuleGroupSetListing) GetSets() []*OutRuleGroupSet { @@ -729,7 +737,7 @@ type FetchRuleGroupSet struct { func (x *FetchRuleGroupSet) Reset() { *x = FetchRuleGroupSet{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[12] + mi := &file_proto_groups_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -742,7 +750,7 @@ func (x *FetchRuleGroupSet) String() string { func (*FetchRuleGroupSet) ProtoMessage() {} func (x *FetchRuleGroupSet) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[12] + mi := &file_proto_groups_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -755,7 +763,7 @@ func (x *FetchRuleGroupSet) ProtoReflect() protoreflect.Message { // Deprecated: Use FetchRuleGroupSet.ProtoReflect.Descriptor instead. func (*FetchRuleGroupSet) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{12} + return file_proto_groups_proto_rawDescGZIP(), []int{12} } func (x *FetchRuleGroupSet) GetId() string { @@ -776,7 +784,7 @@ type DeleteRuleGroupSet struct { func (x *DeleteRuleGroupSet) Reset() { *x = DeleteRuleGroupSet{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[13] + mi := &file_proto_groups_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -789,7 +797,7 @@ func (x *DeleteRuleGroupSet) String() string { func (*DeleteRuleGroupSet) ProtoMessage() {} func (x *DeleteRuleGroupSet) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[13] + mi := &file_proto_groups_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -802,7 +810,7 @@ func (x *DeleteRuleGroupSet) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteRuleGroupSet.ProtoReflect.Descriptor instead. func (*DeleteRuleGroupSet) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{13} + return file_proto_groups_proto_rawDescGZIP(), []int{13} } func (x *DeleteRuleGroupSet) GetId() string { @@ -819,13 +827,13 @@ type OutRuleGroupSet struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Groups []*OutRuleGroup `protobuf:"bytes,2,rep,name=groups,proto3" json:"groups,omitempty"` - Name *string `protobuf:"bytes,3,opt,name=name,proto3,oneof" json:"name,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` } func (x *OutRuleGroupSet) Reset() { *x = OutRuleGroupSet{} if protoimpl.UnsafeEnabled { - mi := &file_groups_proto_msgTypes[14] + mi := &file_proto_groups_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -838,7 +846,7 @@ func (x *OutRuleGroupSet) String() string { func (*OutRuleGroupSet) ProtoMessage() {} func (x *OutRuleGroupSet) ProtoReflect() protoreflect.Message { - mi := &file_groups_proto_msgTypes[14] + mi := &file_proto_groups_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -851,7 +859,7 @@ func (x *OutRuleGroupSet) ProtoReflect() protoreflect.Message { // Deprecated: Use OutRuleGroupSet.ProtoReflect.Descriptor instead. func (*OutRuleGroupSet) Descriptor() ([]byte, []int) { - return file_groups_proto_rawDescGZIP(), []int{14} + return file_proto_groups_proto_rawDescGZIP(), []int{14} } func (x *OutRuleGroupSet) GetId() string { @@ -869,186 +877,187 @@ func (x *OutRuleGroupSet) GetGroups() []*OutRuleGroup { } func (x *OutRuleGroupSet) GetName() string { - if x != nil && x.Name != nil { - return *x.Name + if x != nil { + return x.Name } return "" } -var File_groups_proto protoreflect.FileDescriptor - -var file_groups_proto_rawDesc = []byte{ - 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, - 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0xa7, 0x01, 0x0a, 0x0b, 0x49, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, - 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x48, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, - 0x12, 0x31, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x49, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, - 0x6c, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0xb0, 0x01, 0x0a, 0x06, 0x49, - 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, - 0x72, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, - 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x49, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x4c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 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, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe1, 0x01, - 0x0a, 0x0c, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x04, 0x48, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x32, - 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, - 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x5f, - 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x48, 0x02, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, - 0x45, 0x76, 0x61, 0x6c, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x69, 0x6e, +var File_proto_groups_proto protoreflect.FileDescriptor + +var file_proto_groups_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x0b, 0x49, 0x6e, 0x52, 0x75, 0x6c, + 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x08, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x48, 0x01, 0x52, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x49, 0x6e, 0x52, 0x75, + 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x61, - 0x74, 0x22, 0x84, 0x02, 0x0a, 0x07, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, - 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x40, 0x0a, 0x06, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6c, 0x65, + 0x22, 0xb0, 0x01, 0x0a, 0x06, 0x49, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x63, + 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x49, 0x6e, + 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 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, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xe1, 0x01, 0x0a, 0x0c, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x48, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x88, 0x01, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x48, 0x02, + 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x76, 0x61, 0x6c, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, + 0x0b, 0x0a, 0x09, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x42, 0x08, 0x0a, 0x06, + 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x61, 0x74, 0x22, 0x84, 0x02, 0x0a, 0x07, 0x4f, 0x75, 0x74, 0x52, + 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x65, + 0x78, 0x70, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, + 0x40, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x28, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x12, 0x36, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x64, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, + 0x48, 0x00, 0x52, 0x12, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x76, 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 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, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x76, + 0x61, 0x6c, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x73, 0x22, 0x25, + 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x56, 0x0a, 0x10, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x42, 0x0a, 0x0b, 0x72, 0x75, 0x6c, + 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, + 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x0a, 0x72, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x24, 0x0a, + 0x0e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x14, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x40, 0x0a, 0x0a, 0x72, + 0x75, 0x6c, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x52, 0x09, 0x72, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x70, 0x0a, + 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x53, 0x65, 0x74, 0x12, 0x38, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x49, 0x6e, 0x52, 0x75, 0x6c, 0x65, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x17, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x2a, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x80, 0x01, 0x0a, 0x12, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, + 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x38, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x49, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x17, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x4f, + 0x0a, 0x13, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x4c, 0x69, + 0x73, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x38, 0x0a, 0x04, 0x73, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, + 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x52, 0x04, 0x73, 0x65, 0x74, 0x73, 0x22, + 0x23, 0x0a, 0x11, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x24, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, + 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x70, 0x0a, 0x0f, 0x4f, 0x75, + 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, + 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x32, 0xbe, 0x02, 0x0a, + 0x0a, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x42, 0x0a, 0x04, 0x53, + 0x61, 0x76, 0x65, 0x12, 0x20, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x49, 0x6e, 0x52, 0x75, 0x6c, 0x65, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, + 0x48, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x24, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, - 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x36, 0x0a, 0x15, 0x6c, - 0x61, 0x73, 0x74, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x12, 0x6c, 0x61, - 0x73, 0x74, 0x45, 0x76, 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x73, - 0x88, 0x01, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 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, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x18, - 0x0a, 0x16, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x73, 0x22, 0x25, 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0x56, 0x0a, 0x10, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4c, 0x69, 0x73, 0x74, - 0x69, 0x6e, 0x67, 0x12, 0x42, 0x0a, 0x0b, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x4f, - 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0a, 0x72, 0x75, 0x6c, - 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x24, 0x0a, 0x0e, 0x46, 0x65, 0x74, 0x63, 0x68, - 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x58, 0x0a, - 0x14, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x40, 0x0a, 0x0a, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6c, 0x65, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x04, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x25, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, - 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x09, 0x72, 0x75, - 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x70, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x12, 0x38, 0x0a, - 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x73, 0x2e, 0x49, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, - 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, - 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2a, 0x0a, 0x18, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5e, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x06, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x75, + 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4c, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, + 0x22, 0x00, 0x12, 0x59, 0x0a, 0x05, 0x46, 0x65, 0x74, 0x63, 0x68, 0x12, 0x23, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x2e, 0x49, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x4f, 0x0a, 0x13, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x38, 0x0a, 0x04, - 0x73, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x75, 0x6c, - 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, - 0x52, 0x04, 0x73, 0x65, 0x74, 0x73, 0x22, 0x23, 0x0a, 0x11, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, - 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x24, 0x0a, 0x12, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x22, 0x7e, 0x0a, 0x0f, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, - 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, - 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x32, 0xbe, 0x02, 0x0a, 0x0a, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0x12, 0x42, 0x0a, 0x04, 0x53, 0x61, 0x76, 0x65, 0x12, 0x20, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x49, - 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x24, - 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x47, - 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x25, - 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4c, 0x69, - 0x73, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x05, 0x46, 0x65, 0x74, 0x63, 0x68, - 0x12, 0x23, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, + 0x73, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x1a, 0x29, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x1a, 0x29, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x32, 0xb2, 0x03, + 0x0a, 0x0d, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x73, 0x12, + 0x62, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x27, 0x2e, 0x72, 0x75, 0x6c, 0x65, + 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, + 0x65, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x27, 0x2e, + 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, + 0x12, 0x4a, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x28, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x53, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x05, + 0x46, 0x65, 0x74, 0x63, 0x68, 0x12, 0x26, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x46, 0x65, 0x74, 0x63, - 0x68, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x22, 0x00, 0x32, 0xb2, 0x03, 0x0a, 0x0d, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x53, 0x65, 0x74, 0x73, 0x12, 0x62, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x27, - 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, - 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x12, 0x27, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, - 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x28, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, - 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x52, 0x75, 0x6c, 0x65, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x22, - 0x00, 0x12, 0x57, 0x0a, 0x05, 0x46, 0x65, 0x74, 0x63, 0x68, 0x12, 0x26, 0x2e, 0x72, 0x75, 0x6c, - 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, - 0x65, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x06, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x12, 0x27, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x04, 0x5a, 0x02, 0x2e, 0x2f, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x68, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x1a, 0x24, 0x2e, + 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x2e, 0x4f, 0x75, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x53, 0x65, 0x74, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, + 0x27, 0x2e, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2e, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x00, 0x42, 0x03, 0x5a, 0x01, 0x2e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_groups_proto_rawDescOnce sync.Once - file_groups_proto_rawDescData = file_groups_proto_rawDesc + file_proto_groups_proto_rawDescOnce sync.Once + file_proto_groups_proto_rawDescData = file_proto_groups_proto_rawDesc ) -func file_groups_proto_rawDescGZIP() []byte { - file_groups_proto_rawDescOnce.Do(func() { - file_groups_proto_rawDescData = protoimpl.X.CompressGZIP(file_groups_proto_rawDescData) +func file_proto_groups_proto_rawDescGZIP() []byte { + file_proto_groups_proto_rawDescOnce.Do(func() { + file_proto_groups_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_groups_proto_rawDescData) }) - return file_groups_proto_rawDescData + return file_proto_groups_proto_rawDescData } -var file_groups_proto_msgTypes = make([]protoimpl.MessageInfo, 17) -var file_groups_proto_goTypes = []interface{}{ +var file_proto_groups_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_proto_groups_proto_goTypes = []interface{}{ (*InRuleGroup)(nil), // 0: rule_manager.groups.InRuleGroup (*InRule)(nil), // 1: rule_manager.groups.InRule (*OutRuleGroup)(nil), // 2: rule_manager.groups.OutRuleGroup @@ -1068,7 +1077,7 @@ var file_groups_proto_goTypes = []interface{}{ nil, // 16: rule_manager.groups.OutRule.LabelsEntry (*emptypb.Empty)(nil), // 17: google.protobuf.Empty } -var file_groups_proto_depIdxs = []int32{ +var file_proto_groups_proto_depIdxs = []int32{ 1, // 0: rule_manager.groups.InRuleGroup.rules:type_name -> rule_manager.groups.InRule 15, // 1: rule_manager.groups.InRule.labels:type_name -> rule_manager.groups.InRule.LabelsEntry 3, // 2: rule_manager.groups.OutRuleGroup.rules:type_name -> rule_manager.groups.OutRule @@ -1104,13 +1113,13 @@ var file_groups_proto_depIdxs = []int32{ 0, // [0:10] is the sub-list for field type_name } -func init() { file_groups_proto_init() } -func file_groups_proto_init() { - if File_groups_proto != nil { +func init() { file_proto_groups_proto_init() } +func file_proto_groups_proto_init() { + if File_proto_groups_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_groups_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InRuleGroup); i { case 0: return &v.state @@ -1122,7 +1131,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*InRule); i { case 0: return &v.state @@ -1134,7 +1143,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OutRuleGroup); i { case 0: return &v.state @@ -1146,7 +1155,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OutRule); i { case 0: return &v.state @@ -1158,7 +1167,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeleteRuleGroup); i { case 0: return &v.state @@ -1170,7 +1179,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RuleGroupListing); i { case 0: return &v.state @@ -1182,7 +1191,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FetchRuleGroup); i { case 0: return &v.state @@ -1194,7 +1203,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FetchRuleGroupResult); i { case 0: return &v.state @@ -1206,7 +1215,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRuleGroupSet); i { case 0: return &v.state @@ -1218,7 +1227,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateRuleGroupSetResult); i { case 0: return &v.state @@ -1230,7 +1239,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UpdateRuleGroupSet); i { case 0: return &v.state @@ -1242,7 +1251,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RuleGroupSetListing); i { case 0: return &v.state @@ -1254,7 +1263,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*FetchRuleGroupSet); i { case 0: return &v.state @@ -1266,7 +1275,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeleteRuleGroupSet); i { case 0: return &v.state @@ -1278,7 +1287,7 @@ func file_groups_proto_init() { return nil } } - file_groups_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_proto_groups_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OutRuleGroupSet); i { case 0: return &v.state @@ -1291,27 +1300,27 @@ func file_groups_proto_init() { } } } - file_groups_proto_msgTypes[0].OneofWrappers = []interface{}{} - file_groups_proto_msgTypes[2].OneofWrappers = []interface{}{} - file_groups_proto_msgTypes[3].OneofWrappers = []interface{}{} - file_groups_proto_msgTypes[8].OneofWrappers = []interface{}{} - file_groups_proto_msgTypes[14].OneofWrappers = []interface{}{} + file_proto_groups_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_proto_groups_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_proto_groups_proto_msgTypes[3].OneofWrappers = []interface{}{} + file_proto_groups_proto_msgTypes[8].OneofWrappers = []interface{}{} + file_proto_groups_proto_msgTypes[10].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_groups_proto_rawDesc, + RawDescriptor: file_proto_groups_proto_rawDesc, NumEnums: 0, NumMessages: 17, NumExtensions: 0, NumServices: 2, }, - GoTypes: file_groups_proto_goTypes, - DependencyIndexes: file_groups_proto_depIdxs, - MessageInfos: file_groups_proto_msgTypes, + GoTypes: file_proto_groups_proto_goTypes, + DependencyIndexes: file_proto_groups_proto_depIdxs, + MessageInfos: file_proto_groups_proto_msgTypes, }.Build() - File_groups_proto = out.File - file_groups_proto_rawDesc = nil - file_groups_proto_goTypes = nil - file_groups_proto_depIdxs = nil + File_proto_groups_proto = out.File + file_proto_groups_proto_rawDesc = nil + file_proto_groups_proto_goTypes = nil + file_proto_groups_proto_depIdxs = nil } diff --git a/coralogix/clientset/grpc/recording-rules-groups-sets/v1/groups_grpc.pb.go b/coralogix/clientset/grpc/recording-rules-groups-sets/v1/groups_grpc.pb.go index a90d498d..f8411c4e 100644 --- a/coralogix/clientset/grpc/recording-rules-groups-sets/v1/groups_grpc.pb.go +++ b/coralogix/clientset/grpc/recording-rules-groups-sets/v1/groups_grpc.pb.go @@ -2,7 +2,7 @@ // versions: // - protoc-gen-go-grpc v1.2.0 // - protoc v3.21.8 -// source: groups.proto +// source: proto/groups.proto package __ @@ -218,7 +218,7 @@ var RuleGroups_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "groups.proto", + Metadata: "proto/groups.proto", } // RuleGroupSetsClient is the client API for RuleGroupSets service. @@ -448,5 +448,5 @@ var RuleGroupSets_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "groups.proto", + Metadata: "proto/groups.proto", } diff --git a/coralogix/data_source_coralogix_recording_rules_group.go b/coralogix/data_source_coralogix_recording_rules_group.go index 90d850d2..632d46bd 100644 --- a/coralogix/data_source_coralogix_recording_rules_group.go +++ b/coralogix/data_source_coralogix_recording_rules_group.go @@ -2,43 +2,91 @@ package coralogix import ( "context" + "fmt" "log" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "terraform-provider-coralogix/coralogix/clientset" - recordingrules "terraform-provider-coralogix/coralogix/clientset/grpc/recording-rules-groups-sets/v1" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + rrgs "terraform-provider-coralogix/coralogix/clientset/grpc/recording-rules-groups-sets/v1" ) -func dataSourceCoralogixRecordingRulesGroupsSet() *schema.Resource { - recordingRulesGroupsSetSchema := datasourceSchemaFromResourceSchema(RecordingRulesGroupsSetSchema()) - recordingRulesGroupsSetSchema["id"] = &schema.Schema{ - Type: schema.TypeString, - Required: true, - } +var _ datasource.DataSourceWithConfigure = &RecordingRuleGroupSetDataSource{} + +func NewRecordingRuleGroupSetDataSource() datasource.DataSource { + return &RecordingRuleGroupSetDataSource{} +} + +type RecordingRuleGroupSetDataSource struct { + client *clientset.RecordingRulesGroupsSetsClient +} + +func (d *RecordingRuleGroupSetDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_recording_rules_groups_set" +} - return &schema.Resource{ - ReadContext: dataSourceCoralogixRecordingRulesGroupsSetRead, +func (d *RecordingRuleGroupSetDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } - Schema: recordingRulesGroupsSetSchema, + clientSet, ok := req.ProviderData.(*clientset.ClientSet) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *clientset.ClientSet, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return } + + d.client = clientSet.RecordingRuleGroupsSets() +} + +func (d *RecordingRuleGroupSetDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + var r RecordingRuleGroupSetResource + var resourceResp resource.SchemaResponse + r.Schema(nil, resource.SchemaRequest{}, &resourceResp) + + resp.Schema = frameworkDatasourceSchemaFromFrameworkResourceSchema(resourceResp.Schema) } -func dataSourceCoralogixRecordingRulesGroupsSetRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - id := d.Get("id").(string) - req := &recordingrules.FetchRuleGroupSet{ - Id: id, +func (d *RecordingRuleGroupSetDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data *RecordingRuleGroupSetResourceModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return } - log.Printf("[INFO] Reading recording-rule-group-set %s", id) - resp, err := meta.(*clientset.ClientSet).RecordingRuleGroupsSets().GetRecordingRuleGroupsSet(ctx, req) + + //Get refreshed recording-rule-group-set value from Coralogix + id := data.ID.ValueString() + log.Printf("[INFO] Reading recording-rule-group-set: %s", id) + getResp, err := d.client.GetRecordingRuleGroupsSet(ctx, &rrgs.FetchRuleGroupSet{Id: id}) if err != nil { log.Printf("[ERROR] Received error: %#v", err) - return handleRpcErrorWithID(err, "recording-rule-group-set", req.Id) + if status.Code(err) == codes.NotFound { + data.ID = types.StringNull() + resp.Diagnostics.AddWarning( + fmt.Sprintf("recording-rule-group-set %q is in state, but no longer exists in Coralogix backend", id), + fmt.Sprintf("%s will be recreated when you apply", id), + ) + } else { + resp.Diagnostics.AddError( + "Error reading recording-rule-group-set", + handleRpcErrorNewFramework(err, "recording-rule-group-set"), + ) + } + return } + log.Printf("[INFO] Received recording-rule-group-set: %#v", getResp) - log.Printf("[INFO] Received recording-rule-group-set: %#v", resp) - - d.SetId(resp.Id) - return setRecordingRulesGroupsSet(d, resp) + data, diags := flattenRecordingRuleGroupSet(ctx, &RecordingRuleGroupSetResourceModel{}, getResp) + if diags.HasError() { + resp.Diagnostics = diags + return + } + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) } diff --git a/coralogix/data_source_coralogix_recording_rules_group_test.go b/coralogix/data_source_coralogix_recording_rules_group_test.go index 8ec062ec..c7ca875c 100644 --- a/coralogix/data_source_coralogix_recording_rules_group_test.go +++ b/coralogix/data_source_coralogix_recording_rules_group_test.go @@ -19,8 +19,8 @@ func TestAccCoralogixDataSourceRecordingRulesGroupsSet_basic(t *testing.T) { filePath := parent + "/examples/recording_rules_groups_set/rule-group-set.yaml" resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviderFactories, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, Steps: []resource.TestStep{ { Config: testAccCoralogixResourceRecordingRulesGroupsSetFromYaml(filePath) + diff --git a/coralogix/provider.go b/coralogix/provider.go index bddc3204..f6fd4b08 100644 --- a/coralogix/provider.go +++ b/coralogix/provider.go @@ -61,23 +61,21 @@ func OldProvider() *oldSchema.Provider { }, DataSourcesMap: map[string]*oldSchema.Resource{ - "coralogix_rules_group": dataSourceCoralogixRulesGroup(), - "coralogix_alert": dataSourceCoralogixAlert(), - "coralogix_enrichment": dataSourceCoralogixEnrichment(), - "coralogix_data_set": dataSourceCoralogixDataSet(), - "coralogix_hosted_dashboard": dataSourceCoralogixHostedDashboard(), - "coralogix_recording_rules_groups_set": dataSourceCoralogixRecordingRulesGroupsSet(), - "coralogix_tco_policy_override": dataSourceCoralogixTCOPolicyOverride(), + "coralogix_rules_group": dataSourceCoralogixRulesGroup(), + "coralogix_alert": dataSourceCoralogixAlert(), + "coralogix_enrichment": dataSourceCoralogixEnrichment(), + "coralogix_data_set": dataSourceCoralogixDataSet(), + "coralogix_hosted_dashboard": dataSourceCoralogixHostedDashboard(), + "coralogix_tco_policy_override": dataSourceCoralogixTCOPolicyOverride(), }, ResourcesMap: map[string]*oldSchema.Resource{ - "coralogix_rules_group": resourceCoralogixRulesGroup(), - "coralogix_alert": resourceCoralogixAlert(), - "coralogix_enrichment": resourceCoralogixEnrichment(), - "coralogix_data_set": resourceCoralogixDataSet(), - "coralogix_hosted_dashboard": resourceCoralogixHostedDashboard(), - "coralogix_recording_rules_groups_set": resourceCoralogixRecordingRulesGroupsSet(), - "coralogix_grafana_folder": resourceGrafanaFolder(), + "coralogix_rules_group": resourceCoralogixRulesGroup(), + "coralogix_alert": resourceCoralogixAlert(), + "coralogix_enrichment": resourceCoralogixEnrichment(), + "coralogix_data_set": resourceCoralogixDataSet(), + "coralogix_hosted_dashboard": resourceCoralogixHostedDashboard(), + "coralogix_grafana_folder": resourceGrafanaFolder(), }, ConfigureContextFunc: func(context context.Context, d *oldSchema.ResourceData) (interface{}, diag.Diagnostics) { @@ -281,6 +279,7 @@ func (p *coralogixProvider) DataSources(context.Context) []func() datasource.Dat NewDashboardDataSource, NewSLIDataSource, NewWebhookDataSource, + NewRecordingRuleGroupSetDataSource, } } @@ -293,5 +292,6 @@ func (p *coralogixProvider) Resources(context.Context) []func() resource.Resourc NewDashboardResource, NewSLIResource, NewWebhookResource, + NewRecordingRuleGroupSetResource, } } diff --git a/coralogix/resource_coralogix_recording_rules_groups_set.go b/coralogix/resource_coralogix_recording_rules_groups_set.go index bb4409cd..c8a943c8 100644 --- a/coralogix/resource_coralogix_recording_rules_groups_set.go +++ b/coralogix/resource_coralogix_recording_rules_groups_set.go @@ -4,378 +4,827 @@ import ( "context" "fmt" "log" - "time" + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "gopkg.in/yaml.v3" "terraform-provider-coralogix/coralogix/clientset" rrgs "terraform-provider-coralogix/coralogix/clientset/grpc/recording-rules-groups-sets/v1" +) - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - "gopkg.in/yaml.v3" +var ( + _ resource.ResourceWithConfigure = &RecordingRuleGroupSetResource{} + _ resource.ResourceWithImportState = &RecordingRuleGroupSetResource{} + _ resource.ResourceWithUpgradeState = &RecordingRuleGroupSetResource{} ) -func resourceCoralogixRecordingRulesGroupsSet() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceCoralogixRecordingRulesGroupsSetCreate, - ReadContext: resourceCoralogixRecordingRulesGroupsSetRead, - UpdateContext: resourceCoralogixRecordingRulesGroupsSetUpdate, - DeleteContext: resourceCoralogixRecordingRulesGroupsSetDelete, +func NewRecordingRuleGroupSetResource() resource.Resource { + return &RecordingRuleGroupSetResource{} +} + +type RecordingRuleGroupSetResource struct { + client *clientset.RecordingRulesGroupsSetsClient +} - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, +func (r *RecordingRuleGroupSetResource) UpgradeState(_ context.Context) map[int64]resource.StateUpgrader { + schemaV0 := recordingRuleGroupSetV0() + return map[int64]resource.StateUpgrader{ + 0: { + PriorSchema: &schemaV0, + StateUpgrader: upgradeRecordingRuleGroupSetStateV0ToV1, }, + } +} - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(60 * time.Second), - Read: schema.DefaultTimeout(30 * time.Second), - Update: schema.DefaultTimeout(60 * time.Second), - Delete: schema.DefaultTimeout(30 * time.Second), +func recordingRuleGroupSetV0() schema.Schema { + return schema.Schema{ + Version: 0, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "yaml_content": schema.StringAttribute{ + Optional: true, + }, + "group": schema.SetNestedAttribute{ + Optional: true, + Computed: true, + NestedObject: recordingRuleGroupSchemaV0(), + }, + "name": schema.StringAttribute{ + Optional: true, + Computed: true, + }, }, + } +} - Schema: RecordingRulesGroupsSetSchema(), +func recordingRuleGroupSchemaV0() schema.NestedAttributeObject { + return schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Required: true, + }, + "interval": schema.Int64Attribute{ + Required: true, + }, + "limit": schema.Int64Attribute{ + Optional: true, + }, + "rule": schema.SetNestedAttribute{ + Required: true, + NestedObject: recordingRulesSchemaV0(), + }, + }, + } +} - Description: "Coralogix recording-rules-groups-set. For more information - https://coralogix.com/docs/recording-rules/.", +func recordingRulesSchemaV0() schema.NestedAttributeObject { + return schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "record": schema.StringAttribute{ + Required: true, + }, + "expr": schema.StringAttribute{ + Required: true, + }, + "labels": schema.MapAttribute{ + ElementType: types.StringType, + Optional: true, + }, + }, } } -func resourceCoralogixRecordingRulesGroupsSetCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - req, err := expandRecordingRulesGroupsSet(d) - if err != nil { - return diag.FromErr(err) +func upgradeRecordingRuleGroupSetStateV0ToV1(ctx context.Context, req resource.UpgradeStateRequest, resp *resource.UpgradeStateResponse) { + type RecordingRuleGroupSetResourceModelV0 struct { + ID types.String `tfsdk:"id"` + YamlContent types.String `tfsdk:"yaml_content"` + Group types.Set `tfsdk:"group"` //RecordingRuleGroupModelV0 + Name types.String `tfsdk:"name"` } - log.Printf("[INFO] Creating new recording-rule-group-set: %#v", req) - resp, err := meta.(*clientset.ClientSet).RecordingRuleGroupsSets().CreateRecordingRuleGroupsSet(ctx, req) - if err != nil { - log.Printf("[ERROR] Received error: %#v", err) - return handleRpcError(err, "recording-rule-group-set") + var priorStateData RecordingRuleGroupSetResourceModelV0 + resp.Diagnostics.Append(req.State.Get(ctx, &priorStateData)...) + if resp.Diagnostics.HasError() { + return + } + + groups, diags := upgradeRecordingRulesGroupsV0(ctx, priorStateData.Group) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + + upgradedStateData := RecordingRuleGroupSetResourceModel{ + ID: priorStateData.ID, + YamlContent: priorStateData.YamlContent, + Name: priorStateData.Name, + Groups: groups, } - log.Printf("[INFO] Submitted new recording-rule-group-set: %#v", resp) - d.SetId(resp.Id) - return resourceCoralogixRecordingRulesGroupsSetRead(ctx, d, meta) + resp.Diagnostics.Append(resp.State.Set(ctx, upgradedStateData)...) } -func expandRecordingRulesGroupsSet(d *schema.ResourceData) (*rrgs.CreateRuleGroupSet, error) { - if yamlContent, ok := d.GetOk("yaml_content"); ok { - return expandRecordingRulesGroupsSetFromYaml(yamlContent.(string)) +func upgradeRecordingRulesGroupsV0(ctx context.Context, groups types.Set) (types.Set, diag.Diagnostics) { + type RecordingRuleGroupModelV0 struct { + Name types.String `tfsdk:"name"` + Interval types.Int64 `tfsdk:"interval"` + Limit types.Int64 `tfsdk:"limit"` + Rule types.Set `tfsdk:"rule"` //RecordingRuleModel } - return expandRecordingRulesGroupSetExplicitly(d), nil + var diags diag.Diagnostics + var priorGroupsObjects []types.Object + var upgradedGroups []RecordingRuleGroupModel + groups.ElementsAs(ctx, &priorGroupsObjects, true) + + for _, groupObject := range priorGroupsObjects { + var priorGroup RecordingRuleGroupModelV0 + if dg := groupObject.As(ctx, &priorGroup, basetypes.ObjectAsOptions{}); dg.HasError() { + diags.Append(dg...) + continue + } + + rules, dg := upgradeRecordingRulesV0(ctx, priorGroup.Rule) + if dg.HasError() { + diags.Append(dg...) + continue + } + + upgradedGroup := RecordingRuleGroupModel{ + Name: priorGroup.Name, + Interval: priorGroup.Interval, + Limit: priorGroup.Limit, + Rules: rules, + } + + upgradedGroups = append(upgradedGroups, upgradedGroup) + } + + if diags.HasError() { + return types.SetNull(types.ObjectType{AttrTypes: recordingRuleGroupAttributes()}), diags + } + + return types.SetValueFrom(ctx, types.ObjectType{AttrTypes: recordingRuleGroupAttributes()}, upgradedGroups) } -func expandRecordingRulesGroupsSetFromYaml(yamlContent string) (*rrgs.CreateRuleGroupSet, error) { - var result rrgs.CreateRuleGroupSet - if err := yaml.Unmarshal([]byte(yamlContent), &result); err != nil { - return nil, err +func upgradeRecordingRulesV0(ctx context.Context, rule types.Set) (types.List, diag.Diagnostics) { + var diags diag.Diagnostics + var priorRulesObjects []types.Object + var upgradedRules []RecordingRuleModel + rule.ElementsAs(ctx, &priorRulesObjects, true) + + for _, ruleObject := range priorRulesObjects { + var priorRule RecordingRuleModel + if dg := ruleObject.As(ctx, &priorRule, basetypes.ObjectAsOptions{}); dg.HasError() { + diags.Append(dg...) + continue + } + + upgradedRule := RecordingRuleModel{ + Record: priorRule.Record, + Expr: priorRule.Expr, + Labels: priorRule.Labels, + } + + upgradedRules = append(upgradedRules, upgradedRule) } - return &result, nil + + if diags.HasError() { + return types.ListNull(types.ObjectType{AttrTypes: recordingRuleAttributes()}), diags + } + + return types.ListValueFrom(ctx, types.ObjectType{AttrTypes: recordingRuleAttributes()}, upgradedRules) } -func expandRecordingRulesGroupSetExplicitly(d *schema.ResourceData) *rrgs.CreateRuleGroupSet { - var name *string - if str, ok := d.GetOk("name"); ok && str.(string) != "" { - name = new(string) - *name = str.(string) +func (r *RecordingRuleGroupSetResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} + +func (r *RecordingRuleGroupSetResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return } - groups := expandRecordingRulesGroups(d.Get("group")) - return &rrgs.CreateRuleGroupSet{ - Name: name, - Groups: groups, + clientSet, ok := req.ProviderData.(*clientset.ClientSet) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *clientset.ClientSet, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return } + + r.client = clientSet.RecordingRuleGroupsSets() } -func expandRecordingRulesGroups(v interface{}) []*rrgs.InRuleGroup { - groups := v.(*schema.Set).List() - results := make([]*rrgs.InRuleGroup, 0, len(groups)) +func (r *RecordingRuleGroupSetResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_recording_rules_groups_set" +} - for _, g := range groups { - group := expandRecordingRuleGroup(g) - results = append(results, group) +func (r *RecordingRuleGroupSetResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + Version: 1, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "yaml_content": schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.ConflictsWith( + path.MatchRelative().AtParent().AtName("groups"), + path.MatchRelative().AtParent().AtName("name"), + ), + recordingRulesGroupYamlContentValidator{}, + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplaceIf(JSONStringsEqualPlanModifier, "", ""), + }, + }, + "groups": schema.SetNestedAttribute{ + Optional: true, + Computed: true, + NestedObject: recordingRuleGroupSchema(), + Validators: []validator.Set{ + setvalidator.ExactlyOneOf( + path.MatchRelative().AtParent().AtName("yaml_content"), + ), + }, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.UseStateForUnknown(), + }, + }, + "name": schema.StringAttribute{ + Optional: true, + Computed: true, + Validators: []validator.String{ + stringvalidator.ExactlyOneOf( + path.MatchRelative().AtParent().AtName("yaml_content")), + }, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + }, } +} - return results +func recordingRuleGroupSchema() schema.NestedAttributeObject { + return schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Required: true, + Description: "The rule-group name. Have to be unique.", + Validators: []validator.String{ + stringvalidator.LengthAtLeast(1), + }, + }, + "interval": schema.Int64Attribute{ + Required: true, + Description: "How often rules in the group are evaluated (in seconds).", + Validators: []validator.Int64{ + int64validator.AtLeast(0), + }, + }, + "limit": schema.Int64Attribute{ + Optional: true, + Computed: true, + Default: int64default.StaticInt64(0), + Description: "Limit the number of alerts an alerting rule and series a recording-rule can produce. 0 is no limit.", + }, + "rules": schema.ListNestedAttribute{ + Required: true, + NestedObject: recordingRulesSchema(), + }, + }, + } } -func expandRecordingRuleGroup(v interface{}) *rrgs.InRuleGroup { - m := v.(map[string]interface{}) +func recordingRulesSchema() schema.NestedAttributeObject { + return schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "record": schema.StringAttribute{ + Required: true, + Description: "The name of the time series to output to. Must be a valid metric name.", + }, + "expr": schema.StringAttribute{ + Required: true, + Description: "The PromQL expression to evaluate. " + + "Every evaluation cycle this is evaluated at the current time," + + " and the result recorded as a new set of time series with the metric name as given by 'record'.", + }, + "labels": schema.MapAttribute{ + ElementType: types.StringType, + Optional: true, + Description: "Labels to add or overwrite before storing the result.", + }, + }, + } +} - name := m["name"].(string) - interval := uint32(m["interval"].(int)) - limit := uint64(m["limit"].(int)) - rules := expandRecordingRules(m["rule"]) +func (r *RecordingRuleGroupSetResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan *RecordingRuleGroupSetResourceModel + diags := req.Plan.Get(ctx, &plan) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } - return &rrgs.InRuleGroup{ - Name: name, - Interval: &interval, - Limit: &limit, - Rules: rules, + createRequest, diags := expandRecordingRulesGroupsSet(ctx, plan) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + rrgStr, _ := jsm.MarshalToString(createRequest) + log.Printf("[INFO] Creating new recogring-rule-group-set: %s", rrgStr) + + createResp, err := r.client.CreateRecordingRuleGroupsSet(ctx, createRequest) + if err != nil { + log.Printf("[ERROR] Received error: %#v", err) + resp.Diagnostics.AddError( + "Error creating recording-rule-group-set", + "Could not create recording-rule-group-set, unexpected error: "+err.Error(), + ) + return + } + id := createResp.GetId() + log.Printf("[INFO] Submitted new recording-rule-group-set id: %#v", id) + plan.ID = types.StringValue(id) + + log.Printf("[INFO] Reading recording-rule-group-set id: %#v", id) + getResp, err := r.client.GetRecordingRuleGroupsSet(ctx, &rrgs.FetchRuleGroupSet{Id: id}) + if err != nil { + log.Printf("[ERROR] Received error: %#v", err) + if status.Code(err) == codes.NotFound { + resp.Diagnostics.AddWarning( + fmt.Sprintf("recording-rule-group-set %q is in state, but no longer exists in Coralogix backend", id), + fmt.Sprintf("%s will be recreated when you apply", id), + ) + } else { + resp.Diagnostics.AddError( + "Error reading recording-rule-group-set", + handleRpcErrorNewFramework(err, "recording-rule-group-set"), + ) + } + return } + + rrgStr, _ = jsm.MarshalToString(getResp) + log.Printf("[INFO] Received recogring-rule-group-set: %s", rrgStr) + + plan, diags = flattenRecordingRuleGroupSet(ctx, plan, getResp) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + // Set state to fully populated data + diags = resp.State.Set(ctx, plan) + resp.Diagnostics.Append(diags...) } -func expandRecordingRules(v interface{}) []*rrgs.InRule { - l := v.([]interface{}) - result := make([]*rrgs.InRule, 0, len(l)) - for _, recordingRule := range l { - r := expandRecordingRule(recordingRule) - result = append(result, r) +func flattenRecordingRuleGroupSet(ctx context.Context, plan *RecordingRuleGroupSetResourceModel, resp *rrgs.OutRuleGroupSet) (*RecordingRuleGroupSetResourceModel, diag.Diagnostics) { + if yamlContent := plan.YamlContent.ValueString(); yamlContent != "" { + groups, diags := flattenRecordingRuleGroups(ctx, resp.GetGroups()) + if diags.HasError() { + return nil, diags + } + + return &RecordingRuleGroupSetResourceModel{ + ID: types.StringValue(resp.GetId()), + YamlContent: types.StringValue(plan.YamlContent.ValueString()), + Name: types.StringValue(plan.Name.ValueString()), + Groups: groups, + }, nil + } + + groups, diags := flattenRecordingRuleGroups(ctx, resp.GetGroups()) + if diags.HasError() { + return nil, diags } - return result + + return &RecordingRuleGroupSetResourceModel{ + ID: types.StringValue(resp.GetId()), + Name: types.StringValue(resp.GetName()), + Groups: groups, + YamlContent: types.StringNull(), + }, nil } -func expandRecordingRule(v interface{}) *rrgs.InRule { - m := v.(map[string]interface{}) +func flattenRecordingRuleGroups(ctx context.Context, groups []*rrgs.OutRuleGroup) (types.Set, diag.Diagnostics) { + var diags diag.Diagnostics + var groupsObjects []types.Object + for _, group := range groups { + flattenedGroup, flattenDiags := flattenRecordingRuleGroup(ctx, group) + if flattenDiags.HasError() { + diags.Append(flattenDiags...) + continue + } + groupObject, flattenDiags := types.ObjectValueFrom(ctx, recordingRuleGroupAttributes(), flattenedGroup) + if flattenDiags.HasError() { + diags.Append(flattenDiags...) + continue + } + groupsObjects = append(groupsObjects, groupObject) + } + if diags.HasError() { + return types.SetNull(types.ObjectType{AttrTypes: recordingRuleGroupAttributes()}), diags + } - record := m["record"].(string) - expr := m["expr"].(string) - labels := expandRecordingRuleLabels(m["labels"].(map[string]interface{})) + return types.SetValueFrom(ctx, types.ObjectType{AttrTypes: recordingRuleGroupAttributes()}, groupsObjects) +} - return &rrgs.InRule{ - Record: record, - Expr: expr, - Labels: labels, +func recordingRuleGroupAttributes() map[string]attr.Type { + return map[string]attr.Type{ + "name": types.StringType, + "interval": types.Int64Type, + "limit": types.Int64Type, + "rules": types.ListType{ + ElemType: types.ObjectType{ + AttrTypes: recordingRuleAttributes(), + }, + }, } } -func expandRecordingRuleLabels(m map[string]interface{}) map[string]string { - form := make(map[string]string) - for k, v := range m { - form[k] = v.(string) +func recordingRuleAttributes() map[string]attr.Type { + return map[string]attr.Type{ + "record": types.StringType, + "expr": types.StringType, + "labels": types.MapType{ + ElemType: types.StringType, + }, } - return form } -func resourceCoralogixRecordingRulesGroupsSetRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - id := d.Id() - log.Printf("[INFO] Reading recording-rule-group-set %s", id) - req := &rrgs.FetchRuleGroupSet{ - Id: id, +func flattenRecordingRuleGroup(ctx context.Context, group *rrgs.OutRuleGroup) (*RecordingRuleGroupModel, diag.Diagnostics) { + rules, diags := flattenRecordingRules(ctx, group.GetRules()) + if diags.HasError() { + return nil, diags } - resp, err := meta.(*clientset.ClientSet).RecordingRuleGroupsSets().GetRecordingRuleGroupsSet(ctx, req) + + return &RecordingRuleGroupModel{ + Name: types.StringValue(group.GetName()), + Interval: types.Int64Value(int64(group.GetInterval())), + Limit: types.Int64Value(int64(group.GetLimit())), + Rules: rules, + }, nil +} + +func flattenRecordingRules(ctx context.Context, rules []*rrgs.OutRule) (types.List, diag.Diagnostics) { + var diags diag.Diagnostics + var rulesObjects []types.Object + for _, rule := range rules { + flattenedRule, expandDiags := flattenRecordingRule(ctx, rule) + if expandDiags.HasError() { + diags.Append(expandDiags...) + continue + } + ruleObject, expandDiags := types.ObjectValueFrom(ctx, recordingRuleAttributes(), flattenedRule) + if expandDiags.HasError() { + diags.Append(expandDiags...) + continue + } + rulesObjects = append(rulesObjects, ruleObject) + } + if diags.HasError() { + return types.ListNull(types.ObjectType{AttrTypes: recordingRuleAttributes()}), diags + } + + return types.ListValueFrom(ctx, types.ObjectType{AttrTypes: recordingRuleAttributes()}, rulesObjects) +} + +func flattenRecordingRule(ctx context.Context, rule *rrgs.OutRule) (*RecordingRuleModel, diag.Diagnostics) { + labels, diags := types.MapValueFrom(ctx, types.StringType, rule.GetLabels()) + if diags.HasError() { + return nil, diags + } + + return &RecordingRuleModel{ + Record: types.StringValue(rule.GetRecord()), + Expr: types.StringValue(rule.GetExpr()), + Labels: labels, + }, nil +} + +func (r *RecordingRuleGroupSetResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state *RecordingRuleGroupSetResourceModel + diags := req.State.Get(ctx, &state) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + + id := state.ID.ValueString() + log.Printf("[INFO] Reading recording-rule-group-set id: %s", id) + getResp, err := r.client.GetRecordingRuleGroupsSet(ctx, &rrgs.FetchRuleGroupSet{Id: id}) if err != nil { log.Printf("[ERROR] Received error: %#v", err) if status.Code(err) == codes.NotFound { - d.SetId("") - return diag.Diagnostics{diag.Diagnostic{ - Severity: diag.Warning, - Summary: fmt.Sprintf("RecordingRuleGroup %q is in state, but no longer exists in Coralogix backend", id), - Detail: fmt.Sprintf("%s will be recreated when you apply", id), - }} + resp.Diagnostics.AddWarning( + fmt.Sprintf("recording-rule-group-set %q is in state, but no longer exists in Coralogix backend", id), + fmt.Sprintf("%s will be recreated when you apply", id), + ) + } else { + resp.Diagnostics.AddError( + "Error reading recording-rule-group-set", + handleRpcErrorNewFramework(err, "recording-rule-group-set"), + ) } - return handleRpcErrorWithID(err, "recording-rule-group-set", req.Id) + return } - log.Printf("[INFO] Received recording-rule-group-set: %#v", resp) - setRecordingRulesGroupsSet(d, resp) - return nil + state, diags = flattenRecordingRuleGroupSet(ctx, state, getResp) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + // Set state to fully populated data + diags = resp.State.Set(ctx, state) + resp.Diagnostics.Append(diags...) } -func resourceCoralogixRecordingRulesGroupsSetUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - createReq, err := expandRecordingRulesGroupsSet(d) - if err != nil { - return diag.FromErr(err) +func (r *RecordingRuleGroupSetResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan *RecordingRuleGroupSetResourceModel + diags := req.Plan.Get(ctx, &plan) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return } - updateReq := &rrgs.UpdateRuleGroupSet{ - Id: d.Id(), - Groups: createReq.Groups, + + updateRequest, diags := expandUpdateRecordingRulesGroupsSet(ctx, plan) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return } + rrgStr, _ := jsm.MarshalToString(updateRequest) + log.Printf("[INFO] Updating recording-rule-group-set: %s", rrgStr) - log.Printf("[INFO] Updating recording-rule-group-set: %#v", updateReq) - resp, err := meta.(*clientset.ClientSet).RecordingRuleGroupsSets().UpdateRecordingRuleGroupsSet(ctx, updateReq) + _, err := r.client.UpdateRecordingRuleGroupsSet(ctx, updateRequest) if err != nil { log.Printf("[ERROR] Received error: %#v", err) - return handleRpcErrorWithID(err, "recording-rule-group-set", updateReq.Id) + resp.Diagnostics.AddError( + "Error updating recording-rule-group-set", + handleRpcErrorNewFramework(err, "recording-rule-group-set"), + ) + return } - log.Printf("[INFO] Submitted updated recording-rule-group-set: %#v", resp) - return resourceCoralogixRecordingRulesGroupsSetRead(ctx, d, meta) + log.Printf("[INFO] Reading recording-rule-group-set id: %#v", plan.ID.ValueString()) + getResp, err := r.client.GetRecordingRuleGroupsSet(ctx, &rrgs.FetchRuleGroupSet{Id: plan.ID.ValueString()}) + if err != nil { + log.Printf("[ERROR] Received error: %#v", err) + if status.Code(err) == codes.NotFound { + resp.Diagnostics.AddWarning( + fmt.Sprintf("recording-rule-group-set %q is in state, but no longer exists in Coralogix backend", plan.ID.ValueString()), + fmt.Sprintf("%s will be recreated when you apply", plan.ID.ValueString()), + ) + } else { + resp.Diagnostics.AddError( + "Error reading recording-rule-group-set", + handleRpcErrorNewFramework(err, "recording-rule-group-set"), + ) + } + return + } + + plan, diags = flattenRecordingRuleGroupSet(ctx, plan, getResp) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + // Set state to fully populated data + diags = resp.State.Set(ctx, plan) + resp.Diagnostics.Append(diags...) } -func resourceCoralogixRecordingRulesGroupsSetDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - id := d.Id() - req := &rrgs.DeleteRuleGroupSet{Id: id} - log.Printf("[INFO] Deleting recording-rule-group-set %s", id) - _, err := meta.(*clientset.ClientSet).RecordingRuleGroupsSets().DeleteRecordingRuleGroupsSet(ctx, req) +func (r *RecordingRuleGroupSetResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state *RecordingRuleGroupSetResourceModel + diags := req.State.Get(ctx, &state) + if diags.HasError() { + resp.Diagnostics.Append(diags...) + return + } + id := state.ID.ValueString() + log.Printf("[INFO] Deleting recording-rule-group-set id: %s", id) + _, err := r.client.DeleteRecordingRuleGroupsSet(ctx, &rrgs.DeleteRuleGroupSet{Id: id}) if err != nil { log.Printf("[ERROR] Received error: %#v", err) - return handleRpcErrorWithID(err, "recording-rule-group-set", req.Id) + if status.Code(err) == codes.NotFound { + resp.Diagnostics.AddWarning( + fmt.Sprintf("recording-rule-group-set %q is in state, but no longer exists in Coralogix backend", id), + "", + ) + } else { + resp.Diagnostics.AddError( + "Error deleting recording-rule-group-set", + handleRpcErrorNewFramework(err, "recording-rule-group-set"), + ) + } + return } - log.Printf("[INFO] recording-rule-group-set %s deleted", id) +} + +type RecordingRuleGroupSetResourceModel struct { + ID types.String `tfsdk:"id"` + YamlContent types.String `tfsdk:"yaml_content"` + Groups types.Set `tfsdk:"groups"` //RecordingRuleGroupModel + Name types.String `tfsdk:"name"` +} + +type RecordingRuleGroupModel struct { + Name types.String `tfsdk:"name"` + Interval types.Int64 `tfsdk:"interval"` + Limit types.Int64 `tfsdk:"limit"` + Rules types.List `tfsdk:"rules"` //RecordingRuleModel +} - d.SetId("") - return nil +type RecordingRuleModel struct { + Record types.String `tfsdk:"record"` + Expr types.String `tfsdk:"expr"` + Labels types.Map `tfsdk:"labels"` } -func setRecordingRulesGroupsSet(d *schema.ResourceData, set *rrgs.OutRuleGroupSet) diag.Diagnostics { - if err := d.Set("group", flattenRecordingRulesGroups(set.Groups)); err != nil { - return diag.FromErr(err) +func expandRecordingRulesGroupsSet(ctx context.Context, plan *RecordingRuleGroupSetResourceModel) (*rrgs.CreateRuleGroupSet, diag.Diagnostics) { + if yamlContent := plan.YamlContent.ValueString(); yamlContent != "" { + return expandRecordingRulesGroupsSetFromYaml(yamlContent) } - if name := set.Name; name != nil { - if err := d.Set("name", *name); err != nil { - return diag.FromErr(err) + return expandRecordingRulesGroupSetExplicitly(ctx, plan) +} + +func expandUpdateRecordingRulesGroupsSet(ctx context.Context, plan *RecordingRuleGroupSetResourceModel) (*rrgs.UpdateRuleGroupSet, diag.Diagnostics) { + if yamlContent := plan.YamlContent.ValueString(); yamlContent != "" { + rrg, diags := expandRecordingRulesGroupsSetFromYaml(yamlContent) + if diags.HasError() { + return nil, diags } + + return &rrgs.UpdateRuleGroupSet{ + Id: plan.ID.ValueString(), + Groups: rrg.Groups, + Name: rrg.Name, + }, nil + } + + rrg, diags := expandRecordingRulesGroupSetExplicitly(ctx, plan) + if diags.HasError() { + return nil, diags } - return nil + return &rrgs.UpdateRuleGroupSet{ + Id: plan.ID.ValueString(), + Groups: rrg.Groups, + Name: rrg.Name, + }, nil } -func flattenRecordingRulesGroups(groups []*rrgs.OutRuleGroup) interface{} { - result := make([]interface{}, 0, len(groups)) - for _, g := range groups { - group := flattenRecordingRulesGroup(g) - result = append(result, group) +func expandRecordingRulesGroupsSetFromYaml(yamlContent string) (*rrgs.CreateRuleGroupSet, diag.Diagnostics) { + var result rrgs.CreateRuleGroupSet + if err := yaml.Unmarshal([]byte(yamlContent), &result); err != nil { + return nil, diag.Diagnostics{diag.NewErrorDiagnostic("Error on unmarshal yaml_content", err.Error())} } - return result + return &result, nil } -func flattenRecordingRulesGroup(group *rrgs.OutRuleGroup) interface{} { - rules := flattenRecordingRules(group.Rules) - return map[string]interface{}{ - "name": group.Name, - "interval": group.Interval, - "limit": group.Limit, - "rule": rules, +func expandRecordingRulesGroupSetExplicitly(ctx context.Context, plan *RecordingRuleGroupSetResourceModel) (*rrgs.CreateRuleGroupSet, diag.Diagnostics) { + name := plan.Name.ValueString() + groups, diags := expandRecordingRulesGroups(ctx, plan.Groups) + if diags.HasError() { + return nil, diags } + + return &rrgs.CreateRuleGroupSet{ + Name: &name, + Groups: groups, + }, nil } -func flattenRecordingRules(rules []*rrgs.OutRule) interface{} { - result := make([]interface{}, 0, len(rules)) - for _, rule := range rules { - flattenedRecordingRule := flattenRecordingRule(rule) - result = append(result, flattenedRecordingRule) +func expandRecordingRulesGroups(ctx context.Context, groups types.Set) ([]*rrgs.InRuleGroup, diag.Diagnostics) { + var diags diag.Diagnostics + var groupsObjects []types.Object + var expandedGroups []*rrgs.InRuleGroup + groups.ElementsAs(ctx, &groupsObjects, true) + + for _, groupObject := range groupsObjects { + var group RecordingRuleGroupModel + if dg := groupObject.As(ctx, &group, basetypes.ObjectAsOptions{}); dg.HasError() { + diags.Append(dg...) + continue + } + expandedGroup, expandDiags := expandRecordingRuleGroup(ctx, group) + if expandDiags.HasError() { + diags.Append(expandDiags...) + continue + } + expandedGroups = append(expandedGroups, expandedGroup) } - return result + + return expandedGroups, diags } -func flattenRecordingRule(rule *rrgs.OutRule) interface{} { - labels := flattenRecordingRuleLabels(rule.Labels) - return map[string]interface{}{ - "record": rule.Record, - "expr": rule.Expr, - "labels": labels, +func expandRecordingRuleGroup(ctx context.Context, group RecordingRuleGroupModel) (*rrgs.InRuleGroup, diag.Diagnostics) { + interval := uint32(group.Interval.ValueInt64()) + limit := uint64(group.Limit.ValueInt64()) + rules, diags := expandRecordingRules(ctx, group.Rules) + if diags.HasError() { + return nil, diags } + + return &rrgs.InRuleGroup{ + Name: group.Name.ValueString(), + Interval: &interval, + Limit: &limit, + Rules: rules, + }, nil } -func flattenRecordingRuleLabels(labels map[string]string) map[string]interface{} { - form := make(map[string]interface{}, len(labels)) - for k, v := range labels { - form[k] = v +func expandRecordingRules(ctx context.Context, rules types.List) ([]*rrgs.InRule, diag.Diagnostics) { + var diags diag.Diagnostics + var rulesObjects []types.Object + var expandedRules []*rrgs.InRule + rules.ElementsAs(ctx, &rulesObjects, true) + + for _, ruleObject := range rulesObjects { + var rule RecordingRuleModel + if dg := ruleObject.As(ctx, &rule, basetypes.ObjectAsOptions{}); dg.HasError() { + diags.Append(dg...) + continue + } + expandedRule, expandDiags := expandRecordingRule(ctx, rule) + if expandDiags.HasError() { + diags.Append(expandDiags...) + continue + } + expandedRules = append(expandedRules, expandedRule) } - return form + + return expandedRules, diags } -func RecordingRulesGroupsSetSchema() map[string]*schema.Schema { - return map[string]*schema.Schema{ - "yaml_content": { - Type: schema.TypeString, - Optional: true, - ExactlyOneOf: []string{"yaml_content", "group"}, - ValidateFunc: validateRecordingRulesGroupYamlContent, - Description: "An option to import recording-rule-group-set from yaml file.", - }, - "group": { - Type: schema.TypeSet, - Optional: true, - Computed: true, - ExactlyOneOf: []string{"yaml_content", "group"}, - Elem: recordingRuleGroupSchema(), - Set: schema.HashResource(recordingRuleGroupSchema()), - Description: "An option to define recording-rule-groups explicitly. Will be computed in a case of importing by yaml_content.", - }, - "name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ConflictsWith: []string{"yaml_content"}, - Description: "recording-rule-groups-set name. Optional in a case of defining the recording-rule-groups ('group') explicitly, and computed in a case of importing by yaml_content", - }, +func expandRecordingRule(ctx context.Context, rule RecordingRuleModel) (*rrgs.InRule, diag.Diagnostics) { + labels, diags := typeMapToStringMap(ctx, rule.Labels) + if diags.HasError() { + return nil, diags } + + return &rrgs.InRule{ + Record: rule.Record.ValueString(), + Expr: rule.Expr.ValueString(), + Labels: labels, + }, nil } -func recordingRuleGroupSchema() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringIsNotEmpty, - Description: "The rule-group name. Have to be unique.", - }, - "interval": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(0), - Description: "How often rules in the group are evaluated (in seconds).", - }, - "limit": { - Type: schema.TypeInt, - Optional: true, - Description: "Limit the number of alerts an alerting rule and series a recording-rule can produce. 0 is no limit.", - }, - "rule": { - Type: schema.TypeList, - Required: true, - Elem: recordingRulesSchema(), - }, - }, - } +type recordingRulesGroupYamlContentValidator struct{} + +func (v recordingRulesGroupYamlContentValidator) Description(ctx context.Context) string { + return "validate yaml_content" } -func validateRecordingRulesGroupYamlContent(config interface{}, _ string) ([]string, []error) { +func (v recordingRulesGroupYamlContentValidator) MarkdownDescription(ctx context.Context) string { + return "validate yaml_content" +} + +func (v recordingRulesGroupYamlContentValidator) ValidateString(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) { + if req.ConfigValue.IsNull() { + return + } + var set rrgs.CreateRuleGroupSet - if err := yaml.Unmarshal([]byte(config.(string)), &set); err != nil { - return nil, []error{err} + if err := yaml.Unmarshal([]byte(req.ConfigValue.ValueString()), &set); err != nil { + resp.Diagnostics.AddError("error on validating yaml_content", err.Error()) } groups := set.Groups if len(groups) == 0 { - return nil, []error{fmt.Errorf("groups list can not be empty")} + resp.Diagnostics.AddError("error on validating yaml_content", "groups list can not be empty") } - errors := make([]error, 0) for i, group := range groups { if group.Name == "" { - errors = append(errors, fmt.Errorf("groups[%d] name can not be empty", i)) + resp.Diagnostics.AddError("error on validating yaml_content", fmt.Sprintf("groups[%d] name can not be empty", i)) } if group.Interval == nil { - return nil, append(errors, fmt.Errorf("groups[%d] limit have to be set", i)) + resp.Diagnostics.AddError("error on validating yaml_content", fmt.Sprintf("groups[%d] limit have to be set", i)) } } - if len(errors) != 0 { - return nil, errors - } - - return nil, nil -} - -func recordingRulesSchema() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - "record": { - Type: schema.TypeString, - Required: true, - Description: "The name of the time series to output to. Must be a valid metric name.", - }, - "expr": { - Type: schema.TypeString, - Required: true, - Description: "The PromQL expression to evaluate. " + - "Every evaluation cycle this is evaluated at the current time," + - " and the result recorded as a new set of time series with the metric name as given by 'record'.", - }, - "labels": { - Type: schema.TypeMap, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Optional: true, - Description: "Labels to add or overwrite before storing the result.", - }, - }, - } } diff --git a/coralogix/resource_coralogix_recording_rules_groups_set_test.go b/coralogix/resource_coralogix_recording_rules_groups_set_test.go index feff4dbf..648b0b68 100644 --- a/coralogix/resource_coralogix_recording_rules_groups_set_test.go +++ b/coralogix/resource_coralogix_recording_rules_groups_set_test.go @@ -24,26 +24,26 @@ func TestAccCoralogixRecordingRulesGroupsSetFromYaml(t *testing.T) { parent := filepath.Dir(wd) filePath := parent + "/examples/recording_rules_groups_set/rule-group-set.yaml" resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviderFactories, - CheckDestroy: testAccCheckRecordingRulesGroupDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckRecordingRulesGroupDestroy, Steps: []resource.TestStep{ { Config: testAccCoralogixResourceRecordingRulesGroupsSetFromYaml(filePath), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet(recordingRulesGroupsSetResourceName, "id"), - resource.TestCheckTypeSetElemNestedAttrs(recordingRulesGroupsSetResourceName, "group.*", + resource.TestCheckTypeSetElemNestedAttrs(recordingRulesGroupsSetResourceName, "groups.*", map[string]string{ "name": "Foo", "interval": "180", - "rule.#": "2", + "rules.#": "2", }, ), - resource.TestCheckTypeSetElemNestedAttrs(recordingRulesGroupsSetResourceName, "group.*", + resource.TestCheckTypeSetElemNestedAttrs(recordingRulesGroupsSetResourceName, "groups.*", map[string]string{ "name": "Bar", "interval": "60", - "rule.#": "2", + "rules.#": "2", }, ), ), @@ -54,26 +54,26 @@ func TestAccCoralogixRecordingRulesGroupsSetFromYaml(t *testing.T) { func TestAccCoralogixRecordingRulesGroupsExplicit(t *testing.T) { resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviderFactories, - CheckDestroy: testAccCheckRecordingRulesGroupDestroy, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + CheckDestroy: testAccCheckRecordingRulesGroupDestroy, Steps: []resource.TestStep{ { Config: testAccCoralogixResourceRecordingRulesGroupsSetExplicit(), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet(recordingRulesGroupsSetResourceName, "id"), - resource.TestCheckTypeSetElemNestedAttrs(recordingRulesGroupsSetResourceName, "group.*", + resource.TestCheckTypeSetElemNestedAttrs(recordingRulesGroupsSetResourceName, "groups.*", map[string]string{ "name": "Foo", "interval": "180", - "rule.#": "2", + "rules.#": "2", }, ), - resource.TestCheckTypeSetElemNestedAttrs(recordingRulesGroupsSetResourceName, "group.*", + resource.TestCheckTypeSetElemNestedAttrs(recordingRulesGroupsSetResourceName, "groups.*", map[string]string{ "name": "Bar", "interval": "60", - "rule.#": "2", + "rules.#": "2", }, ), ), @@ -112,32 +112,40 @@ func testAccCoralogixResourceRecordingRulesGroupsSetFromYaml(filePath string) st } func testAccCoralogixResourceRecordingRulesGroupsSetExplicit() string { - return `resource "coralogix_recording_rules_groups_set" "test" { - name = "Name" - group { - name = "Foo" - interval = 180 - rule { - record = "ts3db_live_ingester_write_latency:3m" - expr = "sum(rate(ts3db_live_ingester_write_latency_seconds_count{CX_LEVEL=\"staging\",pod=~\"ts3db-live-ingester.*\"}[2m])) by (pod)" - } - rule { - record = "job:http_requests_total:sum" - expr = "sum(rate(http_requests_total[5m])) by (job)" - } - } - group { - name = "Bar" - interval = 60 - rule { - record = "ts3db_live_ingester_write_latency:3m" - expr = "sum(rate(ts3db_live_ingester_write_latency_seconds_count{CX_LEVEL=\"staging\",pod=~\"ts3db-live-ingester.*\"}[2m])) by (pod)" - } - rule { - record = "job:http_requests_total:sum" - expr = "sum(rate(http_requests_total[5m])) by (job)" - } - } - } + return `resource "coralogix_recording_rules_groups_set" test { + name = "Name" + groups = [ + { + name = "Foo" + interval = 180 + limit = 100 + rules = [ + { + record = "ts3db_live_ingester_write_latency:3m" + expr = "sum(rate(ts3db_live_ingester_write_latency_seconds_count{CX_LEVEL=\"staging\",pod=~\"ts3db-live-ingester.*\"}[2m])) by (pod)" + }, + { + record = "job:http_requests_total:sum" + expr = "sum(rate(http_requests_total[5m])) by (job)" + }, + ] + }, + { + name = "Bar" + interval = 60 + limit = 100 + rules = [ + { + record = "ts3db_live_ingester_write_latency:3m" + expr = "sum(rate(ts3db_live_ingester_write_latency_seconds_count{CX_LEVEL=\"staging\",pod=~\"ts3db-live-ingester.*\"}[2m])) by (pod)" + }, + { + record = "job:http_requests_total:sum" + expr = "sum(rate(http_requests_total[5m])) by (job)" + }, + ] + }, + ] + } ` } diff --git a/docs/data-sources/recording_rules_groups_set.md b/docs/data-sources/recording_rules_groups_set.md index caf33848..bcaf3fec 100644 --- a/docs/data-sources/recording_rules_groups_set.md +++ b/docs/data-sources/recording_rules_groups_set.md @@ -8,37 +8,39 @@ description: |- # coralogix_recording_rules_groups_set (Data Source) +## Example Usage - - +```hcl +data "coralogix_recording_rules_groups_set" "example_imported" { + id = coralogix_recording_rules_groups_set.example.id +} +``` ## Schema ### Read-Only -- `group` (Set of Object) An option to define recording-rule-groups explicitly. Will be computed in a case of importing by yaml_content. (see [below for nested schema](#nestedatt--group)) +- `groups` (Attributes Set) (see [below for nested schema](#nestedatt--groups)) - `id` (String) The ID of this resource. -- `name` (String) recording-rule-groups-set name. Optional in a case of defining the recording-rule-groups ('group') explicitly, and computed in a case of importing by yaml_content -- `yaml_content` (String) An option to import recording-rule-group-set from yaml file. +- `name` (String) +- `yaml_content` (String) - -### Nested Schema for `group` + +### Nested Schema for `groups` Read-Only: -- `interval` (Number) -- `limit` (Number) -- `name` (String) -- `rule` (List of Object) (see [below for nested schema](#nestedobjatt--group--rule)) +- `interval` (Number) How often rules in the group are evaluated (in seconds). +- `limit` (Number) Limit the number of alerts an alerting rule and series a recording-rule can produce. 0 is no limit. +- `name` (String) The rule-group name. Have to be unique. +- `rules` (Attributes List) (see [below for nested schema](#nestedatt--groups--rules)) - -### Nested Schema for `group.rule` + +### Nested Schema for `groups.rules` Read-Only: -- `expr` (String) -- `labels` (Map of String) -- `record` (String) - - +- `expr` (String) The PromQL expression to evaluate. Every evaluation cycle this is evaluated at the current time, and the result recorded as a new set of time series with the metric name as given by 'record'. +- `labels` (Map of String) Labels to add or overwrite before storing the result. +- `record` (String) The name of the time series to output to. Must be a valid metric name. diff --git a/docs/resources/recording_rules_groups_set.md b/docs/resources/recording_rules_groups_set.md index 278d91ec..576ae51d 100644 --- a/docs/resources/recording_rules_groups_set.md +++ b/docs/resources/recording_rules_groups_set.md @@ -7,8 +7,6 @@ description: "Coralogix recording-rules-groups-set. For more information - https # coralogix_recording_rules_groups_set (Resource) -Coralogix recording-rules-groups-set. For more information - https://coralogix.com/docs/recording-rules/. - ## Example Usage ### Import from yaml file @@ -19,66 +17,71 @@ resource "coralogix_recording_rules_groups_set" recording_rules_group { ``` ### Explicitly - ```hcl resource "coralogix_recording_rules_groups_set" recording_rules_groups_set_explicit { - name = "Name" - group { - name = "Foo" - interval = 180 - rule { - record = "ts3db_live_ingester_write_latency:3m" - expr = "sum(rate(ts3db_live_ingester_write_latency_seconds_count{CX_LEVEL=\"staging\",pod=~\"ts3db-live-ingester.*\"}[2m])) by (pod)" - } - rule { - record = "job:http_requests_total:sum" - expr = "sum(rate(http_requests_total[5m])) by (job)" - } - } - group { - name = "Bar" - interval = 180 - rule { - record = "ts3db_live_ingester_write_latency:3m" - expr = "sum(rate(ts3db_live_ingester_write_latency_seconds_count{CX_LEVEL=\"staging\",pod=~\"ts3db-live-ingester.*\"}[2m])) by (pod)" - } - rule { - record = "job:http_requests_total:sum" - expr = "sum(rate(http_requests_total[5m])) by (job)" - } - } + name = "Name" + groups = [ + { + name = "Foo" + interval = 180 + limit = 100 + rules = [ + { + record = "ts3db_live_ingester_write_latency:3m" + expr = "sum(rate(ts3db_live_ingester_write_latency_seconds_count{CX_LEVEL=\"staging\",pod=~\"ts3db-live-ingester.*\"}[2m])) by (pod)" + }, + { + record = "job:http_requests_total:sum" + expr = "sum(rate(http_requests_total[5m])) by (job)" + }, + ] + }, + { + name = "Bar" + interval = 180 + limit = 100 + rules = [ + { + record = "ts3db_live_ingester_write_latency:3m" + expr = "sum(rate(ts3db_live_ingester_write_latency_seconds_count{CX_LEVEL=\"staging\",pod=~\"ts3db-live-ingester.*\"}[2m])) by (pod)" + }, + { + record = "job:http_requests_total:sum" + expr = "sum(rate(http_requests_total[5m])) by (job)" + }, + ] + }, + ] } ``` - ## Schema ### Optional -- `group` (Block Set) An option to define recording-rule-groups explicitly. Will be computed in a case of importing by yaml_content. (see [below for nested schema](#nestedblock--group)) -- `name` (String) recording-rule-groups-set name. Optional in a case of defining the recording-rule-groups ('group') explicitly, and computed in a case of importing by yaml_content -- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) -- `yaml_content` (String) An option to import recording-rule-group-set from yaml file. +- `groups` (Attributes Set) (see [below for nested schema](#nestedatt--groups)) +- `name` (String) +- `yaml_content` (String) ### Read-Only - `id` (String) The ID of this resource. - -### Nested Schema for `group` + +### Nested Schema for `groups` Required: - `interval` (Number) How often rules in the group are evaluated (in seconds). - `name` (String) The rule-group name. Have to be unique. -- `rule` (Block List, Min: 1) (see [below for nested schema](#nestedblock--group--rule)) +- `rules` (Attributes List) (see [below for nested schema](#nestedatt--groups--rules)) Optional: - `limit` (Number) Limit the number of alerts an alerting rule and series a recording-rule can produce. 0 is no limit. - -### Nested Schema for `group.rule` + +### Nested Schema for `groups.rules` Required: @@ -88,32 +91,3 @@ Required: Optional: - `labels` (Map of String) Labels to add or overwrite before storing the result. - - - - -### Nested Schema for `timeouts` - -Optional: - -- `create` (String) -- `delete` (String) -- `read` (String) -- `update` (String) - - -## Import - -```sh -terraform import coralogix_recording_rules_groups_set.example -``` - -to get the coralogix_recording_rules_groups_set id run the following command and look for the id of the coralogix_recording_rules_groups_set you want to import: -```sh -grpcurl -H "Authorization: Bearer " -d @ ng-api-grpc.:443 rule_manager.groups.RuleGroupSets/List <