mirror of https://github.com/milvus-io/milvus.git
Support Role-Based Access Control (#18425)
Signed-off-by: SimFG <bang.fu@zilliz.com>pull/18528/head
parent
4aab6ddaa7
commit
ff0200210a
5
go.mod
5
go.mod
|
@ -12,6 +12,8 @@ require (
|
|||
github.com/apache/arrow/go/v8 v8.0.0-20220322092137-778b1772fd20
|
||||
github.com/apache/pulsar-client-go v0.6.1-0.20210728062540-29414db801a7
|
||||
github.com/bits-and-blooms/bloom/v3 v3.0.1
|
||||
github.com/casbin/casbin/v2 v2.44.2
|
||||
github.com/casbin/json-adapter/v2 v2.0.0
|
||||
github.com/confluentinc/confluent-kafka-go v1.9.1
|
||||
github.com/containerd/cgroups v1.0.2
|
||||
github.com/gin-gonic/gin v1.7.7
|
||||
|
@ -49,6 +51,7 @@ require (
|
|||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
google.golang.org/grpc v1.46.0
|
||||
google.golang.org/grpc/examples v0.0.0-20220617181431-3e7b97febc7f
|
||||
google.golang.org/protobuf v1.28.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
stathat.com/c/consistent v1.0.0
|
||||
)
|
||||
|
@ -60,6 +63,7 @@ require (
|
|||
github.com/AthenZ/athenz v1.10.15 // indirect
|
||||
github.com/DataDog/zstd v1.4.6-0.20210211175136-c6db21d202f4 // indirect
|
||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/apache/pulsar-client-go/oauth2 v0.0.0-20211108044248-fe3b7c4e445b // indirect
|
||||
github.com/ardielle/ardielle-go v1.5.2 // indirect
|
||||
|
@ -172,7 +176,6 @@ require (
|
|||
gonum.org/v1/gonum v0.9.3 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220503193339-ba3ae3f07e29 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
|
9
go.sum
9
go.sum
|
@ -59,6 +59,8 @@ github.com/HdrHistogram/hdrhistogram-go v1.0.1 h1:GX8GAYDuhlFQnI2fRDHQhTlkHMz8bE
|
|||
github.com/HdrHistogram/hdrhistogram-go v1.0.1/go.mod h1:BWJ+nMSHY3L41Zj7CA3uXnloDp7xxV0YvstAE7nKTaM=
|
||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU=
|
||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
||||
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
|
||||
|
@ -109,6 +111,11 @@ github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b/go.mod h1:ac9efd0D
|
|||
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
|
||||
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
|
||||
github.com/casbin/casbin/v2 v2.0.0/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/casbin/casbin/v2 v2.44.2 h1:mlWtgbX872r707frOq+REaHzfvsl+qQw0Eq+ekzJ7J8=
|
||||
github.com/casbin/casbin/v2 v2.44.2/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
|
||||
github.com/casbin/json-adapter/v2 v2.0.0 h1:nOCN3TK1CJKSNQQ/MnakbU9/cUcNR3N0AxBDnEBLSDI=
|
||||
github.com/casbin/json-adapter/v2 v2.0.0/go.mod h1:LvsfPXXr8CD0ZFucAxawcY9Xb0FtLk3mozJ1qcSTUD4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI=
|
||||
|
@ -1160,6 +1167,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
|||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/avro.v0 v0.0.0-20171217001914-a730b5802183/go.mod h1:FvqrFXt+jCsyQibeRv4xxEJBL5iG2DDW5aeJwzDiq4A=
|
||||
|
|
|
@ -305,9 +305,9 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_common_2eproto::offsets[] PROT
|
|||
~0u, // no _extensions_
|
||||
~0u, // no _oneof_case_
|
||||
~0u, // no _weak_field_map_
|
||||
PROTOBUF_FIELD_OFFSET(::milvus::proto::common::PrivilegeExt, resource_type_),
|
||||
PROTOBUF_FIELD_OFFSET(::milvus::proto::common::PrivilegeExt, resource_privilege_),
|
||||
PROTOBUF_FIELD_OFFSET(::milvus::proto::common::PrivilegeExt, resource_name_index_),
|
||||
PROTOBUF_FIELD_OFFSET(::milvus::proto::common::PrivilegeExt, object_type_),
|
||||
PROTOBUF_FIELD_OFFSET(::milvus::proto::common::PrivilegeExt, object_privilege_),
|
||||
PROTOBUF_FIELD_OFFSET(::milvus::proto::common::PrivilegeExt, object_name_index_),
|
||||
};
|
||||
static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
|
||||
{ 0, -1, sizeof(::milvus::proto::common::Status)},
|
||||
|
@ -356,106 +356,107 @@ const char descriptor_table_protodef_common_2eproto[] PROTOBUF_SECTION_VARIABLE(
|
|||
"*\n\004base\030\001 \001(\0132\034.milvus.proto.common.MsgB"
|
||||
"ase\"M\n\014DMLMsgHeader\022*\n\004base\030\001 \001(\0132\034.milv"
|
||||
"us.proto.common.MsgBase\022\021\n\tshardName\030\002 \001"
|
||||
"(\t\"\251\001\n\014PrivilegeExt\0228\n\rresource_type\030\001 \001"
|
||||
"(\0162!.milvus.proto.common.ResourceType\022B\n"
|
||||
"\022resource_privilege\030\002 \001(\0162&.milvus.proto"
|
||||
".common.ResourcePrivilege\022\033\n\023resource_na"
|
||||
"me_index\030\003 \001(\005*\323\010\n\tErrorCode\022\013\n\007Success\020"
|
||||
"\000\022\023\n\017UnexpectedError\020\001\022\021\n\rConnectFailed\020"
|
||||
"\002\022\024\n\020PermissionDenied\020\003\022\027\n\023CollectionNot"
|
||||
"Exists\020\004\022\023\n\017IllegalArgument\020\005\022\024\n\020Illegal"
|
||||
"Dimension\020\007\022\024\n\020IllegalIndexType\020\010\022\031\n\025Ill"
|
||||
"egalCollectionName\020\t\022\017\n\013IllegalTOPK\020\n\022\024\n"
|
||||
"\020IllegalRowRecord\020\013\022\023\n\017IllegalVectorID\020\014"
|
||||
"\022\027\n\023IllegalSearchResult\020\r\022\020\n\014FileNotFoun"
|
||||
"d\020\016\022\016\n\nMetaFailed\020\017\022\017\n\013CacheFailed\020\020\022\026\n\022"
|
||||
"CannotCreateFolder\020\021\022\024\n\020CannotCreateFile"
|
||||
"\020\022\022\026\n\022CannotDeleteFolder\020\023\022\024\n\020CannotDele"
|
||||
"teFile\020\024\022\023\n\017BuildIndexError\020\025\022\020\n\014Illegal"
|
||||
"NLIST\020\026\022\025\n\021IllegalMetricType\020\027\022\017\n\013OutOfM"
|
||||
"emory\020\030\022\021\n\rIndexNotExist\020\031\022\023\n\017EmptyColle"
|
||||
"ction\020\032\022\033\n\027UpdateImportTaskFailure\020\033\022\032\n\026"
|
||||
"CollectionNameNotFound\020\034\022\033\n\027CreateCreden"
|
||||
"tialFailure\020\035\022\033\n\027UpdateCredentialFailure"
|
||||
"\020\036\022\033\n\027DeleteCredentialFailure\020\037\022\030\n\024GetCr"
|
||||
"edentialFailure\020 \022\030\n\024ListCredUsersFailur"
|
||||
"e\020!\022\022\n\016GetUserFailure\020\"\022\025\n\021CreateRoleFai"
|
||||
"lure\020#\022\023\n\017DropRoleFailure\020$\022\032\n\026OperateUs"
|
||||
"erRoleFailure\020%\022\025\n\021SelectRoleFailure\020&\022\025"
|
||||
"\n\021SelectUserFailure\020\'\022\031\n\025SelectResourceF"
|
||||
"ailure\020(\022\033\n\027OperatePrivilegeFailure\020)\022\026\n"
|
||||
"\022SelectGrantFailure\020*\022!\n\035RefreshPolicyIn"
|
||||
"foCacheFailure\020+\022\025\n\021ListPolicyFailure\020,\022"
|
||||
"\022\n\016NotShardLeader\020-\022\026\n\022NoReplicaAvailabl"
|
||||
"e\020.\022\023\n\017SegmentNotFound\020/\022\022\n\rDDRequestRac"
|
||||
"e\020\350\007*X\n\nIndexState\022\022\n\016IndexStateNone\020\000\022\014"
|
||||
"\n\010Unissued\020\001\022\016\n\nInProgress\020\002\022\014\n\010Finished"
|
||||
"\020\003\022\n\n\006Failed\020\004*\202\001\n\014SegmentState\022\024\n\020Segme"
|
||||
"ntStateNone\020\000\022\014\n\010NotExist\020\001\022\013\n\007Growing\020\002"
|
||||
"\022\n\n\006Sealed\020\003\022\013\n\007Flushed\020\004\022\014\n\010Flushing\020\005\022"
|
||||
"\013\n\007Dropped\020\006\022\r\n\tImporting\020\007*>\n\017Placehold"
|
||||
"erType\022\010\n\004None\020\000\022\020\n\014BinaryVector\020d\022\017\n\013Fl"
|
||||
"oatVector\020e*\266\014\n\007MsgType\022\r\n\tUndefined\020\000\022\024"
|
||||
"\n\020CreateCollection\020d\022\022\n\016DropCollection\020e"
|
||||
"\022\021\n\rHasCollection\020f\022\026\n\022DescribeCollectio"
|
||||
"n\020g\022\023\n\017ShowCollections\020h\022\024\n\020GetSystemCon"
|
||||
"figs\020i\022\022\n\016LoadCollection\020j\022\025\n\021ReleaseCol"
|
||||
"lection\020k\022\017\n\013CreateAlias\020l\022\r\n\tDropAlias\020"
|
||||
"m\022\016\n\nAlterAlias\020n\022\024\n\017CreatePartition\020\310\001\022"
|
||||
"\022\n\rDropPartition\020\311\001\022\021\n\014HasPartition\020\312\001\022\026"
|
||||
"\n\021DescribePartition\020\313\001\022\023\n\016ShowPartitions"
|
||||
"\020\314\001\022\023\n\016LoadPartitions\020\315\001\022\026\n\021ReleaseParti"
|
||||
"tions\020\316\001\022\021\n\014ShowSegments\020\372\001\022\024\n\017DescribeS"
|
||||
"egment\020\373\001\022\021\n\014LoadSegments\020\374\001\022\024\n\017ReleaseS"
|
||||
"egments\020\375\001\022\024\n\017HandoffSegments\020\376\001\022\030\n\023Load"
|
||||
"BalanceSegments\020\377\001\022\025\n\020DescribeSegments\020\200"
|
||||
"\002\022\020\n\013CreateIndex\020\254\002\022\022\n\rDescribeIndex\020\255\002\022"
|
||||
"\016\n\tDropIndex\020\256\002\022\013\n\006Insert\020\220\003\022\013\n\006Delete\020\221"
|
||||
"\003\022\n\n\005Flush\020\222\003\022\027\n\022ResendSegmentStats\020\223\003\022\013"
|
||||
"\n\006Search\020\364\003\022\021\n\014SearchResult\020\365\003\022\022\n\rGetInd"
|
||||
"exState\020\366\003\022\032\n\025GetIndexBuildProgress\020\367\003\022\034"
|
||||
"\n\027GetCollectionStatistics\020\370\003\022\033\n\026GetParti"
|
||||
"tionStatistics\020\371\003\022\r\n\010Retrieve\020\372\003\022\023\n\016Retr"
|
||||
"ieveResult\020\373\003\022\024\n\017WatchDmChannels\020\374\003\022\025\n\020R"
|
||||
"emoveDmChannels\020\375\003\022\027\n\022WatchQueryChannels"
|
||||
"\020\376\003\022\030\n\023RemoveQueryChannels\020\377\003\022\035\n\030SealedS"
|
||||
"egmentsChangeInfo\020\200\004\022\027\n\022WatchDeltaChanne"
|
||||
"ls\020\201\004\022\024\n\017GetShardLeaders\020\202\004\022\020\n\013GetReplic"
|
||||
"as\020\203\004\022\020\n\013SegmentInfo\020\330\004\022\017\n\nSystemInfo\020\331\004"
|
||||
"\022\024\n\017GetRecoveryInfo\020\332\004\022\024\n\017GetSegmentStat"
|
||||
"e\020\333\004\022\r\n\010TimeTick\020\260\t\022\023\n\016QueryNodeStats\020\261\t"
|
||||
"\022\016\n\tLoadIndex\020\262\t\022\016\n\tRequestID\020\263\t\022\017\n\nRequ"
|
||||
"estTSO\020\264\t\022\024\n\017AllocateSegment\020\265\t\022\026\n\021Segme"
|
||||
"ntStatistics\020\266\t\022\025\n\020SegmentFlushDone\020\267\t\022\017"
|
||||
"\n\nDataNodeTt\020\270\t\022\025\n\020CreateCredential\020\334\013\022\022"
|
||||
"\n\rGetCredential\020\335\013\022\025\n\020DeleteCredential\020\336"
|
||||
"\013\022\025\n\020UpdateCredential\020\337\013\022\026\n\021ListCredUser"
|
||||
"names\020\340\013\022\017\n\nCreateRole\020\300\014\022\r\n\010DropRole\020\301\014"
|
||||
"\022\024\n\017OperateUserRole\020\302\014\022\017\n\nSelectRole\020\303\014\022"
|
||||
"\017\n\nSelectUser\020\304\014\022\023\n\016SelectResource\020\305\014\022\025\n"
|
||||
"\020OperatePrivilege\020\306\014\022\020\n\013SelectGrant\020\307\014\022\033"
|
||||
"\n\026RefreshPolicyInfoCache\020\310\014\022\017\n\nListPolic"
|
||||
"y\020\311\014*\"\n\007DslType\022\007\n\003Dsl\020\000\022\016\n\nBoolExprV1\020\001"
|
||||
"*B\n\017CompactionState\022\021\n\rUndefiedState\020\000\022\r"
|
||||
"\n\tExecuting\020\001\022\r\n\tCompleted\020\002*X\n\020Consiste"
|
||||
"ncyLevel\022\n\n\006Strong\020\000\022\013\n\007Session\020\001\022\013\n\007Bou"
|
||||
"nded\020\002\022\016\n\nEventually\020\003\022\016\n\nCustomized\020\004*\257"
|
||||
"\001\n\013ImportState\022\021\n\rImportPending\020\000\022\020\n\014Imp"
|
||||
"ortFailed\020\001\022\021\n\rImportStarted\020\002\022\024\n\020Import"
|
||||
"Downloaded\020\003\022\020\n\014ImportParsed\020\004\022\023\n\017Import"
|
||||
"Persisted\020\005\022\023\n\017ImportCompleted\020\006\022\026\n\022Impo"
|
||||
"rtAllocSegment\020\n*\036\n\014ResourceType\022\016\n\nColl"
|
||||
"ection\020\000*\335\001\n\021ResourcePrivilege\022\020\n\014Privil"
|
||||
"egeAll\020\000\022\023\n\017PrivilegeCreate\020\001\022\021\n\rPrivile"
|
||||
"geDrop\020\002\022\022\n\016PrivilegeAlter\020\003\022\021\n\rPrivileg"
|
||||
"eRead\020\004\022\021\n\rPrivilegeLoad\020\005\022\024\n\020PrivilegeR"
|
||||
"elease\020\006\022\024\n\020PrivilegeCompact\020\007\022\023\n\017Privil"
|
||||
"egeInsert\020\010\022\023\n\017PrivilegeDelete\020\t:^\n\021priv"
|
||||
"ilege_ext_obj\022\037.google.protobuf.MessageO"
|
||||
"ptions\030\351\007 \001(\0132!.milvus.proto.common.Priv"
|
||||
"ilegeExtBW\n\016io.milvus.grpcB\013CommonProtoP"
|
||||
"\001Z3github.com/milvus-io/milvus/internal/"
|
||||
"proto/commonpb\240\001\001b\006proto3"
|
||||
"(\t\"\237\001\n\014PrivilegeExt\0224\n\013object_type\030\001 \001(\016"
|
||||
"2\037.milvus.proto.common.ObjectType\022>\n\020obj"
|
||||
"ect_privilege\030\002 \001(\0162$.milvus.proto.commo"
|
||||
"n.ObjectPrivilege\022\031\n\021object_name_index\030\003"
|
||||
" \001(\005*\323\010\n\tErrorCode\022\013\n\007Success\020\000\022\023\n\017Unexp"
|
||||
"ectedError\020\001\022\021\n\rConnectFailed\020\002\022\024\n\020Permi"
|
||||
"ssionDenied\020\003\022\027\n\023CollectionNotExists\020\004\022\023"
|
||||
"\n\017IllegalArgument\020\005\022\024\n\020IllegalDimension\020"
|
||||
"\007\022\024\n\020IllegalIndexType\020\010\022\031\n\025IllegalCollec"
|
||||
"tionName\020\t\022\017\n\013IllegalTOPK\020\n\022\024\n\020IllegalRo"
|
||||
"wRecord\020\013\022\023\n\017IllegalVectorID\020\014\022\027\n\023Illega"
|
||||
"lSearchResult\020\r\022\020\n\014FileNotFound\020\016\022\016\n\nMet"
|
||||
"aFailed\020\017\022\017\n\013CacheFailed\020\020\022\026\n\022CannotCrea"
|
||||
"teFolder\020\021\022\024\n\020CannotCreateFile\020\022\022\026\n\022Cann"
|
||||
"otDeleteFolder\020\023\022\024\n\020CannotDeleteFile\020\024\022\023"
|
||||
"\n\017BuildIndexError\020\025\022\020\n\014IllegalNLIST\020\026\022\025\n"
|
||||
"\021IllegalMetricType\020\027\022\017\n\013OutOfMemory\020\030\022\021\n"
|
||||
"\rIndexNotExist\020\031\022\023\n\017EmptyCollection\020\032\022\033\n"
|
||||
"\027UpdateImportTaskFailure\020\033\022\032\n\026Collection"
|
||||
"NameNotFound\020\034\022\033\n\027CreateCredentialFailur"
|
||||
"e\020\035\022\033\n\027UpdateCredentialFailure\020\036\022\033\n\027Dele"
|
||||
"teCredentialFailure\020\037\022\030\n\024GetCredentialFa"
|
||||
"ilure\020 \022\030\n\024ListCredUsersFailure\020!\022\022\n\016Get"
|
||||
"UserFailure\020\"\022\025\n\021CreateRoleFailure\020#\022\023\n\017"
|
||||
"DropRoleFailure\020$\022\032\n\026OperateUserRoleFail"
|
||||
"ure\020%\022\025\n\021SelectRoleFailure\020&\022\025\n\021SelectUs"
|
||||
"erFailure\020\'\022\031\n\025SelectResourceFailure\020(\022\033"
|
||||
"\n\027OperatePrivilegeFailure\020)\022\026\n\022SelectGra"
|
||||
"ntFailure\020*\022!\n\035RefreshPolicyInfoCacheFai"
|
||||
"lure\020+\022\025\n\021ListPolicyFailure\020,\022\022\n\016NotShar"
|
||||
"dLeader\020-\022\026\n\022NoReplicaAvailable\020.\022\023\n\017Seg"
|
||||
"mentNotFound\020/\022\022\n\rDDRequestRace\020\350\007*X\n\nIn"
|
||||
"dexState\022\022\n\016IndexStateNone\020\000\022\014\n\010Unissued"
|
||||
"\020\001\022\016\n\nInProgress\020\002\022\014\n\010Finished\020\003\022\n\n\006Fail"
|
||||
"ed\020\004*\202\001\n\014SegmentState\022\024\n\020SegmentStateNon"
|
||||
"e\020\000\022\014\n\010NotExist\020\001\022\013\n\007Growing\020\002\022\n\n\006Sealed"
|
||||
"\020\003\022\013\n\007Flushed\020\004\022\014\n\010Flushing\020\005\022\013\n\007Dropped"
|
||||
"\020\006\022\r\n\tImporting\020\007*>\n\017PlaceholderType\022\010\n\004"
|
||||
"None\020\000\022\020\n\014BinaryVector\020d\022\017\n\013FloatVector\020"
|
||||
"e*\266\014\n\007MsgType\022\r\n\tUndefined\020\000\022\024\n\020CreateCo"
|
||||
"llection\020d\022\022\n\016DropCollection\020e\022\021\n\rHasCol"
|
||||
"lection\020f\022\026\n\022DescribeCollection\020g\022\023\n\017Sho"
|
||||
"wCollections\020h\022\024\n\020GetSystemConfigs\020i\022\022\n\016"
|
||||
"LoadCollection\020j\022\025\n\021ReleaseCollection\020k\022"
|
||||
"\017\n\013CreateAlias\020l\022\r\n\tDropAlias\020m\022\016\n\nAlter"
|
||||
"Alias\020n\022\024\n\017CreatePartition\020\310\001\022\022\n\rDropPar"
|
||||
"tition\020\311\001\022\021\n\014HasPartition\020\312\001\022\026\n\021Describe"
|
||||
"Partition\020\313\001\022\023\n\016ShowPartitions\020\314\001\022\023\n\016Loa"
|
||||
"dPartitions\020\315\001\022\026\n\021ReleasePartitions\020\316\001\022\021"
|
||||
"\n\014ShowSegments\020\372\001\022\024\n\017DescribeSegment\020\373\001\022"
|
||||
"\021\n\014LoadSegments\020\374\001\022\024\n\017ReleaseSegments\020\375\001"
|
||||
"\022\024\n\017HandoffSegments\020\376\001\022\030\n\023LoadBalanceSeg"
|
||||
"ments\020\377\001\022\025\n\020DescribeSegments\020\200\002\022\020\n\013Creat"
|
||||
"eIndex\020\254\002\022\022\n\rDescribeIndex\020\255\002\022\016\n\tDropInd"
|
||||
"ex\020\256\002\022\013\n\006Insert\020\220\003\022\013\n\006Delete\020\221\003\022\n\n\005Flush"
|
||||
"\020\222\003\022\027\n\022ResendSegmentStats\020\223\003\022\013\n\006Search\020\364"
|
||||
"\003\022\021\n\014SearchResult\020\365\003\022\022\n\rGetIndexState\020\366\003"
|
||||
"\022\032\n\025GetIndexBuildProgress\020\367\003\022\034\n\027GetColle"
|
||||
"ctionStatistics\020\370\003\022\033\n\026GetPartitionStatis"
|
||||
"tics\020\371\003\022\r\n\010Retrieve\020\372\003\022\023\n\016RetrieveResult"
|
||||
"\020\373\003\022\024\n\017WatchDmChannels\020\374\003\022\025\n\020RemoveDmCha"
|
||||
"nnels\020\375\003\022\027\n\022WatchQueryChannels\020\376\003\022\030\n\023Rem"
|
||||
"oveQueryChannels\020\377\003\022\035\n\030SealedSegmentsCha"
|
||||
"ngeInfo\020\200\004\022\027\n\022WatchDeltaChannels\020\201\004\022\024\n\017G"
|
||||
"etShardLeaders\020\202\004\022\020\n\013GetReplicas\020\203\004\022\020\n\013S"
|
||||
"egmentInfo\020\330\004\022\017\n\nSystemInfo\020\331\004\022\024\n\017GetRec"
|
||||
"overyInfo\020\332\004\022\024\n\017GetSegmentState\020\333\004\022\r\n\010Ti"
|
||||
"meTick\020\260\t\022\023\n\016QueryNodeStats\020\261\t\022\016\n\tLoadIn"
|
||||
"dex\020\262\t\022\016\n\tRequestID\020\263\t\022\017\n\nRequestTSO\020\264\t\022"
|
||||
"\024\n\017AllocateSegment\020\265\t\022\026\n\021SegmentStatisti"
|
||||
"cs\020\266\t\022\025\n\020SegmentFlushDone\020\267\t\022\017\n\nDataNode"
|
||||
"Tt\020\270\t\022\025\n\020CreateCredential\020\334\013\022\022\n\rGetCrede"
|
||||
"ntial\020\335\013\022\025\n\020DeleteCredential\020\336\013\022\025\n\020Updat"
|
||||
"eCredential\020\337\013\022\026\n\021ListCredUsernames\020\340\013\022\017"
|
||||
"\n\nCreateRole\020\300\014\022\r\n\010DropRole\020\301\014\022\024\n\017Operat"
|
||||
"eUserRole\020\302\014\022\017\n\nSelectRole\020\303\014\022\017\n\nSelectU"
|
||||
"ser\020\304\014\022\023\n\016SelectResource\020\305\014\022\025\n\020OperatePr"
|
||||
"ivilege\020\306\014\022\020\n\013SelectGrant\020\307\014\022\033\n\026RefreshP"
|
||||
"olicyInfoCache\020\310\014\022\017\n\nListPolicy\020\311\014*\"\n\007Ds"
|
||||
"lType\022\007\n\003Dsl\020\000\022\016\n\nBoolExprV1\020\001*B\n\017Compac"
|
||||
"tionState\022\021\n\rUndefiedState\020\000\022\r\n\tExecutin"
|
||||
"g\020\001\022\r\n\tCompleted\020\002*X\n\020ConsistencyLevel\022\n"
|
||||
"\n\006Strong\020\000\022\013\n\007Session\020\001\022\013\n\007Bounded\020\002\022\016\n\n"
|
||||
"Eventually\020\003\022\016\n\nCustomized\020\004*\257\001\n\013ImportS"
|
||||
"tate\022\021\n\rImportPending\020\000\022\020\n\014ImportFailed\020"
|
||||
"\001\022\021\n\rImportStarted\020\002\022\024\n\020ImportDownloaded"
|
||||
"\020\003\022\020\n\014ImportParsed\020\004\022\023\n\017ImportPersisted\020"
|
||||
"\005\022\023\n\017ImportCompleted\020\006\022\026\n\022ImportAllocSeg"
|
||||
"ment\020\n*(\n\nObjectType\022\016\n\nCollection\020\000\022\n\n\006"
|
||||
"Global\020\001*\212\002\n\017ObjectPrivilege\022\020\n\014Privileg"
|
||||
"eAll\020\000\022\035\n\031PrivilegeCreateCollection\020\001\022\033\n"
|
||||
"\027PrivilegeDropCollection\020\002\022\037\n\033PrivilegeD"
|
||||
"escribeCollection\020\003\022\034\n\030PrivilegeShowColl"
|
||||
"ections\020\004\022\021\n\rPrivilegeLoad\020\005\022\024\n\020Privileg"
|
||||
"eRelease\020\006\022\027\n\023PrivilegeCompaction\020\007\022\023\n\017P"
|
||||
"rivilegeInsert\020\010\022\023\n\017PrivilegeDelete\020\t:^\n"
|
||||
"\021privilege_ext_obj\022\037.google.protobuf.Mes"
|
||||
"sageOptions\030\351\007 \001(\0132!.milvus.proto.common"
|
||||
".PrivilegeExtBW\n\016io.milvus.grpcB\013CommonP"
|
||||
"rotoP\001Z3github.com/milvus-io/milvus/inte"
|
||||
"rnal/proto/commonpb\240\001\001b\006proto3"
|
||||
;
|
||||
static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_common_2eproto_deps[1] = {
|
||||
&::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto,
|
||||
|
@ -476,7 +477,7 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_com
|
|||
static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_common_2eproto_once;
|
||||
static bool descriptor_table_common_2eproto_initialized = false;
|
||||
const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_common_2eproto = {
|
||||
&descriptor_table_common_2eproto_initialized, descriptor_table_protodef_common_2eproto, "common.proto", 4705,
|
||||
&descriptor_table_common_2eproto_initialized, descriptor_table_protodef_common_2eproto, "common.proto", 4750,
|
||||
&descriptor_table_common_2eproto_once, descriptor_table_common_2eproto_sccs, descriptor_table_common_2eproto_deps, 11, 1,
|
||||
schemas, file_default_instances, TableStruct_common_2eproto::offsets,
|
||||
file_level_metadata_common_2eproto, 11, file_level_enum_descriptors_common_2eproto, file_level_service_descriptors_common_2eproto,
|
||||
|
@ -754,24 +755,25 @@ bool ImportState_IsValid(int value) {
|
|||
}
|
||||
}
|
||||
|
||||
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ResourceType_descriptor() {
|
||||
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ObjectType_descriptor() {
|
||||
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_common_2eproto);
|
||||
return file_level_enum_descriptors_common_2eproto[9];
|
||||
}
|
||||
bool ResourceType_IsValid(int value) {
|
||||
bool ObjectType_IsValid(int value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
case 1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ResourcePrivilege_descriptor() {
|
||||
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ObjectPrivilege_descriptor() {
|
||||
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_common_2eproto);
|
||||
return file_level_enum_descriptors_common_2eproto[10];
|
||||
}
|
||||
bool ResourcePrivilege_IsValid(int value) {
|
||||
bool ObjectPrivilege_IsValid(int value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
case 1:
|
||||
|
@ -3945,16 +3947,16 @@ PrivilegeExt::PrivilegeExt(const PrivilegeExt& from)
|
|||
: ::PROTOBUF_NAMESPACE_ID::Message(),
|
||||
_internal_metadata_(nullptr) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
::memcpy(&resource_type_, &from.resource_type_,
|
||||
static_cast<size_t>(reinterpret_cast<char*>(&resource_name_index_) -
|
||||
reinterpret_cast<char*>(&resource_type_)) + sizeof(resource_name_index_));
|
||||
::memcpy(&object_type_, &from.object_type_,
|
||||
static_cast<size_t>(reinterpret_cast<char*>(&object_name_index_) -
|
||||
reinterpret_cast<char*>(&object_type_)) + sizeof(object_name_index_));
|
||||
// @@protoc_insertion_point(copy_constructor:milvus.proto.common.PrivilegeExt)
|
||||
}
|
||||
|
||||
void PrivilegeExt::SharedCtor() {
|
||||
::memset(&resource_type_, 0, static_cast<size_t>(
|
||||
reinterpret_cast<char*>(&resource_name_index_) -
|
||||
reinterpret_cast<char*>(&resource_type_)) + sizeof(resource_name_index_));
|
||||
::memset(&object_type_, 0, static_cast<size_t>(
|
||||
reinterpret_cast<char*>(&object_name_index_) -
|
||||
reinterpret_cast<char*>(&object_type_)) + sizeof(object_name_index_));
|
||||
}
|
||||
|
||||
PrivilegeExt::~PrivilegeExt() {
|
||||
|
@ -3980,9 +3982,9 @@ void PrivilegeExt::Clear() {
|
|||
// Prevent compiler warnings about cached_has_bits being unused
|
||||
(void) cached_has_bits;
|
||||
|
||||
::memset(&resource_type_, 0, static_cast<size_t>(
|
||||
reinterpret_cast<char*>(&resource_name_index_) -
|
||||
reinterpret_cast<char*>(&resource_type_)) + sizeof(resource_name_index_));
|
||||
::memset(&object_type_, 0, static_cast<size_t>(
|
||||
reinterpret_cast<char*>(&object_name_index_) -
|
||||
reinterpret_cast<char*>(&object_type_)) + sizeof(object_name_index_));
|
||||
_internal_metadata_.Clear();
|
||||
}
|
||||
|
||||
|
@ -3994,26 +3996,26 @@ const char* PrivilegeExt::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_I
|
|||
ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
|
||||
CHK_(ptr);
|
||||
switch (tag >> 3) {
|
||||
// .milvus.proto.common.ResourceType resource_type = 1;
|
||||
// .milvus.proto.common.ObjectType object_type = 1;
|
||||
case 1:
|
||||
if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 8)) {
|
||||
::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr);
|
||||
CHK_(ptr);
|
||||
set_resource_type(static_cast<::milvus::proto::common::ResourceType>(val));
|
||||
set_object_type(static_cast<::milvus::proto::common::ObjectType>(val));
|
||||
} else goto handle_unusual;
|
||||
continue;
|
||||
// .milvus.proto.common.ResourcePrivilege resource_privilege = 2;
|
||||
// .milvus.proto.common.ObjectPrivilege object_privilege = 2;
|
||||
case 2:
|
||||
if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) {
|
||||
::PROTOBUF_NAMESPACE_ID::uint64 val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr);
|
||||
CHK_(ptr);
|
||||
set_resource_privilege(static_cast<::milvus::proto::common::ResourcePrivilege>(val));
|
||||
set_object_privilege(static_cast<::milvus::proto::common::ObjectPrivilege>(val));
|
||||
} else goto handle_unusual;
|
||||
continue;
|
||||
// int32 resource_name_index = 3;
|
||||
// int32 object_name_index = 3;
|
||||
case 3:
|
||||
if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 24)) {
|
||||
resource_name_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr);
|
||||
object_name_index_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint(&ptr);
|
||||
CHK_(ptr);
|
||||
} else goto handle_unusual;
|
||||
continue;
|
||||
|
@ -4047,41 +4049,41 @@ bool PrivilegeExt::MergePartialFromCodedStream(
|
|||
tag = p.first;
|
||||
if (!p.second) goto handle_unusual;
|
||||
switch (::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::GetTagFieldNumber(tag)) {
|
||||
// .milvus.proto.common.ResourceType resource_type = 1;
|
||||
// .milvus.proto.common.ObjectType object_type = 1;
|
||||
case 1: {
|
||||
if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (8 & 0xFF)) {
|
||||
int value = 0;
|
||||
DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive<
|
||||
int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>(
|
||||
input, &value)));
|
||||
set_resource_type(static_cast< ::milvus::proto::common::ResourceType >(value));
|
||||
set_object_type(static_cast< ::milvus::proto::common::ObjectType >(value));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// .milvus.proto.common.ResourcePrivilege resource_privilege = 2;
|
||||
// .milvus.proto.common.ObjectPrivilege object_privilege = 2;
|
||||
case 2: {
|
||||
if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (16 & 0xFF)) {
|
||||
int value = 0;
|
||||
DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive<
|
||||
int, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_ENUM>(
|
||||
input, &value)));
|
||||
set_resource_privilege(static_cast< ::milvus::proto::common::ResourcePrivilege >(value));
|
||||
set_object_privilege(static_cast< ::milvus::proto::common::ObjectPrivilege >(value));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// int32 resource_name_index = 3;
|
||||
// int32 object_name_index = 3;
|
||||
case 3: {
|
||||
if (static_cast< ::PROTOBUF_NAMESPACE_ID::uint8>(tag) == (24 & 0xFF)) {
|
||||
|
||||
DO_((::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::ReadPrimitive<
|
||||
::PROTOBUF_NAMESPACE_ID::int32, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_INT32>(
|
||||
input, &resource_name_index_)));
|
||||
input, &object_name_index_)));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
|
@ -4115,21 +4117,21 @@ void PrivilegeExt::SerializeWithCachedSizes(
|
|||
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
|
||||
(void) cached_has_bits;
|
||||
|
||||
// .milvus.proto.common.ResourceType resource_type = 1;
|
||||
if (this->resource_type() != 0) {
|
||||
// .milvus.proto.common.ObjectType object_type = 1;
|
||||
if (this->object_type() != 0) {
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum(
|
||||
1, this->resource_type(), output);
|
||||
1, this->object_type(), output);
|
||||
}
|
||||
|
||||
// .milvus.proto.common.ResourcePrivilege resource_privilege = 2;
|
||||
if (this->resource_privilege() != 0) {
|
||||
// .milvus.proto.common.ObjectPrivilege object_privilege = 2;
|
||||
if (this->object_privilege() != 0) {
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnum(
|
||||
2, this->resource_privilege(), output);
|
||||
2, this->object_privilege(), output);
|
||||
}
|
||||
|
||||
// int32 resource_name_index = 3;
|
||||
if (this->resource_name_index() != 0) {
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(3, this->resource_name_index(), output);
|
||||
// int32 object_name_index = 3;
|
||||
if (this->object_name_index() != 0) {
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32(3, this->object_name_index(), output);
|
||||
}
|
||||
|
||||
if (_internal_metadata_.have_unknown_fields()) {
|
||||
|
@ -4145,21 +4147,21 @@ void PrivilegeExt::SerializeWithCachedSizes(
|
|||
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
|
||||
(void) cached_has_bits;
|
||||
|
||||
// .milvus.proto.common.ResourceType resource_type = 1;
|
||||
if (this->resource_type() != 0) {
|
||||
// .milvus.proto.common.ObjectType object_type = 1;
|
||||
if (this->object_type() != 0) {
|
||||
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
|
||||
1, this->resource_type(), target);
|
||||
1, this->object_type(), target);
|
||||
}
|
||||
|
||||
// .milvus.proto.common.ResourcePrivilege resource_privilege = 2;
|
||||
if (this->resource_privilege() != 0) {
|
||||
// .milvus.proto.common.ObjectPrivilege object_privilege = 2;
|
||||
if (this->object_privilege() != 0) {
|
||||
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
|
||||
2, this->resource_privilege(), target);
|
||||
2, this->object_privilege(), target);
|
||||
}
|
||||
|
||||
// int32 resource_name_index = 3;
|
||||
if (this->resource_name_index() != 0) {
|
||||
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->resource_name_index(), target);
|
||||
// int32 object_name_index = 3;
|
||||
if (this->object_name_index() != 0) {
|
||||
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->object_name_index(), target);
|
||||
}
|
||||
|
||||
if (_internal_metadata_.have_unknown_fields()) {
|
||||
|
@ -4183,23 +4185,23 @@ size_t PrivilegeExt::ByteSizeLong() const {
|
|||
// Prevent compiler warnings about cached_has_bits being unused
|
||||
(void) cached_has_bits;
|
||||
|
||||
// .milvus.proto.common.ResourceType resource_type = 1;
|
||||
if (this->resource_type() != 0) {
|
||||
// .milvus.proto.common.ObjectType object_type = 1;
|
||||
if (this->object_type() != 0) {
|
||||
total_size += 1 +
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->resource_type());
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->object_type());
|
||||
}
|
||||
|
||||
// .milvus.proto.common.ResourcePrivilege resource_privilege = 2;
|
||||
if (this->resource_privilege() != 0) {
|
||||
// .milvus.proto.common.ObjectPrivilege object_privilege = 2;
|
||||
if (this->object_privilege() != 0) {
|
||||
total_size += 1 +
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->resource_privilege());
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->object_privilege());
|
||||
}
|
||||
|
||||
// int32 resource_name_index = 3;
|
||||
if (this->resource_name_index() != 0) {
|
||||
// int32 object_name_index = 3;
|
||||
if (this->object_name_index() != 0) {
|
||||
total_size += 1 +
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32Size(
|
||||
this->resource_name_index());
|
||||
this->object_name_index());
|
||||
}
|
||||
|
||||
int cached_size = ::PROTOBUF_NAMESPACE_ID::internal::ToCachedSize(total_size);
|
||||
|
@ -4229,14 +4231,14 @@ void PrivilegeExt::MergeFrom(const PrivilegeExt& from) {
|
|||
::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0;
|
||||
(void) cached_has_bits;
|
||||
|
||||
if (from.resource_type() != 0) {
|
||||
set_resource_type(from.resource_type());
|
||||
if (from.object_type() != 0) {
|
||||
set_object_type(from.object_type());
|
||||
}
|
||||
if (from.resource_privilege() != 0) {
|
||||
set_resource_privilege(from.resource_privilege());
|
||||
if (from.object_privilege() != 0) {
|
||||
set_object_privilege(from.object_privilege());
|
||||
}
|
||||
if (from.resource_name_index() != 0) {
|
||||
set_resource_name_index(from.resource_name_index());
|
||||
if (from.object_name_index() != 0) {
|
||||
set_object_name_index(from.object_name_index());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4261,9 +4263,9 @@ bool PrivilegeExt::IsInitialized() const {
|
|||
void PrivilegeExt::InternalSwap(PrivilegeExt* other) {
|
||||
using std::swap;
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
swap(resource_type_, other->resource_type_);
|
||||
swap(resource_privilege_, other->resource_privilege_);
|
||||
swap(resource_name_index_, other->resource_name_index_);
|
||||
swap(object_type_, other->object_type_);
|
||||
swap(object_privilege_, other->object_privilege_);
|
||||
swap(object_name_index_, other->object_name_index_);
|
||||
}
|
||||
|
||||
::PROTOBUF_NAMESPACE_ID::Metadata PrivilegeExt::GetMetadata() const {
|
||||
|
|
|
@ -478,62 +478,63 @@ inline bool ImportState_Parse(
|
|||
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<ImportState>(
|
||||
ImportState_descriptor(), name, value);
|
||||
}
|
||||
enum ResourceType : int {
|
||||
enum ObjectType : int {
|
||||
Collection = 0,
|
||||
ResourceType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
|
||||
ResourceType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
|
||||
Global = 1,
|
||||
ObjectType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
|
||||
ObjectType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
|
||||
};
|
||||
bool ResourceType_IsValid(int value);
|
||||
constexpr ResourceType ResourceType_MIN = Collection;
|
||||
constexpr ResourceType ResourceType_MAX = Collection;
|
||||
constexpr int ResourceType_ARRAYSIZE = ResourceType_MAX + 1;
|
||||
bool ObjectType_IsValid(int value);
|
||||
constexpr ObjectType ObjectType_MIN = Collection;
|
||||
constexpr ObjectType ObjectType_MAX = Global;
|
||||
constexpr int ObjectType_ARRAYSIZE = ObjectType_MAX + 1;
|
||||
|
||||
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ResourceType_descriptor();
|
||||
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ObjectType_descriptor();
|
||||
template<typename T>
|
||||
inline const std::string& ResourceType_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, ResourceType>::value ||
|
||||
inline const std::string& ObjectType_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, ObjectType>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function ResourceType_Name.");
|
||||
"Incorrect type passed to function ObjectType_Name.");
|
||||
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
|
||||
ResourceType_descriptor(), enum_t_value);
|
||||
ObjectType_descriptor(), enum_t_value);
|
||||
}
|
||||
inline bool ResourceType_Parse(
|
||||
const std::string& name, ResourceType* value) {
|
||||
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<ResourceType>(
|
||||
ResourceType_descriptor(), name, value);
|
||||
inline bool ObjectType_Parse(
|
||||
const std::string& name, ObjectType* value) {
|
||||
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<ObjectType>(
|
||||
ObjectType_descriptor(), name, value);
|
||||
}
|
||||
enum ResourcePrivilege : int {
|
||||
enum ObjectPrivilege : int {
|
||||
PrivilegeAll = 0,
|
||||
PrivilegeCreate = 1,
|
||||
PrivilegeDrop = 2,
|
||||
PrivilegeAlter = 3,
|
||||
PrivilegeRead = 4,
|
||||
PrivilegeCreateCollection = 1,
|
||||
PrivilegeDropCollection = 2,
|
||||
PrivilegeDescribeCollection = 3,
|
||||
PrivilegeShowCollections = 4,
|
||||
PrivilegeLoad = 5,
|
||||
PrivilegeRelease = 6,
|
||||
PrivilegeCompact = 7,
|
||||
PrivilegeCompaction = 7,
|
||||
PrivilegeInsert = 8,
|
||||
PrivilegeDelete = 9,
|
||||
ResourcePrivilege_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
|
||||
ResourcePrivilege_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
|
||||
ObjectPrivilege_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::min(),
|
||||
ObjectPrivilege_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::PROTOBUF_NAMESPACE_ID::int32>::max()
|
||||
};
|
||||
bool ResourcePrivilege_IsValid(int value);
|
||||
constexpr ResourcePrivilege ResourcePrivilege_MIN = PrivilegeAll;
|
||||
constexpr ResourcePrivilege ResourcePrivilege_MAX = PrivilegeDelete;
|
||||
constexpr int ResourcePrivilege_ARRAYSIZE = ResourcePrivilege_MAX + 1;
|
||||
bool ObjectPrivilege_IsValid(int value);
|
||||
constexpr ObjectPrivilege ObjectPrivilege_MIN = PrivilegeAll;
|
||||
constexpr ObjectPrivilege ObjectPrivilege_MAX = PrivilegeDelete;
|
||||
constexpr int ObjectPrivilege_ARRAYSIZE = ObjectPrivilege_MAX + 1;
|
||||
|
||||
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ResourcePrivilege_descriptor();
|
||||
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ObjectPrivilege_descriptor();
|
||||
template<typename T>
|
||||
inline const std::string& ResourcePrivilege_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, ResourcePrivilege>::value ||
|
||||
inline const std::string& ObjectPrivilege_Name(T enum_t_value) {
|
||||
static_assert(::std::is_same<T, ObjectPrivilege>::value ||
|
||||
::std::is_integral<T>::value,
|
||||
"Incorrect type passed to function ResourcePrivilege_Name.");
|
||||
"Incorrect type passed to function ObjectPrivilege_Name.");
|
||||
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
|
||||
ResourcePrivilege_descriptor(), enum_t_value);
|
||||
ObjectPrivilege_descriptor(), enum_t_value);
|
||||
}
|
||||
inline bool ResourcePrivilege_Parse(
|
||||
const std::string& name, ResourcePrivilege* value) {
|
||||
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<ResourcePrivilege>(
|
||||
ResourcePrivilege_descriptor(), name, value);
|
||||
inline bool ObjectPrivilege_Parse(
|
||||
const std::string& name, ObjectPrivilege* value) {
|
||||
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<ObjectPrivilege>(
|
||||
ObjectPrivilege_descriptor(), name, value);
|
||||
}
|
||||
// ===================================================================
|
||||
|
||||
|
@ -2108,33 +2109,33 @@ class PrivilegeExt :
|
|||
// accessors -------------------------------------------------------
|
||||
|
||||
enum : int {
|
||||
kResourceTypeFieldNumber = 1,
|
||||
kResourcePrivilegeFieldNumber = 2,
|
||||
kResourceNameIndexFieldNumber = 3,
|
||||
kObjectTypeFieldNumber = 1,
|
||||
kObjectPrivilegeFieldNumber = 2,
|
||||
kObjectNameIndexFieldNumber = 3,
|
||||
};
|
||||
// .milvus.proto.common.ResourceType resource_type = 1;
|
||||
void clear_resource_type();
|
||||
::milvus::proto::common::ResourceType resource_type() const;
|
||||
void set_resource_type(::milvus::proto::common::ResourceType value);
|
||||
// .milvus.proto.common.ObjectType object_type = 1;
|
||||
void clear_object_type();
|
||||
::milvus::proto::common::ObjectType object_type() const;
|
||||
void set_object_type(::milvus::proto::common::ObjectType value);
|
||||
|
||||
// .milvus.proto.common.ResourcePrivilege resource_privilege = 2;
|
||||
void clear_resource_privilege();
|
||||
::milvus::proto::common::ResourcePrivilege resource_privilege() const;
|
||||
void set_resource_privilege(::milvus::proto::common::ResourcePrivilege value);
|
||||
// .milvus.proto.common.ObjectPrivilege object_privilege = 2;
|
||||
void clear_object_privilege();
|
||||
::milvus::proto::common::ObjectPrivilege object_privilege() const;
|
||||
void set_object_privilege(::milvus::proto::common::ObjectPrivilege value);
|
||||
|
||||
// int32 resource_name_index = 3;
|
||||
void clear_resource_name_index();
|
||||
::PROTOBUF_NAMESPACE_ID::int32 resource_name_index() const;
|
||||
void set_resource_name_index(::PROTOBUF_NAMESPACE_ID::int32 value);
|
||||
// int32 object_name_index = 3;
|
||||
void clear_object_name_index();
|
||||
::PROTOBUF_NAMESPACE_ID::int32 object_name_index() const;
|
||||
void set_object_name_index(::PROTOBUF_NAMESPACE_ID::int32 value);
|
||||
|
||||
// @@protoc_insertion_point(class_scope:milvus.proto.common.PrivilegeExt)
|
||||
private:
|
||||
class _Internal;
|
||||
|
||||
::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_;
|
||||
int resource_type_;
|
||||
int resource_privilege_;
|
||||
::PROTOBUF_NAMESPACE_ID::int32 resource_name_index_;
|
||||
int object_type_;
|
||||
int object_privilege_;
|
||||
::PROTOBUF_NAMESPACE_ID::int32 object_name_index_;
|
||||
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
|
||||
friend struct ::TableStruct_common_2eproto;
|
||||
};
|
||||
|
@ -2947,46 +2948,46 @@ inline void DMLMsgHeader::set_allocated_shardname(std::string* shardname) {
|
|||
|
||||
// PrivilegeExt
|
||||
|
||||
// .milvus.proto.common.ResourceType resource_type = 1;
|
||||
inline void PrivilegeExt::clear_resource_type() {
|
||||
resource_type_ = 0;
|
||||
// .milvus.proto.common.ObjectType object_type = 1;
|
||||
inline void PrivilegeExt::clear_object_type() {
|
||||
object_type_ = 0;
|
||||
}
|
||||
inline ::milvus::proto::common::ResourceType PrivilegeExt::resource_type() const {
|
||||
// @@protoc_insertion_point(field_get:milvus.proto.common.PrivilegeExt.resource_type)
|
||||
return static_cast< ::milvus::proto::common::ResourceType >(resource_type_);
|
||||
inline ::milvus::proto::common::ObjectType PrivilegeExt::object_type() const {
|
||||
// @@protoc_insertion_point(field_get:milvus.proto.common.PrivilegeExt.object_type)
|
||||
return static_cast< ::milvus::proto::common::ObjectType >(object_type_);
|
||||
}
|
||||
inline void PrivilegeExt::set_resource_type(::milvus::proto::common::ResourceType value) {
|
||||
inline void PrivilegeExt::set_object_type(::milvus::proto::common::ObjectType value) {
|
||||
|
||||
resource_type_ = value;
|
||||
// @@protoc_insertion_point(field_set:milvus.proto.common.PrivilegeExt.resource_type)
|
||||
object_type_ = value;
|
||||
// @@protoc_insertion_point(field_set:milvus.proto.common.PrivilegeExt.object_type)
|
||||
}
|
||||
|
||||
// .milvus.proto.common.ResourcePrivilege resource_privilege = 2;
|
||||
inline void PrivilegeExt::clear_resource_privilege() {
|
||||
resource_privilege_ = 0;
|
||||
// .milvus.proto.common.ObjectPrivilege object_privilege = 2;
|
||||
inline void PrivilegeExt::clear_object_privilege() {
|
||||
object_privilege_ = 0;
|
||||
}
|
||||
inline ::milvus::proto::common::ResourcePrivilege PrivilegeExt::resource_privilege() const {
|
||||
// @@protoc_insertion_point(field_get:milvus.proto.common.PrivilegeExt.resource_privilege)
|
||||
return static_cast< ::milvus::proto::common::ResourcePrivilege >(resource_privilege_);
|
||||
inline ::milvus::proto::common::ObjectPrivilege PrivilegeExt::object_privilege() const {
|
||||
// @@protoc_insertion_point(field_get:milvus.proto.common.PrivilegeExt.object_privilege)
|
||||
return static_cast< ::milvus::proto::common::ObjectPrivilege >(object_privilege_);
|
||||
}
|
||||
inline void PrivilegeExt::set_resource_privilege(::milvus::proto::common::ResourcePrivilege value) {
|
||||
inline void PrivilegeExt::set_object_privilege(::milvus::proto::common::ObjectPrivilege value) {
|
||||
|
||||
resource_privilege_ = value;
|
||||
// @@protoc_insertion_point(field_set:milvus.proto.common.PrivilegeExt.resource_privilege)
|
||||
object_privilege_ = value;
|
||||
// @@protoc_insertion_point(field_set:milvus.proto.common.PrivilegeExt.object_privilege)
|
||||
}
|
||||
|
||||
// int32 resource_name_index = 3;
|
||||
inline void PrivilegeExt::clear_resource_name_index() {
|
||||
resource_name_index_ = 0;
|
||||
// int32 object_name_index = 3;
|
||||
inline void PrivilegeExt::clear_object_name_index() {
|
||||
object_name_index_ = 0;
|
||||
}
|
||||
inline ::PROTOBUF_NAMESPACE_ID::int32 PrivilegeExt::resource_name_index() const {
|
||||
// @@protoc_insertion_point(field_get:milvus.proto.common.PrivilegeExt.resource_name_index)
|
||||
return resource_name_index_;
|
||||
inline ::PROTOBUF_NAMESPACE_ID::int32 PrivilegeExt::object_name_index() const {
|
||||
// @@protoc_insertion_point(field_get:milvus.proto.common.PrivilegeExt.object_name_index)
|
||||
return object_name_index_;
|
||||
}
|
||||
inline void PrivilegeExt::set_resource_name_index(::PROTOBUF_NAMESPACE_ID::int32 value) {
|
||||
inline void PrivilegeExt::set_object_name_index(::PROTOBUF_NAMESPACE_ID::int32 value) {
|
||||
|
||||
resource_name_index_ = value;
|
||||
// @@protoc_insertion_point(field_set:milvus.proto.common.PrivilegeExt.resource_name_index)
|
||||
object_name_index_ = value;
|
||||
// @@protoc_insertion_point(field_set:milvus.proto.common.PrivilegeExt.object_name_index)
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
@ -3066,15 +3067,15 @@ template <>
|
|||
inline const EnumDescriptor* GetEnumDescriptor< ::milvus::proto::common::ImportState>() {
|
||||
return ::milvus::proto::common::ImportState_descriptor();
|
||||
}
|
||||
template <> struct is_proto_enum< ::milvus::proto::common::ResourceType> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::milvus::proto::common::ObjectType> : ::std::true_type {};
|
||||
template <>
|
||||
inline const EnumDescriptor* GetEnumDescriptor< ::milvus::proto::common::ResourceType>() {
|
||||
return ::milvus::proto::common::ResourceType_descriptor();
|
||||
inline const EnumDescriptor* GetEnumDescriptor< ::milvus::proto::common::ObjectType>() {
|
||||
return ::milvus::proto::common::ObjectType_descriptor();
|
||||
}
|
||||
template <> struct is_proto_enum< ::milvus::proto::common::ResourcePrivilege> : ::std::true_type {};
|
||||
template <> struct is_proto_enum< ::milvus::proto::common::ObjectPrivilege> : ::std::true_type {};
|
||||
template <>
|
||||
inline const EnumDescriptor* GetEnumDescriptor< ::milvus::proto::common::ResourcePrivilege>() {
|
||||
return ::milvus::proto::common::ResourcePrivilege_descriptor();
|
||||
inline const EnumDescriptor* GetEnumDescriptor< ::milvus::proto::common::ObjectPrivilege>() {
|
||||
return ::milvus::proto::common::ObjectPrivilege_descriptor();
|
||||
}
|
||||
|
||||
PROTOBUF_NAMESPACE_CLOSE
|
||||
|
|
|
@ -662,6 +662,38 @@ func (m *mockRootCoordService) GetCredential(ctx context.Context, req *rootcoord
|
|||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m *mockRootCoordService) CreateRole(ctx context.Context, req *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m *mockRootCoordService) DropRole(ctx context.Context, req *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m *mockRootCoordService) OperateUserRole(ctx context.Context, req *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m *mockRootCoordService) SelectRole(ctx context.Context, req *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m *mockRootCoordService) SelectUser(ctx context.Context, req *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m *mockRootCoordService) OperatePrivilege(ctx context.Context, req *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m *mockRootCoordService) SelectGrant(ctx context.Context, req *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m *mockRootCoordService) ListPolicy(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
return &internalpb.ListPolicyResponse{Status: &commonpb.Status{ErrorCode: commonpb.ErrorCode_Success}}, nil
|
||||
}
|
||||
|
||||
type mockHandler struct {
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,11 @@ func Test_NewClient(t *testing.T) {
|
|||
|
||||
r8, err := client.UpdateCredentialCache(ctx, nil)
|
||||
retCheck(retNotNil, r8, err)
|
||||
|
||||
{
|
||||
r, err := client.RefreshPolicyInfoCache(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
}
|
||||
|
||||
client.grpcClient = &mock.GRPCClientBase{
|
||||
|
@ -150,6 +155,11 @@ func Test_NewClient(t *testing.T) {
|
|||
r8Timeout, err := client.UpdateCredentialCache(shortCtx, nil)
|
||||
retCheck(r8Timeout, err)
|
||||
|
||||
{
|
||||
rTimeout, err := client.RefreshPolicyInfoCache(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
|
||||
// cleanup
|
||||
err = client.Stop()
|
||||
assert.Nil(t, err)
|
||||
|
|
|
@ -170,6 +170,7 @@ func (s *Server) startExternalGrpc(grpcPort int, errChan chan error) {
|
|||
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
|
||||
ot.UnaryServerInterceptor(opts...),
|
||||
grpc_auth.UnaryServerInterceptor(proxy.AuthenticationInterceptor),
|
||||
proxy.UnaryServerInterceptor(proxy.PrivilegeInterceptor),
|
||||
)),
|
||||
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
|
||||
ot.StreamServerInterceptor(opts...),
|
||||
|
@ -833,47 +834,34 @@ func (s *Server) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersR
|
|||
return s.proxy.ListCredUsers(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Server) CreateRole(ctx context.Context, request *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (s *Server) CreateRole(ctx context.Context, req *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
return s.proxy.CreateRole(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Server) DropRole(ctx context.Context, request *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (s *Server) DropRole(ctx context.Context, req *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
return s.proxy.DropRole(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Server) OperateUserRole(ctx context.Context, request *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (s *Server) OperateUserRole(ctx context.Context, req *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
return s.proxy.OperateUserRole(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Server) SelectRole(ctx context.Context, request *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (s *Server) SelectRole(ctx context.Context, req *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
return s.proxy.SelectRole(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Server) SelectUser(ctx context.Context, request *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (s *Server) SelectUser(ctx context.Context, req *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
return s.proxy.SelectUser(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Server) SelectResource(ctx context.Context, request *milvuspb.SelectResourceRequest) (*milvuspb.SelectResourceResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (s *Server) OperatePrivilege(ctx context.Context, req *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
return s.proxy.OperatePrivilege(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Server) OperatePrivilege(ctx context.Context, request *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (s *Server) SelectGrant(ctx context.Context, req *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
return s.proxy.SelectGrant(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Server) SelectGrant(ctx context.Context, request *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (s *Server) RefreshPolicyInfoCache(ctx context.Context, request *proxypb.RefreshPolicyInfoCacheRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (s *Server) RefreshPolicyInfoCache(ctx context.Context, req *proxypb.RefreshPolicyInfoCacheRequest) (*commonpb.Status, error) {
|
||||
return s.proxy.RefreshPolicyInfoCache(ctx, req)
|
||||
}
|
||||
|
|
|
@ -258,6 +258,38 @@ func (m *MockRootCoord) GetCredential(ctx context.Context, req *rootcoordpb.GetC
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockRootCoord) CreateRole(ctx context.Context, req *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockRootCoord) DropRole(ctx context.Context, in *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockRootCoord) OperateUserRole(ctx context.Context, in *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockRootCoord) SelectRole(ctx context.Context, in *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockRootCoord) SelectUser(ctx context.Context, in *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockRootCoord) OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockRootCoord) SelectGrant(ctx context.Context, in *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockRootCoord) ListPolicy(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
type MockIndexCoord struct {
|
||||
MockBase
|
||||
|
@ -804,6 +836,38 @@ func (m *MockProxy) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUse
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockProxy) CreateRole(ctx context.Context, req *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockProxy) DropRole(ctx context.Context, req *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockProxy) OperateUserRole(ctx context.Context, req *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockProxy) SelectRole(ctx context.Context, req *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockProxy) SelectUser(ctx context.Context, req *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockProxy) OperatePrivilege(ctx context.Context, req *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockProxy) SelectGrant(ctx context.Context, in *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *MockProxy) RefreshPolicyInfoCache(ctx context.Context, req *proxypb.RefreshPolicyInfoCacheRequest) (*commonpb.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type WaitOption struct {
|
||||
|
@ -1184,6 +1248,46 @@ func Test_NewServer(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("CreateRole", func(t *testing.T) {
|
||||
_, err := server.CreateRole(ctx, nil)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("DropRole", func(t *testing.T) {
|
||||
_, err := server.DropRole(ctx, nil)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("OperateUserRole", func(t *testing.T) {
|
||||
_, err := server.OperateUserRole(ctx, nil)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("SelectRole", func(t *testing.T) {
|
||||
_, err := server.SelectRole(ctx, nil)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("SelectUser", func(t *testing.T) {
|
||||
_, err := server.SelectUser(ctx, nil)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("OperatePrivilege", func(t *testing.T) {
|
||||
_, err := server.OperatePrivilege(ctx, nil)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("SelectGrant", func(t *testing.T) {
|
||||
_, err := server.SelectGrant(ctx, nil)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("RefreshPrivilegeInfoCache", func(t *testing.T) {
|
||||
_, err := server.RefreshPolicyInfoCache(ctx, nil)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
err = server.Stop()
|
||||
assert.Nil(t, err)
|
||||
|
||||
|
|
|
@ -712,19 +712,6 @@ func (c *Client) SelectUser(ctx context.Context, req *milvuspb.SelectUserRequest
|
|||
return ret.(*milvuspb.SelectUserResponse), err
|
||||
}
|
||||
|
||||
func (c *Client) SelectResource(ctx context.Context, req *milvuspb.SelectResourceRequest) (*milvuspb.SelectResourceResponse, error) {
|
||||
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
|
||||
if !funcutil.CheckCtxValid(ctx) {
|
||||
return nil, ctx.Err()
|
||||
}
|
||||
return client.(rootcoordpb.RootCoordClient).SelectResource(ctx, req)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret.(*milvuspb.SelectResourceResponse), err
|
||||
}
|
||||
|
||||
func (c *Client) OperatePrivilege(ctx context.Context, req *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
ret, err := c.grpcClient.ReCall(ctx, func(client interface{}) (interface{}, error) {
|
||||
if !funcutil.CheckCtxValid(ctx) {
|
||||
|
|
|
@ -60,110 +60,178 @@ func Test_NewClient(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
r1, err := client.GetComponentStates(ctx)
|
||||
retCheck(retNotNil, r1, err)
|
||||
|
||||
r2, err := client.GetTimeTickChannel(ctx)
|
||||
retCheck(retNotNil, r2, err)
|
||||
|
||||
r3, err := client.GetStatisticsChannel(ctx)
|
||||
retCheck(retNotNil, r3, err)
|
||||
|
||||
r4, err := client.CreateCollection(ctx, nil)
|
||||
retCheck(retNotNil, r4, err)
|
||||
|
||||
r5, err := client.DropCollection(ctx, nil)
|
||||
retCheck(retNotNil, r5, err)
|
||||
|
||||
r6, err := client.HasCollection(ctx, nil)
|
||||
retCheck(retNotNil, r6, err)
|
||||
|
||||
r7, err := client.DescribeCollection(ctx, nil)
|
||||
retCheck(retNotNil, r7, err)
|
||||
|
||||
r8, err := client.ShowCollections(ctx, nil)
|
||||
retCheck(retNotNil, r8, err)
|
||||
|
||||
r9, err := client.CreatePartition(ctx, nil)
|
||||
retCheck(retNotNil, r9, err)
|
||||
|
||||
r10, err := client.DropPartition(ctx, nil)
|
||||
retCheck(retNotNil, r10, err)
|
||||
|
||||
r11, err := client.HasPartition(ctx, nil)
|
||||
retCheck(retNotNil, r11, err)
|
||||
|
||||
r12, err := client.ShowPartitions(ctx, nil)
|
||||
retCheck(retNotNil, r12, err)
|
||||
|
||||
r13, err := client.CreateIndex(ctx, nil)
|
||||
retCheck(retNotNil, r13, err)
|
||||
|
||||
r14, err := client.DropIndex(ctx, nil)
|
||||
retCheck(retNotNil, r14, err)
|
||||
|
||||
r15, err := client.DescribeIndex(ctx, nil)
|
||||
retCheck(retNotNil, r15, err)
|
||||
|
||||
r16, err := client.AllocTimestamp(ctx, nil)
|
||||
retCheck(retNotNil, r16, err)
|
||||
|
||||
r17, err := client.AllocID(ctx, nil)
|
||||
retCheck(retNotNil, r17, err)
|
||||
|
||||
r18, err := client.UpdateChannelTimeTick(ctx, nil)
|
||||
retCheck(retNotNil, r18, err)
|
||||
|
||||
r19, err := client.DescribeSegment(ctx, nil)
|
||||
retCheck(retNotNil, r19, err)
|
||||
|
||||
r20, err := client.ShowSegments(ctx, nil)
|
||||
retCheck(retNotNil, r20, err)
|
||||
|
||||
r21, err := client.ReleaseDQLMessageStream(ctx, nil)
|
||||
retCheck(retNotNil, r21, err)
|
||||
|
||||
r22, err := client.SegmentFlushCompleted(ctx, nil)
|
||||
retCheck(retNotNil, r22, err)
|
||||
|
||||
r23, err := client.GetMetrics(ctx, nil)
|
||||
retCheck(retNotNil, r23, err)
|
||||
|
||||
r24, err := client.CreateAlias(ctx, nil)
|
||||
retCheck(retNotNil, r24, err)
|
||||
|
||||
r25, err := client.DropAlias(ctx, nil)
|
||||
retCheck(retNotNil, r25, err)
|
||||
|
||||
r26, err := client.AlterAlias(ctx, nil)
|
||||
retCheck(retNotNil, r26, err)
|
||||
|
||||
r27, err := client.Import(ctx, nil)
|
||||
retCheck(retNotNil, r27, err)
|
||||
|
||||
r28, err := client.GetImportState(ctx, nil)
|
||||
retCheck(retNotNil, r28, err)
|
||||
|
||||
r29, err := client.ReportImport(ctx, nil)
|
||||
retCheck(retNotNil, r29, err)
|
||||
|
||||
r30, err := client.CreateCredential(ctx, nil)
|
||||
retCheck(retNotNil, r30, err)
|
||||
|
||||
r31, err := client.GetCredential(ctx, nil)
|
||||
retCheck(retNotNil, r31, err)
|
||||
|
||||
r32, err := client.UpdateCredential(ctx, nil)
|
||||
retCheck(retNotNil, r32, err)
|
||||
|
||||
r33, err := client.DeleteCredential(ctx, nil)
|
||||
retCheck(retNotNil, r33, err)
|
||||
|
||||
r34, err := client.ListCredUsers(ctx, nil)
|
||||
retCheck(retNotNil, r34, err)
|
||||
|
||||
r35, err := client.InvalidateCollectionMetaCache(ctx, nil)
|
||||
retCheck(retNotNil, r35, err)
|
||||
{
|
||||
r, err := client.GetComponentStates(ctx)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.GetTimeTickChannel(ctx)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.GetStatisticsChannel(ctx)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.CreateCollection(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.DropCollection(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.HasCollection(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.DescribeCollection(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.ShowCollections(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.CreatePartition(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.DropPartition(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.HasPartition(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.ShowPartitions(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.CreateIndex(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.DropIndex(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.DescribeIndex(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.AllocTimestamp(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.AllocID(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.UpdateChannelTimeTick(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.DescribeSegment(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.ShowSegments(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.ReleaseDQLMessageStream(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.SegmentFlushCompleted(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.GetMetrics(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.CreateAlias(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.DropAlias(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.AlterAlias(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.Import(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.GetImportState(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.ReportImport(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.CreateCredential(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.GetCredential(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.UpdateCredential(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.DeleteCredential(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.ListCredUsers(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.InvalidateCollectionMetaCache(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.CreateRole(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.DropRole(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.OperateUserRole(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.SelectRole(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.SelectUser(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.OperatePrivilege(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.SelectGrant(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
{
|
||||
r, err := client.ListPolicy(ctx, nil)
|
||||
retCheck(retNotNil, r, err)
|
||||
}
|
||||
}
|
||||
|
||||
client.grpcClient = &mock.GRPCClientBase{
|
||||
|
@ -210,114 +278,182 @@ func Test_NewClient(t *testing.T) {
|
|||
assert.Nil(t, ret)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
r1Timeout, err := client.GetComponentStates(shortCtx)
|
||||
retCheck(r1Timeout, err)
|
||||
|
||||
r2Timeout, err := client.GetTimeTickChannel(shortCtx)
|
||||
retCheck(r2Timeout, err)
|
||||
|
||||
r3Timeout, err := client.GetStatisticsChannel(shortCtx)
|
||||
retCheck(r3Timeout, err)
|
||||
|
||||
r4Timeout, err := client.CreateCollection(shortCtx, nil)
|
||||
retCheck(r4Timeout, err)
|
||||
|
||||
r5Timeout, err := client.DropCollection(shortCtx, nil)
|
||||
retCheck(r5Timeout, err)
|
||||
|
||||
r6Timeout, err := client.HasCollection(shortCtx, nil)
|
||||
retCheck(r6Timeout, err)
|
||||
|
||||
r7Timeout, err := client.DescribeCollection(shortCtx, nil)
|
||||
retCheck(r7Timeout, err)
|
||||
|
||||
r8Timeout, err := client.ShowCollections(shortCtx, nil)
|
||||
retCheck(r8Timeout, err)
|
||||
|
||||
r9Timeout, err := client.CreatePartition(shortCtx, nil)
|
||||
retCheck(r9Timeout, err)
|
||||
|
||||
r10Timeout, err := client.DropPartition(shortCtx, nil)
|
||||
retCheck(r10Timeout, err)
|
||||
|
||||
r11Timeout, err := client.HasPartition(shortCtx, nil)
|
||||
retCheck(r11Timeout, err)
|
||||
|
||||
r12Timeout, err := client.ShowPartitions(shortCtx, nil)
|
||||
retCheck(r12Timeout, err)
|
||||
|
||||
r13Timeout, err := client.CreateIndex(shortCtx, nil)
|
||||
retCheck(r13Timeout, err)
|
||||
|
||||
r14Timeout, err := client.DropIndex(shortCtx, nil)
|
||||
retCheck(r14Timeout, err)
|
||||
|
||||
r15Timeout, err := client.DescribeIndex(shortCtx, nil)
|
||||
retCheck(r15Timeout, err)
|
||||
|
||||
r16Timeout, err := client.AllocTimestamp(shortCtx, nil)
|
||||
retCheck(r16Timeout, err)
|
||||
|
||||
r17Timeout, err := client.AllocID(shortCtx, nil)
|
||||
retCheck(r17Timeout, err)
|
||||
|
||||
r18Timeout, err := client.UpdateChannelTimeTick(shortCtx, nil)
|
||||
retCheck(r18Timeout, err)
|
||||
|
||||
r19Timeout, err := client.DescribeSegment(shortCtx, nil)
|
||||
retCheck(r19Timeout, err)
|
||||
|
||||
r20Timeout, err := client.ShowSegments(shortCtx, nil)
|
||||
retCheck(r20Timeout, err)
|
||||
|
||||
r21Timeout, err := client.ReleaseDQLMessageStream(shortCtx, nil)
|
||||
retCheck(r21Timeout, err)
|
||||
|
||||
r22Timeout, err := client.SegmentFlushCompleted(shortCtx, nil)
|
||||
retCheck(r22Timeout, err)
|
||||
|
||||
r23Timeout, err := client.GetMetrics(shortCtx, nil)
|
||||
retCheck(r23Timeout, err)
|
||||
|
||||
r24Timeout, err := client.CreateAlias(shortCtx, nil)
|
||||
retCheck(r24Timeout, err)
|
||||
|
||||
r25Timeout, err := client.DropAlias(shortCtx, nil)
|
||||
retCheck(r25Timeout, err)
|
||||
|
||||
r26Timeout, err := client.AlterAlias(shortCtx, nil)
|
||||
retCheck(r26Timeout, err)
|
||||
|
||||
r27Timeout, err := client.Import(shortCtx, nil)
|
||||
retCheck(r27Timeout, err)
|
||||
|
||||
r28Timeout, err := client.GetImportState(shortCtx, nil)
|
||||
retCheck(r28Timeout, err)
|
||||
|
||||
r29Timeout, err := client.ReportImport(shortCtx, nil)
|
||||
retCheck(r29Timeout, err)
|
||||
|
||||
r30Timeout, err := client.CreateCredential(shortCtx, nil)
|
||||
retCheck(r30Timeout, err)
|
||||
|
||||
r31Timeout, err := client.GetCredential(shortCtx, nil)
|
||||
retCheck(r31Timeout, err)
|
||||
|
||||
r32Timeout, err := client.UpdateCredential(shortCtx, nil)
|
||||
retCheck(r32Timeout, err)
|
||||
|
||||
r33Timeout, err := client.DeleteCredential(shortCtx, nil)
|
||||
retCheck(r33Timeout, err)
|
||||
|
||||
r34Timeout, err := client.ListCredUsers(shortCtx, nil)
|
||||
retCheck(r34Timeout, err)
|
||||
|
||||
r35Timeout, err := client.ListImportTasks(shortCtx, nil)
|
||||
retCheck(r35Timeout, err)
|
||||
|
||||
r36Timeout, err := client.InvalidateCollectionMetaCache(shortCtx, nil)
|
||||
retCheck(r36Timeout, err)
|
||||
{
|
||||
rTimeout, err := client.GetComponentStates(shortCtx)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.GetTimeTickChannel(shortCtx)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.GetStatisticsChannel(shortCtx)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.CreateCollection(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.DropCollection(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.HasCollection(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.DescribeCollection(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.ShowCollections(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.CreatePartition(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.DropPartition(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.HasPartition(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.ShowPartitions(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.CreateIndex(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.DropIndex(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.DescribeIndex(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.AllocTimestamp(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.AllocID(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.UpdateChannelTimeTick(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.DescribeSegment(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.ShowSegments(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.ReleaseDQLMessageStream(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.SegmentFlushCompleted(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.GetMetrics(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.CreateAlias(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.DropAlias(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.AlterAlias(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.Import(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.GetImportState(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.ReportImport(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.CreateCredential(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.GetCredential(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.UpdateCredential(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.DeleteCredential(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.ListCredUsers(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.ListImportTasks(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.InvalidateCollectionMetaCache(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.CreateRole(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.DropRole(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.OperateUserRole(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.SelectRole(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.SelectUser(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.OperatePrivilege(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.SelectGrant(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
{
|
||||
rTimeout, err := client.ListPolicy(shortCtx, nil)
|
||||
retCheck(rTimeout, err)
|
||||
}
|
||||
|
||||
// clean up
|
||||
err = client.Stop()
|
||||
|
|
|
@ -491,46 +491,33 @@ func (s *Server) ListCredUsers(ctx context.Context, request *milvuspb.ListCredUs
|
|||
}
|
||||
|
||||
func (s *Server) CreateRole(ctx context.Context, request *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return s.rootCoord.CreateRole(ctx, request)
|
||||
}
|
||||
|
||||
func (s *Server) DropRole(ctx context.Context, request *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return s.rootCoord.DropRole(ctx, request)
|
||||
}
|
||||
|
||||
func (s *Server) OperateUserRole(ctx context.Context, request *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return s.rootCoord.OperateUserRole(ctx, request)
|
||||
}
|
||||
|
||||
func (s *Server) SelectRole(ctx context.Context, request *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return s.rootCoord.SelectRole(ctx, request)
|
||||
}
|
||||
|
||||
func (s *Server) SelectUser(ctx context.Context, request *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return s.rootCoord.SelectUser(ctx, request)
|
||||
}
|
||||
|
||||
func (s *Server) SelectResource(ctx context.Context, request *milvuspb.SelectResourceRequest) (*milvuspb.SelectResourceResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (s *Server) OperatePrivilege(ctx context.Context, info *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (s *Server) OperatePrivilege(ctx context.Context, request *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
return s.rootCoord.OperatePrivilege(ctx, request)
|
||||
}
|
||||
|
||||
func (s *Server) SelectGrant(ctx context.Context, request *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return s.rootCoord.SelectGrant(ctx, request)
|
||||
}
|
||||
|
||||
func (s *Server) ListPolicy(ctx context.Context, request *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
return s.rootCoord.ListPolicy(ctx, request)
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ func TestLevelGetterAndSetter(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUpdateLogLevelThroughHttp(t *testing.T) {
|
||||
httpServer := &http.Server{Addr: ":9081"}
|
||||
httpServer := &http.Server{Addr: ":9081", ReadHeaderTimeout: time.Second * 3}
|
||||
go func() {
|
||||
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
Fatal(err.Error())
|
||||
|
|
|
@ -3,6 +3,8 @@ package metastore
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/milvuspb"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/metastore/model"
|
||||
"github.com/milvus-io/milvus/internal/util/typeutil"
|
||||
)
|
||||
|
@ -34,6 +36,16 @@ type Catalog interface {
|
|||
DropCredential(ctx context.Context, username string) error
|
||||
ListCredentials(ctx context.Context) ([]string, error)
|
||||
|
||||
CreateRole(ctx context.Context, tenant string, entity *milvuspb.RoleEntity) error
|
||||
DropRole(ctx context.Context, tenant string, roleName string) error
|
||||
OperateUserRole(ctx context.Context, tenant string, userEntity *milvuspb.UserEntity, roleEntity *milvuspb.RoleEntity, operateType milvuspb.OperateUserRoleType) error
|
||||
SelectRole(ctx context.Context, tenant string, entity *milvuspb.RoleEntity, includeUserInfo bool) ([]*milvuspb.RoleResult, error)
|
||||
SelectUser(ctx context.Context, tenant string, entity *milvuspb.UserEntity, includeRoleInfo bool) ([]*milvuspb.UserResult, error)
|
||||
OperatePrivilege(ctx context.Context, tenant string, entity *milvuspb.GrantEntity, operateType milvuspb.OperatePrivilegeType) error
|
||||
SelectGrant(ctx context.Context, tenant string, entity *milvuspb.GrantEntity) ([]*milvuspb.GrantEntity, error)
|
||||
ListPolicy(ctx context.Context, tenant string) ([]string, error)
|
||||
ListUserRole(ctx context.Context, tenant string) ([]string, error)
|
||||
|
||||
Close()
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,11 @@ import (
|
|||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/funcutil"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/milvuspb"
|
||||
"github.com/milvus-io/milvus/internal/util"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/metastore"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
@ -578,6 +583,367 @@ func (kc *Catalog) ListCredentials(ctx context.Context) ([]string, error) {
|
|||
return usernames, nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) CreateRole(ctx context.Context, tenant string, entity *milvuspb.RoleEntity) error {
|
||||
k := funcutil.HandleTenantForEtcdKey(RolePrefix, tenant, entity.Name)
|
||||
err := kc.Txn.Save(k, "")
|
||||
if err != nil {
|
||||
log.Error("fail to create role", zap.String("key", k), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) DropRole(ctx context.Context, tenant string, roleName string) error {
|
||||
k := funcutil.HandleTenantForEtcdKey(RolePrefix, tenant, roleName)
|
||||
err := kc.Txn.Remove(k)
|
||||
if err != nil {
|
||||
log.Error("fail to drop role", zap.String("key", k), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) OperateUserRole(ctx context.Context, tenant string, userEntity *milvuspb.UserEntity, roleEntity *milvuspb.RoleEntity, operateType milvuspb.OperateUserRoleType) error {
|
||||
k := funcutil.HandleTenantForEtcdKey(RoleMappingPrefix, tenant, fmt.Sprintf("%s/%s", userEntity.Name, roleEntity.Name))
|
||||
var err error
|
||||
if operateType == milvuspb.OperateUserRoleType_AddUserToRole {
|
||||
err = kc.Txn.Save(k, "")
|
||||
if err != nil {
|
||||
log.Error("fail to add user to role", zap.String("key", k), zap.Error(err))
|
||||
}
|
||||
} else if operateType == milvuspb.OperateUserRoleType_RemoveUserFromRole {
|
||||
err = kc.Txn.Remove(k)
|
||||
if err != nil {
|
||||
log.Error("fail to remove user from role", zap.String("key", k), zap.Error(err))
|
||||
}
|
||||
} else {
|
||||
err = fmt.Errorf("invalid operate user role type, operate type: %d", operateType)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (kc *Catalog) SelectRole(ctx context.Context, tenant string, entity *milvuspb.RoleEntity, includeUserInfo bool) ([]*milvuspb.RoleResult, error) {
|
||||
var results []*milvuspb.RoleResult
|
||||
|
||||
roleToUsers := make(map[string][]string)
|
||||
if includeUserInfo {
|
||||
roleMappingKey := funcutil.HandleTenantForEtcdKey(RoleMappingPrefix, tenant, "")
|
||||
keys, _, err := kc.Txn.LoadWithPrefix(roleMappingKey)
|
||||
if err != nil {
|
||||
log.Error("fail to load role mappings", zap.String("key", roleMappingKey), zap.Error(err))
|
||||
return results, err
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
roleMappingInfos := typeutil.AfterN(key, roleMappingKey+"/", "/")
|
||||
if len(roleMappingInfos) != 2 {
|
||||
log.Warn("invalid role mapping key", zap.String("key", key))
|
||||
continue
|
||||
}
|
||||
username := roleMappingInfos[0]
|
||||
roleName := roleMappingInfos[1]
|
||||
roleToUsers[roleName] = append(roleToUsers[roleName], username)
|
||||
}
|
||||
}
|
||||
|
||||
appendRoleResult := func(roleName string) {
|
||||
var users []*milvuspb.UserEntity
|
||||
for _, username := range roleToUsers[roleName] {
|
||||
users = append(users, &milvuspb.UserEntity{Name: username})
|
||||
}
|
||||
results = append(results, &milvuspb.RoleResult{
|
||||
Role: &milvuspb.RoleEntity{Name: roleName},
|
||||
Users: users,
|
||||
})
|
||||
}
|
||||
|
||||
if entity == nil {
|
||||
roleKey := funcutil.HandleTenantForEtcdKey(RolePrefix, tenant, "")
|
||||
keys, _, err := kc.Txn.LoadWithPrefix(roleKey)
|
||||
if err != nil {
|
||||
log.Error("fail to load roles", zap.String("key", roleKey), zap.Error(err))
|
||||
return results, err
|
||||
}
|
||||
for _, key := range keys {
|
||||
infoArr := typeutil.AfterN(key, roleKey+"/", "/")
|
||||
if len(infoArr) != 1 || len(infoArr[0]) == 0 {
|
||||
log.Warn("invalid role key", zap.String("key", key))
|
||||
continue
|
||||
}
|
||||
appendRoleResult(infoArr[0])
|
||||
}
|
||||
} else {
|
||||
if funcutil.IsEmptyString(entity.Name) {
|
||||
return results, fmt.Errorf("role name in the role entity is empty")
|
||||
}
|
||||
roleKey := funcutil.HandleTenantForEtcdKey(RolePrefix, tenant, entity.Name)
|
||||
_, err := kc.Txn.Load(roleKey)
|
||||
if err != nil {
|
||||
log.Error("fail to load a role", zap.String("key", roleKey), zap.Error(err))
|
||||
return results, err
|
||||
}
|
||||
appendRoleResult(entity.Name)
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) getRolesByUsername(tenant string, username string) ([]string, error) {
|
||||
var roles []string
|
||||
k := funcutil.HandleTenantForEtcdKey(RoleMappingPrefix, tenant, username)
|
||||
keys, _, err := kc.Txn.LoadWithPrefix(k)
|
||||
if err != nil {
|
||||
log.Error("fail to load role mappings by the username", zap.String("key", k), zap.Error(err))
|
||||
return roles, err
|
||||
}
|
||||
for _, key := range keys {
|
||||
roleMappingInfos := typeutil.AfterN(key, k+"/", "/")
|
||||
if len(roleMappingInfos) != 1 {
|
||||
log.Warn("invalid role mapping key", zap.String("key", key))
|
||||
continue
|
||||
}
|
||||
roles = append(roles, roleMappingInfos[0])
|
||||
}
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
// getUserResult get the user result by the username. And never return the error because the error means the user isn't added to a role.
|
||||
func (kc *Catalog) getUserResult(tenant string, username string, includeRoleInfo bool) (*milvuspb.UserResult, error) {
|
||||
result := &milvuspb.UserResult{User: &milvuspb.UserEntity{Name: username}}
|
||||
if !includeRoleInfo {
|
||||
return result, nil
|
||||
}
|
||||
roleNames, err := kc.getRolesByUsername(tenant, username)
|
||||
if err != nil {
|
||||
log.Warn("fail to get roles by the username", zap.Error(err))
|
||||
return result, err
|
||||
}
|
||||
var roles []*milvuspb.RoleEntity
|
||||
for _, roleName := range roleNames {
|
||||
roles = append(roles, &milvuspb.RoleEntity{Name: roleName})
|
||||
}
|
||||
result.Roles = roles
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) SelectUser(ctx context.Context, tenant string, entity *milvuspb.UserEntity, includeRoleInfo bool) ([]*milvuspb.UserResult, error) {
|
||||
var (
|
||||
usernames []string
|
||||
err error
|
||||
results []*milvuspb.UserResult
|
||||
)
|
||||
|
||||
appendUserResult := func(username string) error {
|
||||
result, err := kc.getUserResult(tenant, username, includeRoleInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
results = append(results, result)
|
||||
return nil
|
||||
}
|
||||
|
||||
if entity == nil {
|
||||
usernames, err = kc.ListCredentials(ctx)
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
} else {
|
||||
if funcutil.IsEmptyString(entity.Name) {
|
||||
return results, fmt.Errorf("username in the user entity is empty")
|
||||
}
|
||||
_, err = kc.GetCredential(ctx, entity.Name)
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
usernames = append(usernames, entity.Name)
|
||||
}
|
||||
for _, username := range usernames {
|
||||
err = appendUserResult(username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) OperatePrivilege(ctx context.Context, tenant string, entity *milvuspb.GrantEntity, operateType milvuspb.OperatePrivilegeType) error {
|
||||
privilegeName := entity.Grantor.Privilege.Name
|
||||
k := funcutil.HandleTenantForEtcdKey(GranteePrefix, tenant, fmt.Sprintf("%s/%s/%s", entity.Role.Name, entity.Object.Name, entity.ObjectName))
|
||||
|
||||
curGrantPrivilegeEntity := &milvuspb.GrantPrivilegeEntity{}
|
||||
v, err := kc.Txn.Load(k)
|
||||
if err != nil {
|
||||
log.Warn("fail to load grant privilege entity", zap.String("key", k), zap.Any("type", operateType), zap.Error(err))
|
||||
if funcutil.IsRevoke(operateType) {
|
||||
return err
|
||||
}
|
||||
if !funcutil.IsKeyNotExistError(err) {
|
||||
return err
|
||||
}
|
||||
curGrantPrivilegeEntity.Entities = append(curGrantPrivilegeEntity.Entities, &milvuspb.GrantorEntity{
|
||||
Privilege: &milvuspb.PrivilegeEntity{Name: privilegeName},
|
||||
User: &milvuspb.UserEntity{Name: entity.Grantor.User.Name},
|
||||
})
|
||||
} else {
|
||||
err = proto.Unmarshal([]byte(v), curGrantPrivilegeEntity)
|
||||
if err != nil {
|
||||
log.Error("fail to unmarshal the grant privilege entity", zap.String("key", k), zap.Any("type", operateType), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
isExisted := false
|
||||
dropIndex := -1
|
||||
|
||||
for entityIndex, grantorEntity := range curGrantPrivilegeEntity.Entities {
|
||||
if grantorEntity.Privilege.Name == privilegeName {
|
||||
isExisted = true
|
||||
dropIndex = entityIndex
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isExisted && funcutil.IsGrant(operateType) {
|
||||
curGrantPrivilegeEntity.Entities = append(curGrantPrivilegeEntity.Entities, &milvuspb.GrantorEntity{
|
||||
Privilege: &milvuspb.PrivilegeEntity{Name: privilegeName},
|
||||
User: &milvuspb.UserEntity{Name: entity.Grantor.User.Name},
|
||||
})
|
||||
} else if isExisted && funcutil.IsGrant(operateType) {
|
||||
return nil
|
||||
} else if !isExisted && funcutil.IsRevoke(operateType) {
|
||||
return fmt.Errorf("fail to revoke the privilege because the privilege isn't granted for the role, key: /%s", k)
|
||||
} else if isExisted && funcutil.IsRevoke(operateType) {
|
||||
curGrantPrivilegeEntity.Entities = append(curGrantPrivilegeEntity.Entities[:dropIndex], curGrantPrivilegeEntity.Entities[dropIndex+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
if funcutil.IsRevoke(operateType) && len(curGrantPrivilegeEntity.Entities) == 0 {
|
||||
err = kc.Txn.Remove(k)
|
||||
if err != nil {
|
||||
log.Error("fail to remove the grant privilege entity", zap.String("key", k), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
saveValue, err := proto.Marshal(curGrantPrivilegeEntity)
|
||||
if err != nil {
|
||||
log.Error("fail to marshal the grant privilege entity", zap.String("key", k), zap.Any("type", operateType), zap.Error(err))
|
||||
return fmt.Errorf("fail to marshal grant info, key:%s, err:%w", k, err)
|
||||
}
|
||||
err = kc.Txn.Save(k, string(saveValue))
|
||||
if err != nil {
|
||||
log.Error("fail to save the grant privilege entity", zap.String("key", k), zap.Any("type", operateType), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) SelectGrant(ctx context.Context, tenant string, entity *milvuspb.GrantEntity) ([]*milvuspb.GrantEntity, error) {
|
||||
var entities []*milvuspb.GrantEntity
|
||||
|
||||
var k string
|
||||
appendGrantEntity := func(v string, object string, objectName string) error {
|
||||
grantPrivilegeEntity := &milvuspb.GrantPrivilegeEntity{}
|
||||
err := proto.Unmarshal([]byte(v), grantPrivilegeEntity)
|
||||
if err != nil {
|
||||
log.Error("fail to unmarshal the grant privilege entity", zap.String("key", k), zap.Error(err))
|
||||
return err
|
||||
}
|
||||
for _, grantorEntity := range grantPrivilegeEntity.Entities {
|
||||
entities = append(entities, &milvuspb.GrantEntity{
|
||||
Role: &milvuspb.RoleEntity{Name: entity.Role.Name},
|
||||
Object: &milvuspb.ObjectEntity{Name: object},
|
||||
ObjectName: objectName,
|
||||
Grantor: &milvuspb.GrantorEntity{
|
||||
User: &milvuspb.UserEntity{Name: grantorEntity.User.Name},
|
||||
Privilege: &milvuspb.PrivilegeEntity{Name: util.PrivilegeNameForAPI(grantorEntity.Privilege.Name)},
|
||||
},
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if !funcutil.IsEmptyString(entity.ObjectName) && entity.Object != nil && !funcutil.IsEmptyString(entity.Object.Name) {
|
||||
k = funcutil.HandleTenantForEtcdKey(GranteePrefix, tenant, fmt.Sprintf("%s/%s/%s", entity.Role.Name, entity.Object.Name, entity.ObjectName))
|
||||
v, err := kc.Txn.Load(k)
|
||||
if err != nil {
|
||||
log.Error("fail to load the grant privilege entity", zap.String("key", k), zap.Error(err))
|
||||
return entities, err
|
||||
}
|
||||
err = appendGrantEntity(v, entity.Object.Name, entity.ObjectName)
|
||||
if err != nil {
|
||||
return entities, err
|
||||
}
|
||||
} else {
|
||||
k = funcutil.HandleTenantForEtcdKey(GranteePrefix, tenant, entity.Role.Name)
|
||||
keys, values, err := kc.Txn.LoadWithPrefix(k)
|
||||
if err != nil {
|
||||
log.Error("fail to load grant privilege entities", zap.String("key", k), zap.Error(err))
|
||||
return entities, err
|
||||
}
|
||||
for i, key := range keys {
|
||||
grantInfos := typeutil.AfterN(key, k+"/", "/")
|
||||
if len(grantInfos) != 2 {
|
||||
log.Warn("invalid grant key", zap.String("key", key))
|
||||
continue
|
||||
}
|
||||
err = appendGrantEntity(values[i], grantInfos[0], grantInfos[1])
|
||||
if err != nil {
|
||||
return entities, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entities, nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) ListPolicy(ctx context.Context, tenant string) ([]string, error) {
|
||||
var grantInfoStrs []string
|
||||
k := funcutil.HandleTenantForEtcdKey(GranteePrefix, tenant, "")
|
||||
keys, values, err := kc.Txn.LoadWithPrefix(k)
|
||||
if err != nil {
|
||||
log.Error("fail to load all grant privilege entities", zap.String("key", k), zap.Error(err))
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
for i, key := range keys {
|
||||
grantInfos := typeutil.AfterN(key, k+"/", "/")
|
||||
if len(grantInfos) != 3 {
|
||||
log.Warn("invalid grant key", zap.String("key", key))
|
||||
continue
|
||||
}
|
||||
grantPrivilegeEntity := &milvuspb.GrantPrivilegeEntity{}
|
||||
err = proto.Unmarshal([]byte(values[i]), grantPrivilegeEntity)
|
||||
if err != nil {
|
||||
log.Warn("fail to unmarshal the grant privilege entity", zap.String("key", key), zap.Error(err))
|
||||
continue
|
||||
}
|
||||
for _, grantorInfo := range grantPrivilegeEntity.Entities {
|
||||
grantInfoStrs = append(grantInfoStrs,
|
||||
funcutil.PolicyForPrivilege(grantInfos[0], grantInfos[1], grantInfos[2], grantorInfo.Privilege.Name))
|
||||
}
|
||||
}
|
||||
return grantInfoStrs, nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) ListUserRole(ctx context.Context, tenant string) ([]string, error) {
|
||||
var userRoles []string
|
||||
k := funcutil.HandleTenantForEtcdKey(RoleMappingPrefix, tenant, "")
|
||||
keys, _, err := kc.Txn.LoadWithPrefix(k)
|
||||
if err != nil {
|
||||
log.Error("fail to load all user-role mappings", zap.String("key", k), zap.Error(err))
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
userRolesInfos := typeutil.AfterN(key, k+"/", "/")
|
||||
if len(userRolesInfos) != 2 {
|
||||
log.Warn("invalid user-role key", zap.String("key", key))
|
||||
continue
|
||||
}
|
||||
userRoles = append(userRoles, funcutil.EncodeUserRoleCache(userRolesInfos[0], userRolesInfos[1]))
|
||||
}
|
||||
return userRoles, nil
|
||||
}
|
||||
|
||||
func (kc *Catalog) Close() {
|
||||
// do nothing
|
||||
}
|
||||
|
|
|
@ -16,9 +16,22 @@ const (
|
|||
// CollectionAliasMetaPrefix prefix for collection alias meta
|
||||
CollectionAliasMetaPrefix = ComponentPrefix + "/collection-alias"
|
||||
|
||||
// CommonCredentialPrefix subpath for common credential
|
||||
/* #nosec G101 */
|
||||
CommonCredentialPrefix = "/credential"
|
||||
|
||||
// UserSubPrefix subpath for credential user
|
||||
UserSubPrefix = "/credential/users"
|
||||
UserSubPrefix = CommonCredentialPrefix + "/users"
|
||||
|
||||
// CredentialPrefix prefix for credential user
|
||||
CredentialPrefix = ComponentPrefix + UserSubPrefix
|
||||
|
||||
// RolePrefix prefix for role
|
||||
RolePrefix = ComponentPrefix + CommonCredentialPrefix + "/roles"
|
||||
|
||||
// RoleMappingPrefix prefix for mapping between user and role
|
||||
RoleMappingPrefix = ComponentPrefix + CommonCredentialPrefix + "/user-role-mapping"
|
||||
|
||||
// GranteePrefix prefix for mapping among user or role, resource type, resource name
|
||||
GranteePrefix = ComponentPrefix + CommonCredentialPrefix + "/grantee-privileges"
|
||||
)
|
||||
|
|
|
@ -72,6 +72,7 @@ const (
|
|||
queryTypeLabelName = "query_type"
|
||||
segmentStateLabelName = "segment_state"
|
||||
usernameLabelName = "username"
|
||||
rolenameLabelName = "role_name"
|
||||
cacheNameLabelName = "cache_name"
|
||||
cacheStateLabelName = "cache_state"
|
||||
)
|
||||
|
|
|
@ -15,8 +15,6 @@ var (
|
|||
Help: "number of proxy nodes managered by rootcoord",
|
||||
}, []string{})
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// for time tick
|
||||
|
||||
|
@ -126,6 +124,15 @@ var (
|
|||
Name: "credential_num",
|
||||
Help: "number of credentials",
|
||||
})
|
||||
|
||||
// RootCoordNumOfRoles counts the number of credentials.
|
||||
RootCoordNumOfRoles = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: milvusNamespace,
|
||||
Subsystem: typeutil.RootCoordRole,
|
||||
Name: "num_of_roles",
|
||||
Help: "The number of roles",
|
||||
})
|
||||
)
|
||||
|
||||
//RegisterRootCoord registers RootCoord metrics
|
||||
|
@ -154,4 +161,6 @@ func RegisterRootCoord(registry *prometheus.Registry) {
|
|||
|
||||
// for credential
|
||||
registry.MustRegister(RootCoordNumOfCredentials)
|
||||
|
||||
registry.MustRegister(RootCoordNumOfRoles)
|
||||
}
|
||||
|
|
|
@ -273,27 +273,28 @@ enum ImportState {
|
|||
ImportAllocSegment = 10;
|
||||
}
|
||||
|
||||
enum ResourceType {
|
||||
enum ObjectType {
|
||||
Collection = 0;
|
||||
Global = 1;
|
||||
}
|
||||
|
||||
enum ResourcePrivilege {
|
||||
enum ObjectPrivilege {
|
||||
PrivilegeAll = 0;
|
||||
PrivilegeCreate = 1;
|
||||
PrivilegeDrop = 2;
|
||||
PrivilegeAlter = 3;
|
||||
PrivilegeRead = 4;
|
||||
PrivilegeCreateCollection = 1;
|
||||
PrivilegeDropCollection = 2;
|
||||
PrivilegeDescribeCollection = 3;
|
||||
PrivilegeShowCollections = 4;
|
||||
PrivilegeLoad = 5;
|
||||
PrivilegeRelease = 6;
|
||||
PrivilegeCompact = 7;
|
||||
PrivilegeCompaction = 7;
|
||||
PrivilegeInsert = 8;
|
||||
PrivilegeDelete = 9;
|
||||
}
|
||||
|
||||
message PrivilegeExt {
|
||||
ResourceType resource_type = 1;
|
||||
ResourcePrivilege resource_privilege = 2;
|
||||
int32 resource_name_index = 3;
|
||||
ObjectType object_type = 1;
|
||||
ObjectPrivilege object_privilege = 2;
|
||||
int32 object_name_index = 3;
|
||||
}
|
||||
|
||||
extend google.protobuf.MessageOptions {
|
||||
|
|
|
@ -680,74 +680,77 @@ func (ImportState) EnumDescriptor() ([]byte, []int) {
|
|||
return fileDescriptor_555bd8c177793206, []int{8}
|
||||
}
|
||||
|
||||
type ResourceType int32
|
||||
type ObjectType int32
|
||||
|
||||
const (
|
||||
ResourceType_Collection ResourceType = 0
|
||||
ObjectType_Collection ObjectType = 0
|
||||
ObjectType_Global ObjectType = 1
|
||||
)
|
||||
|
||||
var ResourceType_name = map[int32]string{
|
||||
var ObjectType_name = map[int32]string{
|
||||
0: "Collection",
|
||||
1: "Global",
|
||||
}
|
||||
|
||||
var ResourceType_value = map[string]int32{
|
||||
var ObjectType_value = map[string]int32{
|
||||
"Collection": 0,
|
||||
"Global": 1,
|
||||
}
|
||||
|
||||
func (x ResourceType) String() string {
|
||||
return proto.EnumName(ResourceType_name, int32(x))
|
||||
func (x ObjectType) String() string {
|
||||
return proto.EnumName(ObjectType_name, int32(x))
|
||||
}
|
||||
|
||||
func (ResourceType) EnumDescriptor() ([]byte, []int) {
|
||||
func (ObjectType) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_555bd8c177793206, []int{9}
|
||||
}
|
||||
|
||||
type ResourcePrivilege int32
|
||||
type ObjectPrivilege int32
|
||||
|
||||
const (
|
||||
ResourcePrivilege_PrivilegeAll ResourcePrivilege = 0
|
||||
ResourcePrivilege_PrivilegeCreate ResourcePrivilege = 1
|
||||
ResourcePrivilege_PrivilegeDrop ResourcePrivilege = 2
|
||||
ResourcePrivilege_PrivilegeAlter ResourcePrivilege = 3
|
||||
ResourcePrivilege_PrivilegeRead ResourcePrivilege = 4
|
||||
ResourcePrivilege_PrivilegeLoad ResourcePrivilege = 5
|
||||
ResourcePrivilege_PrivilegeRelease ResourcePrivilege = 6
|
||||
ResourcePrivilege_PrivilegeCompact ResourcePrivilege = 7
|
||||
ResourcePrivilege_PrivilegeInsert ResourcePrivilege = 8
|
||||
ResourcePrivilege_PrivilegeDelete ResourcePrivilege = 9
|
||||
ObjectPrivilege_PrivilegeAll ObjectPrivilege = 0
|
||||
ObjectPrivilege_PrivilegeCreateCollection ObjectPrivilege = 1
|
||||
ObjectPrivilege_PrivilegeDropCollection ObjectPrivilege = 2
|
||||
ObjectPrivilege_PrivilegeDescribeCollection ObjectPrivilege = 3
|
||||
ObjectPrivilege_PrivilegeShowCollections ObjectPrivilege = 4
|
||||
ObjectPrivilege_PrivilegeLoad ObjectPrivilege = 5
|
||||
ObjectPrivilege_PrivilegeRelease ObjectPrivilege = 6
|
||||
ObjectPrivilege_PrivilegeCompaction ObjectPrivilege = 7
|
||||
ObjectPrivilege_PrivilegeInsert ObjectPrivilege = 8
|
||||
ObjectPrivilege_PrivilegeDelete ObjectPrivilege = 9
|
||||
)
|
||||
|
||||
var ResourcePrivilege_name = map[int32]string{
|
||||
var ObjectPrivilege_name = map[int32]string{
|
||||
0: "PrivilegeAll",
|
||||
1: "PrivilegeCreate",
|
||||
2: "PrivilegeDrop",
|
||||
3: "PrivilegeAlter",
|
||||
4: "PrivilegeRead",
|
||||
1: "PrivilegeCreateCollection",
|
||||
2: "PrivilegeDropCollection",
|
||||
3: "PrivilegeDescribeCollection",
|
||||
4: "PrivilegeShowCollections",
|
||||
5: "PrivilegeLoad",
|
||||
6: "PrivilegeRelease",
|
||||
7: "PrivilegeCompact",
|
||||
7: "PrivilegeCompaction",
|
||||
8: "PrivilegeInsert",
|
||||
9: "PrivilegeDelete",
|
||||
}
|
||||
|
||||
var ResourcePrivilege_value = map[string]int32{
|
||||
"PrivilegeAll": 0,
|
||||
"PrivilegeCreate": 1,
|
||||
"PrivilegeDrop": 2,
|
||||
"PrivilegeAlter": 3,
|
||||
"PrivilegeRead": 4,
|
||||
"PrivilegeLoad": 5,
|
||||
"PrivilegeRelease": 6,
|
||||
"PrivilegeCompact": 7,
|
||||
"PrivilegeInsert": 8,
|
||||
"PrivilegeDelete": 9,
|
||||
var ObjectPrivilege_value = map[string]int32{
|
||||
"PrivilegeAll": 0,
|
||||
"PrivilegeCreateCollection": 1,
|
||||
"PrivilegeDropCollection": 2,
|
||||
"PrivilegeDescribeCollection": 3,
|
||||
"PrivilegeShowCollections": 4,
|
||||
"PrivilegeLoad": 5,
|
||||
"PrivilegeRelease": 6,
|
||||
"PrivilegeCompaction": 7,
|
||||
"PrivilegeInsert": 8,
|
||||
"PrivilegeDelete": 9,
|
||||
}
|
||||
|
||||
func (x ResourcePrivilege) String() string {
|
||||
return proto.EnumName(ResourcePrivilege_name, int32(x))
|
||||
func (x ObjectPrivilege) String() string {
|
||||
return proto.EnumName(ObjectPrivilege_name, int32(x))
|
||||
}
|
||||
|
||||
func (ResourcePrivilege) EnumDescriptor() ([]byte, []int) {
|
||||
func (ObjectPrivilege) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_555bd8c177793206, []int{10}
|
||||
}
|
||||
|
||||
|
@ -1225,12 +1228,12 @@ func (m *DMLMsgHeader) GetShardName() string {
|
|||
}
|
||||
|
||||
type PrivilegeExt struct {
|
||||
ResourceType ResourceType `protobuf:"varint,1,opt,name=resource_type,json=resourceType,proto3,enum=milvus.proto.common.ResourceType" json:"resource_type,omitempty"`
|
||||
ResourcePrivilege ResourcePrivilege `protobuf:"varint,2,opt,name=resource_privilege,json=resourcePrivilege,proto3,enum=milvus.proto.common.ResourcePrivilege" json:"resource_privilege,omitempty"`
|
||||
ResourceNameIndex int32 `protobuf:"varint,3,opt,name=resource_name_index,json=resourceNameIndex,proto3" json:"resource_name_index,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
ObjectType ObjectType `protobuf:"varint,1,opt,name=object_type,json=objectType,proto3,enum=milvus.proto.common.ObjectType" json:"object_type,omitempty"`
|
||||
ObjectPrivilege ObjectPrivilege `protobuf:"varint,2,opt,name=object_privilege,json=objectPrivilege,proto3,enum=milvus.proto.common.ObjectPrivilege" json:"object_privilege,omitempty"`
|
||||
ObjectNameIndex int32 `protobuf:"varint,3,opt,name=object_name_index,json=objectNameIndex,proto3" json:"object_name_index,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *PrivilegeExt) Reset() { *m = PrivilegeExt{} }
|
||||
|
@ -1258,23 +1261,23 @@ func (m *PrivilegeExt) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_PrivilegeExt proto.InternalMessageInfo
|
||||
|
||||
func (m *PrivilegeExt) GetResourceType() ResourceType {
|
||||
func (m *PrivilegeExt) GetObjectType() ObjectType {
|
||||
if m != nil {
|
||||
return m.ResourceType
|
||||
return m.ObjectType
|
||||
}
|
||||
return ResourceType_Collection
|
||||
return ObjectType_Collection
|
||||
}
|
||||
|
||||
func (m *PrivilegeExt) GetResourcePrivilege() ResourcePrivilege {
|
||||
func (m *PrivilegeExt) GetObjectPrivilege() ObjectPrivilege {
|
||||
if m != nil {
|
||||
return m.ResourcePrivilege
|
||||
return m.ObjectPrivilege
|
||||
}
|
||||
return ResourcePrivilege_PrivilegeAll
|
||||
return ObjectPrivilege_PrivilegeAll
|
||||
}
|
||||
|
||||
func (m *PrivilegeExt) GetResourceNameIndex() int32 {
|
||||
func (m *PrivilegeExt) GetObjectNameIndex() int32 {
|
||||
if m != nil {
|
||||
return m.ResourceNameIndex
|
||||
return m.ObjectNameIndex
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
@ -1298,8 +1301,8 @@ func init() {
|
|||
proto.RegisterEnum("milvus.proto.common.CompactionState", CompactionState_name, CompactionState_value)
|
||||
proto.RegisterEnum("milvus.proto.common.ConsistencyLevel", ConsistencyLevel_name, ConsistencyLevel_value)
|
||||
proto.RegisterEnum("milvus.proto.common.ImportState", ImportState_name, ImportState_value)
|
||||
proto.RegisterEnum("milvus.proto.common.ResourceType", ResourceType_name, ResourceType_value)
|
||||
proto.RegisterEnum("milvus.proto.common.ResourcePrivilege", ResourcePrivilege_name, ResourcePrivilege_value)
|
||||
proto.RegisterEnum("milvus.proto.common.ObjectType", ObjectType_name, ObjectType_value)
|
||||
proto.RegisterEnum("milvus.proto.common.ObjectPrivilege", ObjectPrivilege_name, ObjectPrivilege_value)
|
||||
proto.RegisterType((*Status)(nil), "milvus.proto.common.Status")
|
||||
proto.RegisterType((*KeyValuePair)(nil), "milvus.proto.common.KeyValuePair")
|
||||
proto.RegisterType((*KeyDataPair)(nil), "milvus.proto.common.KeyDataPair")
|
||||
|
@ -1317,150 +1320,152 @@ func init() {
|
|||
func init() { proto.RegisterFile("common.proto", fileDescriptor_555bd8c177793206) }
|
||||
|
||||
var fileDescriptor_555bd8c177793206 = []byte{
|
||||
// 2318 bytes of a gzipped FileDescriptorProto
|
||||
// 2342 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x49, 0x73, 0x24, 0x47,
|
||||
0x15, 0x56, 0xa9, 0x7b, 0xd4, 0xea, 0xec, 0x92, 0x94, 0x93, 0x9a, 0xd1, 0xc8, 0xe3, 0xb1, 0x2d,
|
||||
0x37, 0xb6, 0x11, 0x02, 0x4b, 0x60, 0x47, 0x00, 0x41, 0x84, 0x89, 0x90, 0xba, 0x25, 0x4d, 0x87,
|
||||
0xb5, 0x34, 0x25, 0xc9, 0x76, 0x10, 0x01, 0x8a, 0x54, 0xd5, 0x53, 0xab, 0x3c, 0x55, 0x95, 0x45,
|
||||
0x66, 0xb6, 0x46, 0xcd, 0xc9, 0x98, 0x3f, 0x00, 0xe6, 0x0f, 0xf0, 0x03, 0xd8, 0x17, 0xc3, 0x91,
|
||||
0x1d, 0x9b, 0xed, 0xc2, 0x85, 0xcd, 0xc0, 0x11, 0xee, 0xac, 0x5e, 0x89, 0x97, 0x59, 0x9b, 0x64,
|
||||
0x19, 0x0e, 0xdc, 0x2a, 0xbf, 0xf7, 0xf2, 0x6d, 0xf9, 0x96, 0xcc, 0x22, 0xae, 0x2f, 0xe2, 0x58,
|
||||
0x24, 0xcb, 0xa9, 0x14, 0x5a, 0xb0, 0xd9, 0x38, 0x8c, 0x4e, 0x87, 0xca, 0xae, 0x96, 0x2d, 0xe9,
|
||||
0xe6, 0xc2, 0x40, 0x88, 0x41, 0x04, 0x2b, 0x06, 0x3c, 0x1a, 0x1e, 0xaf, 0x04, 0xa0, 0x7c, 0x19,
|
||||
0xa6, 0x5a, 0x48, 0xcb, 0xd8, 0x3e, 0x24, 0x13, 0x7b, 0x9a, 0xeb, 0xa1, 0x62, 0x4f, 0x10, 0x02,
|
||||
0x52, 0x0a, 0x79, 0xe8, 0x8b, 0x00, 0xe6, 0x9d, 0x05, 0x67, 0x71, 0xfa, 0xb1, 0xfb, 0x97, 0x2f,
|
||||
0x91, 0xba, 0xbc, 0x8e, 0x6c, 0x1d, 0x11, 0x80, 0xd7, 0x84, 0xfc, 0x93, 0xcd, 0x91, 0x09, 0x09,
|
||||
0x5c, 0x89, 0x64, 0x7e, 0x7c, 0xc1, 0x59, 0x6c, 0x7a, 0xd9, 0xaa, 0xfd, 0x41, 0xe2, 0x3e, 0x09,
|
||||
0xa3, 0xa7, 0x78, 0x34, 0x84, 0x3e, 0x0f, 0x25, 0xa3, 0xa4, 0x76, 0x07, 0x46, 0x46, 0x7e, 0xd3,
|
||||
0xc3, 0x4f, 0x76, 0x8d, 0x5c, 0x39, 0x45, 0x72, 0xb6, 0xd1, 0x2e, 0xda, 0x8f, 0x93, 0xd6, 0x93,
|
||||
0x30, 0xea, 0x72, 0xcd, 0xdf, 0x61, 0x1b, 0x23, 0xf5, 0x80, 0x6b, 0x6e, 0x76, 0xb9, 0x9e, 0xf9,
|
||||
0x6e, 0xdf, 0x22, 0xf5, 0xb5, 0x48, 0x1c, 0x95, 0x22, 0x1d, 0x43, 0xcc, 0x44, 0x9e, 0x12, 0xda,
|
||||
0x8f, 0xb8, 0x0f, 0x27, 0x22, 0x0a, 0x40, 0x1a, 0x93, 0x50, 0xae, 0xe6, 0x83, 0x5c, 0xae, 0xe6,
|
||||
0x03, 0xf6, 0x61, 0x52, 0xd7, 0xa3, 0xd4, 0x5a, 0x33, 0xfd, 0xd8, 0x43, 0x97, 0x46, 0xa0, 0x22,
|
||||
0x66, 0x7f, 0x94, 0x82, 0x67, 0x76, 0x60, 0x08, 0x8c, 0x22, 0x35, 0x5f, 0x5b, 0xa8, 0x2d, 0xba,
|
||||
0x5e, 0xb6, 0x6a, 0x7f, 0xe2, 0x9c, 0xde, 0x4d, 0x29, 0x86, 0x29, 0xeb, 0x11, 0x37, 0x2d, 0x31,
|
||||
0x35, 0xef, 0x2c, 0xd4, 0x16, 0x5b, 0x8f, 0x3d, 0xfc, 0xbf, 0xb4, 0x19, 0xa3, 0xbd, 0x73, 0x5b,
|
||||
0xdb, 0x8f, 0x92, 0xc6, 0x6a, 0x10, 0x48, 0x50, 0x8a, 0x4d, 0x93, 0xf1, 0x30, 0xcd, 0x9c, 0x19,
|
||||
0x0f, 0x53, 0x8c, 0x51, 0x2a, 0xa4, 0x36, 0xbe, 0xd4, 0x3c, 0xf3, 0xdd, 0x7e, 0xc1, 0x21, 0x8d,
|
||||
0x6d, 0x35, 0x58, 0xe3, 0x0a, 0xd8, 0x87, 0xc8, 0x64, 0xac, 0x06, 0x87, 0xc6, 0x5f, 0x7b, 0xe2,
|
||||
0xb7, 0x2e, 0xb5, 0x60, 0x5b, 0x0d, 0x8c, 0x9f, 0x8d, 0xd8, 0x7e, 0x60, 0x80, 0x63, 0x35, 0xe8,
|
||||
0x75, 0x33, 0xc9, 0x76, 0xc1, 0x6e, 0x91, 0xa6, 0x0e, 0x63, 0x50, 0x9a, 0xc7, 0xe9, 0x7c, 0x6d,
|
||||
0xc1, 0x59, 0xac, 0x7b, 0x25, 0xc0, 0x6e, 0x92, 0x49, 0x25, 0x86, 0xd2, 0x87, 0x5e, 0x77, 0xbe,
|
||||
0x6e, 0xb6, 0x15, 0xeb, 0xf6, 0x13, 0xa4, 0xb9, 0xad, 0x06, 0xb7, 0x81, 0x07, 0x20, 0xd9, 0xfb,
|
||||
0x49, 0xfd, 0x88, 0x2b, 0x6b, 0x51, 0xeb, 0x9d, 0x2d, 0x42, 0x0f, 0x3c, 0xc3, 0xd9, 0xfe, 0x24,
|
||||
0x71, 0xbb, 0xdb, 0x5b, 0xff, 0x87, 0x04, 0x34, 0x5d, 0x9d, 0x70, 0x19, 0xec, 0xf0, 0x38, 0x4f,
|
||||
0xc4, 0x12, 0x68, 0xbf, 0xe2, 0x10, 0xb7, 0x2f, 0xc3, 0xd3, 0x30, 0x82, 0x01, 0xac, 0x9f, 0x69,
|
||||
0xb6, 0x41, 0xa6, 0x24, 0x58, 0xeb, 0xab, 0xd1, 0x7b, 0xf0, 0x52, 0x4d, 0x5e, 0xc6, 0x69, 0x42,
|
||||
0xe8, 0xca, 0xca, 0x8a, 0x1d, 0x10, 0x56, 0xc8, 0x49, 0x73, 0x05, 0x59, 0xea, 0x3d, 0xf2, 0x5f,
|
||||
0x85, 0x15, 0xe6, 0x78, 0x57, 0xe5, 0x45, 0x88, 0x2d, 0x93, 0xd9, 0x42, 0x6c, 0xc2, 0x63, 0x38,
|
||||
0x0c, 0x93, 0x00, 0xce, 0xcc, 0x91, 0x5c, 0x29, 0xf9, 0xd1, 0xb5, 0x1e, 0x12, 0x96, 0x7e, 0x3d,
|
||||
0x49, 0x9a, 0x45, 0x55, 0xb3, 0x16, 0x69, 0xec, 0x0d, 0x7d, 0x1f, 0x94, 0xa2, 0x63, 0x6c, 0x96,
|
||||
0xcc, 0x1c, 0x24, 0x70, 0x96, 0x82, 0xaf, 0x21, 0x30, 0x3c, 0xd4, 0x61, 0x57, 0xc9, 0x54, 0x47,
|
||||
0x24, 0x09, 0xf8, 0x7a, 0x83, 0x87, 0x11, 0x04, 0x74, 0x9c, 0x5d, 0x23, 0xb4, 0x0f, 0x32, 0x0e,
|
||||
0x95, 0x0a, 0x45, 0xd2, 0x85, 0x24, 0x84, 0x80, 0xd6, 0xd8, 0x0d, 0x32, 0xdb, 0x11, 0x51, 0x04,
|
||||
0xbe, 0x0e, 0x45, 0xb2, 0x23, 0xf4, 0xfa, 0x59, 0xa8, 0xb4, 0xa2, 0x75, 0x14, 0xdb, 0x8b, 0x22,
|
||||
0x18, 0xf0, 0x68, 0x55, 0x0e, 0x86, 0x31, 0x24, 0x9a, 0x5e, 0x41, 0x19, 0x19, 0xd8, 0x0d, 0x63,
|
||||
0x48, 0x50, 0x12, 0x6d, 0x54, 0x50, 0x63, 0x2c, 0xc6, 0x8d, 0x4e, 0xb2, 0x7b, 0xc8, 0xf5, 0x0c,
|
||||
0xad, 0x28, 0xe0, 0x31, 0xd0, 0x26, 0x9b, 0x21, 0xad, 0x8c, 0xb4, 0xbf, 0xdb, 0x7f, 0x92, 0x92,
|
||||
0x8a, 0x04, 0x4f, 0xdc, 0xf5, 0xc0, 0x17, 0x32, 0xa0, 0xad, 0x8a, 0x09, 0x4f, 0x81, 0xaf, 0x85,
|
||||
0xec, 0x75, 0xa9, 0x8b, 0x06, 0x67, 0xe0, 0x1e, 0x70, 0xe9, 0x9f, 0x78, 0xa0, 0x86, 0x91, 0xa6,
|
||||
0x53, 0x8c, 0x12, 0x77, 0x23, 0x8c, 0x60, 0x47, 0xe8, 0x0d, 0x31, 0x4c, 0x02, 0x3a, 0xcd, 0xa6,
|
||||
0x09, 0xd9, 0x06, 0xcd, 0xb3, 0x08, 0xcc, 0xa0, 0xda, 0x0e, 0xf7, 0x4f, 0x20, 0x03, 0x28, 0x9b,
|
||||
0x23, 0xac, 0xc3, 0x93, 0x44, 0xe8, 0x8e, 0x04, 0xae, 0x61, 0xc3, 0xd4, 0x2b, 0xbd, 0x8a, 0xe6,
|
||||
0x9c, 0xc3, 0xc3, 0x08, 0x28, 0x2b, 0xb9, 0xbb, 0x10, 0x41, 0xc1, 0x3d, 0x5b, 0x72, 0x67, 0x38,
|
||||
0x72, 0x5f, 0x43, 0xe3, 0xd7, 0x86, 0x61, 0x14, 0x98, 0x90, 0xd8, 0x63, 0xb9, 0x8e, 0x36, 0x66,
|
||||
0xc6, 0xef, 0x6c, 0xf5, 0xf6, 0xf6, 0xe9, 0x1c, 0xbb, 0x4e, 0xae, 0x66, 0xc8, 0x36, 0x68, 0x19,
|
||||
0xfa, 0x26, 0x78, 0x37, 0xd0, 0xd4, 0xdd, 0xa1, 0xde, 0x3d, 0xde, 0x86, 0x58, 0xc8, 0x11, 0x9d,
|
||||
0xc7, 0x03, 0x35, 0x92, 0xf2, 0x23, 0xa2, 0xf7, 0xa0, 0x86, 0xf5, 0x38, 0xd5, 0xa3, 0x32, 0xbc,
|
||||
0xf4, 0x26, 0xbb, 0x97, 0xdc, 0x38, 0x48, 0x03, 0xae, 0xa1, 0x17, 0x63, 0x33, 0xd9, 0xe7, 0xea,
|
||||
0x0e, 0xba, 0x3b, 0x94, 0x40, 0xef, 0x65, 0x37, 0xc9, 0xdc, 0xf9, 0xb3, 0x28, 0x82, 0x75, 0x0b,
|
||||
0x37, 0x5a, 0x6f, 0x3b, 0x12, 0x02, 0x48, 0x74, 0xc8, 0xa3, 0x7c, 0xe3, 0x7d, 0xa5, 0xd4, 0xb7,
|
||||
0x13, 0xef, 0x47, 0xa2, 0xf5, 0xfc, 0xed, 0xc4, 0x07, 0xd8, 0x3c, 0xb9, 0xb6, 0x09, 0xfa, 0xed,
|
||||
0x94, 0x05, 0xa4, 0x6c, 0x85, 0xca, 0x90, 0x0e, 0x14, 0x48, 0x95, 0x53, 0x1e, 0x64, 0x8c, 0x4c,
|
||||
0x6f, 0x82, 0x46, 0x30, 0xc7, 0xda, 0x18, 0x27, 0x6b, 0x9e, 0x27, 0x22, 0xc8, 0xe1, 0x77, 0x61,
|
||||
0x0c, 0xba, 0x52, 0xa4, 0x55, 0xf0, 0x21, 0x74, 0x73, 0x37, 0x05, 0xc9, 0x35, 0xa0, 0x8c, 0x2a,
|
||||
0xed, 0x61, 0x94, 0xb3, 0x07, 0x18, 0x81, 0x2a, 0xfc, 0x48, 0x09, 0x57, 0xb5, 0xbe, 0x1b, 0x73,
|
||||
0x38, 0xe3, 0xce, 0x2a, 0x32, 0x27, 0x2d, 0xa2, 0xd7, 0x99, 0x92, 0xa2, 0xaa, 0x73, 0xe2, 0x7b,
|
||||
0x30, 0x55, 0xec, 0xbe, 0x4d, 0xc9, 0x13, 0x9d, 0xe3, 0x4b, 0xec, 0x41, 0x72, 0x9f, 0x07, 0xc7,
|
||||
0x12, 0xd4, 0x49, 0x5f, 0x44, 0xa1, 0x3f, 0xea, 0x25, 0xc7, 0xa2, 0x48, 0x49, 0x64, 0x79, 0x2f,
|
||||
0x5a, 0x82, 0x61, 0xb1, 0xf4, 0x1c, 0x7e, 0x1f, 0xc6, 0x64, 0x47, 0xe8, 0x3d, 0x6c, 0x78, 0x5b,
|
||||
0xa6, 0x85, 0xd2, 0x47, 0x51, 0xcb, 0x8e, 0xf0, 0x20, 0x8d, 0x42, 0x9f, 0xaf, 0x9e, 0xf2, 0x30,
|
||||
0xe2, 0x47, 0x11, 0xd0, 0x65, 0x0c, 0xca, 0x1e, 0x0c, 0xb0, 0x64, 0x8b, 0xf3, 0x5d, 0x61, 0x8c,
|
||||
0x4c, 0x75, 0xbb, 0x1e, 0x7c, 0x6a, 0x08, 0x4a, 0x7b, 0xdc, 0x07, 0xfa, 0x97, 0xc6, 0xd2, 0x33,
|
||||
0x84, 0x98, 0xa4, 0xc2, 0x0b, 0x06, 0xa0, 0x8a, 0x72, 0xb5, 0x23, 0x12, 0xa0, 0x63, 0xcc, 0x25,
|
||||
0x93, 0x07, 0x49, 0xa8, 0xd4, 0x10, 0x02, 0xea, 0x60, 0x41, 0xf5, 0x92, 0xbe, 0x14, 0x03, 0x9c,
|
||||
0x65, 0x74, 0x1c, 0xa9, 0x1b, 0x61, 0x12, 0xaa, 0x13, 0xd3, 0x4a, 0x08, 0x99, 0xc8, 0x2a, 0xab,
|
||||
0xbe, 0xf4, 0xbc, 0x43, 0xdc, 0xcc, 0x06, 0x2b, 0xfc, 0x1a, 0xa1, 0xd5, 0x75, 0x29, 0xbe, 0x48,
|
||||
0x68, 0x07, 0xdb, 0xda, 0xa6, 0x14, 0x77, 0xc3, 0x64, 0x40, 0xc7, 0x51, 0xda, 0x1e, 0xf0, 0xc8,
|
||||
0x48, 0x6e, 0x91, 0xc6, 0x46, 0x34, 0x34, 0x6a, 0xea, 0x46, 0x29, 0x2e, 0x90, 0xed, 0x0a, 0x92,
|
||||
0x30, 0x01, 0x52, 0x08, 0xe8, 0x04, 0x9b, 0x22, 0x4d, 0x9b, 0xf6, 0x48, 0x6b, 0x2c, 0x7d, 0x94,
|
||||
0xcc, 0x5c, 0xb8, 0x07, 0xb0, 0x49, 0x52, 0xcf, 0x54, 0x53, 0xe2, 0xae, 0x85, 0x09, 0x97, 0x23,
|
||||
0xdb, 0x5b, 0x68, 0x80, 0x35, 0xb7, 0x11, 0x09, 0xae, 0x33, 0x00, 0x96, 0x5e, 0x74, 0xcd, 0x20,
|
||||
0x36, 0x1b, 0xa7, 0x48, 0xf3, 0x20, 0x09, 0xe0, 0x38, 0x4c, 0x20, 0xa0, 0x63, 0xa6, 0xe6, 0x6d,
|
||||
0xb5, 0x94, 0xc5, 0x17, 0x60, 0x04, 0xd1, 0x98, 0x0a, 0x06, 0x58, 0xb8, 0xb7, 0xb9, 0xaa, 0x40,
|
||||
0xc7, 0x78, 0x6e, 0x5d, 0x73, 0xcd, 0x3b, 0xaa, 0x6e, 0x1f, 0x98, 0x73, 0x3b, 0x11, 0x77, 0x4b,
|
||||
0x4c, 0xd1, 0x13, 0xd4, 0xb4, 0x09, 0x7a, 0x6f, 0xa4, 0x34, 0xc4, 0x1d, 0x91, 0x1c, 0x87, 0x03,
|
||||
0x45, 0x43, 0xd4, 0xb4, 0x25, 0x78, 0x50, 0xd9, 0xfe, 0x2c, 0x66, 0x8e, 0x07, 0x11, 0x70, 0x55,
|
||||
0x95, 0x7a, 0xc7, 0x74, 0x3d, 0x63, 0xea, 0x6a, 0x14, 0x72, 0x45, 0x23, 0x74, 0x05, 0xad, 0xb4,
|
||||
0xcb, 0x18, 0x0f, 0x75, 0x35, 0xd2, 0x20, 0xed, 0x3a, 0x61, 0xd7, 0xc8, 0x8c, 0xe5, 0xef, 0x73,
|
||||
0xa9, 0x43, 0x23, 0xe4, 0x25, 0xc7, 0xa4, 0x8f, 0x14, 0x69, 0x89, 0xbd, 0x8c, 0x43, 0xc6, 0xbd,
|
||||
0xcd, 0x55, 0x09, 0xfd, 0xcc, 0x61, 0x73, 0xe4, 0x6a, 0xee, 0x5a, 0x89, 0xff, 0xdc, 0x61, 0xb3,
|
||||
0x64, 0x1a, 0x5d, 0x2b, 0x30, 0x45, 0x7f, 0x61, 0x40, 0x74, 0xa2, 0x02, 0xfe, 0xd2, 0x48, 0xc8,
|
||||
0xbc, 0xa8, 0xe0, 0xbf, 0x32, 0xca, 0x50, 0x42, 0x96, 0x44, 0x8a, 0xbe, 0xea, 0xa0, 0xa5, 0xb9,
|
||||
0xb2, 0x0c, 0xa6, 0xaf, 0x19, 0x46, 0x94, 0x5a, 0x30, 0xbe, 0x6e, 0x18, 0x33, 0x99, 0x05, 0xfa,
|
||||
0x86, 0x41, 0x6f, 0xf3, 0x24, 0x10, 0xc7, 0xc7, 0x05, 0xfa, 0xa6, 0xc3, 0xe6, 0xc9, 0x2c, 0x6e,
|
||||
0x5f, 0xe3, 0x11, 0x4f, 0xfc, 0x92, 0xff, 0x2d, 0x87, 0x5d, 0x27, 0xf4, 0x82, 0x3a, 0x45, 0x9f,
|
||||
0x1b, 0x67, 0x34, 0x8f, 0xaf, 0x29, 0x1e, 0xfa, 0xa5, 0x71, 0x13, 0xab, 0x8c, 0xd1, 0x62, 0x5f,
|
||||
0x1e, 0x67, 0xd3, 0x36, 0xe8, 0x76, 0xfd, 0x95, 0x71, 0xd6, 0x22, 0x13, 0xbd, 0x44, 0x81, 0xd4,
|
||||
0xf4, 0x73, 0x98, 0xdf, 0x13, 0xb6, 0x83, 0xd2, 0xcf, 0x63, 0x19, 0x5d, 0x31, 0xf9, 0x4d, 0x5f,
|
||||
0xc0, 0xe9, 0xcc, 0x3c, 0x50, 0x90, 0x04, 0x95, 0xda, 0x51, 0xf4, 0x0b, 0x66, 0x87, 0x1d, 0x7f,
|
||||
0xf4, 0x6f, 0x35, 0x13, 0x9a, 0xea, 0x2c, 0xfc, 0x7b, 0x0d, 0x4d, 0xd8, 0x04, 0x5d, 0x96, 0x33,
|
||||
0xfd, 0x47, 0x8d, 0xdd, 0x24, 0xd7, 0x73, 0xcc, 0x4c, 0xa6, 0xa2, 0x90, 0xff, 0x59, 0x63, 0xb7,
|
||||
0xc8, 0x0d, 0x6c, 0xd3, 0x45, 0xde, 0xe0, 0xa6, 0x50, 0xe9, 0xd0, 0x57, 0xf4, 0x5f, 0x35, 0x76,
|
||||
0x2f, 0x99, 0xdb, 0x04, 0x5d, 0x9c, 0x47, 0x85, 0xf8, 0xef, 0x1a, 0x9b, 0x22, 0x93, 0x1e, 0x8e,
|
||||
0x2e, 0x38, 0x05, 0xfa, 0x6a, 0x0d, 0x0f, 0x35, 0x5f, 0x66, 0xe6, 0xbc, 0x56, 0xc3, 0x50, 0x3f,
|
||||
0xcd, 0xb5, 0x7f, 0xd2, 0x8d, 0x3b, 0x27, 0x3c, 0x49, 0x20, 0x52, 0xf4, 0xf5, 0x1a, 0x06, 0xd4,
|
||||
0x83, 0x58, 0x9c, 0x42, 0x05, 0x7e, 0xc3, 0x38, 0x6d, 0x98, 0x3f, 0x36, 0x04, 0x39, 0x2a, 0x08,
|
||||
0x6f, 0xd6, 0xf0, 0x68, 0x2c, 0xff, 0x79, 0xca, 0x5b, 0x35, 0x76, 0x1f, 0x99, 0xb7, 0xcd, 0x22,
|
||||
0x3f, 0x18, 0x24, 0x0e, 0x00, 0xdb, 0x2b, 0x7d, 0xae, 0x5e, 0x48, 0xec, 0x42, 0xa4, 0x79, 0xb1,
|
||||
0xef, 0x33, 0x75, 0xb4, 0x0b, 0x8b, 0xab, 0xec, 0xaa, 0x8a, 0x3e, 0x5f, 0xc7, 0x13, 0xdd, 0x04,
|
||||
0x9d, 0x35, 0x56, 0x45, 0x3f, 0x6b, 0x90, 0x4c, 0xb2, 0x11, 0xf9, 0x9b, 0x3a, 0x9b, 0x21, 0xc4,
|
||||
0xd6, 0xa4, 0x01, 0x7e, 0x9b, 0x8b, 0xc2, 0xbb, 0xcb, 0x29, 0x48, 0xd3, 0xd8, 0xe9, 0xef, 0x0a,
|
||||
0x05, 0x95, 0xce, 0x47, 0x7f, 0x5f, 0xc7, 0x90, 0xed, 0x87, 0x31, 0xec, 0x87, 0xfe, 0x1d, 0xfa,
|
||||
0xb5, 0x26, 0x86, 0xcc, 0x78, 0xb4, 0x23, 0x02, 0xb0, 0x27, 0xfc, 0xf5, 0x26, 0x26, 0x0c, 0xe6,
|
||||
0xa1, 0x4d, 0x98, 0x6f, 0x98, 0x75, 0xd6, 0xbd, 0x7b, 0x5d, 0xfa, 0x4d, 0xbc, 0x43, 0x91, 0x6c,
|
||||
0xbd, 0xbf, 0xb7, 0x4b, 0xbf, 0xd5, 0x44, 0x55, 0xab, 0x51, 0x24, 0x7c, 0xae, 0x8b, 0x6a, 0xf8,
|
||||
0x76, 0x13, 0xcb, 0xa9, 0xa2, 0x3d, 0x3b, 0xb5, 0x17, 0x9b, 0x18, 0xfb, 0x0c, 0x37, 0xc9, 0xd6,
|
||||
0xc5, 0xa6, 0xf8, 0x1d, 0x23, 0x15, 0x5f, 0x74, 0x68, 0xc9, 0xbe, 0xa6, 0xdf, 0x35, 0x7c, 0x17,
|
||||
0xaf, 0x05, 0xf4, 0x0f, 0xad, 0x2c, 0xbf, 0x2a, 0xd8, 0x2b, 0x2d, 0x5b, 0x1f, 0xe7, 0xef, 0x01,
|
||||
0xf4, 0x8f, 0x06, 0xbe, 0x78, 0x77, 0xa0, 0x7f, 0x6a, 0xa1, 0x61, 0xd5, 0xf1, 0x8f, 0x97, 0x60,
|
||||
0x45, 0xff, 0xdc, 0x42, 0x0b, 0xca, 0x41, 0x4f, 0xbf, 0xe7, 0x62, 0xb0, 0xf2, 0x11, 0x4f, 0xbf,
|
||||
0xef, 0xa2, 0x9b, 0x17, 0x86, 0x3b, 0xfd, 0x81, 0x6b, 0x8e, 0xa3, 0x18, 0xeb, 0xf4, 0x87, 0x15,
|
||||
0x00, 0xb9, 0xe8, 0x8f, 0x5c, 0xd3, 0x81, 0xce, 0x8d, 0x72, 0xfa, 0x63, 0x17, 0x6d, 0xbb, 0x38,
|
||||
0xc4, 0xe9, 0x4f, 0x5c, 0x7b, 0xdc, 0xc5, 0xf8, 0xa6, 0x3f, 0x75, 0xb1, 0x02, 0x2e, 0x1f, 0xdc,
|
||||
0xf4, 0x25, 0xa3, 0xab, 0x1c, 0xd9, 0xf4, 0x65, 0x77, 0xa9, 0x4d, 0x1a, 0x5d, 0x15, 0x99, 0xb9,
|
||||
0xd1, 0x20, 0xb5, 0xae, 0x8a, 0xe8, 0x18, 0xb6, 0xd9, 0x35, 0x21, 0xa2, 0xf5, 0xb3, 0x54, 0x3e,
|
||||
0xf5, 0x01, 0xea, 0x2c, 0xad, 0x91, 0x99, 0x8e, 0x88, 0x53, 0x5e, 0x94, 0x9b, 0x19, 0x15, 0x76,
|
||||
0xc6, 0x40, 0x60, 0x53, 0x65, 0x0c, 0x7b, 0xf5, 0xfa, 0x19, 0xf8, 0x43, 0x33, 0xd1, 0x1c, 0x5c,
|
||||
0xe2, 0x26, 0x0c, 0x72, 0x40, 0xc7, 0x97, 0x9e, 0x21, 0xb4, 0x23, 0x12, 0x15, 0x2a, 0x0d, 0x89,
|
||||
0x3f, 0xda, 0x82, 0x53, 0x88, 0xcc, 0xdc, 0xd4, 0x52, 0x24, 0x03, 0x3a, 0x66, 0xde, 0x09, 0x60,
|
||||
0xee, 0xfb, 0x76, 0xba, 0xae, 0xe1, 0x5d, 0xc0, 0x3c, 0x06, 0xa6, 0x09, 0x59, 0x3f, 0x85, 0x44,
|
||||
0x0f, 0x79, 0x14, 0x8d, 0x68, 0x0d, 0xd7, 0x9d, 0xa1, 0xd2, 0x22, 0x0e, 0x3f, 0x6d, 0xe6, 0xf7,
|
||||
0x57, 0x1d, 0xd2, 0xb2, 0xa3, 0xb4, 0x30, 0xcd, 0x2e, 0xfb, 0x90, 0x04, 0xa1, 0x11, 0x8e, 0x77,
|
||||
0x59, 0x03, 0x65, 0x43, 0xdf, 0x29, 0x99, 0xf6, 0x34, 0x97, 0x3a, 0x7f, 0x74, 0x58, 0xa8, 0x2b,
|
||||
0xee, 0x26, 0x91, 0xe0, 0x81, 0x99, 0xe7, 0xc5, 0xd6, 0x3e, 0x97, 0xca, 0x0c, 0x75, 0xbc, 0xea,
|
||||
0x67, 0xf2, 0xa5, 0xf1, 0x27, 0xa0, 0x57, 0x4a, 0xb0, 0xf4, 0x79, 0x02, 0x87, 0xa7, 0x05, 0x4d,
|
||||
0xb2, 0xe7, 0x99, 0x4e, 0x96, 0xee, 0x27, 0x6e, 0xf5, 0x19, 0x67, 0x3c, 0x2a, 0xc7, 0xe0, 0xd8,
|
||||
0xd2, 0x2b, 0x0e, 0x0e, 0x96, 0x8b, 0xef, 0x30, 0x5a, 0x79, 0x36, 0xae, 0x46, 0x91, 0x7d, 0x4e,
|
||||
0x15, 0x88, 0x4d, 0x44, 0xeb, 0x59, 0x01, 0x62, 0x32, 0x52, 0x6c, 0xf2, 0xd3, 0x95, 0x9d, 0x1a,
|
||||
0x24, 0xad, 0x9d, 0x63, 0xf3, 0x80, 0xa3, 0x63, 0x55, 0x08, 0xeb, 0xd9, 0x3e, 0xa2, 0x2a, 0x5c,
|
||||
0x66, 0x2c, 0xd1, 0x89, 0x73, 0x68, 0x96, 0x18, 0xb4, 0x71, 0xce, 0x9a, 0x6c, 0x5e, 0x4c, 0x9e,
|
||||
0x03, 0xb3, 0xb9, 0xd1, 0xfc, 0x88, 0x20, 0x57, 0x8b, 0xf7, 0xe9, 0x21, 0x9c, 0xe9, 0x43, 0x71,
|
||||
0xf4, 0x2c, 0x7b, 0x60, 0xd9, 0xfe, 0x5f, 0x5a, 0xce, 0xff, 0x2f, 0x2d, 0x6f, 0x83, 0x52, 0x7c,
|
||||
0x00, 0xbb, 0xa9, 0x19, 0xac, 0xf3, 0x7f, 0x6d, 0x98, 0x07, 0xf8, 0xe5, 0xcf, 0xe2, 0xea, 0x83,
|
||||
0xda, 0x9b, 0x49, 0x2b, 0xab, 0xdd, 0xa3, 0x67, 0xd7, 0x9e, 0x26, 0xd3, 0xa1, 0xc8, 0xf7, 0x0d,
|
||||
0x64, 0xea, 0xaf, 0xb5, 0x3a, 0x66, 0x5f, 0x1f, 0x65, 0xf4, 0x9d, 0x8f, 0x3f, 0x3e, 0x08, 0xf5,
|
||||
0xc9, 0xf0, 0x08, 0xa5, 0xad, 0x58, 0xb6, 0x47, 0x43, 0x91, 0x7d, 0xad, 0x84, 0x89, 0xc6, 0xa2,
|
||||
0x8f, 0xec, 0x9f, 0xaf, 0x15, 0xab, 0x31, 0x3d, 0xfa, 0xa2, 0xe3, 0x1c, 0x4d, 0x18, 0xe8, 0xf1,
|
||||
0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0xe3, 0xd2, 0xcb, 0x48, 0x3f, 0x13, 0x00, 0x00,
|
||||
0xf5, 0x57, 0x75, 0xf7, 0xa8, 0xd5, 0xd9, 0x2d, 0x29, 0x95, 0xd2, 0x68, 0xda, 0xb3, 0x78, 0xe4,
|
||||
0xfe, 0xdb, 0x7f, 0x44, 0x83, 0x25, 0xb0, 0x23, 0x80, 0x20, 0xc2, 0x04, 0x52, 0xb7, 0xa4, 0xe9,
|
||||
0xb0, 0x96, 0xa6, 0xa4, 0x19, 0x3b, 0x88, 0x00, 0x45, 0x76, 0xd5, 0x53, 0xab, 0x66, 0xaa, 0x2a,
|
||||
0x8b, 0xca, 0x6c, 0x8d, 0x9a, 0x93, 0x31, 0x37, 0x4e, 0x60, 0xbe, 0x00, 0x1f, 0x80, 0x7d, 0x31,
|
||||
0x1c, 0xd9, 0xb1, 0x01, 0x73, 0xe1, 0xc2, 0x0e, 0x47, 0xb8, 0xb3, 0x7a, 0x25, 0x5e, 0x66, 0x6d,
|
||||
0xd2, 0xc8, 0x70, 0xe0, 0x56, 0xf9, 0x7b, 0x2f, 0xdf, 0x96, 0x6f, 0xc9, 0x2c, 0xd2, 0x70, 0x44,
|
||||
0x10, 0x88, 0x70, 0x25, 0x8a, 0x85, 0x12, 0x6c, 0x3e, 0xf0, 0xfc, 0x93, 0x91, 0x34, 0xab, 0x15,
|
||||
0x43, 0xba, 0xba, 0x34, 0x14, 0x62, 0xe8, 0xc3, 0xaa, 0x06, 0x07, 0xa3, 0xa3, 0x55, 0x17, 0xa4,
|
||||
0x13, 0x7b, 0x91, 0x12, 0xb1, 0x61, 0x6c, 0x1d, 0x92, 0xc9, 0x7d, 0xc5, 0xd5, 0x48, 0xb2, 0xa7,
|
||||
0x08, 0x81, 0x38, 0x16, 0xf1, 0xa1, 0x23, 0x5c, 0x68, 0x5a, 0x4b, 0xd6, 0xf2, 0xcc, 0x13, 0x0f,
|
||||
0xaf, 0x5c, 0x20, 0x75, 0x65, 0x03, 0xd9, 0x3a, 0xc2, 0x05, 0xbb, 0x06, 0xe9, 0x27, 0x5b, 0x24,
|
||||
0x93, 0x31, 0x70, 0x29, 0xc2, 0x66, 0x69, 0xc9, 0x5a, 0xae, 0xd9, 0xc9, 0xaa, 0xf5, 0x3e, 0xd2,
|
||||
0x78, 0x1a, 0xc6, 0x77, 0xb8, 0x3f, 0x82, 0x3e, 0xf7, 0x62, 0x46, 0x49, 0xf9, 0x1e, 0x8c, 0xb5,
|
||||
0xfc, 0x9a, 0x8d, 0x9f, 0x6c, 0x81, 0x5c, 0x3a, 0x41, 0x72, 0xb2, 0xd1, 0x2c, 0x5a, 0x4f, 0x92,
|
||||
0xfa, 0xd3, 0x30, 0xee, 0x72, 0xc5, 0xdf, 0x66, 0x1b, 0x23, 0x15, 0x97, 0x2b, 0xae, 0x77, 0x35,
|
||||
0x6c, 0xfd, 0xdd, 0xba, 0x4e, 0x2a, 0xeb, 0xbe, 0x18, 0xe4, 0x22, 0x2d, 0x4d, 0x4c, 0x44, 0x9e,
|
||||
0x10, 0xda, 0xf7, 0xb9, 0x03, 0xc7, 0xc2, 0x77, 0x21, 0xd6, 0x26, 0xa1, 0x5c, 0xc5, 0x87, 0xa9,
|
||||
0x5c, 0xc5, 0x87, 0xec, 0x03, 0xa4, 0xa2, 0xc6, 0x91, 0xb1, 0x66, 0xe6, 0x89, 0x47, 0x2f, 0x8c,
|
||||
0x40, 0x41, 0xcc, 0xc1, 0x38, 0x02, 0x5b, 0xef, 0xc0, 0x10, 0x68, 0x45, 0xb2, 0x59, 0x5e, 0x2a,
|
||||
0x2f, 0x37, 0xec, 0x64, 0xd5, 0xfa, 0xd8, 0x19, 0xbd, 0x5b, 0xb1, 0x18, 0x45, 0xac, 0x47, 0x1a,
|
||||
0x51, 0x8e, 0xc9, 0xa6, 0xb5, 0x54, 0x5e, 0xae, 0x3f, 0xf1, 0xd8, 0x7f, 0xd3, 0xa6, 0x8d, 0xb6,
|
||||
0xcf, 0x6c, 0x6d, 0x3d, 0x4e, 0xaa, 0x6b, 0xae, 0x1b, 0x83, 0x94, 0x6c, 0x86, 0x94, 0xbc, 0x28,
|
||||
0x71, 0xa6, 0xe4, 0x45, 0x18, 0xa3, 0x48, 0xc4, 0x4a, 0xfb, 0x52, 0xb6, 0xf5, 0x77, 0xeb, 0x05,
|
||||
0x8b, 0x54, 0x77, 0xe4, 0x70, 0x9d, 0x4b, 0x60, 0xef, 0x27, 0x53, 0x81, 0x1c, 0x1e, 0x6a, 0x7f,
|
||||
0xcd, 0x89, 0x5f, 0xbf, 0xd0, 0x82, 0x1d, 0x39, 0xd4, 0x7e, 0x56, 0x03, 0xf3, 0x81, 0x01, 0x0e,
|
||||
0xe4, 0xb0, 0xd7, 0x4d, 0x24, 0x9b, 0x05, 0xbb, 0x4e, 0x6a, 0xca, 0x0b, 0x40, 0x2a, 0x1e, 0x44,
|
||||
0xcd, 0xf2, 0x92, 0xb5, 0x5c, 0xb1, 0x73, 0x80, 0x5d, 0x25, 0x53, 0x52, 0x8c, 0x62, 0x07, 0x7a,
|
||||
0xdd, 0x66, 0x45, 0x6f, 0xcb, 0xd6, 0xad, 0xa7, 0x48, 0x6d, 0x47, 0x0e, 0x6f, 0x01, 0x77, 0x21,
|
||||
0x66, 0xef, 0x21, 0x95, 0x01, 0x97, 0xc6, 0xa2, 0xfa, 0xdb, 0x5b, 0x84, 0x1e, 0xd8, 0x9a, 0xb3,
|
||||
0xf5, 0x71, 0xd2, 0xe8, 0xee, 0x6c, 0xff, 0x0f, 0x12, 0xd0, 0x74, 0x79, 0xcc, 0x63, 0x77, 0x97,
|
||||
0x07, 0x69, 0x22, 0xe6, 0x40, 0xeb, 0x15, 0x8b, 0x34, 0xfa, 0xb1, 0x77, 0xe2, 0xf9, 0x30, 0x84,
|
||||
0x8d, 0x53, 0xc5, 0x3e, 0x4c, 0xea, 0x62, 0x70, 0x17, 0x1c, 0x55, 0x8c, 0xdd, 0xcd, 0x0b, 0xf5,
|
||||
0xec, 0x69, 0x3e, 0x1d, 0x3e, 0x22, 0xb2, 0x6f, 0xb6, 0x47, 0x68, 0x22, 0x21, 0x4a, 0x05, 0xff,
|
||||
0xc7, 0x94, 0x33, 0x62, 0x32, 0x23, 0xec, 0x59, 0x71, 0x16, 0x60, 0x6d, 0x32, 0x97, 0x08, 0x0c,
|
||||
0x79, 0x00, 0x87, 0x5e, 0xe8, 0xc2, 0xa9, 0x3e, 0x84, 0x4b, 0x29, 0x2f, 0xba, 0xd2, 0x43, 0xb8,
|
||||
0xfd, 0xcb, 0x29, 0x52, 0xcb, 0xaa, 0x98, 0xd5, 0x49, 0x75, 0x7f, 0xe4, 0x38, 0x20, 0x25, 0x9d,
|
||||
0x60, 0xf3, 0x64, 0xf6, 0x76, 0x08, 0xa7, 0x11, 0x38, 0x0a, 0x5c, 0xcd, 0x43, 0x2d, 0x36, 0x47,
|
||||
0xa6, 0x3b, 0x22, 0x0c, 0xc1, 0x51, 0x9b, 0xdc, 0xf3, 0xc1, 0xa5, 0x25, 0xb6, 0x40, 0x68, 0x1f,
|
||||
0xe2, 0xc0, 0x93, 0xd2, 0x13, 0x61, 0x17, 0x42, 0x0f, 0x5c, 0x5a, 0x66, 0x57, 0xc8, 0x7c, 0x47,
|
||||
0xf8, 0x3e, 0x38, 0xca, 0x13, 0xe1, 0xae, 0x50, 0x1b, 0xa7, 0x9e, 0x54, 0x92, 0x56, 0x50, 0x6c,
|
||||
0xcf, 0xf7, 0x61, 0xc8, 0xfd, 0xb5, 0x78, 0x38, 0x0a, 0x20, 0x54, 0xf4, 0x12, 0xca, 0x48, 0xc0,
|
||||
0xae, 0x17, 0x40, 0x88, 0x92, 0x68, 0xb5, 0x80, 0x6a, 0x63, 0x31, 0x5a, 0x74, 0x8a, 0x3d, 0x44,
|
||||
0x2e, 0x27, 0x68, 0x41, 0x01, 0x0f, 0x80, 0xd6, 0xd8, 0x2c, 0xa9, 0x27, 0xa4, 0x83, 0xbd, 0xfe,
|
||||
0xd3, 0x94, 0x14, 0x24, 0xd8, 0xe2, 0xbe, 0x0d, 0x8e, 0x88, 0x5d, 0x5a, 0x2f, 0x98, 0x70, 0x07,
|
||||
0x1c, 0x25, 0xe2, 0x5e, 0x97, 0x36, 0xd0, 0xe0, 0x04, 0xdc, 0x07, 0x1e, 0x3b, 0xc7, 0x36, 0xc8,
|
||||
0x91, 0xaf, 0xe8, 0x34, 0xa3, 0xa4, 0xb1, 0xe9, 0xf9, 0xb0, 0x2b, 0xd4, 0xa6, 0x18, 0x85, 0x2e,
|
||||
0x9d, 0x61, 0x33, 0x84, 0xec, 0x80, 0xe2, 0x49, 0x04, 0x66, 0x51, 0x6d, 0x87, 0x3b, 0xc7, 0x90,
|
||||
0x00, 0x94, 0x2d, 0x12, 0xd6, 0xe1, 0x61, 0x28, 0x54, 0x27, 0x06, 0xae, 0x60, 0x53, 0xd7, 0x27,
|
||||
0x9d, 0x43, 0x73, 0xce, 0xe0, 0x9e, 0x0f, 0x94, 0xe5, 0xdc, 0x5d, 0xf0, 0x21, 0xe3, 0x9e, 0xcf,
|
||||
0xb9, 0x13, 0x1c, 0xb9, 0x17, 0xd0, 0xf8, 0xf5, 0x91, 0xe7, 0xbb, 0x3a, 0x24, 0xe6, 0x58, 0x2e,
|
||||
0xa3, 0x8d, 0x89, 0xf1, 0xbb, 0xdb, 0xbd, 0xfd, 0x03, 0xba, 0xc8, 0x2e, 0x93, 0xb9, 0x04, 0xd9,
|
||||
0x01, 0x15, 0x7b, 0x8e, 0x0e, 0xde, 0x15, 0x34, 0x75, 0x6f, 0xa4, 0xf6, 0x8e, 0x76, 0x20, 0x10,
|
||||
0xf1, 0x98, 0x36, 0xf1, 0x40, 0xb5, 0xa4, 0xf4, 0x88, 0xe8, 0x43, 0xa8, 0x61, 0x23, 0x88, 0xd4,
|
||||
0x38, 0x0f, 0x2f, 0xbd, 0xca, 0xae, 0x91, 0x2b, 0xb7, 0x23, 0x97, 0x2b, 0xe8, 0x05, 0xd8, 0x3c,
|
||||
0x0e, 0xb8, 0xbc, 0x87, 0xee, 0x8e, 0x62, 0xa0, 0xd7, 0xd8, 0x55, 0xb2, 0x78, 0xf6, 0x2c, 0xb2,
|
||||
0x60, 0x5d, 0xc7, 0x8d, 0xc6, 0xdb, 0x4e, 0x0c, 0x2e, 0x84, 0xca, 0xe3, 0x7e, 0xba, 0xf1, 0x46,
|
||||
0x2e, 0xf5, 0x41, 0xe2, 0xc3, 0x48, 0x34, 0x9e, 0x3f, 0x48, 0xbc, 0xc9, 0x9a, 0x64, 0x61, 0x0b,
|
||||
0xd4, 0x83, 0x94, 0x25, 0xa4, 0x6c, 0x7b, 0x52, 0x93, 0x6e, 0x4b, 0x88, 0x65, 0x4a, 0x79, 0x84,
|
||||
0x31, 0x32, 0xb3, 0x05, 0x0a, 0xc1, 0x14, 0x6b, 0x61, 0x9c, 0x8c, 0x79, 0xb6, 0xf0, 0x21, 0x85,
|
||||
0xff, 0x0f, 0x63, 0xd0, 0x8d, 0x45, 0x54, 0x04, 0x1f, 0x45, 0x37, 0xf7, 0x22, 0x88, 0xb9, 0x02,
|
||||
0x94, 0x51, 0xa4, 0x3d, 0x86, 0x72, 0xf6, 0x01, 0x23, 0x50, 0x84, 0xff, 0x3f, 0x87, 0x8b, 0x5a,
|
||||
0xdf, 0x81, 0x39, 0x9c, 0x70, 0x83, 0xe9, 0x7c, 0x29, 0x69, 0x19, 0xbd, 0x4e, 0x94, 0x64, 0x15,
|
||||
0x9d, 0x12, 0xdf, 0x89, 0xa9, 0x62, 0xf6, 0x6d, 0xc5, 0x3c, 0x54, 0x29, 0xde, 0x66, 0x8f, 0x90,
|
||||
0x1b, 0x36, 0x1c, 0xc5, 0x20, 0x8f, 0xfb, 0xc2, 0xf7, 0x9c, 0x71, 0x2f, 0x3c, 0x12, 0x59, 0x4a,
|
||||
0x22, 0xcb, 0xbb, 0xd0, 0x12, 0x0c, 0x8b, 0xa1, 0xa7, 0xf0, 0xbb, 0x31, 0x26, 0xbb, 0x42, 0xed,
|
||||
0x63, 0x83, 0xdb, 0xd6, 0x2d, 0x93, 0x3e, 0x8e, 0x5a, 0x76, 0x85, 0x0d, 0x91, 0xef, 0x39, 0x7c,
|
||||
0xed, 0x84, 0x7b, 0x3e, 0x1f, 0xf8, 0x40, 0x57, 0x30, 0x28, 0xfb, 0x30, 0xc4, 0x92, 0xcd, 0xce,
|
||||
0x77, 0x95, 0x31, 0x32, 0xdd, 0xed, 0xda, 0xf0, 0x89, 0x11, 0x48, 0x65, 0x73, 0x07, 0xe8, 0x9f,
|
||||
0xab, 0xed, 0x67, 0x09, 0xd1, 0x49, 0x85, 0x17, 0x0a, 0x40, 0x15, 0xf9, 0x6a, 0x57, 0x84, 0x40,
|
||||
0x27, 0x58, 0x83, 0x4c, 0xdd, 0x0e, 0x3d, 0x29, 0x47, 0xe0, 0x52, 0x0b, 0x0b, 0xaa, 0x17, 0xf6,
|
||||
0x63, 0x31, 0xc4, 0xd9, 0x45, 0x4b, 0x48, 0xdd, 0xf4, 0x42, 0x4f, 0x1e, 0xeb, 0x56, 0x42, 0xc8,
|
||||
0x64, 0x52, 0x59, 0x95, 0xf6, 0xf3, 0x16, 0x69, 0x24, 0x36, 0x18, 0xe1, 0x0b, 0x84, 0x16, 0xd7,
|
||||
0xb9, 0xf8, 0x2c, 0xa1, 0x2d, 0x6c, 0x6b, 0x5b, 0xb1, 0xb8, 0xef, 0x85, 0x43, 0x5a, 0x42, 0x69,
|
||||
0xfb, 0xc0, 0x7d, 0x2d, 0xb9, 0x4e, 0xaa, 0x9b, 0xfe, 0x48, 0xab, 0xa9, 0x68, 0xa5, 0xb8, 0x40,
|
||||
0xb6, 0x4b, 0x48, 0xc2, 0x04, 0x88, 0xc0, 0xa5, 0x93, 0x6c, 0x9a, 0xd4, 0x4c, 0xda, 0x23, 0xad,
|
||||
0xda, 0xfe, 0x10, 0x99, 0x3d, 0x37, 0xf7, 0xd9, 0x14, 0xa9, 0x24, 0xaa, 0x29, 0x69, 0xac, 0x7b,
|
||||
0x21, 0x8f, 0xc7, 0xa6, 0xb7, 0x50, 0x17, 0x6b, 0x6e, 0xd3, 0x17, 0x5c, 0x25, 0x00, 0xb4, 0x5f,
|
||||
0x6c, 0xe8, 0xc1, 0xab, 0x37, 0x4e, 0x93, 0xda, 0xed, 0xd0, 0x85, 0x23, 0x2f, 0x04, 0x97, 0x4e,
|
||||
0xe8, 0x9a, 0x37, 0xd5, 0x92, 0x17, 0x9f, 0x8b, 0x11, 0x44, 0x63, 0x0a, 0x18, 0x60, 0xe1, 0xde,
|
||||
0xe2, 0xb2, 0x00, 0x1d, 0xe1, 0xb9, 0x75, 0xf5, 0xb5, 0x6e, 0x50, 0xdc, 0x3e, 0xd4, 0xe7, 0x76,
|
||||
0x2c, 0xee, 0xe7, 0x98, 0xa4, 0xc7, 0xa8, 0x69, 0x0b, 0xd4, 0xfe, 0x58, 0x2a, 0x08, 0x3a, 0x22,
|
||||
0x3c, 0xf2, 0x86, 0x92, 0x7a, 0xa8, 0x69, 0x5b, 0x70, 0xb7, 0xb0, 0xfd, 0x2e, 0x66, 0x8e, 0x0d,
|
||||
0x3e, 0x70, 0x59, 0x94, 0x7a, 0x4f, 0x77, 0x3d, 0x6d, 0xea, 0x9a, 0xef, 0x71, 0x49, 0x7d, 0x74,
|
||||
0x05, 0xad, 0x34, 0xcb, 0x00, 0x0f, 0x75, 0xcd, 0x57, 0x10, 0x9b, 0x75, 0xc8, 0x16, 0xc8, 0xac,
|
||||
0xe1, 0xef, 0xf3, 0x58, 0x79, 0x5a, 0xc8, 0x4b, 0x96, 0x4e, 0x9f, 0x58, 0x44, 0x39, 0xf6, 0x32,
|
||||
0x0e, 0x99, 0xc6, 0x2d, 0x2e, 0x73, 0xe8, 0xa7, 0x16, 0x5b, 0x24, 0x73, 0xa9, 0x6b, 0x39, 0xfe,
|
||||
0x33, 0x8b, 0xcd, 0x93, 0x19, 0x74, 0x2d, 0xc3, 0x24, 0xfd, 0xb9, 0x06, 0xd1, 0x89, 0x02, 0xf8,
|
||||
0x8a, 0x96, 0x90, 0x78, 0x51, 0xc0, 0x7f, 0xa1, 0x95, 0xa1, 0x84, 0x24, 0x89, 0x24, 0x7d, 0xd5,
|
||||
0x42, 0x4b, 0x53, 0x65, 0x09, 0x4c, 0x5f, 0xd3, 0x8c, 0x28, 0x35, 0x63, 0x7c, 0x5d, 0x33, 0x26,
|
||||
0x32, 0x33, 0xf4, 0x0d, 0x8d, 0xde, 0xe2, 0xa1, 0x2b, 0x8e, 0x8e, 0x32, 0xf4, 0x4d, 0x8b, 0x35,
|
||||
0xc9, 0x3c, 0x6e, 0x5f, 0xe7, 0x3e, 0x0f, 0x9d, 0x9c, 0xff, 0x2d, 0x8b, 0x5d, 0x26, 0xf4, 0x9c,
|
||||
0x3a, 0x49, 0x9f, 0x2b, 0x31, 0x9a, 0xc6, 0x57, 0x17, 0x0f, 0xfd, 0x62, 0x49, 0xc7, 0x2a, 0x61,
|
||||
0x34, 0xd8, 0x97, 0x4a, 0x6c, 0xc6, 0x04, 0xdd, 0xac, 0xbf, 0x5c, 0x62, 0x75, 0x32, 0xd9, 0x0b,
|
||||
0x25, 0xc4, 0x8a, 0x7e, 0x16, 0xf3, 0x7b, 0xd2, 0x74, 0x50, 0xfa, 0x39, 0x2c, 0xa3, 0x4b, 0x3a,
|
||||
0xbf, 0xe9, 0x0b, 0x38, 0x9d, 0x99, 0x0d, 0x12, 0x42, 0xb7, 0x50, 0x3b, 0x92, 0x7e, 0x5e, 0xef,
|
||||
0x30, 0xe3, 0x8f, 0xfe, 0xb5, 0xac, 0x43, 0x53, 0x9c, 0x85, 0x7f, 0x2b, 0xa3, 0x09, 0x5b, 0xa0,
|
||||
0xf2, 0x72, 0xa6, 0x7f, 0x2f, 0xb3, 0xab, 0xe4, 0x72, 0x8a, 0xe9, 0xc9, 0x94, 0x15, 0xf2, 0x3f,
|
||||
0xca, 0xec, 0x3a, 0xb9, 0x82, 0x6d, 0x3a, 0xcb, 0x1b, 0xdc, 0xe4, 0x49, 0xe5, 0x39, 0x92, 0xfe,
|
||||
0xb3, 0xcc, 0xae, 0x91, 0xc5, 0x2d, 0x50, 0xd9, 0x79, 0x14, 0x88, 0xff, 0x2a, 0xb3, 0x69, 0x32,
|
||||
0x65, 0xe3, 0xe8, 0x82, 0x13, 0xa0, 0xaf, 0x96, 0xf1, 0x50, 0xd3, 0x65, 0x62, 0xce, 0x6b, 0x65,
|
||||
0x0c, 0xf5, 0x33, 0x5c, 0x39, 0xc7, 0xdd, 0xa0, 0x73, 0xcc, 0xc3, 0x10, 0x7c, 0x49, 0x5f, 0x2f,
|
||||
0x63, 0x40, 0x6d, 0x08, 0xc4, 0x09, 0x14, 0xe0, 0x37, 0xb4, 0xd3, 0x9a, 0xf9, 0x23, 0x23, 0x88,
|
||||
0xc7, 0x19, 0xe1, 0xcd, 0x32, 0x1e, 0x8d, 0xe1, 0x3f, 0x4b, 0x79, 0xab, 0xcc, 0x6e, 0x90, 0xa6,
|
||||
0x69, 0x16, 0xe9, 0xc1, 0x20, 0x71, 0x08, 0xd8, 0x5e, 0xe9, 0x73, 0x95, 0x4c, 0x62, 0x17, 0x7c,
|
||||
0xc5, 0xb3, 0x7d, 0x9f, 0xaa, 0xa0, 0x5d, 0x58, 0x5c, 0x79, 0x57, 0x95, 0xf4, 0xf9, 0x0a, 0x9e,
|
||||
0xe8, 0x16, 0xa8, 0xa4, 0xb1, 0x4a, 0xfa, 0x69, 0x8d, 0x24, 0x92, 0xb5, 0xc8, 0x5f, 0x55, 0xd8,
|
||||
0x2c, 0x21, 0xa6, 0x26, 0x35, 0xf0, 0xeb, 0x54, 0x14, 0xde, 0x5d, 0x4e, 0x20, 0xd6, 0x8d, 0x9d,
|
||||
0xfe, 0x26, 0x53, 0x50, 0xe8, 0x7c, 0xf4, 0xb7, 0x15, 0x0c, 0xd9, 0x81, 0x17, 0xc0, 0x81, 0xe7,
|
||||
0xdc, 0xa3, 0x5f, 0xad, 0x61, 0xc8, 0xb4, 0x47, 0xbb, 0xc2, 0x05, 0x73, 0xc2, 0x5f, 0xab, 0x61,
|
||||
0xc2, 0x60, 0x1e, 0x9a, 0x84, 0xf9, 0xba, 0x5e, 0x27, 0xdd, 0xbb, 0xd7, 0xa5, 0xdf, 0xc0, 0x3b,
|
||||
0x14, 0x49, 0xd6, 0x07, 0xfb, 0x7b, 0xf4, 0x9b, 0x35, 0x54, 0xb5, 0xe6, 0xfb, 0xc2, 0xe1, 0x2a,
|
||||
0xab, 0x86, 0x6f, 0xd5, 0xb0, 0x9c, 0x0a, 0xda, 0x93, 0x53, 0x7b, 0xb1, 0x86, 0xb1, 0x4f, 0x70,
|
||||
0x9d, 0x6c, 0x5d, 0x6c, 0x8a, 0xdf, 0xd6, 0x52, 0xf1, 0x05, 0x87, 0x96, 0x1c, 0x28, 0xfa, 0x1d,
|
||||
0xcd, 0x77, 0xfe, 0x5a, 0x40, 0x7f, 0x57, 0x4f, 0xf2, 0xab, 0x80, 0xfd, 0xbe, 0x6e, 0xea, 0xe3,
|
||||
0xec, 0x3d, 0x80, 0xfe, 0x41, 0xc3, 0xe7, 0xef, 0x0e, 0xf4, 0x8f, 0x75, 0x34, 0xac, 0x38, 0xfe,
|
||||
0xf1, 0x0a, 0x2c, 0xe9, 0x9f, 0xea, 0x68, 0x41, 0x3e, 0xe8, 0xe9, 0x77, 0x1b, 0x18, 0xac, 0x74,
|
||||
0xc4, 0xd3, 0xef, 0x35, 0xd0, 0xcd, 0x73, 0xc3, 0x9d, 0x7e, 0xbf, 0xa1, 0x8f, 0x23, 0x1b, 0xeb,
|
||||
0xf4, 0x07, 0x05, 0x00, 0xb9, 0xe8, 0x0f, 0x1b, 0xba, 0x03, 0x9d, 0x19, 0xe5, 0xf4, 0x47, 0x0d,
|
||||
0xb4, 0xed, 0xfc, 0x10, 0xa7, 0x3f, 0x6e, 0x98, 0xe3, 0xce, 0xc6, 0x37, 0xfd, 0x49, 0x03, 0x2b,
|
||||
0xe0, 0xe2, 0xc1, 0x4d, 0x5f, 0xd2, 0xba, 0xf2, 0x91, 0x4d, 0x5f, 0x6e, 0xb4, 0x5b, 0xa4, 0xda,
|
||||
0x95, 0xbe, 0x9e, 0x1b, 0x55, 0x52, 0xee, 0x4a, 0x9f, 0x4e, 0x60, 0x9b, 0x5d, 0x17, 0xc2, 0xdf,
|
||||
0x38, 0x8d, 0xe2, 0x3b, 0xef, 0xa5, 0x56, 0x7b, 0x9d, 0xcc, 0x76, 0x44, 0x10, 0xf1, 0xac, 0xdc,
|
||||
0xf4, 0xa8, 0x30, 0x33, 0x06, 0x5c, 0x93, 0x2a, 0x13, 0xd8, 0xab, 0x37, 0x4e, 0xc1, 0x19, 0xe9,
|
||||
0x89, 0x66, 0xe1, 0x12, 0x37, 0x61, 0x90, 0x5d, 0x5a, 0x6a, 0x3f, 0x4b, 0x68, 0x47, 0x84, 0xd2,
|
||||
0x93, 0x0a, 0x42, 0x67, 0xbc, 0x0d, 0x27, 0xe0, 0xeb, 0xb9, 0xa9, 0x62, 0x11, 0x0e, 0xe9, 0x84,
|
||||
0x7e, 0x27, 0x80, 0xbe, 0xef, 0x9b, 0xe9, 0xba, 0x8e, 0x77, 0x01, 0xfd, 0x18, 0x98, 0x21, 0x64,
|
||||
0xe3, 0x04, 0x42, 0x35, 0xe2, 0xbe, 0x3f, 0xa6, 0x65, 0x5c, 0x77, 0x46, 0x52, 0x89, 0xc0, 0xfb,
|
||||
0xa4, 0x9e, 0xdf, 0x5f, 0xb1, 0x48, 0xdd, 0x8c, 0xd2, 0xcc, 0x34, 0xb3, 0xec, 0x43, 0xe8, 0x7a,
|
||||
0x5a, 0x38, 0xde, 0x65, 0x35, 0x94, 0x0c, 0x7d, 0x2b, 0x67, 0xda, 0x57, 0x3c, 0x56, 0xe9, 0xa3,
|
||||
0xc3, 0x40, 0x5d, 0x71, 0x3f, 0xf4, 0x05, 0x77, 0xf5, 0x3c, 0xcf, 0xb6, 0xf6, 0x79, 0x2c, 0xf5,
|
||||
0x50, 0xc7, 0xab, 0x7e, 0x22, 0x3f, 0xd6, 0xfe, 0xb8, 0xf4, 0x52, 0x0e, 0xe6, 0x3e, 0x4f, 0xe2,
|
||||
0xf0, 0x34, 0xa0, 0x4e, 0xf6, 0x34, 0xd3, 0x49, 0x7b, 0x99, 0x90, 0xfc, 0xe1, 0xa6, 0xfd, 0xc9,
|
||||
0x87, 0xe0, 0x04, 0x46, 0x65, 0xcb, 0x17, 0x03, 0xee, 0x53, 0xab, 0xfd, 0x99, 0x12, 0x99, 0x3d,
|
||||
0xf7, 0x38, 0x43, 0x8b, 0xb2, 0xc5, 0x9a, 0x8f, 0xe7, 0x75, 0x83, 0x3c, 0x94, 0x21, 0x0f, 0x8c,
|
||||
0x7a, 0x0b, 0xaf, 0x7f, 0x19, 0xf9, 0xdc, 0xcc, 0x2f, 0xb1, 0x9b, 0xe4, 0x5a, 0x4e, 0x7c, 0x70,
|
||||
0xd2, 0x63, 0xbb, 0x6d, 0x66, 0x0c, 0xe7, 0x47, 0x7e, 0x05, 0xe3, 0x98, 0x51, 0xb1, 0x07, 0x98,
|
||||
0x87, 0x57, 0xfe, 0x92, 0x34, 0xa3, 0x8c, 0x4e, 0xe2, 0x5b, 0x28, 0xb7, 0x31, 0x4b, 0x26, 0x5a,
|
||||
0xc5, 0xc8, 0x65, 0x84, 0x64, 0xcc, 0x4c, 0x9d, 0x01, 0x93, 0x71, 0x53, 0xfb, 0xa0, 0x20, 0x73,
|
||||
0xd9, 0x73, 0xf6, 0x10, 0x4e, 0xd5, 0xa1, 0x18, 0xdc, 0x65, 0x37, 0x57, 0xcc, 0x6f, 0xa8, 0x95,
|
||||
0xf4, 0x37, 0xd4, 0xca, 0x0e, 0x48, 0xc9, 0x87, 0xb0, 0x17, 0x69, 0x1b, 0x9b, 0x7f, 0xa9, 0xea,
|
||||
0x77, 0xfa, 0x23, 0x17, 0xff, 0xfd, 0x28, 0xbc, 0xbb, 0xed, 0xd9, 0xa8, 0xb0, 0xda, 0x1b, 0xdc,
|
||||
0x5d, 0x7f, 0x86, 0xcc, 0x78, 0x22, 0xdd, 0x37, 0x8c, 0x23, 0x67, 0xbd, 0xde, 0xd1, 0xfb, 0xfa,
|
||||
0x28, 0xa3, 0x6f, 0x7d, 0xf4, 0xc9, 0xa1, 0xa7, 0x8e, 0x47, 0x03, 0x94, 0xb6, 0x6a, 0xd8, 0x1e,
|
||||
0xf7, 0x44, 0xf2, 0xb5, 0xea, 0x85, 0x0a, 0x7b, 0x85, 0x6f, 0x7e, 0x90, 0xad, 0x1a, 0x8d, 0xd1,
|
||||
0xe0, 0x0b, 0x96, 0x35, 0x98, 0xd4, 0xd0, 0x93, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x59,
|
||||
0x0b, 0xcb, 0x66, 0x13, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -310,6 +310,7 @@ message ListPolicyResponse {
|
|||
// Contain error_code and reason
|
||||
common.Status status = 1;
|
||||
repeated string policy_infos = 2;
|
||||
repeated string user_roles = 3;
|
||||
}
|
||||
|
||||
message ShowConfigurationsRequest {
|
||||
|
|
|
@ -2539,6 +2539,7 @@ type ListPolicyResponse struct {
|
|||
// Contain error_code and reason
|
||||
Status *commonpb.Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
PolicyInfos []string `protobuf:"bytes,2,rep,name=policy_infos,json=policyInfos,proto3" json:"policy_infos,omitempty"`
|
||||
UserRoles []string `protobuf:"bytes,3,rep,name=user_roles,json=userRoles,proto3" json:"user_roles,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
@ -2583,6 +2584,13 @@ func (m *ListPolicyResponse) GetPolicyInfos() []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *ListPolicyResponse) GetUserRoles() []string {
|
||||
if m != nil {
|
||||
return m.UserRoles
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ShowConfigurationsRequest struct {
|
||||
Base *commonpb.MsgBase `protobuf:"bytes,1,opt,name=base,proto3" json:"base,omitempty"`
|
||||
Pattern string `protobuf:"bytes,2,opt,name=pattern,proto3" json:"pattern,omitempty"`
|
||||
|
@ -2722,142 +2730,144 @@ func init() {
|
|||
func init() { proto.RegisterFile("internal.proto", fileDescriptor_41f4a519b878ee3b) }
|
||||
|
||||
var fileDescriptor_41f4a519b878ee3b = []byte{
|
||||
// 2192 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x59, 0xcd, 0x73, 0x1b, 0x49,
|
||||
0x15, 0xdf, 0xd1, 0xc8, 0x96, 0xf4, 0x24, 0xdb, 0x72, 0xc7, 0xd9, 0x55, 0x9c, 0xec, 0xae, 0x33,
|
||||
0x2c, 0x60, 0x12, 0x36, 0x09, 0xde, 0xdd, 0x64, 0x0b, 0x28, 0x42, 0x62, 0x2d, 0xc1, 0x95, 0x0f,
|
||||
0xcc, 0x38, 0xa4, 0x0a, 0x2e, 0x53, 0x2d, 0x4d, 0x5b, 0x6a, 0x32, 0x33, 0x3d, 0xe9, 0xee, 0xb1,
|
||||
0xa3, 0x9c, 0x38, 0x70, 0x82, 0x82, 0x1b, 0x97, 0xad, 0x82, 0x33, 0x17, 0xce, 0x7b, 0x83, 0x2a,
|
||||
0x4e, 0x9c, 0x38, 0x71, 0xe1, 0x5f, 0xa1, 0x38, 0x50, 0xfd, 0x31, 0xa3, 0x91, 0x2c, 0x3b, 0xb2,
|
||||
0x53, 0xbb, 0x1b, 0xaa, 0xf6, 0x36, 0xfd, 0xde, 0xeb, 0xee, 0xd7, 0xef, 0xfd, 0xde, 0xeb, 0xf7,
|
||||
0x7a, 0x60, 0x99, 0x26, 0x92, 0xf0, 0x04, 0x47, 0xd7, 0x52, 0xce, 0x24, 0x43, 0xe7, 0x63, 0x1a,
|
||||
0x1d, 0x64, 0xc2, 0x8c, 0xae, 0xe5, 0xcc, 0xf5, 0x56, 0x9f, 0xc5, 0x31, 0x4b, 0x0c, 0x79, 0xbd,
|
||||
0x25, 0xfa, 0x43, 0x12, 0x63, 0x33, 0xf2, 0xfe, 0xea, 0xc0, 0xd2, 0x36, 0x8b, 0x53, 0x96, 0x90,
|
||||
0x44, 0xee, 0x24, 0xfb, 0x0c, 0xbd, 0x09, 0x8b, 0x09, 0x0b, 0xc9, 0x4e, 0xb7, 0xe3, 0x6c, 0x38,
|
||||
0x9b, 0xae, 0x6f, 0x47, 0x08, 0x41, 0x95, 0xb3, 0x88, 0x74, 0x2a, 0x1b, 0xce, 0x66, 0xc3, 0xd7,
|
||||
0xdf, 0xe8, 0x36, 0x80, 0x90, 0x58, 0x92, 0xa0, 0xcf, 0x42, 0xd2, 0x71, 0x37, 0x9c, 0xcd, 0xe5,
|
||||
0xad, 0x8d, 0x6b, 0x33, 0xb5, 0xb8, 0xb6, 0xa7, 0x04, 0xb7, 0x59, 0x48, 0xfc, 0x86, 0xc8, 0x3f,
|
||||
0xd1, 0x0f, 0x01, 0xc8, 0x73, 0xc9, 0x71, 0x40, 0x93, 0x7d, 0xd6, 0xa9, 0x6e, 0xb8, 0x9b, 0xcd,
|
||||
0xad, 0xcb, 0x93, 0x0b, 0x58, 0xe5, 0xef, 0x93, 0xd1, 0x13, 0x1c, 0x65, 0x64, 0x17, 0x53, 0xee,
|
||||
0x37, 0xf4, 0x24, 0xa5, 0xae, 0xf7, 0x6f, 0x07, 0x56, 0x8a, 0x03, 0xe8, 0x3d, 0x04, 0xfa, 0x2e,
|
||||
0x2c, 0xe8, 0x2d, 0xf4, 0x09, 0x9a, 0x5b, 0xef, 0x1d, 0xa3, 0xd1, 0xc4, 0xb9, 0x7d, 0x33, 0x05,
|
||||
0xfd, 0x0c, 0xce, 0x89, 0xac, 0xd7, 0xcf, 0x59, 0x81, 0xa6, 0x8a, 0x4e, 0x45, 0xab, 0x36, 0xdf,
|
||||
0x4a, 0xa8, 0xbc, 0x80, 0x55, 0xe9, 0x03, 0x58, 0x54, 0x2b, 0x65, 0x42, 0x5b, 0xa9, 0xb9, 0x75,
|
||||
0x71, 0xe6, 0x21, 0xf7, 0xb4, 0x88, 0x6f, 0x45, 0xbd, 0x8b, 0x70, 0xe1, 0x1e, 0x91, 0x53, 0xa7,
|
||||
0xf3, 0xc9, 0xb3, 0x8c, 0x08, 0x69, 0x99, 0x8f, 0x69, 0x4c, 0x1e, 0xd3, 0xfe, 0xd3, 0xed, 0x21,
|
||||
0x4e, 0x12, 0x12, 0xe5, 0xcc, 0xb7, 0xe1, 0xe2, 0x3d, 0xa2, 0x27, 0x50, 0x21, 0x69, 0x5f, 0x4c,
|
||||
0xb1, 0xcf, 0xc3, 0xb9, 0x7b, 0x44, 0x76, 0xc3, 0x29, 0xf2, 0x13, 0xa8, 0x3f, 0x52, 0xce, 0x56,
|
||||
0x30, 0xb8, 0x09, 0x35, 0x1c, 0x86, 0x9c, 0x08, 0x61, 0xad, 0x78, 0x69, 0xa6, 0xc6, 0x77, 0x8c,
|
||||
0x8c, 0x9f, 0x0b, 0xcf, 0x82, 0x89, 0xf7, 0x4b, 0x80, 0x9d, 0x84, 0xca, 0x5d, 0xcc, 0x71, 0x2c,
|
||||
0x8e, 0x05, 0x58, 0x17, 0x5a, 0x42, 0x62, 0x2e, 0x83, 0x54, 0xcb, 0x59, 0x93, 0xcf, 0x81, 0x86,
|
||||
0xa6, 0x9e, 0x66, 0x56, 0xf7, 0x7e, 0x0e, 0xb0, 0x27, 0x39, 0x4d, 0x06, 0x0f, 0xa8, 0x90, 0x6a,
|
||||
0xaf, 0x03, 0x25, 0xa7, 0x0e, 0xe1, 0x6e, 0x36, 0x7c, 0x3b, 0x2a, 0xb9, 0xa3, 0x32, 0xbf, 0x3b,
|
||||
0x6e, 0x43, 0x33, 0x37, 0xf7, 0x43, 0x31, 0x40, 0x37, 0xa0, 0xda, 0xc3, 0x82, 0x9c, 0x68, 0x9e,
|
||||
0x87, 0x62, 0x70, 0x17, 0x0b, 0xe2, 0x6b, 0x49, 0xef, 0x2f, 0x15, 0x58, 0x9b, 0x70, 0x8b, 0x35,
|
||||
0xfc, 0xe9, 0x97, 0x52, 0x66, 0x0e, 0x7b, 0x3b, 0x5d, 0xad, 0xbe, 0xeb, 0xeb, 0x6f, 0xe4, 0x41,
|
||||
0xab, 0xcf, 0xa2, 0x88, 0xf4, 0x25, 0x65, 0xc9, 0x4e, 0x57, 0x23, 0xcd, 0xf5, 0x27, 0x68, 0x4a,
|
||||
0x26, 0xc5, 0x5c, 0x52, 0x33, 0x14, 0x3a, 0xe4, 0x5c, 0x7f, 0x82, 0x86, 0xbe, 0x05, 0x6d, 0xc9,
|
||||
0xf1, 0x01, 0x89, 0x02, 0x49, 0x63, 0x22, 0x24, 0x8e, 0xd3, 0xce, 0xc2, 0x86, 0xb3, 0x59, 0xf5,
|
||||
0x57, 0x0c, 0xfd, 0x71, 0x4e, 0x46, 0xd7, 0xe1, 0xdc, 0x20, 0xc3, 0x1c, 0x27, 0x92, 0x90, 0x92,
|
||||
0xf4, 0xa2, 0x96, 0x46, 0x05, 0x6b, 0x3c, 0xe1, 0x2a, 0xac, 0x2a, 0x31, 0x96, 0xc9, 0x92, 0x78,
|
||||
0x4d, 0x8b, 0xb7, 0x2d, 0xa3, 0x10, 0xf6, 0x3e, 0x73, 0xe0, 0xfc, 0x94, 0xbd, 0x44, 0xca, 0x12,
|
||||
0x41, 0xce, 0x60, 0xb0, 0xb3, 0x78, 0x1c, 0xdd, 0x32, 0x89, 0x44, 0x05, 0xed, 0x9c, 0x58, 0x34,
|
||||
0xf2, 0xde, 0x6f, 0x5c, 0x78, 0x6b, 0x9b, 0x13, 0x9d, 0xe6, 0x72, 0xeb, 0x9f, 0xdd, 0xd9, 0x6f,
|
||||
0x41, 0x2d, 0xec, 0x05, 0x09, 0x8e, 0xf3, 0xb0, 0x5a, 0x0c, 0x7b, 0x8f, 0x70, 0x4c, 0xd0, 0x37,
|
||||
0x60, 0x79, 0xec, 0x5d, 0x45, 0xd1, 0x3e, 0x6f, 0xf8, 0x53, 0x54, 0xf4, 0x1e, 0x2c, 0x15, 0x1e,
|
||||
0xd6, 0x62, 0x55, 0x2d, 0x36, 0x49, 0x2c, 0x30, 0xb5, 0x70, 0x02, 0xa6, 0x16, 0x67, 0x60, 0x6a,
|
||||
0x03, 0x9a, 0x25, 0xfc, 0x68, 0x6f, 0xba, 0x7e, 0x99, 0xa4, 0xc2, 0xd0, 0xdc, 0x3a, 0x9d, 0xfa,
|
||||
0x86, 0xb3, 0xd9, 0xf2, 0xed, 0x08, 0xdd, 0x80, 0x73, 0x07, 0x94, 0xcb, 0x0c, 0x47, 0x36, 0x13,
|
||||
0x29, 0x3d, 0x44, 0xa7, 0xa1, 0x63, 0x75, 0x16, 0x0b, 0x6d, 0xc1, 0x5a, 0x3a, 0x1c, 0x09, 0xda,
|
||||
0x9f, 0x9a, 0x02, 0x7a, 0xca, 0x4c, 0x9e, 0xf7, 0x77, 0x07, 0xce, 0x77, 0x39, 0x4b, 0x5f, 0x0b,
|
||||
0x57, 0xe4, 0x46, 0xae, 0x9e, 0x60, 0xe4, 0x85, 0xa3, 0x46, 0xf6, 0x7e, 0x57, 0x81, 0x37, 0x0d,
|
||||
0xa2, 0x76, 0x73, 0xc3, 0x7e, 0x0e, 0xa7, 0xf8, 0x26, 0xac, 0x8c, 0x77, 0x35, 0x02, 0xb3, 0x8f,
|
||||
0xf1, 0x75, 0x58, 0x2e, 0x1c, 0x6c, 0xe4, 0xbe, 0x58, 0x48, 0x79, 0xbf, 0xad, 0xc0, 0x9a, 0x72,
|
||||
0xea, 0x57, 0xd6, 0x50, 0xd6, 0xf8, 0x93, 0x03, 0xc8, 0xa0, 0xe3, 0x4e, 0x44, 0xb1, 0xf8, 0x32,
|
||||
0x6d, 0xb1, 0x06, 0x0b, 0x58, 0xe9, 0x60, 0x4d, 0x60, 0x06, 0x9e, 0x80, 0xb6, 0xf2, 0xd6, 0xe7,
|
||||
0xa5, 0x5d, 0xb1, 0xa9, 0x5b, 0xde, 0xf4, 0x8f, 0x0e, 0xac, 0xde, 0x89, 0x24, 0xe1, 0xaf, 0xa9,
|
||||
0x51, 0xfe, 0x56, 0xc9, 0xbd, 0xb6, 0x93, 0x84, 0xe4, 0xf9, 0x97, 0xa9, 0xe0, 0xdb, 0x00, 0xfb,
|
||||
0x94, 0x44, 0x61, 0x19, 0xbd, 0x0d, 0x4d, 0x79, 0x25, 0xe4, 0x76, 0xa0, 0xa6, 0x17, 0x29, 0x50,
|
||||
0x9b, 0x0f, 0x55, 0xb5, 0x67, 0x2a, 0x7f, 0x5b, 0xed, 0xd5, 0xe7, 0xae, 0xf6, 0xf4, 0x34, 0x5b,
|
||||
0xed, 0xfd, 0xb3, 0x0a, 0x4b, 0x3b, 0x89, 0x20, 0x5c, 0x9e, 0xdd, 0x78, 0x97, 0xa0, 0x21, 0x86,
|
||||
0x98, 0xeb, 0x83, 0x5a, 0xf3, 0x8d, 0x09, 0x65, 0xd3, 0xba, 0x2f, 0x33, 0x6d, 0x75, 0xce, 0xe4,
|
||||
0xb0, 0x70, 0x52, 0x72, 0x58, 0x3c, 0xc1, 0xc4, 0xb5, 0x97, 0x27, 0x87, 0xfa, 0xd1, 0xdb, 0x57,
|
||||
0x1d, 0x90, 0x0c, 0x62, 0xd5, 0x9e, 0x74, 0x3b, 0x0d, 0xcd, 0x1f, 0x13, 0xd0, 0x3b, 0x00, 0x45,
|
||||
0x25, 0x66, 0xee, 0xd1, 0xaa, 0x5f, 0xa2, 0xa8, 0xbb, 0x9b, 0xb3, 0x43, 0x55, 0x2b, 0x36, 0x75,
|
||||
0xad, 0x68, 0x47, 0xe8, 0x43, 0xa8, 0x73, 0x76, 0x18, 0x84, 0x58, 0xe2, 0x4e, 0x4b, 0x3b, 0xef,
|
||||
0xc2, 0x4c, 0x63, 0xdf, 0x8d, 0x58, 0xcf, 0xaf, 0x71, 0x76, 0xd8, 0xc5, 0x12, 0xa3, 0xdb, 0xd0,
|
||||
0xd4, 0x08, 0x10, 0x66, 0xe2, 0x92, 0x9e, 0xf8, 0xce, 0xe4, 0x44, 0xdb, 0xa0, 0xfe, 0x48, 0xc9,
|
||||
0xa9, 0x49, 0xbe, 0x81, 0xa6, 0xd0, 0x0b, 0x5c, 0x80, 0x7a, 0x92, 0xc5, 0x01, 0x67, 0x87, 0xa2,
|
||||
0xb3, 0xac, 0xeb, 0xc6, 0x5a, 0x92, 0xc5, 0x3e, 0x3b, 0x14, 0xe8, 0x2e, 0xd4, 0x0e, 0x08, 0x17,
|
||||
0x94, 0x25, 0x9d, 0x15, 0xdd, 0x8a, 0x6e, 0x1e, 0xd3, 0xae, 0x19, 0xc4, 0xa8, 0xe5, 0x9e, 0x18,
|
||||
0x79, 0x3f, 0x9f, 0xe8, 0xfd, 0xab, 0x0a, 0x4b, 0x7b, 0x04, 0xf3, 0xfe, 0xf0, 0xec, 0x80, 0x5a,
|
||||
0x83, 0x05, 0x4e, 0x9e, 0x15, 0xc5, 0xb9, 0x19, 0x14, 0xfe, 0x75, 0x4f, 0xf0, 0x6f, 0x75, 0x8e,
|
||||
0x8a, 0x7d, 0x61, 0x46, 0xc5, 0xde, 0x06, 0x37, 0x14, 0x91, 0x86, 0x4e, 0xc3, 0x57, 0x9f, 0xaa,
|
||||
0xce, 0x4e, 0x23, 0xdc, 0x27, 0x43, 0x16, 0x85, 0x84, 0x07, 0x03, 0xce, 0x32, 0x53, 0x67, 0xb7,
|
||||
0xfc, 0x76, 0x89, 0x71, 0x4f, 0xd1, 0xd1, 0x2d, 0xa8, 0x87, 0x22, 0x0a, 0xe4, 0x28, 0x25, 0x1a,
|
||||
0x3f, 0xcb, 0xc7, 0x1c, 0xb3, 0x2b, 0xa2, 0xc7, 0xa3, 0x94, 0xf8, 0xb5, 0xd0, 0x7c, 0xa0, 0x1b,
|
||||
0xb0, 0x26, 0x08, 0xa7, 0x38, 0xa2, 0x2f, 0x48, 0x18, 0x90, 0xe7, 0x29, 0x0f, 0xd2, 0x08, 0x27,
|
||||
0x1a, 0x64, 0x2d, 0x1f, 0x8d, 0x79, 0x9f, 0x3c, 0x4f, 0xf9, 0x6e, 0x84, 0x13, 0xb4, 0x09, 0x6d,
|
||||
0x96, 0xc9, 0x34, 0x93, 0x81, 0x85, 0x01, 0x0d, 0x35, 0xe6, 0x5c, 0x7f, 0xd9, 0xd0, 0xb5, 0xd7,
|
||||
0xc5, 0x4e, 0x38, 0xb3, 0x0b, 0x69, 0x9e, 0xaa, 0x0b, 0x69, 0x9d, 0xae, 0x0b, 0x59, 0x9a, 0xdd,
|
||||
0x85, 0xa0, 0x65, 0xa8, 0x24, 0xcf, 0x34, 0xd6, 0x5c, 0xbf, 0x92, 0x3c, 0x53, 0x8e, 0x94, 0x2c,
|
||||
0x7d, 0xaa, 0x31, 0xe6, 0xfa, 0xfa, 0x5b, 0x05, 0x51, 0x4c, 0x24, 0xa7, 0x7d, 0x65, 0x96, 0x4e,
|
||||
0x5b, 0xfb, 0xa1, 0x44, 0xf1, 0xfe, 0xeb, 0x8e, 0x61, 0x25, 0xb2, 0x48, 0x8a, 0x2f, 0xaa, 0x83,
|
||||
0x29, 0xb0, 0xe8, 0x96, 0xb1, 0xf8, 0x2e, 0x34, 0x8d, 0x72, 0xc6, 0xe7, 0xd5, 0x69, 0x7d, 0x95,
|
||||
0x80, 0x8a, 0xb2, 0x67, 0x19, 0xe1, 0x94, 0x08, 0x9b, 0xf6, 0x21, 0xc9, 0xe2, 0x9f, 0x1a, 0x0a,
|
||||
0x3a, 0x07, 0x0b, 0x92, 0xa5, 0xc1, 0xd3, 0x3c, 0x5d, 0x49, 0x96, 0xde, 0x47, 0xdf, 0x87, 0x75,
|
||||
0x41, 0x70, 0x44, 0xc2, 0xa0, 0x48, 0x2f, 0x22, 0x10, 0xfa, 0xd8, 0x24, 0xec, 0xd4, 0xb4, 0x9b,
|
||||
0x3b, 0x46, 0x62, 0xaf, 0x10, 0xd8, 0xb3, 0x7c, 0xe5, 0xc5, 0xbe, 0x29, 0xdb, 0x27, 0xa6, 0xd5,
|
||||
0x75, 0x65, 0x8f, 0xc6, 0xac, 0x62, 0xc2, 0xc7, 0xd0, 0x19, 0x44, 0xac, 0x87, 0xa3, 0xe0, 0xc8,
|
||||
0xae, 0xba, 0x85, 0x70, 0xfd, 0x37, 0x0d, 0x7f, 0x6f, 0x6a, 0x4b, 0x75, 0x3c, 0x11, 0xd1, 0x3e,
|
||||
0x09, 0x83, 0x5e, 0xc4, 0x7a, 0x1d, 0xd0, 0x70, 0x05, 0x43, 0x52, 0xf9, 0x4a, 0xc1, 0xd4, 0x0a,
|
||||
0x28, 0x33, 0xf4, 0x59, 0x96, 0x48, 0x0d, 0x3e, 0xd7, 0x5f, 0x36, 0xf4, 0x47, 0x59, 0xbc, 0xad,
|
||||
0xa8, 0xe8, 0x6b, 0xb0, 0x64, 0x25, 0xd9, 0xfe, 0xbe, 0x20, 0x52, 0xa3, 0xce, 0xf5, 0x5b, 0x86,
|
||||
0xf8, 0x13, 0x4d, 0xf3, 0x3e, 0x75, 0x61, 0xc5, 0x57, 0xd6, 0x25, 0x07, 0xe4, 0xff, 0x29, 0xaf,
|
||||
0x1c, 0x17, 0xdf, 0x8b, 0xa7, 0x8a, 0xef, 0xda, 0xdc, 0xf1, 0x5d, 0x3f, 0x55, 0x7c, 0x37, 0x4e,
|
||||
0x17, 0xdf, 0x70, 0xcc, 0x2b, 0xc3, 0x9f, 0x27, 0x9c, 0xf3, 0x1a, 0x44, 0xe7, 0x15, 0x70, 0x69,
|
||||
0x68, 0x4a, 0xc5, 0xe6, 0x56, 0x67, 0xe6, 0xdd, 0xb8, 0xd3, 0x15, 0xbe, 0x12, 0x9a, 0xbe, 0x4f,
|
||||
0x17, 0x4e, 0x7d, 0x9f, 0xfe, 0x00, 0x2e, 0x1e, 0x8d, 0x59, 0x6e, 0xcd, 0x11, 0x76, 0x16, 0xb5,
|
||||
0xef, 0x2e, 0x4c, 0x07, 0x6d, 0x6e, 0xaf, 0x10, 0x7d, 0x07, 0xd6, 0x4a, 0x51, 0x3b, 0x9e, 0x58,
|
||||
0x33, 0x3d, 0xfc, 0x98, 0x37, 0x9e, 0x72, 0x52, 0xdc, 0xd6, 0x4f, 0x8a, 0x5b, 0xef, 0x1f, 0x2e,
|
||||
0x2c, 0x75, 0x49, 0x44, 0x24, 0xf9, 0xaa, 0xdc, 0x3b, 0xb6, 0xdc, 0xfb, 0x36, 0x20, 0x9a, 0xc8,
|
||||
0x9b, 0x1f, 0x06, 0x29, 0xa7, 0x31, 0xe6, 0xa3, 0xe0, 0x29, 0x19, 0xe5, 0x09, 0xb1, 0xad, 0x39,
|
||||
0xbb, 0x86, 0x71, 0x9f, 0x8c, 0xc4, 0x4b, 0xcb, 0xbf, 0x72, 0xbd, 0x65, 0x32, 0x60, 0x51, 0x6f,
|
||||
0x7d, 0x0f, 0x5a, 0x13, 0x5b, 0xb4, 0x5e, 0x02, 0xd8, 0x66, 0x3a, 0xde, 0xd7, 0xfb, 0x8f, 0x03,
|
||||
0x8d, 0x07, 0x0c, 0x87, 0xba, 0xf3, 0x39, 0xa3, 0x1b, 0x8b, 0xa2, 0xb6, 0x32, 0x5d, 0xd4, 0x5e,
|
||||
0x82, 0x71, 0xf3, 0x62, 0x1d, 0x59, 0xea, 0x66, 0x4a, 0x5d, 0x49, 0x75, 0xb2, 0x2b, 0x79, 0x17,
|
||||
0x9a, 0x54, 0x29, 0x14, 0xa4, 0x58, 0x0e, 0x4d, 0x4e, 0x6c, 0xf8, 0xa0, 0x49, 0xbb, 0x8a, 0xa2,
|
||||
0xda, 0x96, 0x5c, 0x40, 0xb7, 0x2d, 0x8b, 0x73, 0xb7, 0x2d, 0x76, 0x11, 0xdd, 0xb6, 0xfc, 0xda,
|
||||
0x01, 0xd0, 0x07, 0x57, 0xf9, 0xe0, 0xe8, 0xa2, 0xce, 0x59, 0x16, 0x55, 0xc9, 0x5a, 0x7b, 0x8a,
|
||||
0x44, 0x58, 0x8e, 0x83, 0x4a, 0x58, 0xe3, 0x20, 0xe5, 0x35, 0xc3, 0xb2, 0x01, 0x25, 0xbc, 0xdf,
|
||||
0x3b, 0x00, 0x3a, 0x2b, 0x18, 0x35, 0xa6, 0xe1, 0xe7, 0x9c, 0xdc, 0xd0, 0x55, 0x26, 0x4d, 0x77,
|
||||
0x37, 0x37, 0xdd, 0x09, 0x2f, 0xa6, 0xa5, 0x0a, 0x3c, 0x3f, 0xbc, 0xb5, 0xae, 0xfe, 0xf6, 0xfe,
|
||||
0xe0, 0x40, 0xcb, 0x6a, 0x67, 0x54, 0x9a, 0xf0, 0xb2, 0x33, 0xed, 0x65, 0x5d, 0xc6, 0xc4, 0x8c,
|
||||
0x8f, 0x02, 0x41, 0x5f, 0x10, 0xab, 0x10, 0x18, 0xd2, 0x1e, 0x7d, 0x41, 0x26, 0xc0, 0xeb, 0x4e,
|
||||
0x82, 0xf7, 0x2a, 0xac, 0x72, 0xd2, 0x27, 0x89, 0x8c, 0x46, 0x41, 0xcc, 0x42, 0xba, 0x4f, 0x49,
|
||||
0xa8, 0xd1, 0x50, 0xf7, 0xdb, 0x39, 0xe3, 0xa1, 0xa5, 0x7b, 0xbf, 0x72, 0xa0, 0xf9, 0x50, 0x0c,
|
||||
0x76, 0x99, 0xd0, 0x41, 0x86, 0x2e, 0x43, 0xcb, 0x26, 0x36, 0x13, 0xe1, 0x8e, 0x46, 0x58, 0xb3,
|
||||
0x3f, 0x7e, 0x75, 0x54, 0xa9, 0x3d, 0x16, 0x03, 0x6b, 0xa6, 0x96, 0x6f, 0x06, 0x68, 0x1d, 0xea,
|
||||
0xb1, 0x18, 0xe8, 0xaa, 0xdb, 0xc2, 0xb2, 0x18, 0xab, 0xb3, 0x8e, 0x2f, 0xab, 0xaa, 0xbe, 0xac,
|
||||
0xc6, 0x04, 0xef, 0x33, 0x07, 0x90, 0x7d, 0xd5, 0x7c, 0xa5, 0x9f, 0x10, 0xda, 0xcb, 0xe5, 0x97,
|
||||
0xd3, 0x8a, 0xc6, 0xf8, 0x04, 0x6d, 0x2a, 0x29, 0xb8, 0x47, 0x92, 0xc2, 0x55, 0x58, 0x0d, 0xc9,
|
||||
0x3e, 0xce, 0xa2, 0xf2, 0xfd, 0x6a, 0x54, 0x6e, 0x5b, 0xc6, 0xc4, 0x2b, 0xfe, 0xf2, 0x36, 0x27,
|
||||
0x21, 0x49, 0x24, 0xc5, 0x91, 0xfe, 0xb9, 0xb4, 0x0e, 0xf5, 0x4c, 0x28, 0x24, 0x14, 0xb6, 0x2b,
|
||||
0xc6, 0xe8, 0x7d, 0x40, 0x24, 0xe9, 0xf3, 0x51, 0xaa, 0x40, 0x9c, 0x62, 0x21, 0x0e, 0x19, 0x0f,
|
||||
0x6d, 0xa2, 0x5e, 0x2d, 0x38, 0xbb, 0x96, 0xa1, 0xda, 0x53, 0x49, 0x12, 0x9c, 0xc8, 0x3c, 0x5f,
|
||||
0x9b, 0x91, 0x72, 0x3d, 0x15, 0x81, 0xc8, 0x52, 0xc2, 0xad, 0x5b, 0x6b, 0x54, 0xec, 0xa9, 0xa1,
|
||||
0x4a, 0xe5, 0x62, 0x88, 0xb7, 0x3e, 0xba, 0x39, 0x5e, 0xde, 0xa4, 0xe8, 0x65, 0x43, 0xce, 0xd7,
|
||||
0xf6, 0x3e, 0x81, 0xd5, 0x07, 0x54, 0xc8, 0x5d, 0x16, 0xd1, 0xfe, 0xe8, 0xcc, 0x37, 0x8e, 0x17,
|
||||
0x01, 0x2a, 0x2f, 0x63, 0x7f, 0x61, 0x8c, 0x0b, 0x06, 0x67, 0xfe, 0x82, 0xe1, 0x32, 0xb4, 0x52,
|
||||
0xbd, 0x8c, 0xfe, 0x61, 0x9a, 0x3b, 0xaf, 0x69, 0x68, 0xca, 0xb4, 0xc2, 0x1b, 0xc0, 0x85, 0xbd,
|
||||
0x21, 0x3b, 0xdc, 0x66, 0xc9, 0x3e, 0x1d, 0x64, 0x1c, 0x2b, 0xc0, 0xbe, 0xc2, 0xdb, 0x57, 0x07,
|
||||
0x6a, 0x29, 0x96, 0x2a, 0x6c, 0xad, 0x0f, 0xf2, 0xa1, 0xf7, 0xa9, 0x03, 0xeb, 0xb3, 0x76, 0x7a,
|
||||
0x95, 0xf3, 0xdd, 0x83, 0xa5, 0xbe, 0x59, 0xce, 0xac, 0x36, 0xff, 0x4f, 0xc0, 0xc9, 0x79, 0x57,
|
||||
0x3e, 0x86, 0x46, 0xf1, 0xc3, 0x19, 0xb5, 0xa1, 0xb5, 0x93, 0x50, 0xa9, 0x6b, 0x55, 0x9a, 0x0c,
|
||||
0xda, 0x6f, 0xa0, 0x26, 0xd4, 0x7e, 0x4c, 0x70, 0x24, 0x87, 0xa3, 0xb6, 0x83, 0x5a, 0x50, 0xbf,
|
||||
0xd3, 0x4b, 0x18, 0x8f, 0x71, 0xd4, 0xae, 0x5c, 0xd9, 0x82, 0xd5, 0x23, 0xef, 0x03, 0x4a, 0xc4,
|
||||
0x67, 0x87, 0xca, 0x2c, 0x61, 0xfb, 0x0d, 0xb4, 0x02, 0xcd, 0x6d, 0x16, 0x65, 0x71, 0x62, 0x08,
|
||||
0xce, 0xdd, 0x5b, 0xbf, 0xf8, 0x68, 0x40, 0xe5, 0x30, 0xeb, 0x29, 0xd5, 0xae, 0x1b, 0x5d, 0xdf,
|
||||
0xa7, 0xcc, 0x7e, 0x5d, 0xcf, 0xd3, 0xde, 0x75, 0xad, 0x7e, 0x31, 0x4c, 0x7b, 0xbd, 0x45, 0x4d,
|
||||
0xf9, 0xe0, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x32, 0x32, 0x7c, 0x82, 0xca, 0x1f, 0x00, 0x00,
|
||||
// 2211 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x59, 0xcf, 0x73, 0x1b, 0x49,
|
||||
0xf5, 0xdf, 0xd1, 0xc8, 0x96, 0xf4, 0x24, 0xcb, 0x72, 0xc7, 0xc9, 0x2a, 0x4e, 0xb2, 0xeb, 0xcc,
|
||||
0x77, 0xbf, 0x60, 0x12, 0x36, 0x09, 0xde, 0xdd, 0x64, 0x0b, 0x28, 0x42, 0x62, 0x2d, 0xc1, 0x95,
|
||||
0x1f, 0x98, 0x71, 0x48, 0x15, 0x5c, 0xa6, 0x5a, 0x9a, 0xb6, 0xd4, 0x64, 0x66, 0x7a, 0xdc, 0xdd,
|
||||
0x63, 0x47, 0x39, 0x71, 0xe0, 0xc4, 0x16, 0xdc, 0xb8, 0x6c, 0x15, 0x9c, 0xb9, 0x70, 0xde, 0x1b,
|
||||
0x54, 0x71, 0xe2, 0xc4, 0x89, 0x0b, 0xff, 0x0a, 0xc5, 0x81, 0xea, 0x1f, 0x33, 0xfa, 0x61, 0xd9,
|
||||
0x91, 0x9d, 0xda, 0xdd, 0x50, 0xb5, 0xb7, 0xe9, 0xf7, 0x5e, 0x77, 0xbf, 0x7e, 0xef, 0xf3, 0x5e,
|
||||
0xbf, 0xd7, 0x03, 0x4d, 0x9a, 0x48, 0xc2, 0x13, 0x1c, 0xdd, 0x48, 0x39, 0x93, 0x0c, 0x9d, 0x8f,
|
||||
0x69, 0x74, 0x90, 0x09, 0x33, 0xba, 0x91, 0x33, 0xd7, 0x1a, 0x3d, 0x16, 0xc7, 0x2c, 0x31, 0xe4,
|
||||
0xb5, 0x86, 0xe8, 0x0d, 0x48, 0x8c, 0xcd, 0xc8, 0xfb, 0x8b, 0x03, 0x4b, 0x5b, 0x2c, 0x4e, 0x59,
|
||||
0x42, 0x12, 0xb9, 0x9d, 0xec, 0x31, 0x74, 0x01, 0x16, 0x13, 0x16, 0x92, 0xed, 0x4e, 0xdb, 0x59,
|
||||
0x77, 0x36, 0x5c, 0xdf, 0x8e, 0x10, 0x82, 0x32, 0x67, 0x11, 0x69, 0x97, 0xd6, 0x9d, 0x8d, 0x9a,
|
||||
0xaf, 0xbf, 0xd1, 0x5d, 0x00, 0x21, 0xb1, 0x24, 0x41, 0x8f, 0x85, 0xa4, 0xed, 0xae, 0x3b, 0x1b,
|
||||
0xcd, 0xcd, 0xf5, 0x1b, 0x33, 0xb5, 0xb8, 0xb1, 0xab, 0x04, 0xb7, 0x58, 0x48, 0xfc, 0x9a, 0xc8,
|
||||
0x3f, 0xd1, 0x0f, 0x01, 0xc8, 0x0b, 0xc9, 0x71, 0x40, 0x93, 0x3d, 0xd6, 0x2e, 0xaf, 0xbb, 0x1b,
|
||||
0xf5, 0xcd, 0xab, 0x93, 0x0b, 0x58, 0xe5, 0x1f, 0x92, 0xe1, 0x33, 0x1c, 0x65, 0x64, 0x07, 0x53,
|
||||
0xee, 0xd7, 0xf4, 0x24, 0xa5, 0xae, 0xf7, 0x2f, 0x07, 0x96, 0x8b, 0x03, 0xe8, 0x3d, 0x04, 0xfa,
|
||||
0x2e, 0x2c, 0xe8, 0x2d, 0xf4, 0x09, 0xea, 0x9b, 0xef, 0x1d, 0xa3, 0xd1, 0xc4, 0xb9, 0x7d, 0x33,
|
||||
0x05, 0xfd, 0x0c, 0xce, 0x89, 0xac, 0xdb, 0xcb, 0x59, 0x81, 0xa6, 0x8a, 0x76, 0x49, 0xab, 0x36,
|
||||
0xdf, 0x4a, 0x68, 0x7c, 0x01, 0xab, 0xd2, 0x07, 0xb0, 0xa8, 0x56, 0xca, 0x84, 0xb6, 0x52, 0x7d,
|
||||
0xf3, 0xd2, 0xcc, 0x43, 0xee, 0x6a, 0x11, 0xdf, 0x8a, 0x7a, 0x97, 0xe0, 0xe2, 0x03, 0x22, 0xa7,
|
||||
0x4e, 0xe7, 0x93, 0xfd, 0x8c, 0x08, 0x69, 0x99, 0x4f, 0x69, 0x4c, 0x9e, 0xd2, 0xde, 0xf3, 0xad,
|
||||
0x01, 0x4e, 0x12, 0x12, 0xe5, 0xcc, 0x2b, 0x70, 0xe9, 0x01, 0xd1, 0x13, 0xa8, 0x90, 0xb4, 0x27,
|
||||
0xa6, 0xd8, 0xe7, 0xe1, 0xdc, 0x03, 0x22, 0x3b, 0xe1, 0x14, 0xf9, 0x19, 0x54, 0x9f, 0x28, 0x67,
|
||||
0x2b, 0x18, 0xdc, 0x86, 0x0a, 0x0e, 0x43, 0x4e, 0x84, 0xb0, 0x56, 0xbc, 0x3c, 0x53, 0xe3, 0x7b,
|
||||
0x46, 0xc6, 0xcf, 0x85, 0x67, 0xc1, 0xc4, 0xfb, 0x25, 0xc0, 0x76, 0x42, 0xe5, 0x0e, 0xe6, 0x38,
|
||||
0x16, 0xc7, 0x02, 0xac, 0x03, 0x0d, 0x21, 0x31, 0x97, 0x41, 0xaa, 0xe5, 0xac, 0xc9, 0xe7, 0x40,
|
||||
0x43, 0x5d, 0x4f, 0x33, 0xab, 0x7b, 0x3f, 0x07, 0xd8, 0x95, 0x9c, 0x26, 0xfd, 0x47, 0x54, 0x48,
|
||||
0xb5, 0xd7, 0x81, 0x92, 0x53, 0x87, 0x70, 0x37, 0x6a, 0xbe, 0x1d, 0x8d, 0xb9, 0xa3, 0x34, 0xbf,
|
||||
0x3b, 0xee, 0x42, 0x3d, 0x37, 0xf7, 0x63, 0xd1, 0x47, 0xb7, 0xa0, 0xdc, 0xc5, 0x82, 0x9c, 0x68,
|
||||
0x9e, 0xc7, 0xa2, 0x7f, 0x1f, 0x0b, 0xe2, 0x6b, 0x49, 0xef, 0xcf, 0x25, 0x58, 0x9d, 0x70, 0x8b,
|
||||
0x35, 0xfc, 0xe9, 0x97, 0x52, 0x66, 0x0e, 0xbb, 0xdb, 0x1d, 0xad, 0xbe, 0xeb, 0xeb, 0x6f, 0xe4,
|
||||
0x41, 0xa3, 0xc7, 0xa2, 0x88, 0xf4, 0x24, 0x65, 0xc9, 0x76, 0x47, 0x23, 0xcd, 0xf5, 0x27, 0x68,
|
||||
0x4a, 0x26, 0xc5, 0x5c, 0x52, 0x33, 0x14, 0x3a, 0xe4, 0x5c, 0x7f, 0x82, 0x86, 0xbe, 0x05, 0x2d,
|
||||
0xc9, 0xf1, 0x01, 0x89, 0x02, 0x49, 0x63, 0x22, 0x24, 0x8e, 0xd3, 0xf6, 0xc2, 0xba, 0xb3, 0x51,
|
||||
0xf6, 0x97, 0x0d, 0xfd, 0x69, 0x4e, 0x46, 0x37, 0xe1, 0x5c, 0x3f, 0xc3, 0x1c, 0x27, 0x92, 0x90,
|
||||
0x31, 0xe9, 0x45, 0x2d, 0x8d, 0x0a, 0xd6, 0x68, 0xc2, 0x75, 0x58, 0x51, 0x62, 0x2c, 0x93, 0x63,
|
||||
0xe2, 0x15, 0x2d, 0xde, 0xb2, 0x8c, 0x42, 0xd8, 0xfb, 0xdc, 0x81, 0xf3, 0x53, 0xf6, 0x12, 0x29,
|
||||
0x4b, 0x04, 0x39, 0x83, 0xc1, 0xce, 0xe2, 0x71, 0x74, 0xc7, 0x24, 0x12, 0x15, 0xb4, 0x73, 0x62,
|
||||
0xd1, 0xc8, 0x7b, 0xbf, 0x71, 0xe1, 0xed, 0x2d, 0x4e, 0x74, 0x9a, 0xcb, 0xad, 0x7f, 0x76, 0x67,
|
||||
0xbf, 0x0d, 0x95, 0xb0, 0x1b, 0x24, 0x38, 0xce, 0xc3, 0x6a, 0x31, 0xec, 0x3e, 0xc1, 0x31, 0x41,
|
||||
0xdf, 0x80, 0xe6, 0xc8, 0xbb, 0x8a, 0xa2, 0x7d, 0x5e, 0xf3, 0xa7, 0xa8, 0xe8, 0x3d, 0x58, 0x2a,
|
||||
0x3c, 0xac, 0xc5, 0xca, 0x5a, 0x6c, 0x92, 0x58, 0x60, 0x6a, 0xe1, 0x04, 0x4c, 0x2d, 0xce, 0xc0,
|
||||
0xd4, 0x3a, 0xd4, 0xc7, 0xf0, 0xa3, 0xbd, 0xe9, 0xfa, 0xe3, 0x24, 0x15, 0x86, 0xe6, 0xd6, 0x69,
|
||||
0x57, 0xd7, 0x9d, 0x8d, 0x86, 0x6f, 0x47, 0xe8, 0x16, 0x9c, 0x3b, 0xa0, 0x5c, 0x66, 0x38, 0xb2,
|
||||
0x99, 0x48, 0xe9, 0x21, 0xda, 0x35, 0x1d, 0xab, 0xb3, 0x58, 0x68, 0x13, 0x56, 0xd3, 0xc1, 0x50,
|
||||
0xd0, 0xde, 0xd4, 0x14, 0xd0, 0x53, 0x66, 0xf2, 0xbc, 0xbf, 0x39, 0x70, 0xbe, 0xc3, 0x59, 0xfa,
|
||||
0x46, 0xb8, 0x22, 0x37, 0x72, 0xf9, 0x04, 0x23, 0x2f, 0x1c, 0x35, 0xb2, 0xf7, 0xdb, 0x12, 0x5c,
|
||||
0x30, 0x88, 0xda, 0xc9, 0x0d, 0xfb, 0x05, 0x9c, 0xe2, 0x9b, 0xb0, 0x3c, 0xda, 0xd5, 0x08, 0xcc,
|
||||
0x3e, 0xc6, 0xff, 0x43, 0xb3, 0x70, 0xb0, 0x91, 0xfb, 0x72, 0x21, 0xe5, 0x7d, 0x5a, 0x82, 0x55,
|
||||
0xe5, 0xd4, 0xaf, 0xad, 0xa1, 0xac, 0xf1, 0x47, 0x07, 0x90, 0x41, 0xc7, 0xbd, 0x88, 0x62, 0xf1,
|
||||
0x55, 0xda, 0x62, 0x15, 0x16, 0xb0, 0xd2, 0xc1, 0x9a, 0xc0, 0x0c, 0x3c, 0x01, 0x2d, 0xe5, 0xad,
|
||||
0x2f, 0x4a, 0xbb, 0x62, 0x53, 0x77, 0x7c, 0xd3, 0x3f, 0x38, 0xb0, 0x72, 0x2f, 0x92, 0x84, 0xbf,
|
||||
0xa1, 0x46, 0xf9, 0x6b, 0x29, 0xf7, 0xda, 0x76, 0x12, 0x92, 0x17, 0x5f, 0xa5, 0x82, 0x57, 0x00,
|
||||
0xf6, 0x28, 0x89, 0xc2, 0x71, 0xf4, 0xd6, 0x34, 0xe5, 0xb5, 0x90, 0xdb, 0x86, 0x8a, 0x5e, 0xa4,
|
||||
0x40, 0x6d, 0x3e, 0x54, 0xd5, 0x9e, 0xa9, 0xfc, 0x6d, 0xb5, 0x57, 0x9d, 0xbb, 0xda, 0xd3, 0xd3,
|
||||
0x6c, 0xb5, 0xf7, 0x8f, 0x32, 0x2c, 0x6d, 0x27, 0x82, 0x70, 0x79, 0x76, 0xe3, 0x5d, 0x86, 0x9a,
|
||||
0x18, 0x60, 0xae, 0x0f, 0x6a, 0xcd, 0x37, 0x22, 0x8c, 0x9b, 0xd6, 0x7d, 0x95, 0x69, 0xcb, 0x73,
|
||||
0x26, 0x87, 0x85, 0x93, 0x92, 0xc3, 0xe2, 0x09, 0x26, 0xae, 0xbc, 0x3a, 0x39, 0x54, 0x8f, 0xde,
|
||||
0xbe, 0xea, 0x80, 0xa4, 0x1f, 0xab, 0xf6, 0xa4, 0xd3, 0xae, 0x69, 0xfe, 0x88, 0x80, 0xde, 0x01,
|
||||
0x28, 0x2a, 0x31, 0x73, 0x8f, 0x96, 0xfd, 0x31, 0x8a, 0xba, 0xbb, 0x39, 0x3b, 0x54, 0xb5, 0x62,
|
||||
0x5d, 0xd7, 0x8a, 0x76, 0x84, 0x3e, 0x84, 0x2a, 0x67, 0x87, 0x41, 0x88, 0x25, 0x6e, 0x37, 0xb4,
|
||||
0xf3, 0x2e, 0xce, 0x34, 0xf6, 0xfd, 0x88, 0x75, 0xfd, 0x0a, 0x67, 0x87, 0x1d, 0x2c, 0x31, 0xba,
|
||||
0x0b, 0x75, 0x8d, 0x00, 0x61, 0x26, 0x2e, 0xe9, 0x89, 0xef, 0x4c, 0x4e, 0xb4, 0x0d, 0xea, 0x8f,
|
||||
0x94, 0x9c, 0x9a, 0xe4, 0x1b, 0x68, 0x0a, 0xbd, 0xc0, 0x45, 0xa8, 0x26, 0x59, 0x1c, 0x70, 0x76,
|
||||
0x28, 0xda, 0x4d, 0x5d, 0x37, 0x56, 0x92, 0x2c, 0xf6, 0xd9, 0xa1, 0x40, 0xf7, 0xa1, 0x72, 0x40,
|
||||
0xb8, 0xa0, 0x2c, 0x69, 0x2f, 0xeb, 0x56, 0x74, 0xe3, 0x98, 0x76, 0xcd, 0x20, 0x46, 0x2d, 0xf7,
|
||||
0xcc, 0xc8, 0xfb, 0xf9, 0x44, 0xef, 0x9f, 0x65, 0x58, 0xda, 0x25, 0x98, 0xf7, 0x06, 0x67, 0x07,
|
||||
0xd4, 0x2a, 0x2c, 0x70, 0xb2, 0x5f, 0x14, 0xe7, 0x66, 0x50, 0xf8, 0xd7, 0x3d, 0xc1, 0xbf, 0xe5,
|
||||
0x39, 0x2a, 0xf6, 0x85, 0x19, 0x15, 0x7b, 0x0b, 0xdc, 0x50, 0x44, 0x1a, 0x3a, 0x35, 0x5f, 0x7d,
|
||||
0xaa, 0x3a, 0x3b, 0x8d, 0x70, 0x8f, 0x0c, 0x58, 0x14, 0x12, 0x1e, 0xf4, 0x39, 0xcb, 0x4c, 0x9d,
|
||||
0xdd, 0xf0, 0x5b, 0x63, 0x8c, 0x07, 0x8a, 0x8e, 0xee, 0x40, 0x35, 0x14, 0x51, 0x20, 0x87, 0x29,
|
||||
0xd1, 0xf8, 0x69, 0x1e, 0x73, 0xcc, 0x8e, 0x88, 0x9e, 0x0e, 0x53, 0xe2, 0x57, 0x42, 0xf3, 0x81,
|
||||
0x6e, 0xc1, 0xaa, 0x20, 0x9c, 0xe2, 0x88, 0xbe, 0x24, 0x61, 0x40, 0x5e, 0xa4, 0x3c, 0x48, 0x23,
|
||||
0x9c, 0x68, 0x90, 0x35, 0x7c, 0x34, 0xe2, 0x7d, 0xf2, 0x22, 0xe5, 0x3b, 0x11, 0x4e, 0xd0, 0x06,
|
||||
0xb4, 0x58, 0x26, 0xd3, 0x4c, 0x06, 0x16, 0x06, 0x34, 0xd4, 0x98, 0x73, 0xfd, 0xa6, 0xa1, 0x6b,
|
||||
0xaf, 0x8b, 0xed, 0x70, 0x66, 0x17, 0x52, 0x3f, 0x55, 0x17, 0xd2, 0x38, 0x5d, 0x17, 0xb2, 0x34,
|
||||
0xbb, 0x0b, 0x41, 0x4d, 0x28, 0x25, 0xfb, 0x1a, 0x6b, 0xae, 0x5f, 0x4a, 0xf6, 0x95, 0x23, 0x25,
|
||||
0x4b, 0x9f, 0x6b, 0x8c, 0xb9, 0xbe, 0xfe, 0x56, 0x41, 0x14, 0x13, 0xc9, 0x69, 0x4f, 0x99, 0xa5,
|
||||
0xdd, 0xd2, 0x7e, 0x18, 0xa3, 0x78, 0xff, 0x71, 0x47, 0xb0, 0x12, 0x59, 0x24, 0xc5, 0x97, 0xd5,
|
||||
0xc1, 0x14, 0x58, 0x74, 0xc7, 0xb1, 0xf8, 0x2e, 0xd4, 0x8d, 0x72, 0xc6, 0xe7, 0xe5, 0x69, 0x7d,
|
||||
0x95, 0x80, 0x8a, 0xb2, 0xfd, 0x8c, 0x70, 0x4a, 0x84, 0x4d, 0xfb, 0x90, 0x64, 0xf1, 0x4f, 0x0d,
|
||||
0x05, 0x9d, 0x83, 0x05, 0xc9, 0xd2, 0xe0, 0x79, 0x9e, 0xae, 0x24, 0x4b, 0x1f, 0xa2, 0xef, 0xc3,
|
||||
0x9a, 0x20, 0x38, 0x22, 0x61, 0x50, 0xa4, 0x17, 0x11, 0x08, 0x7d, 0x6c, 0x12, 0xb6, 0x2b, 0xda,
|
||||
0xcd, 0x6d, 0x23, 0xb1, 0x5b, 0x08, 0xec, 0x5a, 0xbe, 0xf2, 0x62, 0xcf, 0x94, 0xed, 0x13, 0xd3,
|
||||
0xaa, 0xba, 0xb2, 0x47, 0x23, 0x56, 0x31, 0xe1, 0x63, 0x68, 0xf7, 0x23, 0xd6, 0xc5, 0x51, 0x70,
|
||||
0x64, 0x57, 0xdd, 0x42, 0xb8, 0xfe, 0x05, 0xc3, 0xdf, 0x9d, 0xda, 0x52, 0x1d, 0x4f, 0x44, 0xb4,
|
||||
0x47, 0xc2, 0xa0, 0x1b, 0xb1, 0x6e, 0x1b, 0x34, 0x5c, 0xc1, 0x90, 0x54, 0xbe, 0x52, 0x30, 0xb5,
|
||||
0x02, 0xca, 0x0c, 0x3d, 0x96, 0x25, 0x52, 0x83, 0xcf, 0xf5, 0x9b, 0x86, 0xfe, 0x24, 0x8b, 0xb7,
|
||||
0x14, 0x15, 0xfd, 0x1f, 0x2c, 0x59, 0x49, 0xb6, 0xb7, 0x27, 0x88, 0xd4, 0xa8, 0x73, 0xfd, 0x86,
|
||||
0x21, 0xfe, 0x44, 0xd3, 0xbc, 0xcf, 0x5c, 0x58, 0xf6, 0x95, 0x75, 0xc9, 0x01, 0xf9, 0x5f, 0xca,
|
||||
0x2b, 0xc7, 0xc5, 0xf7, 0xe2, 0xa9, 0xe2, 0xbb, 0x32, 0x77, 0x7c, 0x57, 0x4f, 0x15, 0xdf, 0xb5,
|
||||
0xd3, 0xc5, 0x37, 0x1c, 0xf3, 0xca, 0xf0, 0xa7, 0x09, 0xe7, 0xbc, 0x01, 0xd1, 0x79, 0x0d, 0x5c,
|
||||
0x1a, 0x9a, 0x52, 0xb1, 0xbe, 0xd9, 0x9e, 0x79, 0x37, 0x6e, 0x77, 0x84, 0xaf, 0x84, 0xa6, 0xef,
|
||||
0xd3, 0x85, 0x53, 0xdf, 0xa7, 0x3f, 0x80, 0x4b, 0x47, 0x63, 0x96, 0x5b, 0x73, 0x84, 0xed, 0x45,
|
||||
0xed, 0xbb, 0x8b, 0xd3, 0x41, 0x9b, 0xdb, 0x2b, 0x44, 0xdf, 0x81, 0xd5, 0xb1, 0xa8, 0x1d, 0x4d,
|
||||
0xac, 0x98, 0x1e, 0x7e, 0xc4, 0x1b, 0x4d, 0x39, 0x29, 0x6e, 0xab, 0x27, 0xc5, 0xad, 0xf7, 0x77,
|
||||
0x17, 0x96, 0x3a, 0x24, 0x22, 0x92, 0x7c, 0x5d, 0xee, 0x1d, 0x5b, 0xee, 0x7d, 0x1b, 0x10, 0x4d,
|
||||
0xe4, 0xed, 0x0f, 0x83, 0x94, 0xd3, 0x18, 0xf3, 0x61, 0xf0, 0x9c, 0x0c, 0xf3, 0x84, 0xd8, 0xd2,
|
||||
0x9c, 0x1d, 0xc3, 0x78, 0x48, 0x86, 0xe2, 0x95, 0xe5, 0xdf, 0x78, 0xbd, 0x65, 0x32, 0x60, 0x51,
|
||||
0x6f, 0x7d, 0x0f, 0x1a, 0x13, 0x5b, 0x34, 0x5e, 0x01, 0xd8, 0x7a, 0x3a, 0xda, 0xd7, 0xfb, 0xb7,
|
||||
0x03, 0xb5, 0x47, 0x0c, 0x87, 0xba, 0xf3, 0x39, 0xa3, 0x1b, 0x8b, 0xa2, 0xb6, 0x34, 0x5d, 0xd4,
|
||||
0x5e, 0x86, 0x51, 0xf3, 0x62, 0x1d, 0x39, 0xd6, 0xcd, 0x8c, 0x75, 0x25, 0xe5, 0xc9, 0xae, 0xe4,
|
||||
0x5d, 0xa8, 0x53, 0xa5, 0x50, 0x90, 0x62, 0x39, 0x30, 0x39, 0xb1, 0xe6, 0x83, 0x26, 0xed, 0x28,
|
||||
0x8a, 0x6a, 0x5b, 0x72, 0x01, 0xdd, 0xb6, 0x2c, 0xce, 0xdd, 0xb6, 0xd8, 0x45, 0x74, 0xdb, 0xf2,
|
||||
0x6b, 0x07, 0x40, 0x1f, 0x5c, 0xe5, 0x83, 0xa3, 0x8b, 0x3a, 0x67, 0x59, 0x54, 0x25, 0x6b, 0xed,
|
||||
0x29, 0x12, 0x61, 0x39, 0x0a, 0x2a, 0x61, 0x8d, 0x83, 0x94, 0xd7, 0x0c, 0xcb, 0x06, 0x94, 0xf0,
|
||||
0x7e, 0xe7, 0x00, 0xe8, 0xac, 0x60, 0xd4, 0x98, 0x86, 0x9f, 0x73, 0x72, 0x43, 0x57, 0x9a, 0x34,
|
||||
0xdd, 0xfd, 0xdc, 0x74, 0x27, 0xbc, 0x98, 0x8e, 0x55, 0xe0, 0xf9, 0xe1, 0xad, 0x75, 0xf5, 0xb7,
|
||||
0xf7, 0x7b, 0x07, 0x1a, 0x56, 0x3b, 0xa3, 0xd2, 0x84, 0x97, 0x9d, 0x69, 0x2f, 0xeb, 0x32, 0x26,
|
||||
0x66, 0x7c, 0x18, 0x08, 0xfa, 0x92, 0x58, 0x85, 0xc0, 0x90, 0x76, 0xe9, 0x4b, 0x32, 0x01, 0x5e,
|
||||
0x77, 0x12, 0xbc, 0xd7, 0x61, 0x85, 0x93, 0x1e, 0x49, 0x64, 0x34, 0x0c, 0x62, 0x16, 0xd2, 0x3d,
|
||||
0x4a, 0x42, 0x8d, 0x86, 0xaa, 0xdf, 0xca, 0x19, 0x8f, 0x2d, 0xdd, 0xfb, 0x95, 0x03, 0xf5, 0xc7,
|
||||
0xa2, 0xbf, 0xc3, 0x84, 0x0e, 0x32, 0x74, 0x15, 0x1a, 0x36, 0xb1, 0x99, 0x08, 0x77, 0x34, 0xc2,
|
||||
0xea, 0xbd, 0xd1, 0xab, 0xa3, 0x4a, 0xed, 0xb1, 0xe8, 0x5b, 0x33, 0x35, 0x7c, 0x33, 0x40, 0x6b,
|
||||
0x50, 0x8d, 0x45, 0x5f, 0x57, 0xdd, 0x16, 0x96, 0xc5, 0x58, 0x9d, 0x75, 0x74, 0x59, 0x95, 0xf5,
|
||||
0x65, 0x35, 0x22, 0x78, 0x9f, 0x3b, 0x80, 0xec, 0xab, 0xe6, 0x6b, 0xfd, 0x84, 0xd0, 0x5e, 0x1e,
|
||||
0x7f, 0x39, 0x2d, 0x69, 0x8c, 0x4f, 0xd0, 0xa6, 0x92, 0x82, 0x7b, 0x24, 0x29, 0x5c, 0x87, 0x95,
|
||||
0x90, 0xec, 0xe1, 0x2c, 0x1a, 0xbf, 0x5f, 0x8d, 0xca, 0x2d, 0xcb, 0x98, 0x78, 0xc5, 0x6f, 0x6e,
|
||||
0x71, 0x12, 0x92, 0x44, 0x52, 0x1c, 0xe9, 0x9f, 0x4b, 0x6b, 0x50, 0xcd, 0x84, 0x42, 0x42, 0x61,
|
||||
0xbb, 0x62, 0x8c, 0xde, 0x07, 0x44, 0x92, 0x1e, 0x1f, 0xa6, 0x0a, 0xc4, 0x29, 0x16, 0xe2, 0x90,
|
||||
0xf1, 0xd0, 0x26, 0xea, 0x95, 0x82, 0xb3, 0x63, 0x19, 0xaa, 0x3d, 0x95, 0x24, 0xc1, 0x89, 0xcc,
|
||||
0xf3, 0xb5, 0x19, 0x29, 0xd7, 0x53, 0x11, 0x88, 0x2c, 0x25, 0xdc, 0xba, 0xb5, 0x42, 0xc5, 0xae,
|
||||
0x1a, 0xaa, 0x54, 0x2e, 0x06, 0x78, 0xf3, 0xa3, 0xdb, 0xa3, 0xe5, 0x4d, 0x8a, 0x6e, 0x1a, 0x72,
|
||||
0xbe, 0xb6, 0xf7, 0x09, 0xac, 0x3c, 0xa2, 0x42, 0xee, 0xb0, 0x88, 0xf6, 0x86, 0x67, 0xbe, 0x71,
|
||||
0xbc, 0x4f, 0x1d, 0x40, 0xe3, 0xeb, 0xd8, 0x7f, 0x18, 0xa3, 0x8a, 0xc1, 0x99, 0xbf, 0x62, 0xb8,
|
||||
0x0a, 0x8d, 0x54, 0x2f, 0xa3, 0xff, 0x98, 0xe6, 0xde, 0xab, 0x1b, 0x9a, 0xb2, 0xad, 0x40, 0x57,
|
||||
0x00, 0x94, 0x31, 0x03, 0xce, 0x22, 0x62, 0x9c, 0x57, 0xf3, 0x6b, 0x8a, 0xe2, 0x2b, 0x82, 0xd7,
|
||||
0x87, 0x8b, 0xbb, 0x03, 0x76, 0xb8, 0xc5, 0x92, 0x3d, 0xda, 0xcf, 0x38, 0x56, 0x80, 0x7e, 0x8d,
|
||||
0xb7, 0xb1, 0x36, 0x54, 0x52, 0x2c, 0x55, 0x58, 0x5b, 0x1f, 0xe5, 0x43, 0xef, 0x33, 0x07, 0xd6,
|
||||
0x66, 0xed, 0xf4, 0x3a, 0xc7, 0x7f, 0x00, 0x4b, 0x3d, 0xb3, 0x9c, 0x59, 0x6d, 0xfe, 0x9f, 0x84,
|
||||
0x93, 0xf3, 0xae, 0x7d, 0x0c, 0xb5, 0xe2, 0x87, 0x34, 0x6a, 0x41, 0x63, 0x3b, 0xa1, 0x52, 0xd7,
|
||||
0xb2, 0x34, 0xe9, 0xb7, 0xde, 0x42, 0x75, 0xa8, 0xfc, 0x98, 0xe0, 0x48, 0x0e, 0x86, 0x2d, 0x07,
|
||||
0x35, 0xa0, 0x7a, 0xaf, 0x9b, 0x30, 0x1e, 0xe3, 0xa8, 0x55, 0xba, 0xb6, 0x09, 0x2b, 0x47, 0xde,
|
||||
0x0f, 0x94, 0x88, 0xcf, 0x0e, 0x95, 0x59, 0xc2, 0xd6, 0x5b, 0x68, 0x19, 0xea, 0x5b, 0x2c, 0xca,
|
||||
0xe2, 0xc4, 0x10, 0x9c, 0xfb, 0x77, 0x7e, 0xf1, 0x51, 0x9f, 0xca, 0x41, 0xd6, 0x55, 0xaa, 0xdd,
|
||||
0x34, 0xba, 0xbe, 0x4f, 0x99, 0xfd, 0xba, 0x99, 0xa7, 0xc5, 0x9b, 0x5a, 0xfd, 0x62, 0x98, 0x76,
|
||||
0xbb, 0x8b, 0x9a, 0xf2, 0xc1, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x10, 0x68, 0x86, 0x3f, 0xea,
|
||||
0x1f, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -81,7 +81,6 @@ service MilvusService {
|
|||
rpc OperateUserRole(OperateUserRoleRequest) returns (common.Status) {}
|
||||
rpc SelectRole(SelectRoleRequest) returns (SelectRoleResponse) {}
|
||||
rpc SelectUser(SelectUserRequest) returns (SelectUserResponse) {}
|
||||
rpc SelectResource(SelectResourceRequest) returns (SelectResourceResponse) {}
|
||||
rpc OperatePrivilege(OperatePrivilegeRequest) returns (common.Status) {}
|
||||
rpc SelectGrant(SelectGrantRequest) returns (SelectGrantResponse) {}
|
||||
}
|
||||
|
@ -111,9 +110,9 @@ message AlterAliasRequest{
|
|||
*/
|
||||
message CreateCollectionRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
resource_type: Collection
|
||||
resource_privilege: PrivilegeCreate
|
||||
resource_name_index: 3
|
||||
object_type: Global
|
||||
object_privilege: PrivilegeCreateCollection
|
||||
object_name_index: -1
|
||||
};
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
|
@ -135,9 +134,9 @@ message CreateCollectionRequest {
|
|||
*/
|
||||
message DropCollectionRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
resource_type: Collection
|
||||
resource_privilege: PrivilegeDrop
|
||||
resource_name_index: 3
|
||||
object_type: Global
|
||||
object_privilege: PrivilegeDropCollection
|
||||
object_name_index: -1
|
||||
};
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
|
@ -151,11 +150,6 @@ message DropCollectionRequest {
|
|||
* Check collection exist in milvus or not.
|
||||
*/
|
||||
message HasCollectionRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
resource_type: Collection
|
||||
resource_privilege: PrivilegeRead
|
||||
resource_name_index: 3
|
||||
};
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
// Not useful for now
|
||||
|
@ -182,9 +176,9 @@ message StringResponse {
|
|||
*/
|
||||
message DescribeCollectionRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
resource_type: Collection
|
||||
resource_privilege: PrivilegeRead
|
||||
resource_name_index: 3
|
||||
object_type: Global
|
||||
object_privilege: PrivilegeDescribeCollection
|
||||
object_name_index: -1
|
||||
};
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
|
@ -233,9 +227,9 @@ message DescribeCollectionResponse {
|
|||
*/
|
||||
message LoadCollectionRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
resource_type: Collection
|
||||
resource_privilege: PrivilegeLoad
|
||||
resource_name_index: 3
|
||||
object_type: Collection
|
||||
object_privilege: PrivilegeLoad
|
||||
object_name_index: 3
|
||||
};
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
|
@ -252,9 +246,9 @@ message LoadCollectionRequest {
|
|||
*/
|
||||
message ReleaseCollectionRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
resource_type: Collection
|
||||
resource_privilege: PrivilegeRelease
|
||||
resource_name_index: 3
|
||||
object_type: Collection
|
||||
object_privilege: PrivilegeRelease
|
||||
object_name_index: 3
|
||||
};
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
|
@ -269,11 +263,6 @@ message ReleaseCollectionRequest {
|
|||
* WARNING: This API is experimental and not useful for now.
|
||||
*/
|
||||
message GetStatisticsRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
resource_type: Collection
|
||||
resource_privilege: PrivilegeRead
|
||||
resource_name_index: 3
|
||||
};
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
// Not useful for now
|
||||
|
@ -301,11 +290,6 @@ message GetStatisticsResponse {
|
|||
* Get collection statistics like row_count.
|
||||
*/
|
||||
message GetCollectionStatisticsRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
resource_type: Collection
|
||||
resource_privilege: PrivilegeRead
|
||||
resource_name_index: 3
|
||||
};
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
// Not useful for now
|
||||
|
@ -339,8 +323,9 @@ enum ShowType {
|
|||
*/
|
||||
message ShowCollectionsRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
resource_type: Collection
|
||||
resource_privilege: PrivilegeRead
|
||||
object_type: Global
|
||||
object_privilege: PrivilegeShowCollections
|
||||
object_name_index: -1
|
||||
};
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
|
@ -633,6 +618,11 @@ message DropIndexRequest {
|
|||
}
|
||||
|
||||
message InsertRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
object_type: Collection
|
||||
object_privilege: PrivilegeInsert
|
||||
object_name_index: 3
|
||||
};
|
||||
common.MsgBase base = 1;
|
||||
string db_name = 2;
|
||||
string collection_name = 3;
|
||||
|
@ -655,6 +645,11 @@ message MutationResult {
|
|||
}
|
||||
|
||||
message DeleteRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
object_type: Collection
|
||||
object_privilege: PrivilegeDelete
|
||||
object_name_index: 3
|
||||
};
|
||||
common.MsgBase base = 1;
|
||||
string db_name = 2;
|
||||
string collection_name = 3;
|
||||
|
@ -834,6 +829,11 @@ message LoadBalanceRequest {
|
|||
}
|
||||
|
||||
message ManualCompactionRequest {
|
||||
option (common.privilege_ext_obj) = {
|
||||
object_type: Collection
|
||||
object_privilege: PrivilegeCompaction
|
||||
object_name_index: 1
|
||||
};
|
||||
int64 collectionID = 1;
|
||||
uint64 timetravel = 2;
|
||||
}
|
||||
|
@ -1075,60 +1075,33 @@ message SelectUserResponse {
|
|||
// Not useful for now
|
||||
common.Status status = 1;
|
||||
// user result array
|
||||
repeated UserResult result = 2;
|
||||
repeated UserResult results = 2;
|
||||
}
|
||||
|
||||
message ResourceEntity {
|
||||
string type = 1;
|
||||
message ObjectEntity {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message PrivilegeEntity {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
message SelectResourceRequest {
|
||||
// Not useful for now
|
||||
common.MsgBase base = 1;
|
||||
// resource
|
||||
ResourceEntity entity = 2;
|
||||
// include privilege info
|
||||
bool include_privilege_info = 3;
|
||||
}
|
||||
|
||||
message ResourceResult {
|
||||
ResourceEntity resource = 1;
|
||||
repeated PrivilegeEntity privileges = 2;
|
||||
}
|
||||
|
||||
message SelectResourceResponse {
|
||||
// Not useful for now
|
||||
common.Status status = 1;
|
||||
// resource result array
|
||||
repeated ResourceResult results = 2;
|
||||
}
|
||||
|
||||
message PrincipalEntity {
|
||||
// principal type, including user, role
|
||||
string principal_type = 1;
|
||||
// principal, including user entity or role entity
|
||||
oneof principal {
|
||||
UserEntity user = 2;
|
||||
RoleEntity role = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message GrantorEntity {
|
||||
UserEntity user = 1;
|
||||
PrivilegeEntity privilege = 2;
|
||||
}
|
||||
|
||||
message GrantPrivilegeEntity {
|
||||
repeated GrantorEntity entities = 1;
|
||||
}
|
||||
|
||||
message GrantEntity {
|
||||
// principal
|
||||
PrincipalEntity principal = 1;
|
||||
// resource
|
||||
ResourceEntity resource = 2;
|
||||
// resource name
|
||||
string resource_name = 3;
|
||||
// role
|
||||
RoleEntity role = 1;
|
||||
// object
|
||||
ObjectEntity object = 2;
|
||||
// object name
|
||||
string object_name = 3;
|
||||
// privilege
|
||||
GrantorEntity grantor = 4;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -131,7 +131,6 @@ service RootCoord {
|
|||
rpc OperateUserRole(milvus.OperateUserRoleRequest) returns (common.Status) {}
|
||||
rpc SelectRole(milvus.SelectRoleRequest) returns (milvus.SelectRoleResponse) {}
|
||||
rpc SelectUser(milvus.SelectUserRequest) returns (milvus.SelectUserResponse) {}
|
||||
rpc SelectResource(milvus.SelectResourceRequest) returns (milvus.SelectResourceResponse) {}
|
||||
rpc OperatePrivilege(milvus.OperatePrivilegeRequest) returns (common.Status) {}
|
||||
rpc SelectGrant(milvus.SelectGrantRequest) returns (milvus.SelectGrantResponse) {}
|
||||
rpc ListPolicy(internal.ListPolicyRequest) returns (internal.ListPolicyResponse) {}
|
||||
|
|
|
@ -676,110 +676,109 @@ func init() {
|
|||
func init() { proto.RegisterFile("root_coord.proto", fileDescriptor_4513485a144f6b06) }
|
||||
|
||||
var fileDescriptor_4513485a144f6b06 = []byte{
|
||||
// 1637 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x5b, 0x73, 0xd3, 0x46,
|
||||
0x14, 0xc6, 0x36, 0xb9, 0x1d, 0x3b, 0x71, 0xd8, 0x21, 0xe0, 0x1a, 0xda, 0x1a, 0x97, 0x82, 0xc3,
|
||||
0xc5, 0x61, 0xc2, 0x0c, 0xa5, 0xbc, 0x91, 0x98, 0x06, 0x4f, 0xc9, 0x10, 0x64, 0xe8, 0xd0, 0x0b,
|
||||
0xe3, 0x6e, 0xa4, 0x83, 0xa3, 0x89, 0xac, 0x35, 0xda, 0x75, 0x2e, 0x8f, 0x9d, 0xe9, 0x7b, 0xff,
|
||||
0x53, 0xfb, 0x53, 0xfa, 0xd6, 0x5f, 0xd1, 0x59, 0xad, 0x24, 0x4b, 0xb2, 0xd6, 0x51, 0x80, 0x37,
|
||||
0xed, 0xee, 0xb7, 0xdf, 0x77, 0xf6, 0x9c, 0xdd, 0xb3, 0x67, 0x05, 0xab, 0x1e, 0x63, 0xa2, 0x6f,
|
||||
0x32, 0xe6, 0x59, 0xed, 0x91, 0xc7, 0x04, 0x23, 0x57, 0x86, 0xb6, 0x73, 0x34, 0xe6, 0xaa, 0xd5,
|
||||
0x96, 0xc3, 0xfe, 0x68, 0xbd, 0x62, 0xb2, 0xe1, 0x90, 0xb9, 0xaa, 0xbf, 0x5e, 0x89, 0xa3, 0xea,
|
||||
0x2b, 0xb6, 0x2b, 0xd0, 0x73, 0xa9, 0x13, 0xb4, 0xcb, 0x23, 0x8f, 0x9d, 0x9c, 0x06, 0x8d, 0x55,
|
||||
0x8b, 0x0a, 0x1a, 0x97, 0xa8, 0x57, 0x51, 0x98, 0x56, 0x7f, 0x88, 0x82, 0x06, 0x1d, 0x97, 0x6c,
|
||||
0xd7, 0xc2, 0x93, 0x38, 0xa6, 0xd9, 0x87, 0xb5, 0xa7, 0x8e, 0xc3, 0xcc, 0xd7, 0xf6, 0x10, 0xb9,
|
||||
0xa0, 0xc3, 0x91, 0x81, 0x1f, 0xc6, 0xc8, 0x05, 0x79, 0x00, 0x17, 0xf7, 0x29, 0xc7, 0x5a, 0xa1,
|
||||
0x51, 0x68, 0x95, 0x37, 0xaf, 0xb7, 0x13, 0xe6, 0x06, 0x36, 0xee, 0xf2, 0xc1, 0x16, 0xe5, 0x68,
|
||||
0xf8, 0x48, 0x72, 0x19, 0xe6, 0x4c, 0x36, 0x76, 0x45, 0xad, 0xd4, 0x28, 0xb4, 0x96, 0x0d, 0xd5,
|
||||
0x68, 0xfe, 0x51, 0x80, 0x2b, 0x69, 0x05, 0x3e, 0x62, 0x2e, 0x47, 0xf2, 0x10, 0xe6, 0xb9, 0xa0,
|
||||
0x62, 0xcc, 0x03, 0x91, 0x6b, 0x99, 0x22, 0x3d, 0x1f, 0x62, 0x04, 0x50, 0x72, 0x1d, 0x96, 0x44,
|
||||
0xc8, 0x54, 0x2b, 0x36, 0x0a, 0xad, 0x8b, 0xc6, 0xa4, 0x43, 0x63, 0xc3, 0x5b, 0x58, 0xf1, 0x4d,
|
||||
0xe8, 0x76, 0x3e, 0xc3, 0xea, 0x8a, 0x71, 0x66, 0x07, 0xaa, 0x11, 0xf3, 0xa7, 0xac, 0x6a, 0x05,
|
||||
0x8a, 0xdd, 0x8e, 0x4f, 0x5d, 0x32, 0x8a, 0xdd, 0x8e, 0x66, 0x1d, 0x7f, 0x17, 0xa1, 0xd2, 0x1d,
|
||||
0x8e, 0x98, 0x27, 0x0c, 0xe4, 0x63, 0x47, 0x7c, 0x9c, 0xd6, 0x55, 0x58, 0x10, 0x94, 0x1f, 0xf6,
|
||||
0x6d, 0x2b, 0x10, 0x9c, 0x97, 0xcd, 0xae, 0x45, 0xbe, 0x86, 0xb2, 0xdc, 0x43, 0x2e, 0xb3, 0x50,
|
||||
0x0e, 0x96, 0xfc, 0x41, 0x08, 0xbb, 0xba, 0x16, 0x79, 0x04, 0x73, 0x92, 0x03, 0x6b, 0x17, 0x1b,
|
||||
0x85, 0xd6, 0xca, 0x66, 0x23, 0x53, 0x4d, 0x19, 0x28, 0x35, 0xd1, 0x50, 0x70, 0x52, 0x87, 0x45,
|
||||
0x8e, 0x83, 0x21, 0xba, 0x82, 0xd7, 0xe6, 0x1a, 0xa5, 0x56, 0xc9, 0x88, 0xda, 0xe4, 0x0b, 0x58,
|
||||
0xa4, 0x63, 0xc1, 0xfa, 0xb6, 0xc5, 0x6b, 0xf3, 0xfe, 0xd8, 0x82, 0x6c, 0x77, 0x2d, 0x4e, 0xae,
|
||||
0xc1, 0x92, 0xc7, 0x8e, 0xfb, 0xca, 0x11, 0x0b, 0xbe, 0x35, 0x8b, 0x1e, 0x3b, 0xde, 0x96, 0x6d,
|
||||
0xf2, 0x1d, 0xcc, 0xd9, 0xee, 0x7b, 0xc6, 0x6b, 0x8b, 0x8d, 0x52, 0xab, 0xbc, 0x79, 0x23, 0xd3,
|
||||
0x96, 0x1f, 0xf1, 0xf4, 0x27, 0xea, 0x8c, 0x71, 0x8f, 0xda, 0x9e, 0xa1, 0xf0, 0xcd, 0xbf, 0x0a,
|
||||
0x70, 0xb5, 0x83, 0xdc, 0xf4, 0xec, 0x7d, 0xec, 0x05, 0x56, 0x7c, 0xfc, 0xb6, 0x68, 0x42, 0xc5,
|
||||
0x64, 0x8e, 0x83, 0xa6, 0xb0, 0x99, 0x1b, 0x85, 0x30, 0xd1, 0x47, 0xbe, 0x02, 0x08, 0x96, 0xdb,
|
||||
0xed, 0xf0, 0x5a, 0xc9, 0x5f, 0x64, 0xac, 0xa7, 0x39, 0x86, 0x6a, 0x60, 0x88, 0x24, 0xee, 0xba,
|
||||
0xef, 0xd9, 0x14, 0x6d, 0x21, 0x83, 0xb6, 0x01, 0xe5, 0x11, 0xf5, 0x84, 0x9d, 0x50, 0x8e, 0x77,
|
||||
0xc9, 0xb3, 0x12, 0xc9, 0x04, 0xe1, 0x9c, 0x74, 0x34, 0xff, 0x2d, 0x42, 0x25, 0xd0, 0x95, 0x9a,
|
||||
0x9c, 0x74, 0x60, 0x49, 0xae, 0xa9, 0x2f, 0xfd, 0x14, 0xb8, 0xe0, 0x76, 0x3b, 0x3b, 0x4d, 0xb5,
|
||||
0x53, 0x06, 0x1b, 0x8b, 0xfb, 0xa1, 0xe9, 0x1d, 0x28, 0xab, 0x34, 0xa3, 0xc2, 0x53, 0xf4, 0xc3,
|
||||
0xf3, 0x4d, 0x92, 0x47, 0x26, 0xa6, 0x76, 0xa4, 0x6d, 0xe1, 0x89, 0xcf, 0x01, 0x76, 0xf8, 0xc9,
|
||||
0x09, 0xc2, 0x25, 0x3c, 0x11, 0x1e, 0xed, 0xc7, 0xb9, 0x4a, 0x3e, 0xd7, 0xf7, 0x67, 0xd8, 0xe4,
|
||||
0x13, 0xb4, 0x9f, 0xc9, 0xd9, 0x11, 0x37, 0x7f, 0xe6, 0x0a, 0xef, 0xd4, 0xa8, 0x62, 0xb2, 0xb7,
|
||||
0xfe, 0x3b, 0x5c, 0xce, 0x02, 0x92, 0x55, 0x28, 0x1d, 0xe2, 0x69, 0xe0, 0x76, 0xf9, 0x49, 0x36,
|
||||
0x61, 0xee, 0x48, 0x6e, 0x25, 0xdf, 0xcf, 0x53, 0x7b, 0xc3, 0x5f, 0xd0, 0x64, 0x25, 0x0a, 0xfa,
|
||||
0xa4, 0xf8, 0xb8, 0xd0, 0xfc, 0xa7, 0x08, 0xb5, 0xe9, 0xed, 0xf6, 0x29, 0xb9, 0x22, 0xcf, 0x96,
|
||||
0x1b, 0xc0, 0x72, 0x10, 0xe8, 0x84, 0xeb, 0xb6, 0x74, 0xae, 0xd3, 0x59, 0x98, 0xf0, 0xa9, 0xf2,
|
||||
0x61, 0x85, 0xc7, 0xba, 0xea, 0x08, 0x97, 0xa6, 0x20, 0x19, 0xde, 0x7b, 0x92, 0xf4, 0xde, 0xcd,
|
||||
0x3c, 0x21, 0x8c, 0x7b, 0xd1, 0x82, 0xcb, 0x3b, 0x28, 0xb6, 0x3d, 0xb4, 0xd0, 0x15, 0x36, 0x75,
|
||||
0x3e, 0xfe, 0xc0, 0xd6, 0x61, 0x71, 0xcc, 0xe5, 0x25, 0x3a, 0x54, 0xc6, 0x2c, 0x19, 0x51, 0xbb,
|
||||
0xf9, 0x67, 0x01, 0xd6, 0x52, 0x32, 0x9f, 0x12, 0xa8, 0x19, 0x52, 0x72, 0x6c, 0x44, 0x39, 0x3f,
|
||||
0x66, 0x9e, 0x4a, 0xb4, 0x4b, 0x46, 0xd4, 0xde, 0xfc, 0xef, 0x26, 0x2c, 0x19, 0x8c, 0x89, 0x6d,
|
||||
0xe9, 0x12, 0x32, 0x02, 0x22, 0x6d, 0x62, 0xc3, 0x11, 0x73, 0xd1, 0x55, 0x89, 0x95, 0x93, 0x07,
|
||||
0x49, 0x03, 0xa2, 0xc2, 0x60, 0x1a, 0x1a, 0xb8, 0xaa, 0x7e, 0x4b, 0x33, 0x23, 0x05, 0x6f, 0x5e,
|
||||
0x20, 0x43, 0x5f, 0x51, 0xde, 0xd7, 0xaf, 0x6d, 0xf3, 0x70, 0xfb, 0x80, 0xba, 0x2e, 0x3a, 0xb3,
|
||||
0x14, 0x53, 0xd0, 0x50, 0x31, 0x75, 0xe8, 0x83, 0x46, 0x4f, 0x78, 0xb6, 0x3b, 0x08, 0x3d, 0xdb,
|
||||
0xbc, 0x40, 0x3e, 0xf8, 0xb1, 0x95, 0xea, 0x36, 0x17, 0xb6, 0xc9, 0x43, 0xc1, 0x4d, 0xbd, 0xe0,
|
||||
0x14, 0xf8, 0x9c, 0x92, 0x7d, 0x58, 0xdd, 0xf6, 0x90, 0x0a, 0xdc, 0x8e, 0x0e, 0x0d, 0xb9, 0x97,
|
||||
0x39, 0x35, 0x0d, 0x0b, 0x85, 0x66, 0x6d, 0x80, 0xe6, 0x05, 0xf2, 0x2b, 0xac, 0x74, 0x3c, 0x36,
|
||||
0x8a, 0xd1, 0xdf, 0xc9, 0xa4, 0x4f, 0x82, 0x72, 0x92, 0xf7, 0x61, 0xf9, 0x39, 0xe5, 0x31, 0xee,
|
||||
0xf5, 0x4c, 0xee, 0x04, 0x26, 0xa4, 0xbe, 0x91, 0x09, 0xdd, 0x62, 0xcc, 0x89, 0xb9, 0xe7, 0x18,
|
||||
0x48, 0x98, 0x10, 0x62, 0x2a, 0xed, 0xec, 0x15, 0x4c, 0x01, 0x43, 0xa9, 0x8d, 0xdc, 0xf8, 0x48,
|
||||
0xf8, 0x0d, 0x94, 0x95, 0xc3, 0x9f, 0x3a, 0x36, 0xe5, 0xe4, 0xf6, 0x8c, 0x90, 0xf8, 0x88, 0x9c,
|
||||
0x0e, 0x7b, 0x05, 0x4b, 0xd2, 0xd1, 0x8a, 0xf4, 0x5b, 0x6d, 0x20, 0xce, 0x43, 0xd9, 0x03, 0x78,
|
||||
0xea, 0x08, 0xf4, 0x14, 0xe7, 0xad, 0x4c, 0xce, 0x09, 0x20, 0x27, 0xa9, 0x0b, 0xd5, 0xde, 0x81,
|
||||
0x2c, 0x70, 0x42, 0xd7, 0x70, 0x72, 0x37, 0x7b, 0x43, 0x27, 0x51, 0x21, 0xfd, 0xbd, 0x7c, 0xe0,
|
||||
0xc8, 0xdd, 0xef, 0xa0, 0xaa, 0x9c, 0xb9, 0x17, 0x16, 0x0d, 0x1a, 0xbd, 0x14, 0x2a, 0xe7, 0x72,
|
||||
0x7e, 0x86, 0x65, 0xe9, 0xd6, 0x09, 0xf9, 0xba, 0xd6, 0xf5, 0xe7, 0xa5, 0x7e, 0x07, 0x95, 0xe7,
|
||||
0x94, 0x4f, 0x98, 0x5b, 0xba, 0x13, 0x30, 0x45, 0x9c, 0xeb, 0x00, 0x1c, 0xc2, 0x8a, 0xf4, 0x5a,
|
||||
0x34, 0x99, 0x6b, 0x8e, 0x6f, 0x12, 0x14, 0x4a, 0xdc, 0xcd, 0x85, 0x8d, 0xc4, 0x5c, 0xa8, 0xa6,
|
||||
0xae, 0x5f, 0x4d, 0x14, 0x52, 0xa8, 0xd9, 0x51, 0x9f, 0x02, 0x47, 0x7a, 0x08, 0x15, 0x69, 0x4b,
|
||||
0x78, 0xd5, 0x6b, 0x7c, 0x17, 0x87, 0x84, 0x4a, 0xeb, 0x39, 0x90, 0xb1, 0x24, 0xb2, 0x9a, 0xae,
|
||||
0x2a, 0xc8, 0x46, 0xfe, 0xfa, 0x43, 0x29, 0x3e, 0x38, 0x6f, 0xc1, 0x12, 0x4f, 0x22, 0x7e, 0x3d,
|
||||
0x36, 0x33, 0x89, 0xf8, 0x88, 0x9c, 0x5b, 0xee, 0x00, 0x96, 0x43, 0x51, 0x45, 0xbc, 0x3e, 0xd3,
|
||||
0xef, 0x09, 0xea, 0x3b, 0x79, 0xa0, 0xd1, 0x02, 0x82, 0x74, 0xa5, 0x54, 0xf4, 0xe9, 0xea, 0x9c,
|
||||
0xc6, 0xef, 0xa0, 0x2a, 0xb5, 0xfd, 0x6b, 0x5e, 0x63, 0x7c, 0x02, 0xa3, 0x31, 0xde, 0x2f, 0xc8,
|
||||
0x93, 0x48, 0x9e, 0xb8, 0xcd, 0x57, 0x92, 0xcf, 0x7d, 0x72, 0x5f, 0x17, 0xc3, 0xcc, 0x1f, 0x0f,
|
||||
0xf5, 0x76, 0x5e, 0x78, 0x24, 0xf9, 0x1b, 0x2c, 0x04, 0x8f, 0xf0, 0x74, 0x22, 0x4e, 0x4d, 0x8e,
|
||||
0xde, 0xff, 0xf5, 0xdb, 0x67, 0xe2, 0x22, 0x76, 0x0a, 0x6b, 0x6f, 0x46, 0x96, 0x2c, 0x02, 0x54,
|
||||
0xa9, 0x11, 0x16, 0x3b, 0x69, 0x17, 0x4e, 0x0a, 0xaa, 0x24, 0x6e, 0x97, 0x0f, 0xce, 0x8a, 0x8e,
|
||||
0x03, 0x57, 0x0d, 0x74, 0x90, 0x72, 0xec, 0xbc, 0x7a, 0xb1, 0x8b, 0x9c, 0xd3, 0x01, 0xf6, 0x84,
|
||||
0x87, 0x74, 0x98, 0x2e, 0x82, 0xd4, 0x0f, 0x1f, 0x0d, 0x38, 0xe7, 0x5e, 0xf0, 0xe0, 0xcb, 0xae,
|
||||
0x7b, 0x44, 0x1d, 0xdb, 0x4a, 0x54, 0x36, 0xbb, 0x28, 0xe8, 0x36, 0x35, 0x0f, 0x30, 0x5b, 0x33,
|
||||
0x39, 0x25, 0x02, 0xe7, 0xd4, 0x34, 0x61, 0x2d, 0x38, 0xa9, 0x3f, 0x38, 0x63, 0x7e, 0x20, 0x6b,
|
||||
0x4e, 0x07, 0x05, 0x5a, 0xe9, 0x4c, 0x67, 0x51, 0x41, 0xdb, 0x99, 0xc8, 0x1c, 0x6e, 0xec, 0x03,
|
||||
0xec, 0xa0, 0xd8, 0x45, 0xe1, 0xd9, 0xa6, 0xee, 0x4e, 0x9e, 0x00, 0x34, 0x5b, 0x21, 0x03, 0x17,
|
||||
0x6d, 0x85, 0x1e, 0xcc, 0xab, 0xbf, 0x1b, 0xa4, 0x99, 0x39, 0x29, 0xfc, 0x37, 0x33, 0xab, 0x16,
|
||||
0x8d, 0xfe, 0xdf, 0xc4, 0xee, 0x1a, 0x79, 0x98, 0x26, 0x7f, 0x4d, 0x34, 0x77, 0x4d, 0x12, 0x34,
|
||||
0xfb, 0xae, 0x49, 0x63, 0xe3, 0x77, 0xcd, 0x0b, 0x9b, 0x07, 0x83, 0xaf, 0x29, 0x3f, 0xd4, 0x55,
|
||||
0x18, 0x29, 0xd4, 0xec, 0xbb, 0x66, 0x0a, 0x1c, 0xf3, 0x58, 0xc5, 0x40, 0x39, 0x10, 0xf8, 0x4d,
|
||||
0xfb, 0xf0, 0x8b, 0xff, 0xd6, 0x3a, 0x2b, 0xce, 0x6f, 0xa3, 0xea, 0x3d, 0x7a, 0xa8, 0xa5, 0xd3,
|
||||
0xe4, 0xe4, 0x30, 0x46, 0x10, 0xf9, 0xa6, 0xcc, 0xc1, 0x1c, 0x9c, 0xf5, 0xcf, 0xcd, 0xdc, 0x97,
|
||||
0xb7, 0xa1, 0xdc, 0xc8, 0x31, 0x66, 0xdd, 0xc5, 0x9d, 0x84, 0xe5, 0xcf, 0xf0, 0x32, 0x0c, 0x72,
|
||||
0xde, 0x1b, 0x8e, 0x1e, 0xd7, 0x64, 0xf8, 0x04, 0x66, 0xf6, 0xf5, 0x94, 0x82, 0xc6, 0xf6, 0xd0,
|
||||
0x72, 0xe2, 0x91, 0x9c, 0x5e, 0xc7, 0x24, 0xa8, 0x59, 0x4f, 0xf6, 0xfa, 0xfd, 0x9c, 0xe8, 0xd8,
|
||||
0x1e, 0x02, 0x15, 0x6e, 0x83, 0x39, 0xa8, 0x39, 0xd6, 0x13, 0x40, 0x4e, 0x77, 0xbd, 0x84, 0x45,
|
||||
0x79, 0x87, 0xfa, 0x94, 0x37, 0xb5, 0x57, 0xec, 0x39, 0x08, 0xdf, 0x41, 0xf5, 0xe5, 0x08, 0x3d,
|
||||
0x2a, 0x50, 0xfa, 0xcb, 0xe7, 0xcd, 0x3e, 0x59, 0x29, 0x54, 0xee, 0x37, 0x1f, 0xf4, 0x50, 0x66,
|
||||
0xea, 0x19, 0x4e, 0x98, 0x00, 0x66, 0xe7, 0xb6, 0x38, 0x2e, 0xf6, 0x24, 0x0e, 0x04, 0xa4, 0x61,
|
||||
0x33, 0x05, 0x7c, 0xcb, 0x73, 0x08, 0x28, 0x5c, 0xa2, 0xa6, 0x56, 0xc2, 0xc8, 0xd9, 0xd8, 0x33,
|
||||
0x75, 0x79, 0x2e, 0x09, 0x3a, 0xa3, 0xa6, 0x4e, 0x61, 0xe3, 0x0f, 0xfc, 0xc0, 0xcf, 0x7b, 0x9e,
|
||||
0x7d, 0x64, 0x3b, 0x38, 0x40, 0xcd, 0x71, 0x4b, 0xc3, 0x72, 0xc6, 0x63, 0x1f, 0xca, 0x4a, 0x7c,
|
||||
0xc7, 0xa3, 0xae, 0x20, 0xb3, 0xfc, 0xe0, 0x23, 0x42, 0xda, 0xd6, 0xd9, 0xc0, 0x68, 0x11, 0x26,
|
||||
0x80, 0x3c, 0x83, 0x7b, 0xcc, 0xb1, 0xcd, 0xd3, 0x74, 0x99, 0x1e, 0xe5, 0xa1, 0x09, 0x44, 0x53,
|
||||
0xa6, 0x67, 0x22, 0x43, 0x91, 0xad, 0xc7, 0xbf, 0x3c, 0x1a, 0xd8, 0xe2, 0x60, 0xbc, 0x2f, 0x97,
|
||||
0xb8, 0xa1, 0x26, 0xde, 0xb7, 0x59, 0xf0, 0xb5, 0x11, 0x4e, 0xde, 0xf0, 0xb9, 0x36, 0xa2, 0xd3,
|
||||
0x3a, 0xda, 0xdf, 0x9f, 0xf7, 0xbb, 0x1e, 0xfe, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xb9, 0x19, 0xf1,
|
||||
0xf3, 0xdc, 0x1a, 0x00, 0x00,
|
||||
// 1621 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x5d, 0x73, 0xd3, 0x46,
|
||||
0x17, 0xc6, 0x36, 0xf9, 0x3a, 0x76, 0xe2, 0xb0, 0x43, 0xc0, 0xaf, 0xe1, 0x6d, 0x8d, 0xa1, 0xe0,
|
||||
0xf0, 0xe1, 0x30, 0x61, 0x86, 0x52, 0xee, 0x48, 0x4c, 0x83, 0xa7, 0x64, 0x08, 0x32, 0x74, 0xe8,
|
||||
0x07, 0xe3, 0x6e, 0xac, 0x83, 0xa3, 0x89, 0xac, 0x35, 0xda, 0x75, 0x3e, 0x2e, 0x3b, 0xd3, 0xfb,
|
||||
0xfe, 0xa7, 0xf6, 0xa7, 0xf4, 0x77, 0x74, 0xa6, 0xb3, 0x5a, 0x49, 0x96, 0x64, 0xad, 0xa2, 0x00,
|
||||
0x77, 0xda, 0xdd, 0x67, 0x9f, 0xe7, 0xec, 0x39, 0xbb, 0x67, 0xcf, 0x0a, 0x56, 0x5d, 0xc6, 0x44,
|
||||
0x7f, 0xc0, 0x98, 0x6b, 0xb6, 0xc7, 0x2e, 0x13, 0x8c, 0x5c, 0x19, 0x59, 0xf6, 0xd1, 0x84, 0xab,
|
||||
0x56, 0x5b, 0x0e, 0x7b, 0xa3, 0xf5, 0xca, 0x80, 0x8d, 0x46, 0xcc, 0x51, 0xfd, 0xf5, 0x4a, 0x14,
|
||||
0x55, 0x5f, 0xb1, 0x1c, 0x81, 0xae, 0x43, 0x6d, 0xbf, 0x5d, 0x1e, 0xbb, 0xec, 0xe4, 0xd4, 0x6f,
|
||||
0xac, 0x9a, 0x54, 0xd0, 0xa8, 0x44, 0xbd, 0x8a, 0x62, 0x60, 0xf6, 0x47, 0x28, 0xa8, 0xdf, 0x71,
|
||||
0xc9, 0x72, 0x4c, 0x3c, 0x89, 0x62, 0x9a, 0x7d, 0x58, 0x7b, 0x66, 0xdb, 0x6c, 0xf0, 0xc6, 0x1a,
|
||||
0x21, 0x17, 0x74, 0x34, 0x36, 0xf0, 0xe3, 0x04, 0xb9, 0x20, 0x0f, 0xe1, 0xe2, 0x3e, 0xe5, 0x58,
|
||||
0x2b, 0x34, 0x0a, 0xad, 0xf2, 0xe6, 0xf5, 0x76, 0xcc, 0x5c, 0xdf, 0xc6, 0x5d, 0x3e, 0xdc, 0xa2,
|
||||
0x1c, 0x0d, 0x0f, 0x49, 0x2e, 0xc3, 0xdc, 0x80, 0x4d, 0x1c, 0x51, 0x2b, 0x35, 0x0a, 0xad, 0x65,
|
||||
0x43, 0x35, 0x9a, 0xbf, 0x17, 0xe0, 0x4a, 0x52, 0x81, 0x8f, 0x99, 0xc3, 0x91, 0x3c, 0x82, 0x79,
|
||||
0x2e, 0xa8, 0x98, 0x70, 0x5f, 0xe4, 0x5a, 0xaa, 0x48, 0xcf, 0x83, 0x18, 0x3e, 0x94, 0x5c, 0x87,
|
||||
0x25, 0x11, 0x30, 0xd5, 0x8a, 0x8d, 0x42, 0xeb, 0xa2, 0x31, 0xed, 0xd0, 0xd8, 0xf0, 0x0e, 0x56,
|
||||
0x3c, 0x13, 0xba, 0x9d, 0x2f, 0xb0, 0xba, 0x62, 0x94, 0xd9, 0x86, 0x6a, 0xc8, 0xfc, 0x39, 0xab,
|
||||
0x5a, 0x81, 0x62, 0xb7, 0xe3, 0x51, 0x97, 0x8c, 0x62, 0xb7, 0xa3, 0x59, 0xc7, 0x5f, 0x45, 0xa8,
|
||||
0x74, 0x47, 0x63, 0xe6, 0x0a, 0x03, 0xf9, 0xc4, 0x16, 0x9f, 0xa6, 0x75, 0x15, 0x16, 0x04, 0xe5,
|
||||
0x87, 0x7d, 0xcb, 0xf4, 0x05, 0xe7, 0x65, 0xb3, 0x6b, 0x92, 0xaf, 0xa1, 0x2c, 0xf7, 0x90, 0xc3,
|
||||
0x4c, 0x94, 0x83, 0x25, 0x6f, 0x10, 0x82, 0xae, 0xae, 0x49, 0x1e, 0xc3, 0x9c, 0xe4, 0xc0, 0xda,
|
||||
0xc5, 0x46, 0xa1, 0xb5, 0xb2, 0xd9, 0x48, 0x55, 0x53, 0x06, 0x4a, 0x4d, 0x34, 0x14, 0x9c, 0xd4,
|
||||
0x61, 0x91, 0xe3, 0x70, 0x84, 0x8e, 0xe0, 0xb5, 0xb9, 0x46, 0xa9, 0x55, 0x32, 0xc2, 0x36, 0xf9,
|
||||
0x1f, 0x2c, 0xd2, 0x89, 0x60, 0x7d, 0xcb, 0xe4, 0xb5, 0x79, 0x6f, 0x6c, 0x41, 0xb6, 0xbb, 0x26,
|
||||
0x27, 0xd7, 0x60, 0xc9, 0x65, 0xc7, 0x7d, 0xe5, 0x88, 0x05, 0xcf, 0x9a, 0x45, 0x97, 0x1d, 0x6f,
|
||||
0xcb, 0x36, 0xf9, 0x16, 0xe6, 0x2c, 0xe7, 0x03, 0xe3, 0xb5, 0xc5, 0x46, 0xa9, 0x55, 0xde, 0xbc,
|
||||
0x91, 0x6a, 0xcb, 0x0f, 0x78, 0xfa, 0x23, 0xb5, 0x27, 0xb8, 0x47, 0x2d, 0xd7, 0x50, 0xf8, 0xe6,
|
||||
0x9f, 0x05, 0xb8, 0xda, 0x41, 0x3e, 0x70, 0xad, 0x7d, 0xec, 0xf9, 0x56, 0x7c, 0xfa, 0xb6, 0x68,
|
||||
0x42, 0x65, 0xc0, 0x6c, 0x1b, 0x07, 0xc2, 0x62, 0x4e, 0x18, 0xc2, 0x58, 0x1f, 0xf9, 0x0a, 0xc0,
|
||||
0x5f, 0x6e, 0xb7, 0xc3, 0x6b, 0x25, 0x6f, 0x91, 0x91, 0x9e, 0xe6, 0x04, 0xaa, 0xbe, 0x21, 0x92,
|
||||
0xb8, 0xeb, 0x7c, 0x60, 0x33, 0xb4, 0x85, 0x14, 0xda, 0x06, 0x94, 0xc7, 0xd4, 0x15, 0x56, 0x4c,
|
||||
0x39, 0xda, 0x25, 0xcf, 0x4a, 0x28, 0xe3, 0x87, 0x73, 0xda, 0xd1, 0xfc, 0xa7, 0x08, 0x15, 0x5f,
|
||||
0x57, 0x6a, 0x72, 0xd2, 0x81, 0x25, 0xb9, 0xa6, 0xbe, 0xf4, 0x93, 0xef, 0x82, 0x3b, 0xed, 0xf4,
|
||||
0x34, 0xd5, 0x4e, 0x18, 0x6c, 0x2c, 0xee, 0x07, 0xa6, 0x77, 0xa0, 0xac, 0xd2, 0x8c, 0x0a, 0x4f,
|
||||
0xd1, 0x0b, 0xcf, 0xcd, 0x38, 0x8f, 0x4c, 0x4c, 0xed, 0x50, 0xdb, 0xc4, 0x13, 0x8f, 0x03, 0xac,
|
||||
0xe0, 0x93, 0x13, 0x84, 0x4b, 0x78, 0x22, 0x5c, 0xda, 0x8f, 0x72, 0x95, 0x3c, 0xae, 0xef, 0xce,
|
||||
0xb0, 0xc9, 0x23, 0x68, 0x3f, 0x97, 0xb3, 0x43, 0x6e, 0xfe, 0xdc, 0x11, 0xee, 0xa9, 0x51, 0xc5,
|
||||
0x78, 0x6f, 0xfd, 0x37, 0xb8, 0x9c, 0x06, 0x24, 0xab, 0x50, 0x3a, 0xc4, 0x53, 0xdf, 0xed, 0xf2,
|
||||
0x93, 0x6c, 0xc2, 0xdc, 0x91, 0xdc, 0x4a, 0x9e, 0x9f, 0x67, 0xf6, 0x86, 0xb7, 0xa0, 0xe9, 0x4a,
|
||||
0x14, 0xf4, 0x69, 0xf1, 0x49, 0xa1, 0xf9, 0x77, 0x11, 0x6a, 0xb3, 0xdb, 0xed, 0x73, 0x72, 0x45,
|
||||
0x9e, 0x2d, 0x37, 0x84, 0x65, 0x3f, 0xd0, 0x31, 0xd7, 0x6d, 0xe9, 0x5c, 0xa7, 0xb3, 0x30, 0xe6,
|
||||
0x53, 0xe5, 0xc3, 0x0a, 0x8f, 0x74, 0xd5, 0x11, 0x2e, 0xcd, 0x40, 0x52, 0xbc, 0xf7, 0x34, 0xee,
|
||||
0xbd, 0x5b, 0x79, 0x42, 0x18, 0xf5, 0xa2, 0x09, 0x97, 0x77, 0x50, 0x6c, 0xbb, 0x68, 0xa2, 0x23,
|
||||
0x2c, 0x6a, 0x7f, 0xfa, 0x81, 0xad, 0xc3, 0xe2, 0x84, 0xcb, 0x4b, 0x74, 0xa4, 0x8c, 0x59, 0x32,
|
||||
0xc2, 0x76, 0xf3, 0x8f, 0x02, 0xac, 0x25, 0x64, 0x3e, 0x27, 0x50, 0x19, 0x52, 0x72, 0x6c, 0x4c,
|
||||
0x39, 0x3f, 0x66, 0xae, 0x4a, 0xb4, 0x4b, 0x46, 0xd8, 0xde, 0xfc, 0xf7, 0x26, 0x2c, 0x19, 0x8c,
|
||||
0x89, 0x6d, 0xe9, 0x12, 0x32, 0x06, 0x22, 0x6d, 0x62, 0xa3, 0x31, 0x73, 0xd0, 0x51, 0x89, 0x95,
|
||||
0x93, 0x87, 0x71, 0x03, 0xc2, 0xc2, 0x60, 0x16, 0xea, 0xbb, 0xaa, 0x7e, 0x5b, 0x33, 0x23, 0x01,
|
||||
0x6f, 0x5e, 0x20, 0x23, 0x4f, 0x51, 0xde, 0xd7, 0x6f, 0xac, 0xc1, 0xe1, 0xf6, 0x01, 0x75, 0x1c,
|
||||
0xb4, 0xb3, 0x14, 0x13, 0xd0, 0x40, 0x31, 0x71, 0xe8, 0xfd, 0x46, 0x4f, 0xb8, 0x96, 0x33, 0x0c,
|
||||
0x3c, 0xdb, 0xbc, 0x40, 0x3e, 0x7a, 0xb1, 0x95, 0xea, 0x16, 0x17, 0xd6, 0x80, 0x07, 0x82, 0x9b,
|
||||
0x7a, 0xc1, 0x19, 0xf0, 0x39, 0x25, 0xfb, 0xb0, 0xba, 0xed, 0x22, 0x15, 0xb8, 0x1d, 0x1e, 0x1a,
|
||||
0x72, 0x3f, 0x75, 0x6a, 0x12, 0x16, 0x08, 0x65, 0x6d, 0x80, 0xe6, 0x05, 0xf2, 0x0b, 0xac, 0x74,
|
||||
0x5c, 0x36, 0x8e, 0xd0, 0xdf, 0x4d, 0xa5, 0x8f, 0x83, 0x72, 0x92, 0xf7, 0x61, 0xf9, 0x05, 0xe5,
|
||||
0x11, 0xee, 0xf5, 0x54, 0xee, 0x18, 0x26, 0xa0, 0xbe, 0x91, 0x0a, 0xdd, 0x62, 0xcc, 0x8e, 0xb8,
|
||||
0xe7, 0x18, 0x48, 0x90, 0x10, 0x22, 0x2a, 0xed, 0xf4, 0x15, 0xcc, 0x00, 0x03, 0xa9, 0x8d, 0xdc,
|
||||
0xf8, 0x50, 0xf8, 0x2d, 0x94, 0x95, 0xc3, 0x9f, 0xd9, 0x16, 0xe5, 0xe4, 0x4e, 0x46, 0x48, 0x3c,
|
||||
0x44, 0x4e, 0x87, 0xbd, 0x86, 0x25, 0xe9, 0x68, 0x45, 0xfa, 0x8d, 0x36, 0x10, 0xe7, 0xa1, 0xec,
|
||||
0x01, 0x3c, 0xb3, 0x05, 0xba, 0x8a, 0xf3, 0x76, 0x2a, 0xe7, 0x14, 0x90, 0x93, 0xd4, 0x81, 0x6a,
|
||||
0xef, 0x40, 0x16, 0x38, 0x81, 0x6b, 0x38, 0xb9, 0x97, 0xbe, 0xa1, 0xe3, 0xa8, 0x80, 0xfe, 0x7e,
|
||||
0x3e, 0x70, 0xe8, 0xee, 0xf7, 0x50, 0x55, 0xce, 0xdc, 0x0b, 0x8a, 0x06, 0x8d, 0x5e, 0x02, 0x95,
|
||||
0x73, 0x39, 0x3f, 0xc1, 0xb2, 0x74, 0xeb, 0x94, 0x7c, 0x5d, 0xeb, 0xfa, 0xf3, 0x52, 0xbf, 0x87,
|
||||
0xca, 0x0b, 0xca, 0xa7, 0xcc, 0x2d, 0xdd, 0x09, 0x98, 0x21, 0xce, 0x75, 0x00, 0x0e, 0x61, 0x45,
|
||||
0x7a, 0x2d, 0x9c, 0xcc, 0x35, 0xc7, 0x37, 0x0e, 0x0a, 0x24, 0xee, 0xe5, 0xc2, 0x86, 0x62, 0x0e,
|
||||
0x54, 0x13, 0xd7, 0xaf, 0x26, 0x0a, 0x09, 0x54, 0x76, 0xd4, 0x67, 0xc0, 0xa1, 0x1e, 0x42, 0x45,
|
||||
0xda, 0x12, 0x5c, 0xf5, 0x1a, 0xdf, 0x45, 0x21, 0x81, 0xd2, 0x7a, 0x0e, 0x64, 0x24, 0x89, 0xac,
|
||||
0x26, 0xab, 0x0a, 0xb2, 0x91, 0xbf, 0xfe, 0x50, 0x8a, 0x0f, 0xcf, 0x5b, 0xb0, 0x44, 0x93, 0x88,
|
||||
0x57, 0x8f, 0x65, 0x26, 0x11, 0x0f, 0x91, 0x73, 0xcb, 0x1d, 0xc0, 0x72, 0x20, 0xaa, 0x88, 0xd7,
|
||||
0x33, 0xfd, 0x1e, 0xa3, 0xbe, 0x9b, 0x07, 0x1a, 0x2e, 0xc0, 0x4f, 0x57, 0x4a, 0x45, 0x9f, 0xae,
|
||||
0xce, 0x69, 0xfc, 0x0e, 0xaa, 0x52, 0xdb, 0xbb, 0xe6, 0x35, 0xc6, 0xc7, 0x30, 0x1a, 0xe3, 0xbd,
|
||||
0x82, 0x3c, 0x8e, 0xe4, 0xb1, 0xdb, 0x7c, 0x25, 0xfe, 0xdc, 0x27, 0x0f, 0x74, 0x31, 0x4c, 0xfd,
|
||||
0xf1, 0x50, 0x6f, 0xe7, 0x85, 0x87, 0x92, 0xbf, 0xc2, 0x82, 0xff, 0x08, 0x4f, 0x26, 0xe2, 0xc4,
|
||||
0xe4, 0xf0, 0xfd, 0x5f, 0xbf, 0x73, 0x26, 0x2e, 0x64, 0xa7, 0xb0, 0xf6, 0x76, 0x6c, 0xca, 0x22,
|
||||
0x40, 0x95, 0x1a, 0x41, 0xb1, 0x93, 0x74, 0xe1, 0xb4, 0xa0, 0x8a, 0xe3, 0x76, 0xf9, 0xf0, 0xac,
|
||||
0xe8, 0xd8, 0x70, 0xd5, 0x40, 0x1b, 0x29, 0xc7, 0xce, 0xeb, 0x97, 0xbb, 0xc8, 0x39, 0x1d, 0x62,
|
||||
0x4f, 0xb8, 0x48, 0x47, 0xc9, 0x22, 0x48, 0xfd, 0xf0, 0xd1, 0x80, 0x73, 0xee, 0x05, 0x17, 0xfe,
|
||||
0xdf, 0x75, 0x8e, 0xa8, 0x6d, 0x99, 0xb1, 0xca, 0x66, 0x17, 0x05, 0xdd, 0xa6, 0x83, 0x03, 0x4c,
|
||||
0xd7, 0x8c, 0x4f, 0x09, 0xc1, 0x39, 0x35, 0x07, 0xb0, 0xe6, 0x9f, 0xd4, 0xef, 0xed, 0x09, 0x3f,
|
||||
0x90, 0x35, 0xa7, 0x8d, 0x02, 0xcd, 0x64, 0xa6, 0x33, 0xa9, 0xa0, 0xed, 0x54, 0x64, 0x0e, 0x37,
|
||||
0xf6, 0x01, 0x76, 0x50, 0xec, 0xa2, 0x70, 0xad, 0x81, 0xee, 0x4e, 0x9e, 0x02, 0x34, 0x5b, 0x21,
|
||||
0x05, 0x17, 0x6e, 0x85, 0x1e, 0xcc, 0xab, 0xbf, 0x1b, 0xa4, 0x99, 0x3a, 0x29, 0xf8, 0x37, 0x93,
|
||||
0x55, 0x8b, 0x86, 0xff, 0x6f, 0x22, 0x77, 0x8d, 0x3c, 0x4c, 0xd3, 0xbf, 0x26, 0x9a, 0xbb, 0x26,
|
||||
0x0e, 0xca, 0xbe, 0x6b, 0x92, 0xd8, 0xe8, 0x5d, 0xf3, 0xd2, 0xe2, 0xfe, 0xe0, 0x1b, 0xca, 0x0f,
|
||||
0x75, 0x15, 0x46, 0x02, 0x95, 0x7d, 0xd7, 0xcc, 0x80, 0x23, 0x1e, 0xab, 0x18, 0x28, 0x07, 0x7c,
|
||||
0xbf, 0x69, 0x1f, 0x7e, 0xd1, 0xdf, 0x5a, 0x67, 0xc5, 0xf9, 0x5d, 0x58, 0xbd, 0x87, 0x0f, 0xb5,
|
||||
0x64, 0x9a, 0x9c, 0x1e, 0xc6, 0x10, 0x22, 0xdf, 0x94, 0x39, 0x98, 0xfd, 0xb3, 0xfe, 0xa5, 0x99,
|
||||
0xfb, 0xf2, 0x36, 0x94, 0x1b, 0x39, 0xc2, 0xac, 0xbb, 0xb8, 0xe3, 0xb0, 0xfc, 0x19, 0x5e, 0x86,
|
||||
0x41, 0xce, 0x7b, 0xcb, 0xd1, 0xe5, 0x9a, 0x0c, 0x1f, 0xc3, 0x64, 0x5f, 0x4f, 0x09, 0x68, 0x64,
|
||||
0x0f, 0x2d, 0xc7, 0x1e, 0xc9, 0xc9, 0x75, 0x4c, 0x83, 0x9a, 0xf6, 0x64, 0xaf, 0x3f, 0xc8, 0x89,
|
||||
0x8e, 0xec, 0x21, 0x50, 0xe1, 0x36, 0x98, 0x8d, 0x9a, 0x63, 0x3d, 0x05, 0xe4, 0x74, 0xd7, 0x2b,
|
||||
0x58, 0x94, 0x77, 0xa8, 0x47, 0x79, 0x4b, 0x7b, 0xc5, 0x9e, 0x83, 0xf0, 0x3d, 0x54, 0x5f, 0x8d,
|
||||
0xd1, 0xa5, 0x02, 0xa5, 0xbf, 0x3c, 0xde, 0xf4, 0x93, 0x95, 0x40, 0xe5, 0x7e, 0xf3, 0x41, 0x0f,
|
||||
0x65, 0xa6, 0xce, 0x70, 0xc2, 0x14, 0x90, 0x9d, 0xdb, 0xa2, 0xb8, 0xc8, 0x93, 0xd8, 0x17, 0x90,
|
||||
0x86, 0x65, 0x0a, 0x78, 0x96, 0xe7, 0x10, 0x50, 0xb8, 0xe8, 0x9b, 0xdb, 0x5f, 0xfa, 0x9e, 0x6b,
|
||||
0x1d, 0x59, 0x36, 0x0e, 0x51, 0x73, 0x02, 0x92, 0xb0, 0x9c, 0x2e, 0xda, 0x87, 0xb2, 0x12, 0xde,
|
||||
0x71, 0xa9, 0x23, 0x48, 0x96, 0x69, 0x1e, 0x22, 0xa0, 0x6d, 0x9d, 0x0d, 0x0c, 0x17, 0x31, 0x00,
|
||||
0x90, 0xc7, 0x62, 0x8f, 0xd9, 0xd6, 0xe0, 0x34, 0x59, 0x39, 0x87, 0xa9, 0x61, 0x0a, 0xd1, 0x54,
|
||||
0xce, 0xa9, 0xc8, 0x40, 0x64, 0xeb, 0xc9, 0xcf, 0x8f, 0x87, 0x96, 0x38, 0x98, 0xec, 0xcb, 0x25,
|
||||
0x6e, 0xa8, 0x89, 0x0f, 0x2c, 0xe6, 0x7f, 0x6d, 0x04, 0x93, 0x37, 0x3c, 0xae, 0x8d, 0xf0, 0x00,
|
||||
0x8d, 0xf7, 0xf7, 0xe7, 0xbd, 0xae, 0x47, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x94, 0xcd,
|
||||
0x4d, 0x6f, 0x1a, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -888,7 +887,6 @@ type RootCoordClient interface {
|
|||
OperateUserRole(ctx context.Context, in *milvuspb.OperateUserRoleRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
|
||||
SelectRole(ctx context.Context, in *milvuspb.SelectRoleRequest, opts ...grpc.CallOption) (*milvuspb.SelectRoleResponse, error)
|
||||
SelectUser(ctx context.Context, in *milvuspb.SelectUserRequest, opts ...grpc.CallOption) (*milvuspb.SelectUserResponse, error)
|
||||
SelectResource(ctx context.Context, in *milvuspb.SelectResourceRequest, opts ...grpc.CallOption) (*milvuspb.SelectResourceResponse, error)
|
||||
OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivilegeRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
|
||||
SelectGrant(ctx context.Context, in *milvuspb.SelectGrantRequest, opts ...grpc.CallOption) (*milvuspb.SelectGrantResponse, error)
|
||||
ListPolicy(ctx context.Context, in *internalpb.ListPolicyRequest, opts ...grpc.CallOption) (*internalpb.ListPolicyResponse, error)
|
||||
|
@ -1289,15 +1287,6 @@ func (c *rootCoordClient) SelectUser(ctx context.Context, in *milvuspb.SelectUse
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *rootCoordClient) SelectResource(ctx context.Context, in *milvuspb.SelectResourceRequest, opts ...grpc.CallOption) (*milvuspb.SelectResourceResponse, error) {
|
||||
out := new(milvuspb.SelectResourceResponse)
|
||||
err := c.cc.Invoke(ctx, "/milvus.proto.rootcoord.RootCoord/SelectResource", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *rootCoordClient) OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivilegeRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
out := new(commonpb.Status)
|
||||
err := c.cc.Invoke(ctx, "/milvus.proto.rootcoord.RootCoord/OperatePrivilege", in, out, opts...)
|
||||
|
@ -1421,7 +1410,6 @@ type RootCoordServer interface {
|
|||
OperateUserRole(context.Context, *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error)
|
||||
SelectRole(context.Context, *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error)
|
||||
SelectUser(context.Context, *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error)
|
||||
SelectResource(context.Context, *milvuspb.SelectResourceRequest) (*milvuspb.SelectResourceResponse, error)
|
||||
OperatePrivilege(context.Context, *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error)
|
||||
SelectGrant(context.Context, *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error)
|
||||
ListPolicy(context.Context, *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error)
|
||||
|
@ -1560,9 +1548,6 @@ func (*UnimplementedRootCoordServer) SelectRole(ctx context.Context, req *milvus
|
|||
func (*UnimplementedRootCoordServer) SelectUser(ctx context.Context, req *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SelectUser not implemented")
|
||||
}
|
||||
func (*UnimplementedRootCoordServer) SelectResource(ctx context.Context, req *milvuspb.SelectResourceRequest) (*milvuspb.SelectResourceResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SelectResource not implemented")
|
||||
}
|
||||
func (*UnimplementedRootCoordServer) OperatePrivilege(ctx context.Context, req *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method OperatePrivilege not implemented")
|
||||
}
|
||||
|
@ -2351,24 +2336,6 @@ func _RootCoord_SelectUser_Handler(srv interface{}, ctx context.Context, dec fun
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RootCoord_SelectResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(milvuspb.SelectResourceRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RootCoordServer).SelectResource(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/milvus.proto.rootcoord.RootCoord/SelectResource",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RootCoordServer).SelectResource(ctx, req.(*milvuspb.SelectResourceRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RootCoord_OperatePrivilege_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(milvuspb.OperatePrivilegeRequest)
|
||||
if err := dec(in); err != nil {
|
||||
|
@ -2599,10 +2566,6 @@ var _RootCoord_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "SelectUser",
|
||||
Handler: _RootCoord_SelectUser_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SelectResource",
|
||||
Handler: _RootCoord_SelectResource_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "OperatePrivilege",
|
||||
Handler: _RootCoord_OperatePrivilege_Handler,
|
||||
|
|
|
@ -25,7 +25,7 @@ func TestValidAuth(t *testing.T) {
|
|||
rootCoord := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, queryCoord, mgr)
|
||||
err := InitMetaCache(ctx, rootCoord, queryCoord, mgr)
|
||||
assert.Nil(t, err)
|
||||
res = validAuth(ctx, []string{crypto.Base64Encode("mockUser:mockPass")})
|
||||
assert.True(t, res)
|
||||
|
@ -54,7 +54,7 @@ func TestAuthenticationInterceptor(t *testing.T) {
|
|||
rootCoord := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
err = InitMetaCache(rootCoord, queryCoord, mgr)
|
||||
err = InitMetaCache(ctx, rootCoord, queryCoord, mgr)
|
||||
assert.Nil(t, err)
|
||||
// with invalid metadata
|
||||
md := metadata.Pairs("xxx", "yyy")
|
||||
|
|
|
@ -23,6 +23,8 @@ import (
|
|||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/errorutil"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
@ -3705,6 +3707,11 @@ func (node *Proxy) checkHealthy() bool {
|
|||
return code == internalpb.StateCode_Healthy
|
||||
}
|
||||
|
||||
func (node *Proxy) checkHealthyAndReturnCode() (internalpb.StateCode, bool) {
|
||||
code := node.stateCode.Load().(internalpb.StateCode)
|
||||
return code, code == internalpb.StateCode_Healthy
|
||||
}
|
||||
|
||||
//unhealthyStatus returns the proxy not healthy status
|
||||
func unhealthyStatus() *commonpb.Status {
|
||||
return &commonpb.Status{
|
||||
|
@ -3816,6 +3823,9 @@ func (node *Proxy) InvalidateCredentialCache(ctx context.Context, request *proxy
|
|||
logutil.Logger(ctx).Debug("received request to invalidate credential cache",
|
||||
zap.String("role", typeutil.ProxyRole),
|
||||
zap.String("username", request.Username))
|
||||
if !node.checkHealthy() {
|
||||
return unhealthyStatus(), errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
username := request.Username
|
||||
if globalMetaCache != nil {
|
||||
|
@ -3837,6 +3847,9 @@ func (node *Proxy) UpdateCredentialCache(ctx context.Context, request *proxypb.U
|
|||
logutil.Logger(ctx).Debug("received request to update credential cache",
|
||||
zap.String("role", typeutil.ProxyRole),
|
||||
zap.String("username", request.Username))
|
||||
if !node.checkHealthy() {
|
||||
return unhealthyStatus(), errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
credInfo := &internalpb.CredentialInfo{
|
||||
Username: request.Username,
|
||||
|
@ -3856,7 +3869,14 @@ func (node *Proxy) UpdateCredentialCache(ctx context.Context, request *proxypb.U
|
|||
}
|
||||
|
||||
func (node *Proxy) CreateCredential(ctx context.Context, req *milvuspb.CreateCredentialRequest) (*commonpb.Status, error) {
|
||||
log.Debug("CreateCredential", zap.String("role", typeutil.RootCoordRole), zap.String("username", req.Username))
|
||||
log.Debug("CreateCredential", zap.String("role", typeutil.ProxyRole), zap.String("username", req.Username))
|
||||
if !node.checkHealthy() {
|
||||
return unhealthyStatus(), errorutil.UnhealthyError()
|
||||
}
|
||||
// validate root permission
|
||||
if isValid, status := node.validateAdminPermission(ctx); !isValid {
|
||||
return status, errorutil.PermissionDenyError()
|
||||
}
|
||||
// validate params
|
||||
username := req.Username
|
||||
if err := ValidateUsername(username); err != nil {
|
||||
|
@ -3888,6 +3908,7 @@ func (node *Proxy) CreateCredential(ctx context.Context, req *milvuspb.CreateCre
|
|||
Reason: "encrypt password fail key:" + req.Username,
|
||||
}, nil
|
||||
}
|
||||
|
||||
credInfo := &internalpb.CredentialInfo{
|
||||
Username: req.Username,
|
||||
EncryptedPassword: encryptedPassword,
|
||||
|
@ -3905,7 +3926,10 @@ func (node *Proxy) CreateCredential(ctx context.Context, req *milvuspb.CreateCre
|
|||
}
|
||||
|
||||
func (node *Proxy) UpdateCredential(ctx context.Context, req *milvuspb.UpdateCredentialRequest) (*commonpb.Status, error) {
|
||||
log.Debug("UpdateCredential", zap.String("role", typeutil.RootCoordRole), zap.String("username", req.Username))
|
||||
log.Debug("UpdateCredential", zap.String("role", typeutil.ProxyRole), zap.String("username", req.Username))
|
||||
if !node.checkHealthy() {
|
||||
return unhealthyStatus(), errorutil.UnhealthyError()
|
||||
}
|
||||
rawOldPassword, err := crypto.Base64Decode(req.OldPassword)
|
||||
if err != nil {
|
||||
log.Error("decode old password fail", zap.String("username", req.Username), zap.Error(err))
|
||||
|
@ -3971,7 +3995,15 @@ func (node *Proxy) UpdateCredential(ctx context.Context, req *milvuspb.UpdateCre
|
|||
}
|
||||
|
||||
func (node *Proxy) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error) {
|
||||
log.Debug("DeleteCredential", zap.String("role", typeutil.RootCoordRole), zap.String("username", req.Username))
|
||||
log.Debug("DeleteCredential", zap.String("role", typeutil.ProxyRole), zap.String("username", req.Username))
|
||||
if !node.checkHealthy() {
|
||||
return unhealthyStatus(), errorutil.UnhealthyError()
|
||||
}
|
||||
// validate root permission
|
||||
if isValid, status := node.validateAdminPermission(ctx); !isValid {
|
||||
return status, errorutil.PermissionDenyError()
|
||||
}
|
||||
|
||||
if req.Username == util.UserRoot {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_DeleteCredentialFailure,
|
||||
|
@ -3990,7 +4022,10 @@ func (node *Proxy) DeleteCredential(ctx context.Context, req *milvuspb.DeleteCre
|
|||
}
|
||||
|
||||
func (node *Proxy) ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error) {
|
||||
log.Debug("ListCredUsers", zap.String("role", typeutil.RootCoordRole))
|
||||
log.Debug("ListCredUsers", zap.String("role", typeutil.ProxyRole))
|
||||
if !node.checkHealthy() {
|
||||
return &milvuspb.ListCredUsersResponse{Status: unhealthyStatus()}, errorutil.UnhealthyError()
|
||||
}
|
||||
rootCoordReq := &milvuspb.ListCredUsersRequest{
|
||||
Base: &commonpb.MsgBase{
|
||||
MsgType: commonpb.MsgType_ListCredUsernames,
|
||||
|
@ -4029,47 +4064,334 @@ func (node *Proxy) SendRetrieveResult(ctx context.Context, req *internalpb.Retri
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (node *Proxy) CreateRole(ctx context.Context, request *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (node *Proxy) validateAdminPermission(ctx context.Context) (bool, *commonpb.Status) {
|
||||
err := ValidateAdminPermission(ctx)
|
||||
if err != nil {
|
||||
logger.Error("fail to validate admin permission", zap.Error(err))
|
||||
return false, &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_PermissionDenied,
|
||||
Reason: err.Error(),
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (node *Proxy) DropRole(ctx context.Context, request *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (node *Proxy) CreateRole(ctx context.Context, req *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
logger.Debug("CreateRole", zap.Any("req", req))
|
||||
if code, ok := node.checkHealthyAndReturnCode(); !ok {
|
||||
return errorutil.UnhealthyStatus(code), errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
var roleName string
|
||||
if req.Entity != nil {
|
||||
roleName = req.Entity.Name
|
||||
}
|
||||
if err := ValidateRoleName(roleName); err != nil {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_IllegalArgument,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
|
||||
if isValid, status := node.validateAdminPermission(ctx); !isValid {
|
||||
return status, errorutil.PermissionDenyError()
|
||||
}
|
||||
|
||||
result, err := node.rootCoord.CreateRole(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error("fail to create role", zap.Error(err))
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (node *Proxy) OperateUserRole(ctx context.Context, request *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (node *Proxy) DropRole(ctx context.Context, req *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
logger.Debug("DropRole", zap.Any("req", req))
|
||||
if code, ok := node.checkHealthyAndReturnCode(); !ok {
|
||||
return errorutil.UnhealthyStatus(code), errorutil.UnhealthyError()
|
||||
}
|
||||
if err := ValidateRoleName(req.RoleName); err != nil {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_IllegalArgument,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
if isValid, status := node.validateAdminPermission(ctx); !isValid {
|
||||
return status, errorutil.PermissionDenyError()
|
||||
}
|
||||
result, err := node.rootCoord.DropRole(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error("fail to drop role", zap.String("role_name", req.RoleName), zap.Error(err))
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (node *Proxy) SelectRole(ctx context.Context, request *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (node *Proxy) OperateUserRole(ctx context.Context, req *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
logger.Debug("OperateUserRole", zap.Any("req", req))
|
||||
if code, ok := node.checkHealthyAndReturnCode(); !ok {
|
||||
return errorutil.UnhealthyStatus(code), errorutil.UnhealthyError()
|
||||
}
|
||||
if err := ValidateUsername(req.Username); err != nil {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_IllegalArgument,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
if err := ValidateRoleName(req.RoleName); err != nil {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_IllegalArgument,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
if isValid, status := node.validateAdminPermission(ctx); !isValid {
|
||||
return status, errorutil.PermissionDenyError()
|
||||
}
|
||||
|
||||
result, err := node.rootCoord.OperateUserRole(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error("fail to operate user role", zap.Error(err))
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (node *Proxy) SelectUser(ctx context.Context, request *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (node *Proxy) SelectRole(ctx context.Context, req *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
logger.Debug("SelectRole", zap.Any("req", req))
|
||||
if code, ok := node.checkHealthyAndReturnCode(); !ok {
|
||||
return &milvuspb.SelectRoleResponse{Status: errorutil.UnhealthyStatus(code)}, errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
if req.Role != nil {
|
||||
if err := ValidateRoleName(req.Role.Name); err != nil {
|
||||
return &milvuspb.SelectRoleResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_IllegalArgument,
|
||||
Reason: err.Error(),
|
||||
},
|
||||
}, err
|
||||
}
|
||||
}
|
||||
if isValid, status := node.validateAdminPermission(ctx); !isValid {
|
||||
return &milvuspb.SelectRoleResponse{
|
||||
Status: status,
|
||||
}, errorutil.PermissionDenyError()
|
||||
}
|
||||
|
||||
result, err := node.rootCoord.SelectRole(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error("fail to select role", zap.Error(err))
|
||||
return &milvuspb.SelectRoleResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: err.Error(),
|
||||
},
|
||||
}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (node *Proxy) SelectResource(ctx context.Context, request *milvuspb.SelectResourceRequest) (*milvuspb.SelectResourceResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (node *Proxy) SelectUser(ctx context.Context, req *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
logger.Debug("SelectUser", zap.Any("req", req))
|
||||
if code, ok := node.checkHealthyAndReturnCode(); !ok {
|
||||
return &milvuspb.SelectUserResponse{Status: errorutil.UnhealthyStatus(code)}, errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
if req.User != nil {
|
||||
if err := ValidateUsername(req.User.Name); err != nil {
|
||||
return &milvuspb.SelectUserResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_IllegalArgument,
|
||||
Reason: err.Error(),
|
||||
},
|
||||
}, err
|
||||
}
|
||||
}
|
||||
curUser, err := GetCurUserFromContext(ctx)
|
||||
if err != nil {
|
||||
return &milvuspb.SelectUserResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: err.Error(),
|
||||
},
|
||||
}, err
|
||||
}
|
||||
isSelf := req.User != nil && req.User.Name == curUser
|
||||
if isValid, status := node.validateAdminPermission(ctx); !isValid && !isSelf {
|
||||
return &milvuspb.SelectUserResponse{
|
||||
Status: status,
|
||||
}, errorutil.PermissionDenyError()
|
||||
}
|
||||
|
||||
result, err := node.rootCoord.SelectUser(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error("fail to select user", zap.Error(err))
|
||||
return &milvuspb.SelectUserResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: err.Error(),
|
||||
},
|
||||
}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (node *Proxy) OperatePrivilege(ctx context.Context, request *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (node *Proxy) validPrivilegeParams(req *milvuspb.OperatePrivilegeRequest) error {
|
||||
if req.Entity == nil {
|
||||
return fmt.Errorf("the entity in the request is nil")
|
||||
}
|
||||
if req.Entity.Grantor == nil {
|
||||
return fmt.Errorf("the grantor entity in the grant entity is nil")
|
||||
}
|
||||
if req.Entity.Grantor.Privilege == nil {
|
||||
return fmt.Errorf("the privilege entity in the grantor entity is nil")
|
||||
}
|
||||
if err := ValidatePrivilege(req.Entity.Grantor.Privilege.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if req.Entity.Object == nil {
|
||||
return fmt.Errorf("the resource entity in the grant entity is nil")
|
||||
}
|
||||
if err := ValidateObjectType(req.Entity.Object.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ValidateObjectName(req.Entity.ObjectName); err != nil {
|
||||
return err
|
||||
}
|
||||
if req.Entity.Role == nil {
|
||||
return fmt.Errorf("the object entity in the grant entity is nil")
|
||||
}
|
||||
if err := ValidateRoleName(req.Entity.Role.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (node *Proxy) SelectGrant(ctx context.Context, request *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (node *Proxy) OperatePrivilege(ctx context.Context, req *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
logger.Debug("OperatePrivilege", zap.Any("req", req))
|
||||
if code, ok := node.checkHealthyAndReturnCode(); !ok {
|
||||
return errorutil.UnhealthyStatus(code), errorutil.UnhealthyError()
|
||||
}
|
||||
if isValid, status := node.validateAdminPermission(ctx); !isValid {
|
||||
return status, errorutil.PermissionDenyError()
|
||||
}
|
||||
if err := node.validPrivilegeParams(req); err != nil {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_IllegalArgument,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
curUser, err := GetCurUserFromContext(ctx)
|
||||
if err != nil {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
req.Entity.Grantor.User = &milvuspb.UserEntity{Name: curUser}
|
||||
result, err := node.rootCoord.OperatePrivilege(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error("fail to operate privilege", zap.Error(err))
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (node *Proxy) RefreshPolicyInfoCache(ctx context.Context, request *proxypb.RefreshPolicyInfoCacheRequest) (*commonpb.Status, error) {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
func (node *Proxy) validGrantParams(req *milvuspb.SelectGrantRequest) error {
|
||||
if req.Entity == nil {
|
||||
return fmt.Errorf("the grant entity in the request is nil")
|
||||
}
|
||||
|
||||
if req.Entity.Object != nil {
|
||||
if err := ValidateObjectType(req.Entity.Object.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ValidateObjectName(req.Entity.ObjectName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if req.Entity.Role == nil {
|
||||
return fmt.Errorf("the role entity in the grant entity is nil")
|
||||
}
|
||||
|
||||
if err := ValidateRoleName(req.Entity.Role.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (node *Proxy) SelectGrant(ctx context.Context, req *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
logger.Debug("SelectGrant", zap.Any("req", req))
|
||||
if code, ok := node.checkHealthyAndReturnCode(); !ok {
|
||||
return &milvuspb.SelectGrantResponse{Status: errorutil.UnhealthyStatus(code)}, errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
if isValid, status := node.validateAdminPermission(ctx); !isValid {
|
||||
return &milvuspb.SelectGrantResponse{
|
||||
Status: status,
|
||||
}, errorutil.PermissionDenyError()
|
||||
}
|
||||
|
||||
if err := node.validGrantParams(req); err != nil {
|
||||
return &milvuspb.SelectGrantResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_IllegalArgument,
|
||||
Reason: err.Error(),
|
||||
},
|
||||
}, err
|
||||
}
|
||||
|
||||
result, err := node.rootCoord.SelectGrant(ctx, req)
|
||||
if err != nil {
|
||||
logger.Error("fail to select grant", zap.Error(err))
|
||||
return &milvuspb.SelectGrantResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: err.Error(),
|
||||
},
|
||||
}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (node *Proxy) RefreshPolicyInfoCache(ctx context.Context, req *proxypb.RefreshPolicyInfoCacheRequest) (*commonpb.Status, error) {
|
||||
logger.Debug("RefreshPrivilegeInfoCache", zap.Any("req", req))
|
||||
if code, ok := node.checkHealthyAndReturnCode(); !ok {
|
||||
return errorutil.UnhealthyStatus(code), errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
if globalMetaCache != nil {
|
||||
err := globalMetaCache.RefreshPolicyInfo(typeutil.CacheOp{
|
||||
OpType: typeutil.CacheOpType(req.OpType),
|
||||
OpKey: req.OpKey,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("fail to refresh policy info", zap.Error(err))
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_RefreshPolicyInfoCacheFailure,
|
||||
Reason: err.Error(),
|
||||
}, err
|
||||
}
|
||||
}
|
||||
logger.Debug("RefreshPrivilegeInfoCache success")
|
||||
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_Success,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/funcutil"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/common"
|
||||
|
@ -36,6 +38,7 @@ import (
|
|||
"github.com/milvus-io/milvus/internal/proto/rootcoordpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/types"
|
||||
"github.com/milvus-io/milvus/internal/util"
|
||||
"github.com/milvus-io/milvus/internal/util/retry"
|
||||
"github.com/milvus-io/milvus/internal/util/timerecord"
|
||||
"github.com/milvus-io/milvus/internal/util/typeutil"
|
||||
|
@ -65,6 +68,11 @@ type Cache interface {
|
|||
GetCredentialInfo(ctx context.Context, username string) (*internalpb.CredentialInfo, error)
|
||||
RemoveCredential(username string)
|
||||
UpdateCredential(credInfo *internalpb.CredentialInfo)
|
||||
|
||||
GetPrivilegeInfo(ctx context.Context) []string
|
||||
GetUserRole(username string) []string
|
||||
RefreshPolicyInfo(op typeutil.CacheOp) error
|
||||
InitPolicyInfo(info []string, userRoles []string)
|
||||
}
|
||||
|
||||
type collectionInfo struct {
|
||||
|
@ -104,34 +112,48 @@ type MetaCache struct {
|
|||
rootCoord types.RootCoord
|
||||
queryCoord types.QueryCoord
|
||||
|
||||
collInfo map[string]*collectionInfo
|
||||
credMap map[string]*internalpb.CredentialInfo // cache for credential, lazy load
|
||||
mu sync.RWMutex
|
||||
credMut sync.RWMutex
|
||||
shardMgr *shardClientMgr
|
||||
collInfo map[string]*collectionInfo
|
||||
credMap map[string]*internalpb.CredentialInfo // cache for credential, lazy load
|
||||
privilegeInfos map[string]struct{} // privileges cache
|
||||
userToRoles map[string]map[string]struct{} // user to role cache
|
||||
mu sync.RWMutex
|
||||
credMut sync.RWMutex
|
||||
privilegeMut sync.RWMutex
|
||||
shardMgr *shardClientMgr
|
||||
}
|
||||
|
||||
// globalMetaCache is singleton instance of Cache
|
||||
var globalMetaCache Cache
|
||||
|
||||
// InitMetaCache initializes globalMetaCache
|
||||
func InitMetaCache(rootCoord types.RootCoord, queryCoord types.QueryCoord, shardMgr *shardClientMgr) error {
|
||||
func InitMetaCache(ctx context.Context, rootCoord types.RootCoord, queryCoord types.QueryCoord, shardMgr *shardClientMgr) error {
|
||||
var err error
|
||||
globalMetaCache, err = NewMetaCache(rootCoord, queryCoord, shardMgr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// The privilege info is a little more. And to get this info, the query operation of involving multiple table queries is required.
|
||||
resp, err := rootCoord.ListPolicy(ctx, &internalpb.ListPolicyRequest{})
|
||||
if err != nil {
|
||||
log.Error("fail to init meta cache", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
globalMetaCache.InitPolicyInfo(resp.PolicyInfos, resp.UserRoles)
|
||||
log.Debug("success to init meta cache", zap.Strings("policy_infos", resp.PolicyInfos))
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewMetaCache creates a MetaCache with provided RootCoord and QueryNode
|
||||
func NewMetaCache(rootCoord types.RootCoord, queryCoord types.QueryCoord, shardMgr *shardClientMgr) (*MetaCache, error) {
|
||||
return &MetaCache{
|
||||
rootCoord: rootCoord,
|
||||
queryCoord: queryCoord,
|
||||
collInfo: map[string]*collectionInfo{},
|
||||
credMap: map[string]*internalpb.CredentialInfo{},
|
||||
shardMgr: shardMgr,
|
||||
rootCoord: rootCoord,
|
||||
queryCoord: queryCoord,
|
||||
collInfo: map[string]*collectionInfo{},
|
||||
credMap: map[string]*internalpb.CredentialInfo{},
|
||||
shardMgr: shardMgr,
|
||||
privilegeInfos: map[string]struct{}{},
|
||||
userToRoles: map[string]map[string]struct{}{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -641,3 +663,60 @@ func (m *MetaCache) ClearShards(collectionName string) {
|
|||
_ = m.shardMgr.UpdateShardLeaders(info.shardLeaders, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MetaCache) InitPolicyInfo(info []string, userRoles []string) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
m.privilegeInfos = util.StringSet(info)
|
||||
for _, userRole := range userRoles {
|
||||
user, role := funcutil.DecodeUserRoleCache(userRole)
|
||||
if m.userToRoles[user] == nil {
|
||||
m.userToRoles[user] = make(map[string]struct{})
|
||||
}
|
||||
m.userToRoles[user][role] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MetaCache) GetPrivilegeInfo(ctx context.Context) []string {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
return util.StringList(m.privilegeInfos)
|
||||
}
|
||||
|
||||
func (m *MetaCache) GetUserRole(user string) []string {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
return util.StringList(m.userToRoles[user])
|
||||
}
|
||||
|
||||
func (m *MetaCache) RefreshPolicyInfo(op typeutil.CacheOp) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if op.OpKey == "" {
|
||||
return errors.New("empty op key")
|
||||
}
|
||||
switch op.OpType {
|
||||
case typeutil.CacheGrantPrivilege:
|
||||
m.privilegeInfos[op.OpKey] = struct{}{}
|
||||
case typeutil.CacheRevokePrivilege:
|
||||
delete(m.privilegeInfos, op.OpKey)
|
||||
case typeutil.CacheAddUserToRole:
|
||||
user, role := funcutil.DecodeUserRoleCache(op.OpKey)
|
||||
if m.userToRoles[user] == nil {
|
||||
m.userToRoles[user] = make(map[string]struct{})
|
||||
}
|
||||
m.userToRoles[user][role] = struct{}{}
|
||||
case typeutil.CacheRemoveUserFromRole:
|
||||
user, role := funcutil.DecodeUserRoleCache(op.OpKey)
|
||||
if m.userToRoles[user] != nil {
|
||||
delete(m.userToRoles[user], role)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid opType, op_type: %d, op_key: %s", int(op.OpType), op.OpKey)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -22,11 +22,14 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/funcutil"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/log"
|
||||
"github.com/milvus-io/milvus/internal/proto/commonpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/internalpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/milvuspb"
|
||||
"github.com/milvus-io/milvus/internal/proto/querypb"
|
||||
"github.com/milvus-io/milvus/internal/proto/rootcoordpb"
|
||||
|
@ -40,6 +43,8 @@ type MockRootCoordClientInterface struct {
|
|||
types.RootCoord
|
||||
Error bool
|
||||
AccessCount int
|
||||
|
||||
listPolicy func(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error)
|
||||
}
|
||||
|
||||
type MockQueryCoordClientInterface struct {
|
||||
|
@ -178,6 +183,17 @@ func (m *MockRootCoordClientInterface) ListCredUsers(ctx context.Context, req *m
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (m *MockRootCoordClientInterface) ListPolicy(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
if m.listPolicy != nil {
|
||||
return m.listPolicy(ctx, in)
|
||||
}
|
||||
return &internalpb.ListPolicyResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_Success,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *MockQueryCoordClientInterface) ShowCollections(ctx context.Context, req *querypb.ShowCollectionsRequest) (*querypb.ShowCollectionsResponse, error) {
|
||||
if m.Error {
|
||||
return nil, errors.New("mocked error")
|
||||
|
@ -199,7 +215,7 @@ func TestMetaCache_GetCollection(t *testing.T) {
|
|||
rootCoord := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, queryCoord, mgr)
|
||||
err := InitMetaCache(ctx, rootCoord, queryCoord, mgr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
id, err := globalMetaCache.GetCollectionID(ctx, "collection1")
|
||||
|
@ -247,7 +263,7 @@ func TestMetaCache_GetCollectionFailure(t *testing.T) {
|
|||
rootCoord := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, queryCoord, mgr)
|
||||
err := InitMetaCache(ctx, rootCoord, queryCoord, mgr)
|
||||
assert.Nil(t, err)
|
||||
rootCoord.Error = true
|
||||
|
||||
|
@ -278,7 +294,7 @@ func TestMetaCache_GetNonExistCollection(t *testing.T) {
|
|||
rootCoord := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, queryCoord, mgr)
|
||||
err := InitMetaCache(ctx, rootCoord, queryCoord, mgr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
id, err := globalMetaCache.GetCollectionID(ctx, "collection3")
|
||||
|
@ -294,7 +310,7 @@ func TestMetaCache_GetPartitionID(t *testing.T) {
|
|||
rootCoord := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, queryCoord, mgr)
|
||||
err := InitMetaCache(ctx, rootCoord, queryCoord, mgr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
id, err := globalMetaCache.GetPartitionID(ctx, "collection1", "par1")
|
||||
|
@ -316,7 +332,7 @@ func TestMetaCache_GetPartitionError(t *testing.T) {
|
|||
rootCoord := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, queryCoord, mgr)
|
||||
err := InitMetaCache(ctx, rootCoord, queryCoord, mgr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Test the case where ShowPartitionsResponse is not aligned
|
||||
|
@ -344,16 +360,17 @@ func TestMetaCache_GetPartitionError(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMetaCache_GetShards(t *testing.T) {
|
||||
var (
|
||||
ctx = context.Background()
|
||||
collectionName = "collection1"
|
||||
)
|
||||
|
||||
rootCoord := &MockRootCoordClientInterface{}
|
||||
qc := NewQueryCoordMock()
|
||||
shardMgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, qc, shardMgr)
|
||||
err := InitMetaCache(ctx, rootCoord, qc, shardMgr)
|
||||
require.Nil(t, err)
|
||||
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
collectionName = "collection1"
|
||||
)
|
||||
qc.Init()
|
||||
qc.Start()
|
||||
defer qc.Stop()
|
||||
|
@ -391,16 +408,17 @@ func TestMetaCache_GetShards(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMetaCache_ClearShards(t *testing.T) {
|
||||
rootCoord := &MockRootCoordClientInterface{}
|
||||
qc := NewQueryCoordMock()
|
||||
mgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, qc, mgr)
|
||||
require.Nil(t, err)
|
||||
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
collectionName = "collection1"
|
||||
)
|
||||
|
||||
rootCoord := &MockRootCoordClientInterface{}
|
||||
qc := NewQueryCoordMock()
|
||||
mgr := newShardClientMgr()
|
||||
err := InitMetaCache(ctx, rootCoord, qc, mgr)
|
||||
require.Nil(t, err)
|
||||
|
||||
qc.Init()
|
||||
qc.Start()
|
||||
defer qc.Stop()
|
||||
|
@ -429,7 +447,88 @@ func TestMetaCache_ClearShards(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
assert.Empty(t, shards)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMetaCache_PolicyInfo(t *testing.T) {
|
||||
client := &MockRootCoordClientInterface{}
|
||||
qc := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
|
||||
t.Run("InitMetaCache", func(t *testing.T) {
|
||||
client.listPolicy = func(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
return nil, fmt.Errorf("mock error")
|
||||
}
|
||||
err := InitMetaCache(context.Background(), client, qc, mgr)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
client.listPolicy = func(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
return &internalpb.ListPolicyResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_Success,
|
||||
},
|
||||
PolicyInfos: []string{"policy1", "policy2", "policy3"},
|
||||
}, nil
|
||||
}
|
||||
err = InitMetaCache(context.Background(), client, qc, mgr)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("GetPrivilegeInfo", func(t *testing.T) {
|
||||
client.listPolicy = func(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
return &internalpb.ListPolicyResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_Success,
|
||||
},
|
||||
PolicyInfos: []string{"policy1", "policy2", "policy3"},
|
||||
UserRoles: []string{funcutil.EncodeUserRoleCache("foo", "role1"), funcutil.EncodeUserRoleCache("foo", "role2"), funcutil.EncodeUserRoleCache("foo2", "role2")},
|
||||
}, nil
|
||||
}
|
||||
err := InitMetaCache(context.Background(), client, qc, mgr)
|
||||
assert.Nil(t, err)
|
||||
policyInfos := globalMetaCache.GetPrivilegeInfo(context.Background())
|
||||
assert.Equal(t, 3, len(policyInfos))
|
||||
roles := globalMetaCache.GetUserRole("foo")
|
||||
assert.Equal(t, 2, len(roles))
|
||||
})
|
||||
|
||||
t.Run("GetPrivilegeInfo", func(t *testing.T) {
|
||||
client.listPolicy = func(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
return &internalpb.ListPolicyResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_Success,
|
||||
},
|
||||
PolicyInfos: []string{"policy1", "policy2", "policy3"},
|
||||
UserRoles: []string{funcutil.EncodeUserRoleCache("foo", "role1"), funcutil.EncodeUserRoleCache("foo", "role2"), funcutil.EncodeUserRoleCache("foo2", "role2")},
|
||||
}, nil
|
||||
}
|
||||
err := InitMetaCache(context.Background(), client, qc, mgr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = globalMetaCache.RefreshPolicyInfo(typeutil.CacheOp{OpType: typeutil.CacheGrantPrivilege, OpKey: "policyX"})
|
||||
assert.Nil(t, err)
|
||||
policyInfos := globalMetaCache.GetPrivilegeInfo(context.Background())
|
||||
assert.Equal(t, 4, len(policyInfos))
|
||||
|
||||
err = globalMetaCache.RefreshPolicyInfo(typeutil.CacheOp{OpType: typeutil.CacheRevokePrivilege, OpKey: "policyX"})
|
||||
assert.Nil(t, err)
|
||||
policyInfos = globalMetaCache.GetPrivilegeInfo(context.Background())
|
||||
assert.Equal(t, 3, len(policyInfos))
|
||||
|
||||
err = globalMetaCache.RefreshPolicyInfo(typeutil.CacheOp{OpType: typeutil.CacheAddUserToRole, OpKey: funcutil.EncodeUserRoleCache("foo", "role3")})
|
||||
assert.Nil(t, err)
|
||||
roles := globalMetaCache.GetUserRole("foo")
|
||||
assert.Equal(t, 3, len(roles))
|
||||
|
||||
err = globalMetaCache.RefreshPolicyInfo(typeutil.CacheOp{OpType: typeutil.CacheRemoveUserFromRole, OpKey: funcutil.EncodeUserRoleCache("foo", "role3")})
|
||||
assert.Nil(t, err)
|
||||
roles = globalMetaCache.GetUserRole("foo")
|
||||
assert.Equal(t, 2, len(roles))
|
||||
|
||||
err = globalMetaCache.RefreshPolicyInfo(typeutil.CacheOp{OpType: typeutil.CacheGrantPrivilege, OpKey: ""})
|
||||
assert.NotNil(t, err)
|
||||
err = globalMetaCache.RefreshPolicyInfo(typeutil.CacheOp{OpType: 100, OpKey: "policyX"})
|
||||
assert.NotNil(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMetaCache_LoadCache(t *testing.T) {
|
||||
|
@ -437,7 +536,7 @@ func TestMetaCache_LoadCache(t *testing.T) {
|
|||
rootCoord := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, queryCoord, mgr)
|
||||
err := InitMetaCache(ctx, rootCoord, queryCoord, mgr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
t.Run("test IsCollectionLoaded", func(t *testing.T) {
|
||||
|
@ -481,7 +580,7 @@ func TestMetaCache_RemoveCollection(t *testing.T) {
|
|||
rootCoord := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
shardMgr := newShardClientMgr()
|
||||
err := InitMetaCache(rootCoord, queryCoord, shardMgr)
|
||||
err := InitMetaCache(ctx, rootCoord, queryCoord, shardMgr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
info, err := globalMetaCache.GetCollectionInfo(ctx, "collection1")
|
||||
|
|
|
@ -10,12 +10,14 @@ import (
|
|||
type getCollectionIDFunc func(ctx context.Context, collectionName string) (typeutil.UniqueID, error)
|
||||
type getCollectionSchemaFunc func(ctx context.Context, collectionName string) (*schemapb.CollectionSchema, error)
|
||||
type getCollectionInfoFunc func(ctx context.Context, collectionName string) (*collectionInfo, error)
|
||||
type getUserRoleFunc func(username string) []string
|
||||
|
||||
type mockCache struct {
|
||||
Cache
|
||||
getIDFunc getCollectionIDFunc
|
||||
getSchemaFunc getCollectionSchemaFunc
|
||||
getInfoFunc getCollectionInfoFunc
|
||||
getIDFunc getCollectionIDFunc
|
||||
getSchemaFunc getCollectionSchemaFunc
|
||||
getInfoFunc getCollectionInfoFunc
|
||||
getUserRoleFunc getUserRoleFunc
|
||||
}
|
||||
|
||||
func (m *mockCache) GetCollectionID(ctx context.Context, collectionName string) (typeutil.UniqueID, error) {
|
||||
|
@ -42,6 +44,13 @@ func (m *mockCache) GetCollectionInfo(ctx context.Context, collectionName string
|
|||
func (m *mockCache) RemoveCollection(ctx context.Context, collectionName string) {
|
||||
}
|
||||
|
||||
func (m *mockCache) GetUserRole(username string) []string {
|
||||
if m.getUserRoleFunc != nil {
|
||||
return m.getUserRoleFunc(username)
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (m *mockCache) setGetIDFunc(f getCollectionIDFunc) {
|
||||
m.getIDFunc = f
|
||||
}
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util"
|
||||
|
||||
"github.com/casbin/casbin/v2"
|
||||
"github.com/casbin/casbin/v2/model"
|
||||
jsonadapter "github.com/casbin/json-adapter/v2"
|
||||
"github.com/milvus-io/milvus/internal/log"
|
||||
"github.com/milvus-io/milvus/internal/util/funcutil"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type PrivilegeFunc func(ctx context.Context, req interface{}) (context.Context, error)
|
||||
|
||||
const (
|
||||
// sub -> role name, like admin, public
|
||||
// obj -> contact object with object name, like Global-*, Collection-col1
|
||||
// act -> privilege, like CreateCollection, DescribeCollection
|
||||
ModelStr = `
|
||||
[request_definition]
|
||||
r = sub, obj, act
|
||||
|
||||
[policy_definition]
|
||||
p = sub, obj, act
|
||||
|
||||
[policy_effect]
|
||||
e = some(where (p.eft == allow))
|
||||
|
||||
[matchers]
|
||||
m = r.sub == p.sub && globMatch(p.obj, r.obj) && globMatch(p.act, r.act) || r.sub == "admin" || r.act == "All"
|
||||
`
|
||||
ModelKey = "casbin"
|
||||
)
|
||||
|
||||
var modelStore = make(map[string]model.Model, 1)
|
||||
|
||||
func initPolicyModel() (model.Model, error) {
|
||||
if policyModel, ok := modelStore[ModelStr]; ok {
|
||||
return policyModel, nil
|
||||
}
|
||||
policyModel, err := model.NewModelFromString(ModelStr)
|
||||
if err != nil {
|
||||
log.Error("NewModelFromString fail", zap.String("model", ModelStr), zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
modelStore[ModelKey] = policyModel
|
||||
return modelStore[ModelKey], nil
|
||||
}
|
||||
|
||||
// UnaryServerInterceptor returns a new unary server interceptors that performs per-request privilege access.
|
||||
func UnaryServerInterceptor(privilegeFunc PrivilegeFunc) grpc.UnaryServerInterceptor {
|
||||
initPolicyModel()
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
newCtx, err := privilegeFunc(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return handler(newCtx, req)
|
||||
}
|
||||
}
|
||||
|
||||
func PrivilegeInterceptor(ctx context.Context, req interface{}) (context.Context, error) {
|
||||
if !Params.CommonCfg.AuthorizationEnabled {
|
||||
return ctx, nil
|
||||
}
|
||||
log.Debug("PrivilegeInterceptor", zap.String("type", reflect.TypeOf(req).String()))
|
||||
privilegeExt, err := funcutil.GetPrivilegeExtObj(req)
|
||||
if err != nil {
|
||||
log.Debug("GetPrivilegeExtObj err", zap.Error(err))
|
||||
return ctx, nil
|
||||
}
|
||||
username, err := GetCurUserFromContext(ctx)
|
||||
if err != nil {
|
||||
log.Error("GetCurUserFromContext fail", zap.Error(err))
|
||||
return ctx, err
|
||||
}
|
||||
roleNames, err := GetRole(username)
|
||||
if err != nil {
|
||||
log.Error("GetRole fail", zap.String("username", username), zap.Error(err))
|
||||
return ctx, err
|
||||
}
|
||||
roleNames = append(roleNames, util.RolePublic)
|
||||
resourceType := privilegeExt.ObjectType.String()
|
||||
resourceNameIndex := privilegeExt.ObjectNameIndex
|
||||
resourceName := funcutil.GetResourceName(req, privilegeExt.ObjectNameIndex)
|
||||
resourcePrivilege := privilegeExt.ObjectPrivilege.String()
|
||||
policyInfo := strings.Join(globalMetaCache.GetPrivilegeInfo(ctx), ",")
|
||||
|
||||
log.Debug("current request info", zap.String("username", username), zap.Strings("role_names", roleNames),
|
||||
zap.String("resource_type", resourceType), zap.String("resource_privilege", resourcePrivilege), zap.Int32("resource_index", resourceNameIndex), zap.String("resource_name", resourceName),
|
||||
zap.String("policy_info", policyInfo))
|
||||
|
||||
policy := fmt.Sprintf("[%s]", strings.Join(globalMetaCache.GetPrivilegeInfo(ctx), ","))
|
||||
b := []byte(policy)
|
||||
a := jsonadapter.NewAdapter(&b)
|
||||
policyModel, err := initPolicyModel()
|
||||
if err != nil {
|
||||
errStr := "fail to get policy model"
|
||||
log.Error(errStr, zap.Error(err))
|
||||
return ctx, err
|
||||
}
|
||||
e, err := casbin.NewEnforcer(policyModel, a)
|
||||
if err != nil {
|
||||
log.Error("NewEnforcer fail", zap.String("policy", policy), zap.Error(err))
|
||||
return ctx, err
|
||||
}
|
||||
for _, roleName := range roleNames {
|
||||
isPermit, err := e.Enforce(roleName, funcutil.PolicyForResource(resourceType, resourceName), privilegeExt.ObjectPrivilege.String())
|
||||
if err != nil {
|
||||
log.Error("Enforce fail", zap.String("policy", policy), zap.String("role", roleName), zap.Error(err))
|
||||
return ctx, err
|
||||
}
|
||||
if isPermit {
|
||||
return ctx, nil
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug("permission deny", zap.String("policy", policy), zap.Strings("roles", roleNames))
|
||||
return ctx, &ErrPermissionDenied{}
|
||||
}
|
||||
|
||||
type ErrPermissionDenied struct{}
|
||||
|
||||
func (e ErrPermissionDenied) Error() string {
|
||||
return "permission deny"
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/funcutil"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/commonpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/internalpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/milvuspb"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUnaryServerInterceptor(t *testing.T) {
|
||||
interceptor := UnaryServerInterceptor(PrivilegeInterceptor)
|
||||
assert.NotNil(t, interceptor)
|
||||
}
|
||||
|
||||
func TestPrivilegeInterceptor(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
t.Run("Authorization Disabled", func(t *testing.T) {
|
||||
Params.CommonCfg.AuthorizationEnabled = false
|
||||
_, err := PrivilegeInterceptor(ctx, &milvuspb.LoadCollectionRequest{
|
||||
DbName: "db_test",
|
||||
CollectionName: "col1",
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("Authorization Enabled", func(t *testing.T) {
|
||||
Params.CommonCfg.AuthorizationEnabled = true
|
||||
|
||||
_, err := PrivilegeInterceptor(ctx, &milvuspb.HasCollectionRequest{})
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = PrivilegeInterceptor(ctx, &milvuspb.LoadCollectionRequest{
|
||||
DbName: "db_test",
|
||||
CollectionName: "col1",
|
||||
})
|
||||
assert.NotNil(t, err)
|
||||
|
||||
ctx = GetContext(context.Background(), "alice:123456")
|
||||
client := &MockRootCoordClientInterface{}
|
||||
queryCoord := &MockQueryCoordClientInterface{}
|
||||
mgr := newShardClientMgr()
|
||||
|
||||
client.listPolicy = func(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
return &internalpb.ListPolicyResponse{
|
||||
Status: &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_Success,
|
||||
},
|
||||
PolicyInfos: []string{
|
||||
funcutil.PolicyForPrivilege("role1", commonpb.ObjectType_Collection.String(), "col1", commonpb.ObjectPrivilege_PrivilegeLoad.String()),
|
||||
},
|
||||
UserRoles: []string{
|
||||
funcutil.EncodeUserRoleCache("alice", "role1"),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
_, err = PrivilegeInterceptor(GetContext(context.Background(), "foo:123456"), &milvuspb.LoadCollectionRequest{
|
||||
DbName: "db_test",
|
||||
CollectionName: "col1",
|
||||
})
|
||||
assert.NotNil(t, err)
|
||||
|
||||
err = InitMetaCache(ctx, client, queryCoord, mgr)
|
||||
assert.Nil(t, err)
|
||||
_, err = PrivilegeInterceptor(ctx, &milvuspb.HasCollectionRequest{
|
||||
DbName: "db_test",
|
||||
CollectionName: "col1",
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
_, err = PrivilegeInterceptor(ctx, &milvuspb.LoadCollectionRequest{
|
||||
DbName: "db_test",
|
||||
CollectionName: "col1",
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, err = PrivilegeInterceptor(GetContext(context.Background(), "foo:123456"), &milvuspb.LoadCollectionRequest{
|
||||
DbName: "db_test",
|
||||
CollectionName: "col1",
|
||||
})
|
||||
assert.NotNil(t, err)
|
||||
_, err = PrivilegeInterceptor(ctx, &milvuspb.InsertRequest{
|
||||
DbName: "db_test",
|
||||
CollectionName: "col1",
|
||||
})
|
||||
assert.NotNil(t, err)
|
||||
|
||||
})
|
||||
|
||||
}
|
|
@ -221,7 +221,7 @@ func (node *Proxy) Init() error {
|
|||
log.Debug("create metrics cache manager done", zap.String("role", typeutil.ProxyRole))
|
||||
|
||||
log.Debug("init meta cache", zap.String("role", typeutil.ProxyRole))
|
||||
if err := InitMetaCache(node.rootCoord, node.queryCoord, node.shardMgr); err != nil {
|
||||
if err := InitMetaCache(node.ctx, node.rootCoord, node.queryCoord, node.shardMgr); err != nil {
|
||||
log.Warn("failed to init meta cache", zap.Error(err), zap.String("role", typeutil.ProxyRole))
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package proxy
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
|
@ -38,6 +39,7 @@ import (
|
|||
"github.com/milvus-io/milvus/internal/log"
|
||||
"github.com/milvus-io/milvus/internal/metrics"
|
||||
"github.com/milvus-io/milvus/internal/rootcoord"
|
||||
"github.com/milvus-io/milvus/internal/util"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/crypto"
|
||||
"github.com/milvus-io/milvus/internal/util/dependency"
|
||||
|
@ -408,6 +410,7 @@ func TestProxy(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx = GetContext(ctx, "root:123456")
|
||||
localMsg := true
|
||||
factory := dependency.NewDefaultFactory(localMsg)
|
||||
alias := "TestProxy"
|
||||
|
@ -2165,8 +2168,12 @@ func TestProxy(t *testing.T) {
|
|||
Password: crypto.Base64Encode(password),
|
||||
}
|
||||
}
|
||||
// success
|
||||
createCredentialReq := constructCreateCredentialRequest()
|
||||
// permission deny
|
||||
invalidCtx := GetContext(context.Background(), "foo:12345")
|
||||
_, err := proxy.CreateCredential(invalidCtx, createCredentialReq)
|
||||
assert.Error(t, err)
|
||||
// success
|
||||
resp, err := proxy.CreateCredential(ctx, createCredentialReq)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
@ -2304,11 +2311,20 @@ func TestProxy(t *testing.T) {
|
|||
}
|
||||
}
|
||||
delCredReq := constructDelCredRequest()
|
||||
// permission deny
|
||||
invalidCtx := GetContext(context.Background(), "foo:12345")
|
||||
_, err := proxy.DeleteCredential(invalidCtx, delCredReq)
|
||||
assert.Error(t, err)
|
||||
|
||||
deleteResp, err := proxy.DeleteCredential(ctx, delCredReq)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, deleteResp.ErrorCode)
|
||||
})
|
||||
|
||||
testProxyRole(ctx, t, proxy)
|
||||
testProxyPrivilege(ctx, t, proxy)
|
||||
testProxyRefreshPolicyInfoCache(ctx, t, proxy)
|
||||
|
||||
// proxy unhealthy
|
||||
//
|
||||
//notStateCode := "not state code"
|
||||
|
@ -2593,6 +2609,58 @@ func TestProxy(t *testing.T) {
|
|||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("InvalidateCredCache fail, unhealthy", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, err := proxy.InvalidateCredentialCache(ctx, &proxypb.InvalidateCredCacheRequest{Username: "xxx"})
|
||||
assert.Error(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("UpdateCredentialCache fail, unhealthy", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, err := proxy.UpdateCredentialCache(ctx, &proxypb.UpdateCredCacheRequest{Username: "xxx", Password: "xxx"})
|
||||
assert.Error(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("CreateCredential fail, unhealthy", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, err := proxy.CreateCredential(ctx, &milvuspb.CreateCredentialRequest{Username: "xxx"})
|
||||
assert.Error(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("UpdateCredential fail, unhealthy", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, err := proxy.UpdateCredential(ctx, &milvuspb.UpdateCredentialRequest{Username: "xxx"})
|
||||
assert.Error(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("DeleteCredential fail, unhealthy", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, err := proxy.DeleteCredential(ctx, &milvuspb.DeleteCredentialRequest{Username: "xxx"})
|
||||
assert.Error(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("ListCredUsers fail, unhealthy", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, err := proxy.ListCredUsers(ctx, &milvuspb.ListCredUsersRequest{})
|
||||
assert.Error(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
})
|
||||
|
||||
testProxyRoleUnhealthy(ctx, t, proxy)
|
||||
testProxyPrivilegeUnhealthy(ctx, t, proxy)
|
||||
testProxyRefreshPolicyInfoCacheUnhealthy(ctx, t, proxy)
|
||||
|
||||
proxy.UpdateStateCode(internalpb.StateCode_Healthy)
|
||||
|
||||
// queue full
|
||||
|
@ -3100,12 +3168,464 @@ func TestProxy(t *testing.T) {
|
|||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
testProxyRoleTimeout(shortCtx, t, proxy)
|
||||
testProxyPrivilegeTimeout(shortCtx, t, proxy)
|
||||
|
||||
testServer.gracefulStop()
|
||||
|
||||
wg.Wait()
|
||||
cancel()
|
||||
}
|
||||
|
||||
func getNotRootCtx() context.Context {
|
||||
return GetContext(context.Background(), "foo:12345")
|
||||
}
|
||||
|
||||
func testProxyRole(ctx context.Context, t *testing.T, proxy *Proxy) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
t.Run("Create Role", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
|
||||
entity := &milvuspb.RoleEntity{Name: " "}
|
||||
resp, _ := proxy.CreateRole(ctx, &milvuspb.CreateRoleRequest{Entity: entity})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
entity.Name = "unit_test"
|
||||
_, err := proxy.CreateRole(getNotRootCtx(), &milvuspb.CreateRoleRequest{Entity: entity})
|
||||
assert.Error(t, err)
|
||||
|
||||
resp, _ = proxy.CreateRole(ctx, &milvuspb.CreateRoleRequest{Entity: entity})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.CreateRole(ctx, &milvuspb.CreateRoleRequest{Entity: entity})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.DropRole(ctx, &milvuspb.DropRoleRequest{RoleName: entity.Name})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("Drop Role", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
|
||||
resp, _ := proxy.DropRole(ctx, &milvuspb.DropRoleRequest{RoleName: " "})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
username := "root"
|
||||
roleName := "unit_test"
|
||||
|
||||
roleEntity := &milvuspb.RoleEntity{Name: roleName}
|
||||
roleResp, _ := proxy.CreateRole(ctx, &milvuspb.CreateRoleRequest{Entity: roleEntity})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, roleResp.ErrorCode)
|
||||
|
||||
privilegeRequest := &milvuspb.OperatePrivilegeRequest{
|
||||
Type: milvuspb.OperatePrivilegeType_Grant,
|
||||
Entity: &milvuspb.GrantEntity{
|
||||
ObjectName: "col1",
|
||||
Object: &milvuspb.ObjectEntity{Name: commonpb.ObjectType_Collection.String()},
|
||||
Role: &milvuspb.RoleEntity{Name: roleName},
|
||||
Grantor: &milvuspb.GrantorEntity{Privilege: &milvuspb.PrivilegeEntity{Name: util.Load.String()}},
|
||||
},
|
||||
}
|
||||
privilegeResp, _ := proxy.OperatePrivilege(ctx, privilegeRequest)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, privilegeResp.ErrorCode)
|
||||
|
||||
_, err := proxy.SelectUser(context.Background(), &milvuspb.SelectUserRequest{User: &milvuspb.UserEntity{Name: username}, IncludeRoleInfo: true})
|
||||
assert.Error(t, err)
|
||||
|
||||
_, err = proxy.SelectUser(getNotRootCtx(), &milvuspb.SelectUserRequest{User: &milvuspb.UserEntity{Name: username}, IncludeRoleInfo: true})
|
||||
assert.Error(t, err)
|
||||
|
||||
userResp, _ := proxy.SelectUser(ctx, &milvuspb.SelectUserRequest{User: &milvuspb.UserEntity{Name: username}, IncludeRoleInfo: true})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, userResp.Status.ErrorCode)
|
||||
roleNumOfUser := len(userResp.Results[0].Roles)
|
||||
|
||||
_, err = proxy.OperateUserRole(getNotRootCtx(), &milvuspb.OperateUserRoleRequest{
|
||||
Username: username,
|
||||
RoleName: roleName,
|
||||
Type: milvuspb.OperateUserRoleType_AddUserToRole,
|
||||
})
|
||||
assert.Error(t, err)
|
||||
roleResp, _ = proxy.OperateUserRole(ctx, &milvuspb.OperateUserRoleRequest{
|
||||
Username: username,
|
||||
RoleName: roleName,
|
||||
Type: milvuspb.OperateUserRoleType_AddUserToRole,
|
||||
})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, roleResp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.DropRole(ctx, &milvuspb.DropRoleRequest{RoleName: roleName})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
privilegeRequest.Type = milvuspb.OperatePrivilegeType_Revoke
|
||||
privilegeResp, _ = proxy.OperatePrivilege(ctx, privilegeRequest)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, privilegeResp.ErrorCode)
|
||||
|
||||
_, err = proxy.DropRole(getNotRootCtx(), &milvuspb.DropRoleRequest{RoleName: roleName})
|
||||
assert.Error(t, err)
|
||||
|
||||
roleResp, _ = proxy.DropRole(ctx, &milvuspb.DropRoleRequest{RoleName: roleName})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, roleResp.ErrorCode)
|
||||
|
||||
userResp, _ = proxy.SelectUser(ctx, &milvuspb.SelectUserRequest{User: &milvuspb.UserEntity{Name: username}, IncludeRoleInfo: true})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, userResp.Status.ErrorCode)
|
||||
assert.Equal(t, roleNumOfUser, len(userResp.Results[0].Roles))
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("Operate User Role", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
|
||||
username := "root"
|
||||
roleName := "public"
|
||||
// AddUserToRole
|
||||
resp, _ := proxy.OperateUserRole(ctx, &milvuspb.OperateUserRoleRequest{Username: " "})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.OperateUserRole(ctx, &milvuspb.OperateUserRoleRequest{Username: username, RoleName: " "})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.OperateUserRole(ctx, &milvuspb.OperateUserRoleRequest{Username: "not_existed", RoleName: roleName})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.OperateUserRole(ctx, &milvuspb.OperateUserRoleRequest{Username: username, RoleName: "not_existed"})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.OperateUserRole(ctx, &milvuspb.OperateUserRoleRequest{Username: username, RoleName: roleName})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.OperateUserRole(ctx, &milvuspb.OperateUserRoleRequest{Username: username, RoleName: roleName, Type: milvuspb.OperateUserRoleType_RemoveUserFromRole})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("Select Role", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
|
||||
_, err := proxy.SelectRole(ctx, &milvuspb.SelectRoleRequest{Role: &milvuspb.RoleEntity{Name: " "}})
|
||||
assert.Error(t, err)
|
||||
|
||||
_, err = proxy.SelectRole(getNotRootCtx(), &milvuspb.SelectRoleRequest{Role: &milvuspb.RoleEntity{Name: " "}})
|
||||
assert.Error(t, err)
|
||||
|
||||
resp, _ := proxy.SelectRole(ctx, &milvuspb.SelectRoleRequest{})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
roleNum := len(resp.Results)
|
||||
|
||||
roleName := "unit_test"
|
||||
roleResp, _ := proxy.CreateRole(ctx, &milvuspb.CreateRoleRequest{Entity: &milvuspb.RoleEntity{Name: roleName}})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, roleResp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.SelectRole(ctx, &milvuspb.SelectRoleRequest{})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
assert.Equal(t, roleNum+1, len(resp.Results))
|
||||
|
||||
roleResp, _ = proxy.DropRole(ctx, &milvuspb.DropRoleRequest{RoleName: roleName})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, roleResp.ErrorCode)
|
||||
|
||||
resp, _ = proxy.SelectRole(ctx, &milvuspb.SelectRoleRequest{Role: &milvuspb.RoleEntity{Name: "admin"}, IncludeUserInfo: true})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
assert.NotEqual(t, 0, len(resp.Results))
|
||||
assert.NotEqual(t, 0, len(resp.Results[0].Users))
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run("Select User", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
|
||||
entity := &milvuspb.UserEntity{Name: " "}
|
||||
resp, _ := proxy.SelectUser(ctx, &milvuspb.SelectUserRequest{User: entity})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
|
||||
entity.Name = "not_existed"
|
||||
resp, _ = proxy.SelectUser(ctx, &milvuspb.SelectUserRequest{User: entity})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
|
||||
entity.Name = "root"
|
||||
resp, _ = proxy.SelectUser(ctx, &milvuspb.SelectUserRequest{User: entity})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
assert.NotEqual(t, 0, len(resp.Results))
|
||||
|
||||
resp, _ = proxy.SelectUser(ctx, &milvuspb.SelectUserRequest{User: entity, IncludeRoleInfo: true})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
assert.NotEqual(t, 0, len(resp.Results))
|
||||
assert.NotEqual(t, 0, len(resp.Results[0].Roles))
|
||||
})
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func testProxyRoleUnhealthy(ctx context.Context, t *testing.T, proxy *Proxy) {
|
||||
testProxyRoleFail(ctx, t, proxy, "unhealthy")
|
||||
}
|
||||
|
||||
func testProxyRoleTimeout(ctx context.Context, t *testing.T, proxy *Proxy) {
|
||||
testProxyRoleFail(ctx, t, proxy, "timeout")
|
||||
}
|
||||
|
||||
func testProxyRoleFail(ctx context.Context, t *testing.T, proxy *Proxy, reason string) {
|
||||
var wg sync.WaitGroup
|
||||
roleName := "xxx"
|
||||
|
||||
wg.Add(1)
|
||||
t.Run(fmt.Sprintf("CreateRole fail, %s", reason), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, _ := proxy.CreateRole(ctx, &milvuspb.CreateRoleRequest{Entity: &milvuspb.RoleEntity{Name: roleName}})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run(fmt.Sprintf("DropRole fail, %s", reason), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, _ := proxy.DropRole(ctx, &milvuspb.DropRoleRequest{RoleName: roleName})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run(fmt.Sprintf("OperateUserRole fail, %s", reason), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, _ := proxy.OperateUserRole(ctx, &milvuspb.OperateUserRoleRequest{Username: "root", RoleName: "public"})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run(fmt.Sprintf("SelectRole fail, %s", reason), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, _ := proxy.SelectRole(ctx, &milvuspb.SelectRoleRequest{})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run(fmt.Sprintf("SelectUser fail, %s", reason), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, _ := proxy.SelectUser(ctx, &milvuspb.SelectUserRequest{})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func testProxyPrivilege(ctx context.Context, t *testing.T, proxy *Proxy) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
t.Run("Operate Privilege, Select Grant", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
|
||||
// GrantPrivilege
|
||||
req := &milvuspb.OperatePrivilegeRequest{}
|
||||
resp, _ := proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity = &milvuspb.GrantEntity{}
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity.Grantor = &milvuspb.GrantorEntity{}
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity.Grantor.Privilege = &milvuspb.PrivilegeEntity{}
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity.Grantor.Privilege.Name = util.All.String()
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity.Object = &milvuspb.ObjectEntity{}
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity.Object.Name = commonpb.ObjectType_Global.String()
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity.ObjectName = "col1"
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity.Role = &milvuspb.RoleEntity{}
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity.Role = &milvuspb.RoleEntity{Name: "admin"}
|
||||
_, err := proxy.OperatePrivilege(getNotRootCtx(), req)
|
||||
assert.Error(t, err)
|
||||
_, err = proxy.OperatePrivilege(context.Background(), req)
|
||||
assert.Error(t, err)
|
||||
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
req.Entity.Grantor.Privilege.Name = "not existed"
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
req.Entity.Grantor.Privilege.Name = util.All.String()
|
||||
|
||||
req.Entity.Object.Name = "not existed"
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
req.Entity.Object.Name = commonpb.ObjectType_Global.String()
|
||||
|
||||
req.Entity.Role.Name = "not existed"
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
req.Entity.Role = &milvuspb.RoleEntity{Name: "admin"}
|
||||
|
||||
roleReq := &milvuspb.OperatePrivilegeRequest{
|
||||
Entity: &milvuspb.GrantEntity{
|
||||
Role: &milvuspb.RoleEntity{Name: "public"},
|
||||
Object: &milvuspb.ObjectEntity{Name: commonpb.ObjectType_Collection.String()},
|
||||
ObjectName: "col1",
|
||||
Grantor: &milvuspb.GrantorEntity{Privilege: &milvuspb.PrivilegeEntity{Name: util.Load.String()}},
|
||||
},
|
||||
Type: milvuspb.OperatePrivilegeType_Grant,
|
||||
}
|
||||
resp, _ = proxy.OperatePrivilege(ctx, roleReq)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
// select grant
|
||||
selectReq := &milvuspb.SelectGrantRequest{}
|
||||
results, _ := proxy.SelectGrant(ctx, selectReq)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
|
||||
selectReq.Entity = &milvuspb.GrantEntity{}
|
||||
results, _ = proxy.SelectGrant(ctx, selectReq)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
|
||||
selectReq.Entity.Object = &milvuspb.ObjectEntity{}
|
||||
results, _ = proxy.SelectGrant(ctx, selectReq)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
|
||||
selectReq.Entity.Object.Name = commonpb.ObjectType_Collection.String()
|
||||
results, _ = proxy.SelectGrant(ctx, selectReq)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
|
||||
selectReq.Entity.ObjectName = "col1"
|
||||
results, _ = proxy.SelectGrant(ctx, selectReq)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
|
||||
selectReq.Entity.Role = &milvuspb.RoleEntity{}
|
||||
results, _ = proxy.SelectGrant(ctx, selectReq)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
|
||||
selectReq.Entity.Role = &milvuspb.RoleEntity{Name: "public"}
|
||||
_, err = proxy.SelectGrant(getNotRootCtx(), selectReq)
|
||||
assert.Error(t, err)
|
||||
|
||||
results, _ = proxy.SelectGrant(ctx, selectReq)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
assert.NotEqual(t, 0, len(results.Entities))
|
||||
|
||||
selectReq.Entity.Object.Name = "not existed"
|
||||
results, _ = proxy.SelectGrant(ctx, selectReq)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
selectReq.Entity.Object.Name = commonpb.ObjectType_Collection.String()
|
||||
|
||||
selectReq.Entity.Role = &milvuspb.RoleEntity{Name: "not existed"}
|
||||
results, _ = proxy.SelectGrant(ctx, selectReq)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
|
||||
results, _ = proxy.SelectGrant(ctx, &milvuspb.SelectGrantRequest{
|
||||
Entity: &milvuspb.GrantEntity{
|
||||
Role: &milvuspb.RoleEntity{Name: "public"},
|
||||
},
|
||||
})
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, results.Status.ErrorCode)
|
||||
assert.NotEqual(t, 0, len(results.Entities))
|
||||
|
||||
req.Type = milvuspb.OperatePrivilegeType_Revoke
|
||||
resp, _ = proxy.OperatePrivilege(ctx, req)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
|
||||
roleReq.Type = milvuspb.OperatePrivilegeType_Revoke
|
||||
resp, _ = proxy.OperatePrivilege(ctx, roleReq)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func testProxyPrivilegeUnhealthy(ctx context.Context, t *testing.T, proxy *Proxy) {
|
||||
testProxyPrivilegeFail(ctx, t, proxy, "unhealthy")
|
||||
}
|
||||
|
||||
func testProxyPrivilegeTimeout(ctx context.Context, t *testing.T, proxy *Proxy) {
|
||||
testProxyPrivilegeFail(ctx, t, proxy, "timeout")
|
||||
}
|
||||
|
||||
func testProxyPrivilegeFail(ctx context.Context, t *testing.T, proxy *Proxy, reason string) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
t.Run(fmt.Sprintf("Operate Grant fail, %s", reason), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, _ := proxy.OperatePrivilege(ctx, &milvuspb.OperatePrivilegeRequest{
|
||||
Entity: &milvuspb.GrantEntity{
|
||||
Role: &milvuspb.RoleEntity{Name: "admin"},
|
||||
ObjectName: "col1",
|
||||
Object: &milvuspb.ObjectEntity{Name: commonpb.ObjectType_Collection.String()},
|
||||
Grantor: &milvuspb.GrantorEntity{Privilege: &milvuspb.PrivilegeEntity{Name: util.All.String()}},
|
||||
},
|
||||
})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
|
||||
wg.Add(1)
|
||||
t.Run(fmt.Sprintf("SelectGrant fail, %s", reason), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
|
||||
resp, _ := proxy.SelectGrant(ctx, &milvuspb.SelectGrantRequest{
|
||||
Entity: &milvuspb.GrantEntity{
|
||||
Role: &milvuspb.RoleEntity{Name: "admin"},
|
||||
},
|
||||
})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
})
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func testProxyRefreshPolicyInfoCache(ctx context.Context, t *testing.T, proxy *Proxy) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
t.Run("RefreshPolicyInfoCache", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
|
||||
resp, err := proxy.RefreshPolicyInfoCache(ctx, &proxypb.RefreshPolicyInfoCacheRequest{
|
||||
OpType: int32(typeutil.CacheAddUserToRole),
|
||||
OpKey: funcutil.EncodeUserRoleCache("foo", "public"),
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
_, err = proxy.RefreshPolicyInfoCache(ctx, &proxypb.RefreshPolicyInfoCacheRequest{})
|
||||
assert.Error(t, err)
|
||||
|
||||
_, err = proxy.RefreshPolicyInfoCache(ctx, &proxypb.RefreshPolicyInfoCacheRequest{
|
||||
OpType: 100,
|
||||
OpKey: funcutil.EncodeUserRoleCache("foo", "public"),
|
||||
})
|
||||
assert.Error(t, err)
|
||||
})
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func testProxyRefreshPolicyInfoCacheUnhealthy(ctx context.Context, t *testing.T, proxy *Proxy) {
|
||||
testProxyRefreshPolicyInfoCacheFail(ctx, t, proxy, "unhealthy")
|
||||
}
|
||||
|
||||
func testProxyRefreshPolicyInfoCacheFail(ctx context.Context, t *testing.T, proxy *Proxy, reason string) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
t.Run(fmt.Sprintf("RefreshPolicyInfoCache fail, %s", reason), func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
resp, _ := proxy.RefreshPolicyInfoCache(ctx, &proxypb.RefreshPolicyInfoCacheRequest{
|
||||
OpType: int32(typeutil.CacheAddUserToRole),
|
||||
OpKey: funcutil.EncodeUserRoleCache("foo", "public"),
|
||||
})
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
})
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func Test_GetCompactionState(t *testing.T) {
|
||||
t.Run("get compaction state", func(t *testing.T) {
|
||||
datacoord := &DataCoordMock{}
|
||||
|
|
|
@ -1081,6 +1081,38 @@ func (coord *RootCoordMock) GetCredential(ctx context.Context, req *rootcoordpb.
|
|||
return &rootcoordpb.GetCredentialResponse{}, nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) CreateRole(ctx context.Context, req *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
return &commonpb.Status{}, nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) DropRole(ctx context.Context, req *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
return &commonpb.Status{}, nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) OperateUserRole(ctx context.Context, req *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
return &commonpb.Status{}, nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) SelectRole(ctx context.Context, req *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
return &milvuspb.SelectRoleResponse{}, nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) SelectUser(ctx context.Context, req *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
return &milvuspb.SelectUserResponse{}, nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) OperatePrivilege(ctx context.Context, req *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
return &commonpb.Status{}, nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) SelectGrant(ctx context.Context, req *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
return &milvuspb.SelectGrantResponse{}, nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) ListPolicy(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
return &internalpb.ListPolicyResponse{}, nil
|
||||
}
|
||||
|
||||
type DescribeCollectionFunc func(ctx context.Context, request *milvuspb.DescribeCollectionRequest) (*milvuspb.DescribeCollectionResponse, error)
|
||||
type ShowPartitionsFunc func(ctx context.Context, request *milvuspb.ShowPartitionsRequest) (*milvuspb.ShowPartitionsResponse, error)
|
||||
type DescribeIndexFunc func(ctx context.Context, request *milvuspb.DescribeIndexRequest) (*milvuspb.DescribeIndexResponse, error)
|
||||
|
@ -1158,6 +1190,10 @@ func (m *mockRootCoord) GetIndexState(ctx context.Context, request *milvuspb.Get
|
|||
return nil, errors.New("mock")
|
||||
}
|
||||
|
||||
func (m *mockRootCoord) ListPolicy(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
return &internalpb.ListPolicyResponse{}, nil
|
||||
}
|
||||
|
||||
func newMockRootCoord() *mockRootCoord {
|
||||
return &mockRootCoord{}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ func TestGetIndexStateTask_Execute(t *testing.T) {
|
|||
|
||||
shardMgr := newShardClientMgr()
|
||||
// failed to get collection id.
|
||||
_ = InitMetaCache(rootCoord, queryCoord, shardMgr)
|
||||
_ = InitMetaCache(ctx, rootCoord, queryCoord, shardMgr)
|
||||
assert.Error(t, gist.Execute(ctx))
|
||||
rootCoord.GetIndexStateFunc = func(ctx context.Context, request *milvuspb.GetIndexStateRequest) (*indexpb.GetIndexStatesResponse, error) {
|
||||
return &indexpb.GetIndexStatesResponse{
|
||||
|
|
|
@ -56,7 +56,7 @@ func TestQueryTask_all(t *testing.T) {
|
|||
qc.Start()
|
||||
defer qc.Stop()
|
||||
|
||||
err = InitMetaCache(rc, qc, mgr)
|
||||
err = InitMetaCache(ctx, rc, qc, mgr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
fieldName2Types := map[string]schemapb.DataType{
|
||||
|
|
|
@ -123,7 +123,7 @@ func TestSearchTask_PreExecute(t *testing.T) {
|
|||
defer rc.Stop()
|
||||
require.NoError(t, err)
|
||||
mgr := newShardClientMgr()
|
||||
err = InitMetaCache(rc, qc, mgr)
|
||||
err = InitMetaCache(ctx, rc, qc, mgr)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = qc.Start()
|
||||
|
@ -335,7 +335,7 @@ func TestSearchTaskV2_Execute(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
defer rc.Stop()
|
||||
mgr := newShardClientMgr()
|
||||
err = InitMetaCache(rc, qc, mgr)
|
||||
err = InitMetaCache(ctx, rc, qc, mgr)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = qc.Start()
|
||||
|
@ -442,7 +442,7 @@ func TestSearchTaskWithInvalidRoundDecimal(t *testing.T) {
|
|||
//
|
||||
// ctx := context.Background()
|
||||
//
|
||||
// err = InitMetaCache(rc)
|
||||
// err = InitMetaCache(ctx, rc)
|
||||
// assert.NoError(t, err)
|
||||
//
|
||||
// shardsNum := int32(2)
|
||||
|
@ -685,7 +685,7 @@ func TestSearchTaskV2_all(t *testing.T) {
|
|||
//
|
||||
// ctx := context.Background()
|
||||
//
|
||||
// err = InitMetaCache(rc)
|
||||
// err = InitMetaCache(ctx, rc)
|
||||
// assert.NoError(t, err)
|
||||
//
|
||||
// shardsNum := int32(2)
|
||||
|
@ -930,7 +930,7 @@ func TestSearchTaskV2_7803_reduce(t *testing.T) {
|
|||
//
|
||||
// ctx := context.Background()
|
||||
//
|
||||
// err = InitMetaCache(rc)
|
||||
// err = InitMetaCache(ctx, rc)
|
||||
// assert.NoError(t, err)
|
||||
//
|
||||
// shardsNum := int32(2)
|
||||
|
@ -1619,7 +1619,7 @@ func TestSearchTask_ErrExecute(t *testing.T) {
|
|||
qc.Start()
|
||||
defer qc.Stop()
|
||||
|
||||
err = InitMetaCache(rc, qc, mgr)
|
||||
err = InitMetaCache(ctx, rc, qc, mgr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
fieldName2Types := map[string]schemapb.DataType{
|
||||
|
|
|
@ -830,7 +830,7 @@ func TestHasCollectionTask(t *testing.T) {
|
|||
defer qc.Stop()
|
||||
ctx := context.Background()
|
||||
mgr := newShardClientMgr()
|
||||
InitMetaCache(rc, qc, mgr)
|
||||
InitMetaCache(ctx, rc, qc, mgr)
|
||||
prefix := "TestHasCollectionTask"
|
||||
dbName := ""
|
||||
collectionName := prefix + funcutil.GenRandomStr()
|
||||
|
@ -916,7 +916,7 @@ func TestDescribeCollectionTask(t *testing.T) {
|
|||
defer qc.Stop()
|
||||
ctx := context.Background()
|
||||
mgr := newShardClientMgr()
|
||||
InitMetaCache(rc, qc, mgr)
|
||||
InitMetaCache(ctx, rc, qc, mgr)
|
||||
prefix := "TestDescribeCollectionTask"
|
||||
dbName := ""
|
||||
collectionName := prefix + funcutil.GenRandomStr()
|
||||
|
@ -979,7 +979,7 @@ func TestDescribeCollectionTask_ShardsNum1(t *testing.T) {
|
|||
defer qc.Stop()
|
||||
ctx := context.Background()
|
||||
mgr := newShardClientMgr()
|
||||
InitMetaCache(rc, qc, mgr)
|
||||
InitMetaCache(ctx, rc, qc, mgr)
|
||||
prefix := "TestDescribeCollectionTask"
|
||||
dbName := ""
|
||||
collectionName := prefix + funcutil.GenRandomStr()
|
||||
|
@ -1044,7 +1044,7 @@ func TestDescribeCollectionTask_ShardsNum2(t *testing.T) {
|
|||
defer qc.Stop()
|
||||
ctx := context.Background()
|
||||
mgr := newShardClientMgr()
|
||||
InitMetaCache(rc, qc, mgr)
|
||||
InitMetaCache(ctx, rc, qc, mgr)
|
||||
prefix := "TestDescribeCollectionTask"
|
||||
dbName := ""
|
||||
collectionName := prefix + funcutil.GenRandomStr()
|
||||
|
@ -1311,7 +1311,7 @@ func TestTask_Int64PrimaryKey(t *testing.T) {
|
|||
ctx := context.Background()
|
||||
|
||||
mgr := newShardClientMgr()
|
||||
err = InitMetaCache(rc, qc, mgr)
|
||||
err = InitMetaCache(ctx, rc, qc, mgr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
shardsNum := int32(2)
|
||||
|
@ -1565,7 +1565,7 @@ func TestTask_VarCharPrimaryKey(t *testing.T) {
|
|||
ctx := context.Background()
|
||||
|
||||
mgr := newShardClientMgr()
|
||||
err = InitMetaCache(rc, qc, mgr)
|
||||
err = InitMetaCache(ctx, rc, qc, mgr)
|
||||
assert.NoError(t, err)
|
||||
|
||||
shardsNum := int32(2)
|
||||
|
|
|
@ -17,12 +17,20 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/log"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util"
|
||||
"github.com/milvus-io/milvus/internal/util/crypto"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/commonpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/util/tsoutil"
|
||||
|
@ -39,6 +47,8 @@ const enableMultipleVectorFields = false
|
|||
const maxVarCharLengthKey = "max_length"
|
||||
const defaultMaxVarCharLength = 65535
|
||||
|
||||
var logger = log.L().WithOptions(zap.Fields(zap.String("role", typeutil.ProxyRole)))
|
||||
|
||||
// isAlpha check if c is alpha.
|
||||
func isAlpha(c uint8) bool {
|
||||
if (c < 'A' || c > 'Z') && (c < 'a' || c > 'z') {
|
||||
|
@ -593,3 +603,114 @@ func parseGuaranteeTs(ts, tMax typeutil.Timestamp) typeutil.Timestamp {
|
|||
}
|
||||
return ts
|
||||
}
|
||||
|
||||
func validateName(entity string, nameType string) error {
|
||||
entity = strings.TrimSpace(entity)
|
||||
|
||||
if entity == "" {
|
||||
return fmt.Errorf("%s should not be empty", nameType)
|
||||
}
|
||||
|
||||
invalidMsg := fmt.Sprintf("invalid %s: %s. ", nameType, entity)
|
||||
if int64(len(entity)) > Params.ProxyCfg.MaxNameLength {
|
||||
msg := invalidMsg + fmt.Sprintf("the length of %s must be less than ", nameType) +
|
||||
strconv.FormatInt(Params.ProxyCfg.MaxNameLength, 10) + " characters."
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
firstChar := entity[0]
|
||||
if firstChar != '_' && !isAlpha(firstChar) {
|
||||
msg := invalidMsg + fmt.Sprintf("the first character of %s must be an underscore or letter.", nameType)
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
for i := 1; i < len(entity); i++ {
|
||||
c := entity[i]
|
||||
if c != '_' && c != '$' && !isAlpha(c) && !isNumber(c) {
|
||||
msg := invalidMsg + fmt.Sprintf("%s can only contain numbers, letters, dollars and underscores.", nameType)
|
||||
return errors.New(msg)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateRoleName(entity string) error {
|
||||
return validateName(entity, "role name")
|
||||
}
|
||||
|
||||
func ValidateObjectName(entity string) error {
|
||||
entity = strings.TrimSpace(entity)
|
||||
if entity == "" {
|
||||
return fmt.Errorf("objectName should not be empty")
|
||||
}
|
||||
|
||||
if int64(len(entity)) > Params.ProxyCfg.MaxNameLength {
|
||||
msg := fmt.Sprintf("invalid object name: %s. The length of resource name must be less than %s characters",
|
||||
entity, strconv.FormatInt(Params.ProxyCfg.MaxNameLength, 10))
|
||||
return errors.New(msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateObjectType(entity string) error {
|
||||
return validateName(entity, "ObjectType")
|
||||
}
|
||||
|
||||
func ValidatePrincipalName(entity string) error {
|
||||
return validateName(entity, "PrincipalName")
|
||||
}
|
||||
|
||||
func ValidatePrincipalType(entity string) error {
|
||||
return validateName(entity, "PrincipalType")
|
||||
}
|
||||
|
||||
func ValidatePrivilege(entity string) error {
|
||||
return validateName(entity, "Privilege")
|
||||
}
|
||||
|
||||
func GetCurUserFromContext(ctx context.Context) (string, error) {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("fail to get md from the context")
|
||||
}
|
||||
authorization := md[strings.ToLower(util.HeaderAuthorize)]
|
||||
if len(authorization) < 1 {
|
||||
return "", fmt.Errorf("fail to get authorization from the md, authorize:[%s]", util.HeaderAuthorize)
|
||||
}
|
||||
token := authorization[0]
|
||||
rawToken, err := crypto.Base64Decode(token)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("fail to decode the token, token: %s", token)
|
||||
}
|
||||
secrets := strings.SplitN(rawToken, util.CredentialSeperator, 2)
|
||||
if len(secrets) < 2 {
|
||||
return "", fmt.Errorf("fail to get user info from the raw token, raw token: %s", rawToken)
|
||||
}
|
||||
username := secrets[0]
|
||||
return username, nil
|
||||
}
|
||||
|
||||
func GetRole(username string) ([]string, error) {
|
||||
if globalMetaCache == nil {
|
||||
return []string{}, ErrProxyNotReady()
|
||||
}
|
||||
return globalMetaCache.GetUserRole(username), nil
|
||||
}
|
||||
|
||||
func ValidateAdminPermission(ctx context.Context) error {
|
||||
curUser, err := GetCurUserFromContext(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fail to get current user info from the context, err: %w", err)
|
||||
}
|
||||
roles, err := GetRole(curUser)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fail to get role for the current user info, currtent user:%s, err: %w", curUser, err)
|
||||
}
|
||||
for _, role := range roles {
|
||||
if role == util.RoleAdmin {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("the current user doesn't have privileges of the admin role, can't execute this api")
|
||||
}
|
||||
|
|
|
@ -17,12 +17,18 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/commonpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/util"
|
||||
"github.com/milvus-io/milvus/internal/util/crypto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
func TestValidateCollectionName(t *testing.T) {
|
||||
|
@ -616,3 +622,121 @@ func TestReplaceID2Name(t *testing.T) {
|
|||
dstStr := "collection default_collection has not been loaded to memory or load failed"
|
||||
assert.Equal(t, dstStr, ReplaceID2Name(srcStr, int64(432682805904801793), "default_collection"))
|
||||
}
|
||||
|
||||
func TestValidateName(t *testing.T) {
|
||||
Params.InitOnce()
|
||||
nameType := "Test"
|
||||
validNames := []string{
|
||||
"abc",
|
||||
"_123abc",
|
||||
}
|
||||
for _, name := range validNames {
|
||||
assert.Nil(t, validateName(name, nameType))
|
||||
assert.Nil(t, ValidateRoleName(name))
|
||||
assert.Nil(t, ValidateObjectName(name))
|
||||
assert.Nil(t, ValidateObjectType(name))
|
||||
assert.Nil(t, ValidatePrincipalName(name))
|
||||
assert.Nil(t, ValidatePrincipalType(name))
|
||||
assert.Nil(t, ValidatePrivilege(name))
|
||||
}
|
||||
|
||||
longName := make([]byte, 256)
|
||||
for i := 0; i < len(longName); i++ {
|
||||
longName[i] = 'a'
|
||||
}
|
||||
invalidNames := []string{
|
||||
" ",
|
||||
"123abc",
|
||||
"$abc",
|
||||
"_12 ac",
|
||||
" ",
|
||||
"",
|
||||
string(longName),
|
||||
"中文",
|
||||
}
|
||||
|
||||
for _, name := range invalidNames {
|
||||
assert.NotNil(t, validateName(name, nameType))
|
||||
assert.NotNil(t, ValidateRoleName(name))
|
||||
assert.NotNil(t, ValidateObjectType(name))
|
||||
assert.NotNil(t, ValidatePrincipalName(name))
|
||||
assert.NotNil(t, ValidatePrincipalType(name))
|
||||
assert.NotNil(t, ValidatePrivilege(name))
|
||||
}
|
||||
assert.NotNil(t, ValidateObjectName(" "))
|
||||
assert.NotNil(t, ValidateObjectName(string(longName)))
|
||||
}
|
||||
|
||||
func GetContext(ctx context.Context, originValue string) context.Context {
|
||||
authKey := strings.ToLower(util.HeaderAuthorize)
|
||||
authValue := crypto.Base64Encode(originValue)
|
||||
contextMap := map[string]string{
|
||||
authKey: authValue,
|
||||
}
|
||||
md := metadata.New(contextMap)
|
||||
return metadata.NewIncomingContext(ctx, md)
|
||||
}
|
||||
|
||||
func TestGetCurUserFromContext(t *testing.T) {
|
||||
_, err := GetCurUserFromContext(context.Background())
|
||||
assert.NotNil(t, err)
|
||||
|
||||
_, err = GetCurUserFromContext(metadata.NewIncomingContext(context.Background(), metadata.New(map[string]string{})))
|
||||
assert.NotNil(t, err)
|
||||
|
||||
_, err = GetCurUserFromContext(GetContext(context.Background(), "123456"))
|
||||
assert.NotNil(t, err)
|
||||
|
||||
root := "root"
|
||||
password := "123456"
|
||||
username, err := GetCurUserFromContext(GetContext(context.Background(), fmt.Sprintf("%s%s%s", root, util.CredentialSeperator, password)))
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "root", username)
|
||||
}
|
||||
|
||||
func TestGetRole(t *testing.T) {
|
||||
globalMetaCache = nil
|
||||
_, err := GetRole("foo")
|
||||
assert.NotNil(t, err)
|
||||
globalMetaCache = &mockCache{
|
||||
getUserRoleFunc: func(username string) []string {
|
||||
if username == "root" {
|
||||
return []string{"role1", "admin", "role2"}
|
||||
}
|
||||
return []string{"role1"}
|
||||
},
|
||||
}
|
||||
roles, err := GetRole("root")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(roles))
|
||||
|
||||
roles, err = GetRole("foo")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(roles))
|
||||
}
|
||||
|
||||
func TestValidateAdminPermission(t *testing.T) {
|
||||
root := "root"
|
||||
password := "123456"
|
||||
|
||||
err := ValidateAdminPermission(context.Background())
|
||||
assert.NotNil(t, err)
|
||||
|
||||
globalMetaCache = nil
|
||||
err = ValidateAdminPermission(GetContext(context.Background(), fmt.Sprintf("%s%s%s", root, util.CredentialSeperator, password)))
|
||||
assert.NotNil(t, err)
|
||||
|
||||
globalMetaCache = &mockCache{
|
||||
getUserRoleFunc: func(username string) []string {
|
||||
if username == "root" {
|
||||
return []string{"role1", "admin", "role2"}
|
||||
}
|
||||
return []string{"role1"}
|
||||
},
|
||||
}
|
||||
err = ValidateAdminPermission(GetContext(context.Background(), fmt.Sprintf("%s%s%s", root, util.CredentialSeperator, password)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = ValidateAdminPermission(GetContext(context.Background(), fmt.Sprintf("%s%s%s", "test", util.CredentialSeperator, password)))
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ import (
|
|||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/funcutil"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/common"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/kv"
|
||||
|
@ -1350,3 +1352,88 @@ func (mt *MetaTable) getSegIdxMetaBySegID(segID int64) (model.SegmentIndex, erro
|
|||
|
||||
return segmentIdx, nil
|
||||
}
|
||||
|
||||
// CreateRole create role
|
||||
func (mt *MetaTable) CreateRole(tenant string, entity *milvuspb.RoleEntity) error {
|
||||
if funcutil.IsEmptyString(entity.Name) {
|
||||
return fmt.Errorf("the role name in the role info is empty")
|
||||
}
|
||||
return mt.catalog.CreateRole(mt.ctx, tenant, entity)
|
||||
}
|
||||
|
||||
// DropRole drop role info
|
||||
func (mt *MetaTable) DropRole(tenant string, roleName string) error {
|
||||
return mt.catalog.DropRole(mt.ctx, tenant, roleName)
|
||||
}
|
||||
|
||||
// OperateUserRole operate the relationship between a user and a role, including adding a user to a role and removing a user from a role
|
||||
func (mt *MetaTable) OperateUserRole(tenant string, userEntity *milvuspb.UserEntity, roleEntity *milvuspb.RoleEntity, operateType milvuspb.OperateUserRoleType) error {
|
||||
if funcutil.IsEmptyString(userEntity.Name) {
|
||||
return fmt.Errorf("username in the user entity is empty")
|
||||
}
|
||||
if funcutil.IsEmptyString(roleEntity.Name) {
|
||||
return fmt.Errorf("role name in the role entity is empty")
|
||||
}
|
||||
|
||||
return mt.catalog.OperateUserRole(mt.ctx, tenant, userEntity, roleEntity, operateType)
|
||||
}
|
||||
|
||||
// SelectRole select role.
|
||||
// Enter the role condition by the entity param. And this param is nil, which means selecting all roles.
|
||||
// Get all users that are added to the role by setting the includeUserInfo param to true.
|
||||
func (mt *MetaTable) SelectRole(tenant string, entity *milvuspb.RoleEntity, includeUserInfo bool) ([]*milvuspb.RoleResult, error) {
|
||||
return mt.catalog.SelectRole(mt.ctx, tenant, entity, includeUserInfo)
|
||||
}
|
||||
|
||||
// SelectUser select user.
|
||||
// Enter the user condition by the entity param. And this param is nil, which means selecting all users.
|
||||
// Get all roles that are added the user to by setting the includeRoleInfo param to true.
|
||||
func (mt *MetaTable) SelectUser(tenant string, entity *milvuspb.UserEntity, includeRoleInfo bool) ([]*milvuspb.UserResult, error) {
|
||||
return mt.catalog.SelectUser(mt.ctx, tenant, entity, includeRoleInfo)
|
||||
}
|
||||
|
||||
// OperatePrivilege grant or revoke privilege by setting the operateType param
|
||||
func (mt *MetaTable) OperatePrivilege(tenant string, entity *milvuspb.GrantEntity, operateType milvuspb.OperatePrivilegeType) error {
|
||||
if funcutil.IsEmptyString(entity.ObjectName) {
|
||||
return fmt.Errorf("the object name in the grant entity is empty")
|
||||
}
|
||||
if entity.Object == nil || funcutil.IsEmptyString(entity.Object.Name) {
|
||||
return fmt.Errorf("the object entity in the grant entity is invalid")
|
||||
}
|
||||
if entity.Role == nil || funcutil.IsEmptyString(entity.Role.Name) {
|
||||
return fmt.Errorf("the role entity in the grant entity is invalid")
|
||||
}
|
||||
if entity.Grantor == nil {
|
||||
return fmt.Errorf("the grantor in the grant entity is empty")
|
||||
}
|
||||
if entity.Grantor.Privilege == nil || funcutil.IsEmptyString(entity.Grantor.Privilege.Name) {
|
||||
return fmt.Errorf("the privilege name in the grant entity is empty")
|
||||
}
|
||||
if entity.Grantor.User == nil || funcutil.IsEmptyString(entity.Grantor.User.Name) {
|
||||
return fmt.Errorf("the grantor name in the grant entity is empty")
|
||||
}
|
||||
if !funcutil.IsRevoke(operateType) && !funcutil.IsGrant(operateType) {
|
||||
return fmt.Errorf("the operate type in the grant entity is invalid")
|
||||
}
|
||||
|
||||
return mt.catalog.OperatePrivilege(mt.ctx, tenant, entity, operateType)
|
||||
}
|
||||
|
||||
// SelectGrant select grant
|
||||
// The principal entity MUST be not empty in the grant entity
|
||||
// The resource entity and the resource name are optional, and the two params should be not empty together when you select some grants about the resource kind.
|
||||
func (mt *MetaTable) SelectGrant(tenant string, entity *milvuspb.GrantEntity) ([]*milvuspb.GrantEntity, error) {
|
||||
var entities []*milvuspb.GrantEntity
|
||||
if entity.Role == nil || funcutil.IsEmptyString(entity.Role.Name) {
|
||||
return entities, fmt.Errorf("the role entity in the grant entity is invalid")
|
||||
}
|
||||
return mt.catalog.SelectGrant(mt.ctx, tenant, entity)
|
||||
}
|
||||
|
||||
func (mt *MetaTable) ListPolicy(tenant string) ([]string, error) {
|
||||
return mt.catalog.ListPolicy(mt.ctx, tenant)
|
||||
}
|
||||
|
||||
func (mt *MetaTable) ListUserRole(tenant string) ([]string, error) {
|
||||
return mt.catalog.ListUserRole(mt.ctx, tenant)
|
||||
}
|
||||
|
|
|
@ -18,14 +18,22 @@ package rootcoord
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/milvus-io/milvus/internal/proto/milvuspb"
|
||||
"github.com/milvus-io/milvus/internal/util"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/common"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/metastore"
|
||||
|
@ -47,7 +55,7 @@ import (
|
|||
)
|
||||
|
||||
type mockTestKV struct {
|
||||
kv.TxnKV
|
||||
kv.SnapShotKV
|
||||
|
||||
loadWithPrefix func(key string, ts typeutil.Timestamp) ([]string, []string, error)
|
||||
save func(key, value string, ts typeutil.Timestamp) error
|
||||
|
@ -82,6 +90,7 @@ type mockTestTxnKV struct {
|
|||
multiSaveAndRemoveWithPrefix func(saves map[string]string, removals []string) error
|
||||
remove func(key string) error
|
||||
multiRemove func(keys []string) error
|
||||
load func(key string) (string, error)
|
||||
}
|
||||
|
||||
func (m *mockTestTxnKV) LoadWithPrefix(key string) ([]string, []string, error) {
|
||||
|
@ -108,6 +117,49 @@ func (m *mockTestTxnKV) MultiRemove(keys []string) error {
|
|||
return m.multiRemove(keys)
|
||||
}
|
||||
|
||||
func (m *mockTestTxnKV) Load(key string) (string, error) {
|
||||
return m.load(key)
|
||||
}
|
||||
|
||||
func generateMetaTable(t *testing.T) (*MetaTable, *mockTestKV, *mockTestTxnKV, func()) {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
randVal := rand.Int()
|
||||
Params.Init()
|
||||
rootPath := fmt.Sprintf("/test/meta/%d", randVal)
|
||||
etcdCli, err := etcd.GetEtcdClient(&Params.EtcdCfg)
|
||||
require.Nil(t, err)
|
||||
|
||||
skv, err := kvmetestore.NewMetaSnapshot(etcdCli, rootPath, TimestampPrefix, 7)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, skv)
|
||||
|
||||
txnkv := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
||||
mt, err := NewMetaTable(context.TODO(), txnkv, skv)
|
||||
assert.Nil(t, err)
|
||||
mockSnapshotKV := &mockTestKV{
|
||||
SnapShotKV: mt.snapshot,
|
||||
loadWithPrefix: func(key string, ts typeutil.Timestamp) ([]string, []string, error) {
|
||||
return skv.LoadWithPrefix(key, ts)
|
||||
},
|
||||
}
|
||||
mockTxnKV := &mockTestTxnKV{
|
||||
TxnKV: mt.txn,
|
||||
loadWithPrefix: func(key string) ([]string, []string, error) { return txnkv.LoadWithPrefix(key) },
|
||||
save: func(key, value string) error { return txnkv.Save(key, value) },
|
||||
multiSave: func(kvs map[string]string) error { return txnkv.MultiSave(kvs) },
|
||||
multiSaveAndRemoveWithPrefix: func(kvs map[string]string, removal []string) error {
|
||||
return txnkv.MultiSaveAndRemoveWithPrefix(kvs, removal)
|
||||
},
|
||||
remove: func(key string) error { return txnkv.Remove(key) },
|
||||
}
|
||||
|
||||
mockMt, err := NewMetaTable(context.TODO(), mockTxnKV, mockSnapshotKV)
|
||||
assert.Nil(t, err)
|
||||
return mockMt, mockSnapshotKV, mockTxnKV, func() {
|
||||
etcdCli.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestMetaTable(t *testing.T) {
|
||||
const (
|
||||
collName = "testColl"
|
||||
|
@ -1011,9 +1063,468 @@ func TestMetaTable(t *testing.T) {
|
|||
err := mt.DeleteCredential("")
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestRbacCreateRole(t *testing.T) {
|
||||
mt, _, mockTxnKV, closeCli := generateMetaTable(t)
|
||||
defer closeCli()
|
||||
var err error
|
||||
err = mt.CreateRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: ""})
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.save = func(key, value string) error {
|
||||
return nil
|
||||
}
|
||||
err = mt.CreateRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: "role1"})
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockTxnKV.save = func(key, value string) error {
|
||||
return fmt.Errorf("save error")
|
||||
}
|
||||
err = mt.CreateRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: "role2"})
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestRbacDropRole(t *testing.T) {
|
||||
mt, _, mockTxnKV, closeCli := generateMetaTable(t)
|
||||
defer closeCli()
|
||||
var err error
|
||||
|
||||
mockTxnKV.remove = func(key string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = mt.DropRole(util.DefaultTenant, "role1")
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockTxnKV.remove = func(key string) error {
|
||||
return fmt.Errorf("delete error")
|
||||
}
|
||||
|
||||
err = mt.DropRole(util.DefaultTenant, "role2")
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestRbacOperateRole(t *testing.T) {
|
||||
mt, _, mockTxnKV, closeCli := generateMetaTable(t)
|
||||
defer closeCli()
|
||||
var err error
|
||||
|
||||
err = mt.OperateUserRole(util.DefaultTenant, &milvuspb.UserEntity{Name: " "}, &milvuspb.RoleEntity{Name: "role"}, milvuspb.OperateUserRoleType_AddUserToRole)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
err = mt.OperateUserRole(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, &milvuspb.RoleEntity{Name: " "}, milvuspb.OperateUserRoleType_AddUserToRole)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.save = func(key, value string) error {
|
||||
return nil
|
||||
}
|
||||
err = mt.OperateUserRole(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, &milvuspb.RoleEntity{Name: "role"}, milvuspb.OperateUserRoleType(100))
|
||||
assert.NotNil(t, err)
|
||||
|
||||
err = mt.OperateUserRole(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, &milvuspb.RoleEntity{Name: "role"}, milvuspb.OperateUserRoleType_AddUserToRole)
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockTxnKV.save = func(key, value string) error {
|
||||
return fmt.Errorf("save error")
|
||||
}
|
||||
err = mt.OperateUserRole(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, &milvuspb.RoleEntity{Name: "role"}, milvuspb.OperateUserRoleType_AddUserToRole)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.remove = func(key string) error {
|
||||
return nil
|
||||
}
|
||||
err = mt.OperateUserRole(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, &milvuspb.RoleEntity{Name: "role"}, milvuspb.OperateUserRoleType_RemoveUserFromRole)
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockTxnKV.remove = func(key string) error {
|
||||
return fmt.Errorf("remove error")
|
||||
}
|
||||
err = mt.OperateUserRole(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, &milvuspb.RoleEntity{Name: "role"}, milvuspb.OperateUserRoleType_RemoveUserFromRole)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestRbacSelectRole(t *testing.T) {
|
||||
mt, _, mockTxnKV, closeCli := generateMetaTable(t)
|
||||
defer closeCli()
|
||||
var err error
|
||||
|
||||
_, err = mt.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: ""}, false)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{}, []string{}, fmt.Errorf("load with prefix error")
|
||||
}
|
||||
_, err = mt.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: "role"}, true)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{key + "/key1", key + "/key2", key + "/a/err"}, []string{"value1", "value2", "values3"}, nil
|
||||
}
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
results, _ := mt.SelectRole(util.DefaultTenant, nil, false)
|
||||
assert.Equal(t, 2, len(results))
|
||||
results, _ = mt.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: "role"}, false)
|
||||
assert.Equal(t, 1, len(results))
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{}, []string{}, fmt.Errorf("load with prefix error")
|
||||
}
|
||||
_, err = mt.SelectRole(util.DefaultTenant, nil, false)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return "", fmt.Errorf("load error")
|
||||
}
|
||||
_, err = mt.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: "role"}, false)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
roleName := "role1"
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{key + "/user1/" + roleName, key + "/user2/role2", key + "/user3/" + roleName, key + "/err"}, []string{"value1", "value2", "values3", "value4"}, nil
|
||||
}
|
||||
results, err = mt.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: roleName}, true)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(results))
|
||||
assert.Equal(t, 2, len(results[0].Users))
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
if key == kvmetestore.RoleMappingPrefix {
|
||||
return []string{key + "/user1/role2", key + "/user2/role2", key + "/user1/role1", key + "/user2/role1"}, []string{"value1", "value2", "values3", "value4"}, nil
|
||||
} else if key == kvmetestore.RolePrefix {
|
||||
return []string{key + "/role1", key + "/role2", key + "/role3"}, []string{"value1", "value2", "values3"}, nil
|
||||
} else {
|
||||
return []string{}, []string{}, fmt.Errorf("load with prefix error")
|
||||
}
|
||||
}
|
||||
results, err = mt.SelectRole(util.DefaultTenant, nil, true)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(results))
|
||||
for _, result := range results {
|
||||
if result.Role.Name == "role1" {
|
||||
assert.Equal(t, 2, len(result.Users))
|
||||
} else if result.Role.Name == "role2" {
|
||||
assert.Equal(t, 2, len(result.Users))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRbacSelectUser(t *testing.T) {
|
||||
mt, _, mockTxnKV, closeCli := generateMetaTable(t)
|
||||
defer closeCli()
|
||||
var err error
|
||||
|
||||
_, err = mt.SelectUser(util.DefaultTenant, &milvuspb.UserEntity{Name: ""}, false)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
credentialInfo := internalpb.CredentialInfo{
|
||||
EncryptedPassword: "password",
|
||||
}
|
||||
credentialInfoByte, _ := json.Marshal(credentialInfo)
|
||||
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return string(credentialInfoByte), nil
|
||||
}
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{key + "/key1", key + "/key2"}, []string{string(credentialInfoByte), string(credentialInfoByte)}, nil
|
||||
}
|
||||
results, err := mt.SelectUser(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(results))
|
||||
results, err = mt.SelectUser(util.DefaultTenant, nil, false)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(results))
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{key + "/key1", key + "/key2", key + "/a/err"}, []string{"value1", "value2", "values3"}, nil
|
||||
}
|
||||
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return string(credentialInfoByte), nil
|
||||
}
|
||||
results, err = mt.SelectUser(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, true)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 1, len(results))
|
||||
assert.Equal(t, 2, len(results[0].Roles))
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
logger.Debug("simfg", zap.String("key", key))
|
||||
if strings.Contains(key, kvmetestore.RoleMappingPrefix) {
|
||||
if strings.Contains(key, "user1") {
|
||||
return []string{key + "/role2", key + "/role1", key + "/role3"}, []string{"value1", "value4", "value2"}, nil
|
||||
} else if strings.Contains(key, "user2") {
|
||||
return []string{key + "/role2"}, []string{"value1"}, nil
|
||||
}
|
||||
return []string{}, []string{}, nil
|
||||
} else if key == kvmetestore.CredentialPrefix {
|
||||
return []string{key + "/user1", key + "/user2", key + "/user3"}, []string{string(credentialInfoByte), string(credentialInfoByte), string(credentialInfoByte)}, nil
|
||||
} else {
|
||||
return []string{}, []string{}, fmt.Errorf("load with prefix error")
|
||||
}
|
||||
}
|
||||
results, err = mt.SelectUser(util.DefaultTenant, nil, true)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(results))
|
||||
for _, result := range results {
|
||||
if result.User.Name == "user1" {
|
||||
assert.Equal(t, 3, len(result.Roles))
|
||||
} else if result.User.Name == "user2" {
|
||||
assert.Equal(t, 1, len(result.Roles))
|
||||
}
|
||||
}
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{}, []string{}, nil
|
||||
}
|
||||
_, err = mt.SelectUser(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, true)
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{}, []string{}, fmt.Errorf("load with prefix error")
|
||||
}
|
||||
_, err = mt.SelectUser(util.DefaultTenant, &milvuspb.UserEntity{Name: "user"}, true)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
_, err = mt.SelectUser(util.DefaultTenant, nil, true)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestRbacOperatePrivilege(t *testing.T) {
|
||||
mt, _, mockTxnKV, closeCli := generateMetaTable(t)
|
||||
defer closeCli()
|
||||
var err error
|
||||
|
||||
entity := &milvuspb.GrantEntity{}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
entity.ObjectName = "col1"
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
entity.Object = &milvuspb.ObjectEntity{Name: commonpb.ObjectType_Collection.String()}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
entity.Role = &milvuspb.RoleEntity{Name: "admin"}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
entity.Grantor = &milvuspb.GrantorEntity{}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
entity.Grantor.Privilege = &milvuspb.PrivilegeEntity{Name: commonpb.ObjectPrivilege_PrivilegeLoad.String()}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, 100)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.save = func(key, value string) error {
|
||||
return nil
|
||||
}
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return "fail", fmt.Errorf("load error")
|
||||
}
|
||||
entity.Grantor.User = &milvuspb.UserEntity{Name: "user2"}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Revoke)
|
||||
assert.NotNil(t, err)
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.NotNil(t, err)
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return "unmarshal", nil
|
||||
}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return "fail", fmt.Errorf("there is no value on key = %s", key)
|
||||
}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.Nil(t, err)
|
||||
|
||||
grantPrivilegeEntity := &milvuspb.GrantPrivilegeEntity{Entities: []*milvuspb.GrantorEntity{
|
||||
{User: &milvuspb.UserEntity{Name: "aaa"}, Privilege: &milvuspb.PrivilegeEntity{Name: commonpb.ObjectPrivilege_PrivilegeLoad.String()}},
|
||||
}}
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
grantPrivilegeEntityByte, _ := proto.Marshal(grantPrivilegeEntity)
|
||||
return string(grantPrivilegeEntityByte), nil
|
||||
}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.Nil(t, err)
|
||||
entity.Grantor.Privilege = &milvuspb.PrivilegeEntity{Name: commonpb.ObjectPrivilege_PrivilegeRelease.String()}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Revoke)
|
||||
assert.NotNil(t, err)
|
||||
entity.Grantor.Privilege = &milvuspb.PrivilegeEntity{Name: commonpb.ObjectPrivilege_PrivilegeLoad.String()}
|
||||
grantPrivilegeEntity = &milvuspb.GrantPrivilegeEntity{Entities: []*milvuspb.GrantorEntity{
|
||||
{User: &milvuspb.UserEntity{Name: "user2"}, Privilege: &milvuspb.PrivilegeEntity{Name: commonpb.ObjectPrivilege_PrivilegeLoad.String()}},
|
||||
}}
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
grantPrivilegeEntityByte, _ := proto.Marshal(grantPrivilegeEntity)
|
||||
return string(grantPrivilegeEntityByte), nil
|
||||
}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.Nil(t, err)
|
||||
mockTxnKV.remove = func(key string) error {
|
||||
return fmt.Errorf("remove error")
|
||||
}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Revoke)
|
||||
assert.NotNil(t, err)
|
||||
mockTxnKV.remove = func(key string) error {
|
||||
return nil
|
||||
}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Revoke)
|
||||
assert.Nil(t, err)
|
||||
|
||||
grantPrivilegeEntity = &milvuspb.GrantPrivilegeEntity{Entities: []*milvuspb.GrantorEntity{
|
||||
{User: &milvuspb.UserEntity{Name: "u3"}, Privilege: &milvuspb.PrivilegeEntity{Name: commonpb.ObjectPrivilege_PrivilegeInsert.String()}},
|
||||
}}
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
grantPrivilegeEntityByte, _ := proto.Marshal(grantPrivilegeEntity)
|
||||
return string(grantPrivilegeEntityByte), nil
|
||||
}
|
||||
mockTxnKV.save = func(key, value string) error {
|
||||
return fmt.Errorf("save error")
|
||||
}
|
||||
err = mt.OperatePrivilege(util.DefaultTenant, entity, milvuspb.OperatePrivilegeType_Grant)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestRbacSelectGrant(t *testing.T) {
|
||||
mt, _, mockTxnKV, closeCli := generateMetaTable(t)
|
||||
defer closeCli()
|
||||
var err error
|
||||
|
||||
entity := &milvuspb.GrantEntity{}
|
||||
_, err = mt.SelectGrant(util.DefaultTenant, entity)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
//entity.Role = &milvuspb.RoleEntity{Name: "admin"}
|
||||
_, err = mt.SelectGrant(util.DefaultTenant, entity)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return "unmarshal error", nil
|
||||
}
|
||||
_, err = mt.SelectGrant(util.DefaultTenant, entity)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
entity.Role = &milvuspb.RoleEntity{Name: "role1"}
|
||||
entity.ObjectName = "col1"
|
||||
entity.Object = &milvuspb.ObjectEntity{Name: "Collection"}
|
||||
|
||||
grantPrivilegeEntity := &milvuspb.GrantPrivilegeEntity{Entities: []*milvuspb.GrantorEntity{
|
||||
{User: &milvuspb.UserEntity{Name: "aaa"}, Privilege: &milvuspb.PrivilegeEntity{Name: "111"}},
|
||||
{User: &milvuspb.UserEntity{Name: "bbb"}, Privilege: &milvuspb.PrivilegeEntity{Name: "222"}},
|
||||
}}
|
||||
grantPrivilegeEntityByte, _ := proto.Marshal(grantPrivilegeEntity)
|
||||
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return "unmarshal error", nil
|
||||
}
|
||||
_, err = mt.SelectGrant(util.DefaultTenant, entity)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return string(grantPrivilegeEntityByte), nil
|
||||
}
|
||||
results, err := mt.SelectGrant(util.DefaultTenant, entity)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(results))
|
||||
|
||||
mockTxnKV.load = func(key string) (string, error) {
|
||||
return "", fmt.Errorf("load error")
|
||||
}
|
||||
_, err = mt.SelectGrant(util.DefaultTenant, entity)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
grantPrivilegeEntity2 := &milvuspb.GrantPrivilegeEntity{Entities: []*milvuspb.GrantorEntity{
|
||||
{User: &milvuspb.UserEntity{Name: "ccc"}, Privilege: &milvuspb.PrivilegeEntity{Name: "333"}},
|
||||
}}
|
||||
grantPrivilegeEntityByte2, _ := proto.Marshal(grantPrivilegeEntity2)
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{key + "/collection/col1", key + "/collection/col2", key + "/collection/a/col3"}, []string{string(grantPrivilegeEntityByte), string(grantPrivilegeEntityByte2), string(grantPrivilegeEntityByte2)}, nil
|
||||
}
|
||||
entity.ObjectName = ""
|
||||
entity.Object = nil
|
||||
results, err = mt.SelectGrant(util.DefaultTenant, entity)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(results))
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return nil, nil, fmt.Errorf("load with prefix error")
|
||||
}
|
||||
_, err = mt.SelectGrant(util.DefaultTenant, entity)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{key + "/collection/col1"}, []string{"unmarshal error"}, nil
|
||||
}
|
||||
_, err = mt.SelectGrant(util.DefaultTenant, entity)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestRbacListPolicy(t *testing.T) {
|
||||
mt, _, mockTxnKV, closeCli := generateMetaTable(t)
|
||||
defer closeCli()
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{}, []string{}, fmt.Errorf("load with prefix err")
|
||||
}
|
||||
policies, err := mt.ListPolicy(util.DefaultTenant)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, 0, len(policies))
|
||||
|
||||
grantPrivilegeEntity := &milvuspb.GrantPrivilegeEntity{Entities: []*milvuspb.GrantorEntity{
|
||||
{User: &milvuspb.UserEntity{Name: "aaa"}, Privilege: &milvuspb.PrivilegeEntity{Name: "111"}},
|
||||
{User: &milvuspb.UserEntity{Name: "bbb"}, Privilege: &milvuspb.PrivilegeEntity{Name: "222"}},
|
||||
}}
|
||||
grantPrivilegeEntityByte, _ := proto.Marshal(grantPrivilegeEntity)
|
||||
grantPrivilegeEntity2 := &milvuspb.GrantPrivilegeEntity{Entities: []*milvuspb.GrantorEntity{
|
||||
{User: &milvuspb.UserEntity{Name: "ccc"}, Privilege: &milvuspb.PrivilegeEntity{Name: "333"}},
|
||||
}}
|
||||
grantPrivilegeEntityByte2, _ := proto.Marshal(grantPrivilegeEntity2)
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{key + "/alice/collection/col1", key + "/tom/collection/col2", key + "/tom/collection/a/col2"}, []string{string(grantPrivilegeEntityByte), string(grantPrivilegeEntityByte2), string(grantPrivilegeEntityByte2)}, nil
|
||||
}
|
||||
policies, err = mt.ListPolicy(util.DefaultTenant)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(policies))
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{key + "/alice/collection/col1"}, []string{"unmarshal error"}, nil
|
||||
}
|
||||
_, err = mt.ListPolicy(util.DefaultTenant)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestRbacListUserRole(t *testing.T) {
|
||||
mt, _, mockTxnKV, closeCli := generateMetaTable(t)
|
||||
defer closeCli()
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{}, []string{}, fmt.Errorf("load with prefix err")
|
||||
}
|
||||
userRoles, err := mt.ListUserRole(util.DefaultTenant)
|
||||
assert.NotNil(t, err)
|
||||
assert.Equal(t, 0, len(userRoles))
|
||||
|
||||
mockTxnKV.loadWithPrefix = func(key string) ([]string, []string, error) {
|
||||
return []string{key + "/user1/role2", key + "/user2/role2", key + "/user1/role1", key + "/user2/role1", key + "/user2/role1/a"}, []string{"value1", "value2", "values3", "value4", "value5"}, nil
|
||||
}
|
||||
userRoles, err = mt.ListUserRole(util.DefaultTenant)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 4, len(userRoles))
|
||||
}
|
||||
|
||||
func TestMetaWithTimestamp(t *testing.T) {
|
||||
const (
|
||||
collID1 = typeutil.UniqueID(1)
|
||||
|
|
|
@ -207,3 +207,26 @@ func (p *proxyClientManager) UpdateCredentialCache(ctx context.Context, request
|
|||
}
|
||||
return group.Wait()
|
||||
}
|
||||
|
||||
func (p *proxyClientManager) RefreshPolicyInfoCache(ctx context.Context, req *proxypb.RefreshPolicyInfoCacheRequest) error {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
if len(p.proxyClient) == 0 {
|
||||
log.Warn("proxy client is empty, RefreshPrivilegeInfoCache will not send to any client")
|
||||
return nil
|
||||
}
|
||||
|
||||
group := &errgroup.Group{}
|
||||
for k, v := range p.proxyClient {
|
||||
k, v := k, v
|
||||
group.Go(func() error {
|
||||
_, err := v.RefreshPolicyInfoCache(ctx, req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("RefreshPolicyInfoCache failed, proxyID = %d, err = %s", k, err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
return group.Wait()
|
||||
}
|
||||
|
|
|
@ -239,3 +239,41 @@ func TestProxyClientManager_InvalidateCredentialCache(t *testing.T) {
|
|||
err = pcm.InvalidateCredentialCache(ctx, nil)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestProxyClientManager_RefreshPolicyInfoCache(t *testing.T) {
|
||||
Params.Init()
|
||||
ctx := context.Background()
|
||||
|
||||
core, err := NewCore(ctx, nil)
|
||||
assert.Nil(t, err)
|
||||
cli, err := etcd.GetEtcdClient(&Params.EtcdCfg)
|
||||
assert.Nil(t, err)
|
||||
defer cli.Close()
|
||||
core.etcdCli = cli
|
||||
|
||||
pcm := newProxyClientManager(core)
|
||||
|
||||
ch := make(chan struct{})
|
||||
pcm.helper = proxyClientManagerHelper{
|
||||
afterConnect: func() { ch <- struct{}{} },
|
||||
}
|
||||
err = pcm.RefreshPolicyInfoCache(ctx, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
core.SetNewProxyClient(
|
||||
func(se *sessionutil.Session) (types.Proxy, error) {
|
||||
return &proxyMock{}, nil
|
||||
},
|
||||
)
|
||||
|
||||
session := &sessionutil.Session{
|
||||
ServerID: 100,
|
||||
Address: "localhost",
|
||||
}
|
||||
pcm.AddProxyClient(session)
|
||||
<-ch
|
||||
|
||||
err = pcm.RefreshPolicyInfoCache(ctx, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,9 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/errorutil"
|
||||
"github.com/milvus-io/milvus/internal/util/funcutil"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/allocator"
|
||||
|
@ -1245,6 +1248,11 @@ func (c *Core) Init() error {
|
|||
if initError != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if initError = c.initRbac(); initError != nil {
|
||||
return
|
||||
}
|
||||
log.Debug("RootCoord init user root done")
|
||||
})
|
||||
if initError != nil {
|
||||
log.Debug("RootCoord init error", zap.Error(initError))
|
||||
|
@ -1264,6 +1272,45 @@ func (c *Core) initData() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Core) initRbac() (initError error) {
|
||||
// create default roles, including admin, public
|
||||
if initError = c.MetaTable.CreateRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: util.RoleAdmin}); initError != nil {
|
||||
return
|
||||
}
|
||||
if initError = c.MetaTable.CreateRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: util.RolePublic}); initError != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// create default rolemapping, root -> admin
|
||||
if initError = c.MetaTable.OperateUserRole(util.DefaultTenant,
|
||||
&milvuspb.UserEntity{Name: util.UserRoot},
|
||||
&milvuspb.RoleEntity{Name: util.RoleAdmin},
|
||||
milvuspb.OperateUserRoleType_AddUserToRole); initError != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// grant privileges for the public role
|
||||
globalPrivileges := []string{
|
||||
commonpb.ObjectPrivilege_PrivilegeDescribeCollection.String(),
|
||||
commonpb.ObjectPrivilege_PrivilegeShowCollections.String(),
|
||||
}
|
||||
|
||||
for _, globalPrivilege := range globalPrivileges {
|
||||
if initError = c.MetaTable.OperatePrivilege(util.DefaultTenant, &milvuspb.GrantEntity{
|
||||
Role: &milvuspb.RoleEntity{Name: util.RolePublic},
|
||||
Object: &milvuspb.ObjectEntity{Name: commonpb.ObjectType_Global.String()},
|
||||
ObjectName: funcutil.GlobalResourceName,
|
||||
Grantor: &milvuspb.GrantorEntity{
|
||||
User: &milvuspb.UserEntity{Name: util.RoleAdmin},
|
||||
Privilege: &milvuspb.PrivilegeEntity{Name: globalPrivilege},
|
||||
},
|
||||
}, milvuspb.OperatePrivilegeType_Grant); initError != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Core) reSendDdMsg(ctx context.Context, force bool) error {
|
||||
if !force {
|
||||
flag, err := c.MetaTable.txn.Load(DDMsgSendPrefix)
|
||||
|
@ -2850,11 +2897,21 @@ func (c *Core) CreateCredential(ctx context.Context, credInfo *internalpb.Creden
|
|||
log.Debug("CreateCredential", zap.String("role", typeutil.RootCoordRole),
|
||||
zap.String("username", credInfo.Username))
|
||||
|
||||
usersInfo, err := c.MetaTable.ListCredentialUsernames()
|
||||
if err != nil {
|
||||
log.Error("CreateCredential get credential username list failed", zap.String("role", typeutil.RootCoordRole),
|
||||
zap.String("username", credInfo.Username), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_CreateCredentialFailure, "CreateCredential failed, fail to get credential username list to check the user number, error: "+err.Error()), nil
|
||||
}
|
||||
if len(usersInfo.Usernames) >= Params.ProxyCfg.MaxUserNum {
|
||||
return failStatus(commonpb.ErrorCode_CreateCredentialFailure, "unable to add user because the number of users has reached the limit"), nil
|
||||
}
|
||||
|
||||
if cred, _ := c.MetaTable.getCredential(credInfo.Username); cred != nil {
|
||||
return failStatus(commonpb.ErrorCode_CreateCredentialFailure, "user already exists:"+credInfo.Username), nil
|
||||
}
|
||||
// insert to db
|
||||
err := c.MetaTable.AddCredential(credInfo)
|
||||
err = c.MetaTable.AddCredential(credInfo)
|
||||
if err != nil {
|
||||
log.Error("CreateCredential save credential failed", zap.String("role", typeutil.RootCoordRole),
|
||||
zap.String("username", credInfo.Username), zap.Error(err))
|
||||
|
@ -2992,3 +3049,449 @@ func (c *Core) ListCredUsers(ctx context.Context, in *milvuspb.ListCredUsersRequ
|
|||
Usernames: credInfo.Usernames,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateRole create role
|
||||
// - check the node health
|
||||
// - check if the role is existed
|
||||
// - check if the role num has reached the limit
|
||||
// - create the role by the metatable api
|
||||
func (c *Core) CreateRole(ctx context.Context, in *milvuspb.CreateRoleRequest) (*commonpb.Status, error) {
|
||||
method := "CreateRole"
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.TotalLabel).Inc()
|
||||
tr := timerecord.NewTimeRecorder(method)
|
||||
logger.Debug(method, zap.Any("in", in))
|
||||
|
||||
if code, ok := c.checkHealthy(); !ok {
|
||||
return errorutil.UnhealthyStatus(code), errorutil.UnhealthyError()
|
||||
}
|
||||
entity := in.Entity
|
||||
_, err := c.MetaTable.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: entity.Name}, false)
|
||||
if err == nil {
|
||||
errMsg := "role already exists:" + entity.Name
|
||||
return failStatus(commonpb.ErrorCode_CreateRoleFailure, errMsg), errors.New(errMsg)
|
||||
}
|
||||
if !funcutil.IsKeyNotExistError(err) {
|
||||
return failStatus(commonpb.ErrorCode_CreateRoleFailure, err.Error()), err
|
||||
}
|
||||
|
||||
results, err := c.MetaTable.SelectRole(util.DefaultTenant, nil, false)
|
||||
if err != nil {
|
||||
logger.Error("fail to select roles", zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_CreateRoleFailure, "fail to select roles to check the role number, error: "+err.Error()), err
|
||||
}
|
||||
if len(results) >= Params.ProxyCfg.MaxRoleNum {
|
||||
errMsg := "unable to add role because the number of roles has reached the limit"
|
||||
return failStatus(commonpb.ErrorCode_CreateRoleFailure, errMsg), errors.New(errMsg)
|
||||
}
|
||||
|
||||
err = c.MetaTable.CreateRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: entity.Name})
|
||||
if err != nil {
|
||||
logger.Error("fail to create role", zap.String("role_name", entity.Name), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_CreateRoleFailure, "CreateCollection role failed: "+err.Error()), err
|
||||
}
|
||||
|
||||
logger.Debug(method+" success", zap.String("role_name", entity.Name))
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.SuccessLabel).Inc()
|
||||
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
metrics.RootCoordNumOfRoles.Inc()
|
||||
|
||||
return succStatus(), nil
|
||||
}
|
||||
|
||||
// DropRole drop role
|
||||
// - check the node health
|
||||
// - check if the role name is existed
|
||||
// - check if the role has some grant info
|
||||
// - get all role mapping of this role
|
||||
// - drop these role mappings
|
||||
// - drop the role by the metatable api
|
||||
func (c *Core) DropRole(ctx context.Context, in *milvuspb.DropRoleRequest) (*commonpb.Status, error) {
|
||||
method := "DropRole"
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.TotalLabel).Inc()
|
||||
tr := timerecord.NewTimeRecorder(method)
|
||||
logger.Debug(method, zap.Any("in", in))
|
||||
|
||||
if code, ok := c.checkHealthy(); !ok {
|
||||
return errorutil.UnhealthyStatus(code), errorutil.UnhealthyError()
|
||||
}
|
||||
if _, err := c.MetaTable.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: in.RoleName}, false); err != nil {
|
||||
logger.Error("the role isn't existed", zap.String("role_name", in.RoleName), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_DropRoleFailure, fmt.Sprintf("the role isn't existed, role name: %s", in.RoleName)), err
|
||||
}
|
||||
|
||||
grantEntities, err := c.MetaTable.SelectGrant(util.DefaultTenant, &milvuspb.GrantEntity{
|
||||
Role: &milvuspb.RoleEntity{Name: in.RoleName},
|
||||
})
|
||||
if len(grantEntities) != 0 {
|
||||
errMsg := "fail to drop the role that it has privileges. Use REVOKE API to revoke privileges"
|
||||
logger.Error(errMsg, zap.String("role_name", in.RoleName), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_DropRoleFailure, errMsg), errors.New(errMsg)
|
||||
}
|
||||
roleResults, err := c.MetaTable.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: in.RoleName}, true)
|
||||
if err != nil {
|
||||
errMsg := "fail to select a role by role name"
|
||||
logger.Error("fail to select a role by role name", zap.String("role_name", in.RoleName), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_DropRoleFailure, errMsg), err
|
||||
}
|
||||
logger.Debug("role to user info", zap.Int("counter", len(roleResults)))
|
||||
for _, roleResult := range roleResults {
|
||||
for index, userEntity := range roleResult.Users {
|
||||
if err = c.MetaTable.OperateUserRole(util.DefaultTenant, &milvuspb.UserEntity{Name: userEntity.Name}, &milvuspb.RoleEntity{Name: roleResult.Role.Name}, milvuspb.OperateUserRoleType_RemoveUserFromRole); err != nil {
|
||||
errMsg := "fail to remove user from role"
|
||||
logger.Error(errMsg, zap.String("role_name", roleResult.Role.Name), zap.String("username", userEntity.Name), zap.Int("current_index", index), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_OperateUserRoleFailure, errMsg), err
|
||||
}
|
||||
}
|
||||
}
|
||||
if err = c.MetaTable.DropRole(util.DefaultTenant, in.RoleName); err != nil {
|
||||
errMsg := "fail to drop the role"
|
||||
logger.Error(errMsg, zap.String("role_name", in.RoleName), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_DropRoleFailure, errMsg), err
|
||||
}
|
||||
|
||||
logger.Debug(method+" success", zap.String("role_name", in.RoleName))
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.SuccessLabel).Inc()
|
||||
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
metrics.RootCoordNumOfRoles.Dec()
|
||||
return succStatus(), nil
|
||||
}
|
||||
|
||||
// OperateUserRole operate the relationship between a user and a role
|
||||
// - check the node health
|
||||
// - check if the role is valid
|
||||
// - check if the user is valid
|
||||
// - operate the user-role by the metatable api
|
||||
// - update the policy cache
|
||||
func (c *Core) OperateUserRole(ctx context.Context, in *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error) {
|
||||
method := "OperateUserRole-" + in.Type.String()
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.TotalLabel).Inc()
|
||||
tr := timerecord.NewTimeRecorder(method)
|
||||
logger.Debug(method, zap.Any("in", in))
|
||||
|
||||
if code, ok := c.checkHealthy(); !ok {
|
||||
return errorutil.UnhealthyStatus(code), errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
if _, err := c.MetaTable.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: in.RoleName}, false); err != nil {
|
||||
errMsg := "fail to check the role name"
|
||||
logger.Error(errMsg, zap.String("role_name", in.RoleName), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_OperateUserRoleFailure, errMsg), err
|
||||
}
|
||||
if _, err := c.MetaTable.SelectUser(util.DefaultTenant, &milvuspb.UserEntity{Name: in.Username}, false); err != nil {
|
||||
errMsg := "fail to check the username"
|
||||
logger.Error(errMsg, zap.String("username", in.Username), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_OperateUserRoleFailure, errMsg), err
|
||||
}
|
||||
if err := c.MetaTable.OperateUserRole(util.DefaultTenant, &milvuspb.UserEntity{Name: in.Username}, &milvuspb.RoleEntity{Name: in.RoleName}, in.Type); err != nil {
|
||||
errMsg := "fail to operate user to role"
|
||||
logger.Error(errMsg, zap.String("role_name", in.RoleName), zap.String("username", in.Username), zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_OperateUserRoleFailure, errMsg), err
|
||||
}
|
||||
|
||||
var opType int32
|
||||
if in.Type == milvuspb.OperateUserRoleType_AddUserToRole {
|
||||
opType = int32(typeutil.CacheAddUserToRole)
|
||||
} else if in.Type == milvuspb.OperateUserRoleType_RemoveUserFromRole {
|
||||
opType = int32(typeutil.CacheRemoveUserFromRole)
|
||||
}
|
||||
if err := c.proxyClientManager.RefreshPolicyInfoCache(ctx, &proxypb.RefreshPolicyInfoCacheRequest{
|
||||
OpType: opType,
|
||||
OpKey: funcutil.EncodeUserRoleCache(in.Username, in.RoleName),
|
||||
}); err != nil {
|
||||
return failStatus(commonpb.ErrorCode_OperateUserRoleFailure, err.Error()), err
|
||||
}
|
||||
|
||||
logger.Debug(method + " success")
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.SuccessLabel).Inc()
|
||||
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
return succStatus(), nil
|
||||
}
|
||||
|
||||
// SelectRole select role
|
||||
// - check the node health
|
||||
// - check if the role is valid when this param is provided
|
||||
// - select role by the metatable api
|
||||
func (c *Core) SelectRole(ctx context.Context, in *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error) {
|
||||
method := "SelectRole"
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.TotalLabel).Inc()
|
||||
tr := timerecord.NewTimeRecorder(method)
|
||||
logger.Debug(method, zap.Any("in", in))
|
||||
|
||||
if code, ok := c.checkHealthy(); !ok {
|
||||
return &milvuspb.SelectRoleResponse{Status: errorutil.UnhealthyStatus(code)}, errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
if in.Role != nil {
|
||||
if _, err := c.MetaTable.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: in.Role.Name}, false); err != nil {
|
||||
errMsg := "fail to select the role to check the role name"
|
||||
logger.Error(errMsg, zap.String("role_name", in.Role.Name), zap.Error(err))
|
||||
return &milvuspb.SelectRoleResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_SelectRoleFailure, errMsg),
|
||||
}, err
|
||||
}
|
||||
}
|
||||
roleResults, err := c.MetaTable.SelectRole(util.DefaultTenant, in.Role, in.IncludeUserInfo)
|
||||
if err != nil {
|
||||
errMsg := "fail to select the role"
|
||||
logger.Error(errMsg, zap.Error(err))
|
||||
return &milvuspb.SelectRoleResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_SelectRoleFailure, errMsg),
|
||||
}, err
|
||||
}
|
||||
|
||||
logger.Debug(method + " success")
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.SuccessLabel).Inc()
|
||||
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
return &milvuspb.SelectRoleResponse{
|
||||
Status: succStatus(),
|
||||
Results: roleResults,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SelectUser select user
|
||||
// - check the node health
|
||||
// - check if the user is valid when this param is provided
|
||||
// - select user by the metatable api
|
||||
func (c *Core) SelectUser(ctx context.Context, in *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error) {
|
||||
method := "SelectUser"
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.TotalLabel).Inc()
|
||||
tr := timerecord.NewTimeRecorder(method)
|
||||
logger.Debug(method, zap.Any("in", in))
|
||||
|
||||
if code, ok := c.checkHealthy(); !ok {
|
||||
return &milvuspb.SelectUserResponse{Status: errorutil.UnhealthyStatus(code)}, errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
if in.User != nil {
|
||||
if _, err := c.MetaTable.SelectUser(util.DefaultTenant, &milvuspb.UserEntity{Name: in.User.Name}, false); err != nil {
|
||||
errMsg := "fail to select the user to check the username"
|
||||
logger.Error(errMsg, zap.String("username", in.User.Name), zap.Error(err))
|
||||
return &milvuspb.SelectUserResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_SelectUserFailure, errMsg),
|
||||
}, err
|
||||
}
|
||||
}
|
||||
userResults, err := c.MetaTable.SelectUser(util.DefaultTenant, in.User, in.IncludeRoleInfo)
|
||||
if err != nil {
|
||||
errMsg := "fail to select the user"
|
||||
log.Error(errMsg, zap.Error(err))
|
||||
return &milvuspb.SelectUserResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_SelectUserFailure, errMsg),
|
||||
}, err
|
||||
}
|
||||
|
||||
logger.Debug(method + " success")
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.SuccessLabel).Inc()
|
||||
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
return &milvuspb.SelectUserResponse{
|
||||
Status: succStatus(),
|
||||
Results: userResults,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Core) isValidRole(entity *milvuspb.RoleEntity) error {
|
||||
if entity == nil {
|
||||
return fmt.Errorf("the role entity is nil")
|
||||
}
|
||||
if entity.Name == "" {
|
||||
return fmt.Errorf("the name in the role entity is empty")
|
||||
}
|
||||
if _, err := c.MetaTable.SelectRole(util.DefaultTenant, &milvuspb.RoleEntity{Name: entity.Name}, false); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Core) isValidObject(entity *milvuspb.ObjectEntity) error {
|
||||
if entity == nil {
|
||||
return fmt.Errorf("the object entity is nil")
|
||||
}
|
||||
if _, ok := commonpb.ObjectType_value[entity.Name]; !ok {
|
||||
return fmt.Errorf("the object type in the object entity is invalid, current value: %s", entity.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Core) isValidGrantor(entity *milvuspb.GrantorEntity, object string) error {
|
||||
if entity == nil {
|
||||
return fmt.Errorf("the grantor entity is nil")
|
||||
}
|
||||
if entity.User == nil {
|
||||
return fmt.Errorf("the user entity in the grantor entity is nil")
|
||||
}
|
||||
if entity.User.Name == "" {
|
||||
return fmt.Errorf("the name in the user entity of the grantor entity is empty")
|
||||
}
|
||||
if _, err := c.MetaTable.SelectUser(util.DefaultTenant, &milvuspb.UserEntity{Name: entity.GetUser().Name}, false); err != nil {
|
||||
return err
|
||||
}
|
||||
if entity.Privilege == nil {
|
||||
return fmt.Errorf("the privilege entity in the grantor entity is nil")
|
||||
}
|
||||
if privilegeName := util.PrivilegeNameForDb(entity.Privilege.Name); privilegeName == "" {
|
||||
return fmt.Errorf("the privilege name in the privilege entity is invalid, current value: %s", entity.Privilege.Name)
|
||||
}
|
||||
privileges, ok := util.GetObjectPrivileges()[object]
|
||||
if !ok {
|
||||
return fmt.Errorf("the object type is invalid, current value: %s", object)
|
||||
}
|
||||
for _, privilege := range privileges {
|
||||
if privilege == entity.Privilege.Name {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("the privilege name is invalid, current value: %s", entity.Privilege.Name)
|
||||
}
|
||||
|
||||
// OperatePrivilege operate the privilege, including grant and revoke
|
||||
// - check the node health
|
||||
// - check if the operating type is valid
|
||||
// - check if the entity is nil
|
||||
// - check if the params, including the resource entity, the principal entity, the grantor entity, is valid
|
||||
// - operate the privilege by the metatable api
|
||||
// - update the policy cache
|
||||
func (c *Core) OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error) {
|
||||
method := "OperatePrivilege"
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.TotalLabel).Inc()
|
||||
tr := timerecord.NewTimeRecorder(method)
|
||||
logger.Debug(method, zap.Any("in", in))
|
||||
|
||||
if code, ok := c.checkHealthy(); !ok {
|
||||
return errorutil.UnhealthyStatus(code), errorutil.UnhealthyError()
|
||||
}
|
||||
if in.Type != milvuspb.OperatePrivilegeType_Grant && in.Type != milvuspb.OperatePrivilegeType_Revoke {
|
||||
errMsg := fmt.Sprintf("invalid operate privilege type, current type: %s, valid value: [%s, %s]", in.Type, milvuspb.OperatePrivilegeType_Grant, milvuspb.OperatePrivilegeType_Revoke)
|
||||
return failStatus(commonpb.ErrorCode_OperatePrivilegeFailure, errMsg), errors.New(errMsg)
|
||||
}
|
||||
if in.Entity == nil {
|
||||
errMsg := "the grant entity in the request is nil"
|
||||
return failStatus(commonpb.ErrorCode_OperatePrivilegeFailure, errMsg), errors.New(errMsg)
|
||||
}
|
||||
if err := c.isValidObject(in.Entity.Object); err != nil {
|
||||
return failStatus(commonpb.ErrorCode_OperatePrivilegeFailure, err.Error()), err
|
||||
}
|
||||
if err := c.isValidRole(in.Entity.Role); err != nil {
|
||||
return failStatus(commonpb.ErrorCode_OperatePrivilegeFailure, err.Error()), err
|
||||
}
|
||||
if err := c.isValidGrantor(in.Entity.Grantor, in.Entity.Object.Name); err != nil {
|
||||
return failStatus(commonpb.ErrorCode_OperatePrivilegeFailure, err.Error()), err
|
||||
}
|
||||
|
||||
logger.Debug("before PrivilegeNameForDb", zap.String("privilege", in.Entity.Grantor.Privilege.Name))
|
||||
in.Entity.Grantor.Privilege.Name = util.PrivilegeNameForDb(in.Entity.Grantor.Privilege.Name)
|
||||
logger.Debug("after PrivilegeNameForDb", zap.String("privilege", in.Entity.Grantor.Privilege.Name))
|
||||
if in.Entity.Object.Name == commonpb.ObjectType_Global.String() {
|
||||
in.Entity.ObjectName = funcutil.GlobalResourceName
|
||||
}
|
||||
if err := c.MetaTable.OperatePrivilege(util.DefaultTenant, in.Entity, in.Type); err != nil {
|
||||
errMsg := "fail to operate the privilege"
|
||||
logger.Error(errMsg, zap.Error(err))
|
||||
return failStatus(commonpb.ErrorCode_OperatePrivilegeFailure, errMsg), err
|
||||
}
|
||||
|
||||
var opType int32
|
||||
if in.Type == milvuspb.OperatePrivilegeType_Grant {
|
||||
opType = int32(typeutil.CacheGrantPrivilege)
|
||||
} else if in.Type == milvuspb.OperatePrivilegeType_Revoke {
|
||||
opType = int32(typeutil.CacheRevokePrivilege)
|
||||
}
|
||||
if err := c.proxyClientManager.RefreshPolicyInfoCache(ctx, &proxypb.RefreshPolicyInfoCacheRequest{
|
||||
OpType: opType,
|
||||
OpKey: funcutil.PolicyForPrivilege(in.Entity.Role.Name, in.Entity.Object.Name, in.Entity.ObjectName, in.Entity.Grantor.Privilege.Name),
|
||||
}); err != nil {
|
||||
return failStatus(commonpb.ErrorCode_OperatePrivilegeFailure, err.Error()), err
|
||||
}
|
||||
|
||||
logger.Debug(method + " success")
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.SuccessLabel).Inc()
|
||||
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
return succStatus(), nil
|
||||
}
|
||||
|
||||
// SelectGrant select grant
|
||||
// - check the node health
|
||||
// - check if the principal entity is valid
|
||||
// - check if the resource entity which is provided by the user is valid
|
||||
// - select grant by the metatable api
|
||||
func (c *Core) SelectGrant(ctx context.Context, in *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error) {
|
||||
method := "SelectGrant"
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.TotalLabel).Inc()
|
||||
tr := timerecord.NewTimeRecorder(method)
|
||||
logger.Debug(method, zap.Any("in", in))
|
||||
|
||||
if code, ok := c.checkHealthy(); !ok {
|
||||
return &milvuspb.SelectGrantResponse{
|
||||
Status: errorutil.UnhealthyStatus(code),
|
||||
}, errorutil.UnhealthyError()
|
||||
}
|
||||
if in.Entity == nil {
|
||||
errMsg := "the grant entity in the request is nil"
|
||||
return &milvuspb.SelectGrantResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_SelectGrantFailure, errMsg),
|
||||
}, errors.New(errMsg)
|
||||
}
|
||||
if err := c.isValidRole(in.Entity.Role); err != nil {
|
||||
return &milvuspb.SelectGrantResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_SelectGrantFailure, err.Error()),
|
||||
}, err
|
||||
}
|
||||
if in.Entity.Object != nil {
|
||||
if err := c.isValidObject(in.Entity.Object); err != nil {
|
||||
return &milvuspb.SelectGrantResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_SelectGrantFailure, err.Error()),
|
||||
}, err
|
||||
}
|
||||
}
|
||||
|
||||
grantEntities, err := c.MetaTable.SelectGrant(util.DefaultTenant, in.Entity)
|
||||
if err != nil {
|
||||
errMsg := "fail to select the grant"
|
||||
logger.Error(errMsg, zap.Error(err))
|
||||
return &milvuspb.SelectGrantResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_SelectGrantFailure, errMsg),
|
||||
}, err
|
||||
}
|
||||
|
||||
logger.Debug(method + " success")
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.SuccessLabel).Inc()
|
||||
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
return &milvuspb.SelectGrantResponse{
|
||||
Status: succStatus(),
|
||||
Entities: grantEntities,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Core) ListPolicy(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
|
||||
method := "PolicyList"
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.TotalLabel).Inc()
|
||||
tr := timerecord.NewTimeRecorder(method)
|
||||
logger.Debug(method, zap.Any("in", in))
|
||||
|
||||
if code, ok := c.checkHealthy(); !ok {
|
||||
return &internalpb.ListPolicyResponse{
|
||||
Status: errorutil.UnhealthyStatus(code),
|
||||
}, errorutil.UnhealthyError()
|
||||
}
|
||||
|
||||
policies, err := c.MetaTable.ListPolicy(util.DefaultTenant)
|
||||
if err != nil {
|
||||
return &internalpb.ListPolicyResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_ListPolicyFailure, "fail to list policy"),
|
||||
}, err
|
||||
}
|
||||
userRoles, err := c.MetaTable.ListUserRole(util.DefaultTenant)
|
||||
if err != nil {
|
||||
return &internalpb.ListPolicyResponse{
|
||||
Status: failStatus(commonpb.ErrorCode_ListPolicyFailure, "fail to list user-role"),
|
||||
}, err
|
||||
}
|
||||
|
||||
logger.Debug(method + " success")
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues(method, metrics.SuccessLabel).Inc()
|
||||
metrics.RootCoordDDLReqLatency.WithLabelValues(method).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
return &internalpb.ListPolicyResponse{
|
||||
Status: succStatus(),
|
||||
PolicyInfos: policies,
|
||||
UserRoles: userRoles,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -146,6 +146,12 @@ func (p *proxyMock) InvalidateCredentialCache(ctx context.Context, request *prox
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (p *proxyMock) RefreshPolicyInfoCache(ctx context.Context, req *proxypb.RefreshPolicyInfoCacheRequest) (*commonpb.Status, error) {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_Success,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type dataMock struct {
|
||||
types.DataCoord
|
||||
randVal int
|
||||
|
@ -790,6 +796,7 @@ func TestRootCoordInitData(t *testing.T) {
|
|||
return fmt.Errorf("save error")
|
||||
},
|
||||
remove: func(key string) error { return txnKV.Remove(key) },
|
||||
load: func(key string) (string, error) { return txnKV.Load(key) },
|
||||
}
|
||||
//mt.txn = mockTxnKV
|
||||
mt.catalog = &kvmetestore.Catalog{Txn: mockTxnKV, Snapshot: snapshotKV}
|
||||
|
@ -3592,3 +3599,61 @@ func TestCore_GetIndexState(t *testing.T) {
|
|||
assert.Equal(t, commonpb.ErrorCode_Success, resp.Status.GetErrorCode())
|
||||
})
|
||||
}
|
||||
|
||||
func TestCore_Rbac(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
c := &Core{
|
||||
ctx: ctx,
|
||||
}
|
||||
|
||||
// not healthy.
|
||||
c.stateCode.Store(internalpb.StateCode_Abnormal)
|
||||
|
||||
{
|
||||
resp, err := c.CreateRole(ctx, &milvuspb.CreateRoleRequest{})
|
||||
assert.NotNil(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
}
|
||||
|
||||
{
|
||||
resp, err := c.DropRole(ctx, &milvuspb.DropRoleRequest{})
|
||||
assert.NotNil(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
}
|
||||
|
||||
{
|
||||
resp, err := c.OperateUserRole(ctx, &milvuspb.OperateUserRoleRequest{})
|
||||
assert.NotNil(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
}
|
||||
|
||||
{
|
||||
resp, err := c.SelectRole(ctx, &milvuspb.SelectRoleRequest{})
|
||||
assert.NotNil(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
}
|
||||
|
||||
{
|
||||
resp, err := c.SelectUser(ctx, &milvuspb.SelectUserRequest{})
|
||||
assert.NotNil(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
}
|
||||
|
||||
{
|
||||
resp, err := c.OperatePrivilege(ctx, &milvuspb.OperatePrivilegeRequest{})
|
||||
assert.NotNil(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.ErrorCode)
|
||||
}
|
||||
|
||||
{
|
||||
resp, err := c.SelectGrant(ctx, &milvuspb.SelectGrantRequest{})
|
||||
assert.NotNil(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
}
|
||||
|
||||
{
|
||||
resp, err := c.ListPolicy(ctx, &internalpb.ListPolicyRequest{})
|
||||
assert.NotNil(t, err)
|
||||
assert.NotEqual(t, commonpb.ErrorCode_Success, resp.Status.ErrorCode)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/log"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/common"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/metastore/model"
|
||||
|
@ -30,6 +33,8 @@ import (
|
|||
"github.com/milvus-io/milvus/internal/util/typeutil"
|
||||
)
|
||||
|
||||
var logger = log.L().WithOptions(zap.Fields(zap.String("role", typeutil.RootCoordRole)))
|
||||
|
||||
// EqualKeyPairArray check whether 2 KeyValuePairs are equal
|
||||
func EqualKeyPairArray(p1 []*commonpb.KeyValuePair, p2 []*commonpb.KeyValuePair) bool {
|
||||
if len(p1) != len(p2) {
|
||||
|
|
|
@ -686,6 +686,15 @@ type RootCoord interface {
|
|||
ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error)
|
||||
// GetCredential get credential by username
|
||||
GetCredential(ctx context.Context, req *rootcoordpb.GetCredentialRequest) (*rootcoordpb.GetCredentialResponse, error)
|
||||
|
||||
CreateRole(ctx context.Context, req *milvuspb.CreateRoleRequest) (*commonpb.Status, error)
|
||||
DropRole(ctx context.Context, req *milvuspb.DropRoleRequest) (*commonpb.Status, error)
|
||||
OperateUserRole(ctx context.Context, req *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error)
|
||||
SelectRole(ctx context.Context, req *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error)
|
||||
SelectUser(ctx context.Context, req *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error)
|
||||
OperatePrivilege(ctx context.Context, req *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error)
|
||||
SelectGrant(ctx context.Context, req *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error)
|
||||
ListPolicy(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error)
|
||||
}
|
||||
|
||||
// RootCoordComponent is used by grpc server of RootCoord
|
||||
|
@ -775,6 +784,8 @@ type Proxy interface {
|
|||
|
||||
SendSearchResult(ctx context.Context, req *internalpb.SearchResults) (*commonpb.Status, error)
|
||||
SendRetrieveResult(ctx context.Context, req *internalpb.RetrieveResults) (*commonpb.Status, error)
|
||||
|
||||
RefreshPolicyInfoCache(ctx context.Context, req *proxypb.RefreshPolicyInfoCacheRequest) (*commonpb.Status, error)
|
||||
}
|
||||
|
||||
// ProxyComponent defines the interface of proxy component.
|
||||
|
@ -1196,6 +1207,14 @@ type ProxyComponent interface {
|
|||
DeleteCredential(ctx context.Context, req *milvuspb.DeleteCredentialRequest) (*commonpb.Status, error)
|
||||
// ListCredUsers list all usernames
|
||||
ListCredUsers(ctx context.Context, req *milvuspb.ListCredUsersRequest) (*milvuspb.ListCredUsersResponse, error)
|
||||
|
||||
CreateRole(ctx context.Context, req *milvuspb.CreateRoleRequest) (*commonpb.Status, error)
|
||||
DropRole(ctx context.Context, req *milvuspb.DropRoleRequest) (*commonpb.Status, error)
|
||||
OperateUserRole(ctx context.Context, req *milvuspb.OperateUserRoleRequest) (*commonpb.Status, error)
|
||||
SelectRole(ctx context.Context, req *milvuspb.SelectRoleRequest) (*milvuspb.SelectRoleResponse, error)
|
||||
SelectUser(ctx context.Context, req *milvuspb.SelectUserRequest) (*milvuspb.SelectUserResponse, error)
|
||||
OperatePrivilege(ctx context.Context, req *milvuspb.OperatePrivilegeRequest) (*commonpb.Status, error)
|
||||
SelectGrant(ctx context.Context, req *milvuspb.SelectGrantRequest) (*milvuspb.SelectGrantResponse, error)
|
||||
}
|
||||
|
||||
// QueryNode is the interface `querynode` package implements
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package util
|
||||
|
||||
import "github.com/milvus-io/milvus/internal/proto/commonpb"
|
||||
|
||||
// Meta Prefix consts
|
||||
const (
|
||||
SegmentMetaPrefix = "queryCoord-segmentMeta"
|
||||
|
@ -29,4 +31,132 @@ const (
|
|||
CredentialSeperator = ":"
|
||||
UserRoot = "root"
|
||||
DefaultRootPassword = "Milvus"
|
||||
DefaultTenant = ""
|
||||
RoleAdmin = "admin"
|
||||
RolePublic = "public"
|
||||
)
|
||||
|
||||
// ObjectPrivilegeAPI privilege name for using api
|
||||
type ObjectPrivilegeAPI int32
|
||||
|
||||
func (o ObjectPrivilegeAPI) String() string {
|
||||
switch o {
|
||||
case All:
|
||||
return "All"
|
||||
case CreateCollection:
|
||||
return "CreateCollection"
|
||||
case DropCollection:
|
||||
return "DropCollection"
|
||||
case DescribeCollection:
|
||||
return "DescribeCollection"
|
||||
case ShowCollections:
|
||||
return "ShowCollections"
|
||||
case Load:
|
||||
return "Load"
|
||||
case Release:
|
||||
return "Release"
|
||||
case Compact:
|
||||
return "Compact"
|
||||
case Insert:
|
||||
return "Insert"
|
||||
case Delete:
|
||||
return "Delete"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
All ObjectPrivilegeAPI = iota
|
||||
CreateCollection
|
||||
DropCollection
|
||||
DescribeCollection
|
||||
ShowCollections
|
||||
Load
|
||||
Release
|
||||
Compact
|
||||
Insert
|
||||
Delete
|
||||
|
||||
None = 999
|
||||
)
|
||||
|
||||
func GetObjectPrivilegeFromName(name string) ObjectPrivilegeAPI {
|
||||
switch name {
|
||||
case All.String():
|
||||
return All
|
||||
case CreateCollection.String():
|
||||
return CreateCollection
|
||||
case DropCollection.String():
|
||||
return DropCollection
|
||||
case DescribeCollection.String():
|
||||
return DescribeCollection
|
||||
case ShowCollections.String():
|
||||
return ShowCollections
|
||||
case Load.String():
|
||||
return Load
|
||||
case Release.String():
|
||||
return Release
|
||||
case Compact.String():
|
||||
return Compact
|
||||
case Insert.String():
|
||||
return Insert
|
||||
case Delete.String():
|
||||
return Delete
|
||||
default:
|
||||
return None
|
||||
}
|
||||
}
|
||||
|
||||
// StringSet convert array to map for conveniently check if the array contains an element
|
||||
func StringSet(strings []string) map[string]struct{} {
|
||||
stringsMap := make(map[string]struct{})
|
||||
for _, str := range strings {
|
||||
stringsMap[str] = struct{}{}
|
||||
}
|
||||
return stringsMap
|
||||
}
|
||||
|
||||
func StringList(stringMap map[string]struct{}) []string {
|
||||
strs := make([]string, 0, len(stringMap))
|
||||
for k := range stringMap {
|
||||
strs = append(strs, k)
|
||||
}
|
||||
return strs
|
||||
}
|
||||
|
||||
// GetObjectPrivileges get the mapping between object types and privileges. This kind of data is constant and doesn't support to CRUD
|
||||
func GetObjectPrivileges() map[string][]string {
|
||||
return map[string][]string{
|
||||
commonpb.ObjectType_Collection.String(): {
|
||||
Load.String(),
|
||||
Release.String(),
|
||||
Compact.String(),
|
||||
Insert.String(),
|
||||
Delete.String(),
|
||||
},
|
||||
commonpb.ObjectType_Global.String(): {
|
||||
All.String(),
|
||||
CreateCollection.String(),
|
||||
DropCollection.String(),
|
||||
DescribeCollection.String(),
|
||||
ShowCollections.String(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func PrivilegeNameForAPI(name string) string {
|
||||
index, ok := commonpb.ObjectPrivilege_value[name]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return ObjectPrivilegeAPI(index).String()
|
||||
}
|
||||
|
||||
func PrivilegeNameForDb(name string) string {
|
||||
o := GetObjectPrivilegeFromName(name)
|
||||
if o == None {
|
||||
return ""
|
||||
}
|
||||
return commonpb.ObjectPrivilege_name[int32(o)]
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package errorutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/commonpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/internalpb"
|
||||
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ErrorList for print error log
|
||||
|
@ -25,3 +30,18 @@ func (el ErrorList) Error() string {
|
|||
}
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
func UnhealthyStatus(code internalpb.StateCode) *commonpb.Status {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: "proxy not healthy, StateCode=" + internalpb.StateCode_name[int32(code)],
|
||||
}
|
||||
}
|
||||
|
||||
func UnhealthyError() error {
|
||||
return errors.New("unhealthy node")
|
||||
}
|
||||
|
||||
func PermissionDenyError() error {
|
||||
return errors.New("permission deny")
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/milvuspb"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/go-basic/ipv4"
|
||||
|
@ -359,3 +361,42 @@ func IsGrpcErr(err error) bool {
|
|||
err = errors.Unwrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
func IsEmptyString(str string) bool {
|
||||
return strings.TrimSpace(str) == ""
|
||||
}
|
||||
|
||||
func HandleTenantForEtcdKey(prefix string, tenant string, key string) string {
|
||||
res := prefix
|
||||
if tenant != "" {
|
||||
res += "/" + tenant
|
||||
}
|
||||
if key != "" {
|
||||
res += "/" + key
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func IsRevoke(operateType milvuspb.OperatePrivilegeType) bool {
|
||||
return operateType == milvuspb.OperatePrivilegeType_Revoke
|
||||
}
|
||||
|
||||
func IsGrant(operateType milvuspb.OperatePrivilegeType) bool {
|
||||
return operateType == milvuspb.OperatePrivilegeType_Grant
|
||||
}
|
||||
|
||||
// IsKeyNotExistError Judging by the error message whether the key does not exist or not for the ectd server
|
||||
func IsKeyNotExistError(err error) bool {
|
||||
return strings.Contains(err.Error(), "there is no value on key")
|
||||
}
|
||||
|
||||
func EncodeUserRoleCache(user string, role string) string {
|
||||
return fmt.Sprintf("%s/%s", user, role)
|
||||
}
|
||||
|
||||
func DecodeUserRoleCache(cache string) (string, string) {
|
||||
index := strings.LastIndex(cache, "/")
|
||||
user := cache[:index]
|
||||
role := cache[index+1:]
|
||||
return user, role
|
||||
}
|
||||
|
|
|
@ -503,3 +503,43 @@ func TestIsGrpcErr(t *testing.T) {
|
|||
assert.True(t, IsGrpcErr(errWrap))
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsEmptyString(t *testing.T) {
|
||||
assert.Equal(t, IsEmptyString(""), true)
|
||||
assert.Equal(t, IsEmptyString(" "), true)
|
||||
assert.Equal(t, IsEmptyString("hello"), false)
|
||||
}
|
||||
|
||||
func TestHandleTenantForEtcdKey(t *testing.T) {
|
||||
assert.Equal(t, "a/b/c", HandleTenantForEtcdKey("a", "b", "c"))
|
||||
|
||||
assert.Equal(t, "a/b", HandleTenantForEtcdKey("a", "", "b"))
|
||||
|
||||
assert.Equal(t, "a/b", HandleTenantForEtcdKey("a", "b", ""))
|
||||
|
||||
assert.Equal(t, "a", HandleTenantForEtcdKey("a", "", ""))
|
||||
}
|
||||
|
||||
func TestIsRevoke(t *testing.T) {
|
||||
assert.Equal(t, true, IsRevoke(milvuspb.OperatePrivilegeType_Revoke))
|
||||
assert.Equal(t, false, IsRevoke(milvuspb.OperatePrivilegeType_Grant))
|
||||
}
|
||||
|
||||
func TestIsGrant(t *testing.T) {
|
||||
assert.Equal(t, true, IsGrant(milvuspb.OperatePrivilegeType_Grant))
|
||||
assert.Equal(t, false, IsGrant(milvuspb.OperatePrivilegeType_Revoke))
|
||||
}
|
||||
|
||||
func TestIsKeyNotExistError(t *testing.T) {
|
||||
assert.Equal(t, true, IsKeyNotExistError(fmt.Errorf("there is no value on key = %s", "foo")))
|
||||
assert.Equal(t, false, IsKeyNotExistError(fmt.Errorf("err: key = %s", "fooo")))
|
||||
}
|
||||
|
||||
func TestUserRoleCache(t *testing.T) {
|
||||
user, role := "foo", "root"
|
||||
cache := EncodeUserRoleCache(user, role)
|
||||
assert.Equal(t, fmt.Sprintf("%s/%s", user, role), cache)
|
||||
u, r := DecodeUserRoleCache(cache)
|
||||
assert.Equal(t, user, u)
|
||||
assert.Equal(t, role, r)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package funcutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/protobuf/descriptor"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/milvus-io/milvus/internal/log"
|
||||
"github.com/milvus-io/milvus/internal/proto/commonpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/milvuspb"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
const (
|
||||
GlobalResourceName = "*"
|
||||
)
|
||||
|
||||
func GetVersion(m proto.GeneratedMessage) (string, error) {
|
||||
md, _ := descriptor.MessageDescriptorProto(m)
|
||||
if md == nil {
|
||||
log.Error("MessageDescriptorProto result is nil")
|
||||
return "", fmt.Errorf("MessageDescriptorProto result is nil")
|
||||
}
|
||||
extObj, err := proto.GetExtension(md.Options, milvuspb.E_MilvusExtObj)
|
||||
if err != nil {
|
||||
log.Error("GetExtension fail", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
version := extObj.(*milvuspb.MilvusExt).Version
|
||||
log.Debug("GetVersion success", zap.String("version", version))
|
||||
return version, nil
|
||||
}
|
||||
|
||||
func GetPrivilegeExtObj(m proto.GeneratedMessage) (commonpb.PrivilegeExt, error) {
|
||||
_, md := descriptor.MessageDescriptorProto(m)
|
||||
if md == nil {
|
||||
log.Error("MessageDescriptorProto result is nil")
|
||||
return commonpb.PrivilegeExt{}, fmt.Errorf("MessageDescriptorProto result is nil")
|
||||
}
|
||||
|
||||
extObj, err := proto.GetExtension(md.Options, commonpb.E_PrivilegeExtObj)
|
||||
if err != nil {
|
||||
log.Error("GetExtension fail", zap.Error(err))
|
||||
return commonpb.PrivilegeExt{}, err
|
||||
}
|
||||
privilegeExt := extObj.(*commonpb.PrivilegeExt)
|
||||
log.Debug("GetPrivilegeExtObj success", zap.String("resource_type", privilegeExt.ObjectType.String()), zap.String("resource_privilege", privilegeExt.ObjectPrivilege.String()))
|
||||
return commonpb.PrivilegeExt{
|
||||
ObjectType: privilegeExt.ObjectType,
|
||||
ObjectPrivilege: privilegeExt.ObjectPrivilege,
|
||||
ObjectNameIndex: privilegeExt.ObjectNameIndex,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetResourceName(m proto.GeneratedMessage, index int32) string {
|
||||
if index <= 0 {
|
||||
return GlobalResourceName
|
||||
}
|
||||
msg := proto.MessageReflect(proto.MessageV1(m))
|
||||
msgDesc := msg.Descriptor()
|
||||
return msg.Get(msgDesc.Fields().ByNumber(protoreflect.FieldNumber(index))).String()
|
||||
}
|
||||
|
||||
func PolicyForPrivilege(roleName string, objectType string, objectName string, privilege string) string {
|
||||
return fmt.Sprintf(`{"PType":"p","V0":"%s","V1":"%s","V2":"%s"}`, roleName, PolicyForResource(objectType, objectName), privilege)
|
||||
}
|
||||
|
||||
func PolicyForResource(objectType string, objectName string) string {
|
||||
return fmt.Sprintf("%s-%s", objectType, objectName)
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package funcutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/commonpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/milvuspb"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_GetVersion(t *testing.T) {
|
||||
request := &milvuspb.HasCollectionRequest{
|
||||
Base: &commonpb.MsgBase{
|
||||
MsgType: commonpb.MsgType_Undefined,
|
||||
MsgID: 123,
|
||||
},
|
||||
DbName: "test",
|
||||
CollectionName: "col1",
|
||||
}
|
||||
str, err := GetVersion(request)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, str, "2.1.0")
|
||||
|
||||
request2 := &commonpb.MsgBase{}
|
||||
_, err = GetVersion(request2)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func Test_GetPrivilegeExtObj(t *testing.T) {
|
||||
request := &milvuspb.LoadCollectionRequest{
|
||||
DbName: "test",
|
||||
CollectionName: "col1",
|
||||
}
|
||||
privilegeExt, err := GetPrivilegeExtObj(request)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, commonpb.ObjectType_Collection, privilegeExt.ObjectType)
|
||||
assert.Equal(t, commonpb.ObjectPrivilege_PrivilegeLoad, privilegeExt.ObjectPrivilege)
|
||||
assert.Equal(t, int32(3), privilegeExt.ObjectNameIndex)
|
||||
|
||||
request2 := &milvuspb.CreatePartitionRequest{}
|
||||
_, err = GetPrivilegeExtObj(request2)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func Test_GetResourceName(t *testing.T) {
|
||||
request := &milvuspb.HasCollectionRequest{
|
||||
DbName: "test",
|
||||
CollectionName: "col1",
|
||||
}
|
||||
assert.Equal(t, "*", GetResourceName(request, 0))
|
||||
assert.Equal(t, "col1", GetResourceName(request, 3))
|
||||
}
|
||||
|
||||
func Test_PolicyForPrivilege(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
`{"PType":"p","V0":"admin","V1":"COLLECTION-col1","V2":"ALL"}`,
|
||||
PolicyForPrivilege("admin", "COLLECTION", "col1", "ALL"))
|
||||
}
|
||||
|
||||
func Test_PolicyForResource(t *testing.T) {
|
||||
assert.Equal(t,
|
||||
`COLLECTION-col1`,
|
||||
PolicyForResource("COLLECTION", "col1"))
|
||||
}
|
|
@ -9,6 +9,9 @@
|
|||
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package metricsinfo
|
||||
|
||||
import (
|
|
@ -57,10 +57,6 @@ func (m *GrpcRootCoordClient) SelectUser(ctx context.Context, in *milvuspb.Selec
|
|||
return &milvuspb.SelectUserResponse{}, m.Err
|
||||
}
|
||||
|
||||
func (m *GrpcRootCoordClient) SelectResource(ctx context.Context, in *milvuspb.SelectResourceRequest, opts ...grpc.CallOption) (*milvuspb.SelectResourceResponse, error) {
|
||||
return &milvuspb.SelectResourceResponse{}, m.Err
|
||||
}
|
||||
|
||||
func (m *GrpcRootCoordClient) OperatePrivilege(ctx context.Context, in *milvuspb.OperatePrivilegeRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
return &commonpb.Status{}, m.Err
|
||||
}
|
||||
|
|
|
@ -433,6 +433,8 @@ type proxyConfig struct {
|
|||
MaxShardNum int32
|
||||
MaxDimension int64
|
||||
GinLogging bool
|
||||
MaxUserNum int
|
||||
MaxRoleNum int
|
||||
|
||||
// required from QueryCoord
|
||||
SearchResultChannelNames []string
|
||||
|
@ -460,6 +462,8 @@ func (p *proxyConfig) init(base *BaseTable) {
|
|||
|
||||
p.initMaxTaskNum()
|
||||
p.initGinLogging()
|
||||
p.initMaxUserNum()
|
||||
p.initMaxRoleNum()
|
||||
}
|
||||
|
||||
// InitAlias initialize Alias member.
|
||||
|
@ -560,6 +564,24 @@ func (p *proxyConfig) GetNodeID() UniqueID {
|
|||
return 0
|
||||
}
|
||||
|
||||
func (p *proxyConfig) initMaxUserNum() {
|
||||
str := p.Base.LoadWithDefault("proxy.maxUserNum", "100")
|
||||
maxUserNum, err := strconv.ParseInt(str, 10, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
p.MaxUserNum = int(maxUserNum)
|
||||
}
|
||||
|
||||
func (p *proxyConfig) initMaxRoleNum() {
|
||||
str := p.Base.LoadWithDefault("proxy.maxRoleNum", "10")
|
||||
maxRoleNum, err := strconv.ParseInt(str, 10, 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
p.MaxRoleNum = int(maxRoleNum)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// --- querycoord ---
|
||||
type queryCoordConfig struct {
|
||||
|
|
|
@ -200,6 +200,16 @@ func TestComponentParam(t *testing.T) {
|
|||
Params.Base.Save("proxy.maxTaskNum", "-asdf")
|
||||
Params.initMaxTaskNum()
|
||||
})
|
||||
|
||||
shouldPanic(t, "proxy.maxUserNum", func() {
|
||||
Params.Base.Save("proxy.maxUserNum", "abc")
|
||||
Params.initMaxUserNum()
|
||||
})
|
||||
|
||||
shouldPanic(t, "proxy.maxRoleNum", func() {
|
||||
Params.Base.Save("proxy.maxRoleNum", "abc")
|
||||
Params.initMaxRoleNum()
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("test queryNodeConfig", func(t *testing.T) {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package typeutil
|
||||
|
||||
type CacheOpType int32
|
||||
|
||||
const (
|
||||
CacheAddUserToRole CacheOpType = iota + 1
|
||||
CacheRemoveUserFromRole
|
||||
CacheGrantPrivilege
|
||||
CacheRevokePrivilege
|
||||
)
|
||||
|
||||
type CacheOp struct {
|
||||
OpType CacheOpType
|
||||
OpKey string
|
||||
}
|
|
@ -47,3 +47,8 @@ func After(str string, sub string) string {
|
|||
}
|
||||
return str[adjustedPos:]
|
||||
}
|
||||
|
||||
// AfterN Split slices After(str) into all substrings separated by sep
|
||||
func AfterN(str string, sub string, sep string) []string {
|
||||
return strings.Split(After(str, sub), sep)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue