api/internal/utils/utils.go (168 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License 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. */ package utils import ( "bytes" "encoding/json" "errors" "fmt" "net" "os" "sort" "strconv" "strings" "github.com/sony/sonyflake" "github.com/yuin/gopher-lua/parse" ) var _sf *sonyflake.Sonyflake func init() { saltStr, ok := os.LookupEnv("FLAKE_SALT") var salt uint16 if ok { i, err := strconv.ParseUint(saltStr, 10, 16) if err != nil { panic(err) } salt = uint16(i) } ips, err := getLocalIPs() if err != nil { panic(err) } _sf = sonyflake.NewSonyflake(sonyflake.Settings{ MachineID: func() (u uint16, e error) { return sumIPs(ips) + salt, nil }, }) if _sf == nil { panic("sonyflake init failed") } } func sumIPs(ips []net.IP) uint16 { total := 0 for _, ip := range ips { for i := range ip { total += int(ip[i]) } } return uint16(total) } func getLocalIPs() ([]net.IP, error) { var ips []net.IP addrs, err := net.InterfaceAddrs() if err != nil { return ips, err } for _, a := range addrs { if ipNet, ok := a.(*net.IPNet); ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil { ips = append(ips, ipNet.IP) } } return ips, nil } func GetFlakeUid() uint64 { uid, err := _sf.NextID() if err != nil { panic("get sony flake uid failed:" + err.Error()) } return uid } func GetFlakeUidStr() string { return strconv.FormatUint(GetFlakeUid(), 10) } func InterfaceToString(val interface{}) string { if val == nil { return "" } str := fmt.Sprintf("%v", val) return str } // Note: json.Marshal and json.Unmarshal may cause the precision loss func ObjectClone(origin, copy interface{}) error { byt, err := json.Marshal(origin) if err != nil { return err } err = json.Unmarshal(byt, copy) return err } func GenLabelMap(label string) (map[string]struct{}, error) { var err = errors.New("malformed label") mp := make(map[string]struct{}) if label == "" { return mp, nil } labels := strings.Split(label, ",") for _, l := range labels { kv := strings.Split(l, ":") if len(kv) == 2 { if kv[0] == "" || kv[1] == "" { return nil, err } // Because the labels may contain the same key, like this: label=version:v1,version:v2 // we need to combine them as a map's key mp[l] = struct{}{} } else if len(kv) == 1 { if kv[0] == "" { return nil, err } mp[kv[0]] = struct{}{} } else { return nil, err } } return mp, nil } func LabelContains(labels map[string]string, reqLabels map[string]struct{}) bool { if len(reqLabels) == 0 { return true } for k, v := range labels { // first check the key if _, exist := reqLabels[k]; exist { return true } // second check the key:value if _, exist := reqLabels[k+":"+v]; exist { return true } } return false } // ValidateLuaCode validates lua syntax for input code, return nil // if passed, otherwise a non-nil error will be returned func ValidateLuaCode(code string) error { _, err := parse.Parse(strings.NewReader(code), "<string>") return err } func StringSliceContains(a, b []string) bool { if (a == nil) != (b == nil) { return false } for i := range a { for j := range b { if a[i] == b[j] { return true } } } return false } // func StringSliceEqual(a, b []string) bool { if (a == nil) != (b == nil) { return false } if len(a) != len(b) { return false } sort.Strings(a) sort.Strings(b) for i := range a { if a[i] != b[i] { return false } } return true } // value compare func ValueEqual(a interface{}, b interface{}) bool { aBytes, err := json.Marshal(a) if err != nil { return false } bBytes, err := json.Marshal(b) if err != nil { return false } return bytes.Equal(aBytes, bBytes) }