Chore: Replace entity GRN with infra/grn GRN (#74198)

replace entity GRN with infra/grn GRN
This commit is contained in:
Dan Cech
2023-08-31 15:43:35 -04:00
committed by GitHub
parent 27c4362135
commit 85a207fceb
24 changed files with 983 additions and 843 deletions
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
# To compile all protobuf files in this repository, run
# "make protobuf" at the top-level.
set -eu
DST_DIR=./
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
cd "$DIR"
protoc \
-I ./ \
-I ../../../ \
--go_out=${DST_DIR} \
--go_opt=paths=source_relative \
--go-grpc_out=${DST_DIR} \
--go-grpc_opt=paths=source_relative \
--go-grpc_opt=require_unimplemented_servers=false \
*.proto
+16 -27
View File
@@ -6,32 +6,10 @@ import (
"strings"
)
// Grafana resource name. See also:
// https://github.com/grafana/grafana/blob/main/pkg/services/store/entity/entity.proto#L6
// NOTE: This structure/format is still under active development and is subject to change
type GRN struct {
// TenantID contains the ID of the tenant (in hosted grafana) or
// organization (in other environments) the resource belongs to. This field
// may be omitted for global Grafana resources which are not associated with
// an organization.
TenantID int64
// The kind of resource being identified, for e.g. "dashboard" or "user".
// The caller is responsible for validating the value.
ResourceKind string
// ResourceIdentifier is used by the underlying service to identify the
// resource.
ResourceIdentifier string
// GRN can not be extended
_ any
}
// ParseStr attempts to parse a string into a GRN. It returns an error if the
// given string does not match the GRN format, but does not validate the values.
func ParseStr(str string) (GRN, error) {
ret := GRN{}
func ParseStr(str string) (*GRN, error) {
ret := &GRN{}
parts := strings.Split(str, ":")
if len(parts) != 3 {
@@ -65,7 +43,7 @@ func ParseStr(str string) (GRN, error) {
// MustParseStr is a wrapper around ParseStr that panics if the given input is
// not a valid GRN. This is intended for use in tests.
func MustParseStr(str string) GRN {
func MustParseStr(str string) *GRN {
grn, err := ParseStr(str)
if err != nil {
panic("bad grn!")
@@ -73,8 +51,19 @@ func MustParseStr(str string) GRN {
return grn
}
// String returns a string representation of a grn in the format
// ToGRNString returns a string representation of a grn in the format
// grn:tenantID:kind/resourceIdentifier
func (g *GRN) String() string {
func (g *GRN) ToGRNString() string {
return fmt.Sprintf("grn:%d:%s/%s", g.TenantID, g.ResourceKind, g.ResourceIdentifier)
}
// Check if the two GRNs reference to the same object
// we can not use simple `*x == *b` because of the internal settings
func (g *GRN) Equal(b *GRN) bool {
if b == nil {
return false
}
return g == b || (g.TenantID == b.TenantID &&
g.ResourceKind == b.ResourceKind &&
g.ResourceIdentifier == b.ResourceIdentifier)
}
+172
View File
@@ -0,0 +1,172 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.30.0
// protoc v4.23.4
// source: grn.proto
package grn
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type GRN struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// TenantID contains the ID of the tenant (in hosted grafana) or
// organization (in other environments) the resource belongs to. This field
// may be omitted for global Grafana resources which are not associated with
// an organization.
TenantID int64 `protobuf:"varint,1,opt,name=TenantID,proto3" json:"TenantID,omitempty"`
// The kind of resource being identified, for e.g. "dashboard" or "user".
// The caller is responsible for validating the value.
ResourceKind string `protobuf:"bytes,3,opt,name=ResourceKind,proto3" json:"ResourceKind,omitempty"`
// ResourceIdentifier is used by the underlying service to identify the
// resource.
ResourceIdentifier string `protobuf:"bytes,4,opt,name=ResourceIdentifier,proto3" json:"ResourceIdentifier,omitempty"`
}
func (x *GRN) Reset() {
*x = GRN{}
if protoimpl.UnsafeEnabled {
mi := &file_grn_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GRN) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GRN) ProtoMessage() {}
func (x *GRN) ProtoReflect() protoreflect.Message {
mi := &file_grn_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GRN.ProtoReflect.Descriptor instead.
func (*GRN) Descriptor() ([]byte, []int) {
return file_grn_proto_rawDescGZIP(), []int{0}
}
func (x *GRN) GetTenantID() int64 {
if x != nil {
return x.TenantID
}
return 0
}
func (x *GRN) GetResourceKind() string {
if x != nil {
return x.ResourceKind
}
return ""
}
func (x *GRN) GetResourceIdentifier() string {
if x != nil {
return x.ResourceIdentifier
}
return ""
}
var File_grn_proto protoreflect.FileDescriptor
var file_grn_proto_rawDesc = []byte{
0x0a, 0x09, 0x67, 0x72, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x67, 0x72, 0x6e,
0x22, 0x75, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x1a, 0x0a, 0x08, 0x54, 0x65, 0x6e, 0x61, 0x6e,
0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x54, 0x65, 0x6e, 0x61, 0x6e,
0x74, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b,
0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x04, 0x20,
0x01, 0x28, 0x09, 0x52, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65,
0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x67, 0x72,
0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x2f,
0x67, 0x72, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_grn_proto_rawDescOnce sync.Once
file_grn_proto_rawDescData = file_grn_proto_rawDesc
)
func file_grn_proto_rawDescGZIP() []byte {
file_grn_proto_rawDescOnce.Do(func() {
file_grn_proto_rawDescData = protoimpl.X.CompressGZIP(file_grn_proto_rawDescData)
})
return file_grn_proto_rawDescData
}
var file_grn_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_grn_proto_goTypes = []interface{}{
(*GRN)(nil), // 0: grn.GRN
}
var file_grn_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_grn_proto_init() }
func file_grn_proto_init() {
if File_grn_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_grn_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GRN); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_grn_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_grn_proto_goTypes,
DependencyIndexes: file_grn_proto_depIdxs,
MessageInfos: file_grn_proto_msgTypes,
}.Build()
File_grn_proto = out.File
file_grn_proto_rawDesc = nil
file_grn_proto_goTypes = nil
file_grn_proto_depIdxs = nil
}
+20
View File
@@ -0,0 +1,20 @@
syntax = "proto3";
package grn;
option go_package = "github.com/grafana/grafana/pkg/infra/grn";
message GRN {
// TenantID contains the ID of the tenant (in hosted grafana) or
// organization (in other environments) the resource belongs to. This field
// may be omitted for global Grafana resources which are not associated with
// an organization.
int64 TenantID = 1;
// The kind of resource being identified, for e.g. "dashboard" or "user".
// The caller is responsible for validating the value.
string ResourceKind = 3;
// ResourceIdentifier is used by the underlying service to identify the
// resource.
string ResourceIdentifier = 4;
}
+13 -11
View File
@@ -3,57 +3,59 @@ package grn
import (
"fmt"
"testing"
"github.com/google/go-cmp/cmp"
)
func TestParseGRNStr(t *testing.T) {
tests := []struct {
input string
expect GRN
expect *GRN
expectErr bool
}{
{ // empty
"",
GRN{},
&GRN{},
true,
},
{ // too few parts
"grn:dashboards",
GRN{},
&GRN{},
true,
},
{ // too many parts
"grn::dashboards:user:orgs:otherthings:hello:stillgoing",
GRN{},
&GRN{},
true,
},
{ // Does not look like a GRN
"hrn:grafana::123:dashboards/foo",
GRN{},
&GRN{},
true,
},
{ // Missing Kind
"grn::foo",
GRN{},
&GRN{},
true,
},
{ // good!
"grn::roles/Admin",
GRN{TenantID: 0, ResourceKind: "roles", ResourceIdentifier: "Admin"},
&GRN{TenantID: 0, ResourceKind: "roles", ResourceIdentifier: "Admin"},
false,
},
{ // good!
"grn::roles/Admin/with/some/slashes",
GRN{TenantID: 0, ResourceKind: "roles", ResourceIdentifier: "Admin/with/some/slashes"},
&GRN{TenantID: 0, ResourceKind: "roles", ResourceIdentifier: "Admin/with/some/slashes"},
false,
},
{ // good!
"grn:123456789:roles/Admin/with/some/slashes",
GRN{TenantID: 123456789, ResourceKind: "roles", ResourceIdentifier: "Admin/with/some/slashes"},
&GRN{TenantID: 123456789, ResourceKind: "roles", ResourceIdentifier: "Admin/with/some/slashes"},
false,
},
{ // Weird, but valid.
"grn::roles///Admin/with/leading/slashes",
GRN{TenantID: 0, ResourceKind: "roles", ResourceIdentifier: "//Admin/with/leading/slashes"},
&GRN{TenantID: 0, ResourceKind: "roles", ResourceIdentifier: "//Admin/with/leading/slashes"},
false,
},
}
@@ -69,7 +71,7 @@ func TestParseGRNStr(t *testing.T) {
t.Fatalf("wrong result. Expected success, got error %s", err.Error())
}
if got != test.expect {
if !cmp.Equal(test.expect, got) {
t.Fatalf("wrong result. Wanted %s, got %s\n", test.expect.String(), got.String())
}
})