github.com/matrixorigin/matrixone@v1.2.0/pkg/proxy/label_info.go (about) 1 // Copyright 2021 - 2023 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package proxy 16 17 import ( 18 "encoding/json" 19 "net" 20 "strings" 21 22 "github.com/matrixorigin/matrixone/pkg/clusterservice" 23 "github.com/matrixorigin/matrixone/pkg/frontend" 24 ) 25 26 // LabelHash defines hash value, which is hashed from labelInfo. 27 type LabelHash string 28 29 // labelInfo contains tenant and labels. 30 // NB: It is the request from client, but not the information of server. 31 // 32 // All fields in labelInfo should start with capital letter 33 // to get correct hash result. 34 type labelInfo struct { 35 Tenant Tenant 36 Labels map[string]string 37 } 38 39 // clientInfo contains the information of client, e.g. Tenant of the client 40 type clientInfo struct { 41 // labelInfo contains tenant and labels of the client 42 labelInfo 43 // username of the client, unique under each tenant 44 username string 45 // originIP that client used to communicate with server 46 originIP net.IP 47 // originPort is the origin port of client. 48 originPort uint16 49 } 50 51 // reservedLabels are the labels not allowed in user labels. 52 // Ref: https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html 53 var reservedLabels = map[string]struct{}{ 54 "os_user": {}, 55 "os_sudouser": {}, 56 "program_name": {}, 57 } 58 59 // newLabelInfo creates labelInfo. 60 func newLabelInfo(tenant Tenant, labels map[string]string) labelInfo { 61 // Filter out reserved connection attributes. 62 for k := range labels { 63 if _, ok := reservedLabels[k]; ok || strings.HasPrefix(k, "_") { 64 delete(labels, k) 65 } 66 } 67 return labelInfo{ 68 Tenant: tenant, 69 Labels: labels, 70 } 71 } 72 73 // allLabels returns all labels including tenant. 74 func (l *labelInfo) allLabels() map[string]string { 75 all := l.commonLabels() 76 if l.Tenant != "" { 77 all[tenantLabelKey] = string(l.Tenant) 78 } 79 return all 80 } 81 82 // commonLabels returns all labels except tenant. 83 func (l *labelInfo) commonLabels() map[string]string { 84 common := make(map[string]string) 85 for k, v := range l.Labels { 86 if k != "" && v != "" { 87 common[k] = v 88 } 89 } 90 return common 91 } 92 93 // tenantLabel returns just tenant label. 94 func (l *labelInfo) tenantLabel() map[string]string { 95 t := make(map[string]string) 96 if l.Tenant != "" { 97 t[tenantLabelKey] = string(l.Tenant) 98 } 99 return t 100 } 101 102 // isSuperTenant returns true if the tenant is sys or empty. 103 func (l *labelInfo) isSuperTenant() bool { 104 if l.Tenant == "" || strings.ToLower(string(l.Tenant)) == frontend.GetDefaultTenant() { 105 return true 106 } 107 return false 108 } 109 110 // genSelector generates the label selector according to labels in labelInfo. 111 func (l *labelInfo) genSelector(op clusterservice.Op) clusterservice.Selector { 112 return clusterservice.NewSelector().SelectByLabel( 113 l.allLabels(), op, 114 ) 115 } 116 117 // getHash calculate the hash value of the labelInfo. 118 func (l *labelInfo) getHash() (LabelHash, error) { 119 targetBytes, err := json.Marshal(*l) 120 if err != nil { 121 return "", err 122 } 123 var targetMap map[string]any 124 if err = json.Unmarshal(targetBytes, &targetMap); err != nil { 125 return "", err 126 } 127 s := sortMap(targetMap) 128 s = sortSimpleMap(s) 129 return LabelHash(rawHash(s)), nil 130 }