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  }