github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/providers/agent/mcorpc/ddl/common/common.go (about)

     1  // Copyright (c) 2021-2022, R.I. Pienaar and the Choria Project contributors
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package common
     6  
     7  import (
     8  	"encoding/json"
     9  	"fmt"
    10  	"os"
    11  	"path/filepath"
    12  	"strconv"
    13  	"strings"
    14  )
    15  
    16  // EachFile calls cb with a path to every found DD of type kind, stops looking when br is true
    17  func EachFile(kind string, libdirs []string, cb func(name string, path string) (br bool)) {
    18  	for _, dir := range libdirs {
    19  		for _, n := range []string{"choria", "mcollective"} {
    20  			filepath.Walk(filepath.Join(dir, n, kind), func(path string, info os.FileInfo, err error) error {
    21  				if err != nil {
    22  					return err
    23  				}
    24  
    25  				if info.IsDir() {
    26  					return nil
    27  				}
    28  
    29  				_, name := filepath.Split(path)
    30  				extension := filepath.Ext(name)
    31  
    32  				if extension != ".json" {
    33  					return nil
    34  				}
    35  
    36  				cb(strings.TrimSuffix(name, extension), path)
    37  
    38  				return nil
    39  			})
    40  		}
    41  	}
    42  }
    43  
    44  // ValToDDLType converts val into the type described in typedef where typedef is a typical choria DDL supported type
    45  func ValToDDLType(typedef string, val string) (res any, err error) {
    46  	switch strings.ToLower(typedef) {
    47  	case "integer":
    48  		i, err := strconv.Atoi(val)
    49  		if err != nil {
    50  			return nil, fmt.Errorf("'%s' is not a valid integer", val)
    51  		}
    52  
    53  		return int64(i), nil
    54  
    55  	case "float", "number":
    56  		f, err := strconv.ParseFloat(val, 64)
    57  		if err != nil {
    58  			return nil, fmt.Errorf("'%s' is not a valid float", val)
    59  		}
    60  
    61  		return f, nil
    62  
    63  	case "string", "list":
    64  		return val, nil
    65  
    66  	case "boolean":
    67  		b, err := strconv.ParseBool(val)
    68  		if err != nil {
    69  			return nil, fmt.Errorf("'%s' is not a valid boolean", val)
    70  		}
    71  
    72  		return b, nil
    73  
    74  	case "hash":
    75  		res := map[string]any{}
    76  		err := json.Unmarshal([]byte(val), &res)
    77  		if err != nil {
    78  			return nil, fmt.Errorf("'%s' is not a valid JSON string with a hash inside", val)
    79  		}
    80  
    81  		return res, nil
    82  
    83  	case "array":
    84  		res := []any{}
    85  		err := json.Unmarshal([]byte(val), &res)
    86  		if err != nil {
    87  			return nil, fmt.Errorf("'%s' is not a valid JSON string with an array inside", val)
    88  		}
    89  
    90  		return res, nil
    91  
    92  	}
    93  
    94  	return nil, fmt.Errorf("unsupported type '%s'", typedef)
    95  }