/
loader.go
132 lines (109 loc) · 3.6 KB
/
loader.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
120
121
122
123
124
125
126
127
128
129
130
131
132
package cmd
import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"time"
"github.com/cmd-tools/aws-commander/executor"
"github.com/cmd-tools/aws-commander/logger"
"golang.org/x/exp/maps"
"gopkg.in/yaml.v2"
)
var ConfigurationsRelativeFilePath = "./configurations"
var ConfigurationsRelativeFileExtension = ".yaml"
var Resources = map[string]Resource{}
type Command struct {
Name string `yaml:"name"`
ResourceName string `yaml:"resourceName"`
DefaultCommand string `yaml:"defaultCommand"`
Arguments []string `yaml:"arguments"`
View string `yaml:"view"`
Parse Parse `yaml:"parse"`
}
type Parse struct {
Type string `yaml:"type"`
AttributeName string `yaml:"attributeName"`
}
type Resource struct {
Name string `yaml:"name"`
DefaultCommand string `yaml:"defaultCommand"`
Commands []Command `yaml:"commands"`
}
func Init() {
entries, err := os.ReadDir(ConfigurationsRelativeFilePath)
if err != nil {
log.Fatal(err)
}
channel := make(chan Resource)
for _, e := range entries {
if filepath.Ext(e.Name()) == ConfigurationsRelativeFileExtension {
go processConfigurationFile(channel, fmt.Sprintf("%s/%s", ConfigurationsRelativeFilePath, e.Name()))
resource := <-channel
Resources[resource.Name] = resource
}
}
logger.Logger.Debug().Msg(fmt.Sprintf("Loaded %d configurations", len(Resources)))
}
func GetAvailableResourceNames() []string {
if len(Resources) == 0 {
logger.Logger.Warn().Msg("No resources found, try to load from configuration again")
Init()
}
if len(Resources) == 0 {
logger.Logger.Error().Msg("No resources found after trying a second loading")
return []string{}
}
return maps.Keys(Resources)
}
func (resource *Resource) GetCommandNames() []string {
commandNames := []string{}
for _, command := range resource.Commands {
commandNames = append(commandNames, command.Name)
}
return commandNames
}
func (resource *Resource) GetCommand(name string) Command {
for _, command := range resource.Commands {
if command.Name == name {
return command
}
}
panic(fmt.Sprintf("Requested command %s does not exists in %s resouce", name, resource.Name))
}
func (command *Command) Run(resource string, profile string) string {
binaryName := "aws"
args := []string{resource, command.Name, "--profile", profile}
args = append(args, replaceVariablesOnCommandArguments(command.Arguments)...)
logger.Logger.Debug().Msg(fmt.Sprintf("Running: %s %s", binaryName, strings.Join(args, " ")))
start := time.Now()
output := executor.ExecCommand(binaryName, args)
logger.Logger.Debug().Msg(fmt.Sprintf("Execution time %s", time.Since(start)))
return output
}
func processConfigurationFile(channel chan Resource, filename string) {
logger.Logger.Debug().Msg(fmt.Sprintf("[Worker] Loading configurations from: %s", filename))
resource := Resource{}
yamlFile, err := os.ReadFile(filename)
if err != nil {
logger.Logger.Error().Msg(fmt.Sprintf("[Worker] Error while reading: %s, description: #%v", filename, err))
}
err = yaml.Unmarshal(yamlFile, &resource)
if err != nil {
logger.Logger.Error().Msg(fmt.Sprintf("[Worker] Error while unmarshalling: %s, description: #%v", filename, err))
}
logger.Logger.Debug().Msg(fmt.Sprintf("[Worker] Loaded resource: %s, which contains %d commands", resource.Name, len(resource.Commands)))
channel <- resource
}
func replaceVariablesOnCommandArguments(arguments []string) []string {
for index, item := range arguments {
if strings.HasPrefix(item, "$") {
value, exists := UiState.SelectedItems[item]
if exists {
arguments[index] = value
}
}
}
return arguments
}