istio
1// Copyright Istio Authors
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
15package util16
17import (18"bytes"19"fmt"20"os"21"path/filepath"22"strconv"23"strings"24"text/template"25
26"google.golang.org/protobuf/types/known/structpb"27)
28
29type FileFilter func(fileName string) bool30
31// StringBoolMapToSlice creates and returns a slice of all the map keys with true.
32func StringBoolMapToSlice(m map[string]bool) []string {33s := make([]string, 0, len(m))34for k, v := range m {35if v {36s = append(s, k)37}38}39return s40}
41
42// ReadFilesWithFilter reads files from path, for a directory it recursively reads files and filters the results
43// for single file it directly reads the file. It returns a concatenated output of all matching files' content.
44func ReadFilesWithFilter(path string, filter FileFilter) (string, error) {45fileList, err := FindFiles(path, filter)46if err != nil {47return "", err48}49var sb strings.Builder50for _, file := range fileList {51a, err := os.ReadFile(file)52if err != nil {53return "", err54}55if _, err := sb.WriteString(string(a) + "\n"); err != nil {56return "", err57}58}59return sb.String(), nil60}
61
62// FindFiles reads files from path, and returns the file names that match the filter.
63func FindFiles(path string, filter FileFilter) ([]string, error) {64fi, err := os.Stat(path)65if err != nil {66return nil, err67}68var fileList []string69if fi.IsDir() {70err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {71if err != nil {72return err73}74if info.IsDir() || !filter(path) {75return nil76}77fileList = append(fileList, path)78return nil79})80if err != nil {81return nil, err82}83} else {84fileList = append(fileList, path)85}86return fileList, nil87}
88
89// ParseValue parses string into a value
90func ParseValue(valueStr string) any {91var value any92if v, err := strconv.Atoi(valueStr); err == nil {93value = v94} else if v, err := strconv.ParseFloat(valueStr, 64); err == nil {95value = v96} else if v, err := strconv.ParseBool(valueStr); err == nil {97value = v98} else {99value = strings.ReplaceAll(valueStr, "\\,", ",")100}101return value102}
103
104// ConsolidateLog is a helper function to dedup the log message.
105func ConsolidateLog(logMessage string) string {106logCountMap := make(map[string]int)107stderrSlice := strings.Split(logMessage, "\n")108for _, item := range stderrSlice {109if item == "" {110continue111}112_, exist := logCountMap[item]113if exist {114logCountMap[item]++115} else {116logCountMap[item] = 1117}118}119var sb strings.Builder120for _, item := range stderrSlice {121if logCountMap[item] == 0 {122continue123}124sb.WriteString(fmt.Sprintf("%s (repeated %v times)\n", item, logCountMap[item]))125// reset seen log count126logCountMap[item] = 0127}128return sb.String()129}
130
131// RenderTemplate is a helper method to render a template with the given values.
132func RenderTemplate(tmpl string, ts any) (string, error) {133t, err := template.New("").Parse(tmpl)134if err != nil {135return "", err136}137buf := new(bytes.Buffer)138err = t.Execute(buf, ts)139if err != nil {140return "", err141}142return buf.String(), nil143}
144
145func ValueString(v *structpb.Value) string {146switch x := v.Kind.(type) {147case *structpb.Value_StringValue:148return x.StringValue149case *structpb.Value_NumberValue:150return fmt.Sprint(x.NumberValue)151default:152return v.String()153}154}
155
156func MustStruct(m map[string]any) *structpb.Struct {157s, _ := structpb.NewStruct(m)158return s159}
160