This repository has been archived by the owner on Jan 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 560
/
apimodel_merger.go
119 lines (104 loc) · 3.25 KB
/
apimodel_merger.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package transform
import (
"fmt"
"io/ioutil"
"os"
"regexp"
"strconv"
"strings"
"github.com/Jeffail/gabs"
log "github.com/sirupsen/logrus"
)
// APIModelValue represents a value in the APIModel JSON file
type APIModelValue struct {
stringValue string
intValue int64
arrayValue bool
arrayIndex int
arrayProperty string
arrayName string
}
// MapValues converts an arraw of rwa ApiModel values (like ["masterProfile.count=4","linuxProfile.adminUsername=admin"]) to a map
func MapValues(m map[string]APIModelValue, values []string) {
if values == nil || len(values) == 0 {
return
}
for _, value := range values {
splittedValues := strings.Split(value, ",")
if len(splittedValues) > 1 {
MapValues(m, splittedValues)
} else {
keyValueSplitted := strings.Split(value, "=")
key := keyValueSplitted[0]
stringValue := keyValueSplitted[1]
flagValue := APIModelValue{}
if asInteger, err := strconv.ParseInt(stringValue, 10, 64); err == nil {
flagValue.intValue = asInteger
} else {
flagValue.stringValue = stringValue
}
// use regex to find array[index].property pattern in the key
re := regexp.MustCompile(`(.*?)\[(.*?)\]\.(.*?)$`)
match := re.FindStringSubmatch(key)
// it's an array
if len(match) != 0 {
i, err := strconv.ParseInt(match[2], 10, 32)
if err != nil {
log.Warnln(fmt.Sprintf("array index is not specified for property %s", key))
} else {
arrayIndex := int(i)
flagValue.arrayValue = true
flagValue.arrayName = match[1]
flagValue.arrayIndex = arrayIndex
flagValue.arrayProperty = match[3]
m[key] = flagValue
}
} else {
m[key] = flagValue
}
}
}
}
// MergeValuesWithAPIModel takes the path to an ApiModel JSON file, loads it and merges it with the values in the map to another temp file
func MergeValuesWithAPIModel(apiModelPath string, m map[string]APIModelValue) (string, error) {
// load the apiModel file from path
fileContent, err := ioutil.ReadFile(apiModelPath)
if err != nil {
return "", err
}
// parse the json from file content
jsonObj, err := gabs.ParseJSON(fileContent)
if err != nil {
return "", err
}
// update api model definition with each value in the map
for key, flagValue := range m {
// working on an array
if flagValue.arrayValue {
log.Infoln(fmt.Sprintf("--set flag array value detected. Name: %s, Index: %b, PropertyName: %s", flagValue.arrayName, flagValue.arrayIndex, flagValue.arrayProperty))
arrayValue := jsonObj.Path(fmt.Sprint("properties.", flagValue.arrayName))
if flagValue.stringValue != "" {
arrayValue.Index(flagValue.arrayIndex).SetP(flagValue.stringValue, flagValue.arrayProperty)
} else {
arrayValue.Index(flagValue.arrayIndex).SetP(flagValue.intValue, flagValue.arrayProperty)
}
} else {
if flagValue.stringValue != "" {
jsonObj.SetP(flagValue.stringValue, fmt.Sprint("properties.", key))
} else {
jsonObj.SetP(flagValue.intValue, fmt.Sprint("properties.", key))
}
}
}
// generate a new file
tmpFile, err := ioutil.TempFile("", "mergedApiModel")
if err != nil {
return "", err
}
tmpFileName := tmpFile.Name()
err = ioutil.WriteFile(tmpFileName, []byte(jsonObj.String()), os.ModeAppend)
if err != nil {
return "", err
}
return tmpFileName, nil
}