-
Notifications
You must be signed in to change notification settings - Fork 10
/
create_edgekv.go
217 lines (190 loc) · 6.94 KB
/
create_edgekv.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
// Package edgeworkers contains code for exporting edge workers and edge kv configuration
package edgeworkers
import (
"context"
"embed"
"errors"
"fmt"
"path/filepath"
"strings"
"text/template"
"github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/edgeworkers"
"github.com/akamai/cli-terraform/pkg/edgegrid"
"github.com/akamai/cli-terraform/pkg/templates"
"github.com/akamai/cli-terraform/pkg/tools"
"github.com/akamai/cli/pkg/terminal"
"github.com/fatih/color"
"github.com/urfave/cli/v2"
)
type (
// TFEdgeKVData represents the data used in EdgeKV templates
TFEdgeKVData struct {
Name string
Network edgeworkers.NamespaceNetwork
GroupID int
Retention int
GeoLocation string
Section string
GroupItems map[string]map[string]edgeworkers.Item
}
)
var (
//go:embed templates/*
templateFiles embed.FS
// ErrFetchingEdgeKV is returned when fetching edgekv fails
ErrFetchingEdgeKV = errors.New("unable to fetch edgekv with given namespace_name and network")
// ErrFetchingEdgeKVItems is returned when fetching edgekv items fails
ErrFetchingEdgeKVItems = errors.New("unable to fetch edgekv items with given group id")
// ErrFetchingEdgeKVItem is returned when fetching edgekv item fails
ErrFetchingEdgeKVItem = errors.New("unable to fetch edgekv item with given group and item id")
// ErrFetchingEdgeKVGroups is returned when fetching edgekv groups fails
ErrFetchingEdgeKVGroups = errors.New("unable to fetch edgekv groups with given namespace_name and network")
)
// CmdCreateEdgeKV is an entrypoint to create-edgekv command
func CmdCreateEdgeKV(c *cli.Context) error {
ctx := c.Context
sess := edgegrid.GetSession(c.Context)
client := edgeworkers.Client(sess)
// tfWorkPath is a target directory for generated terraform resources
var tfWorkPath = "./"
if c.IsSet("tfworkpath") {
tfWorkPath = c.String("tfworkpath")
}
edgeKVPath := filepath.Join(tfWorkPath, "edgekv.tf")
variablesPath := filepath.Join(tfWorkPath, "variables.tf")
importPath := filepath.Join(tfWorkPath, "import.sh")
err := tools.CheckFiles(edgeKVPath, variablesPath, importPath)
if err != nil {
return cli.Exit(color.RedString(err.Error()), 1)
}
templateToFile := map[string]string{
"edgekv.tmpl": edgeKVPath,
"edgekv-variables.tmpl": variablesPath,
"edgekv-imports.tmpl": importPath,
}
processor := templates.FSTemplateProcessor{
TemplatesFS: templateFiles,
TemplateTargets: templateToFile,
AdditionalFuncs: template.FuncMap{
"ToLower": func(network edgeworkers.ActivationNetwork) string {
return strings.ToLower(string(network))
},
"Escape": tools.Escape,
},
}
namespace := c.Args().First()
network := edgeworkers.NamespaceNetwork(c.Args().Get(1))
section := edgegrid.GetEdgercSection(c)
if err = createEdgeKV(ctx, namespace, network, section, client, processor); err != nil {
return cli.Exit(color.RedString(fmt.Sprintf("Error exporting edgekv HCL: %s", err)), 1)
}
return nil
}
func createEdgeKV(ctx context.Context, namespace string, network edgeworkers.NamespaceNetwork, section string, client edgeworkers.Edgeworkers, templateProcessor templates.TemplateProcessor) error {
term := terminal.Get(ctx)
fmt.Println("Configuring EdgeKV")
term.Spinner().Start("Fetching EdgeKV %s", namespace)
edgeKV, err := getEdgeKV(ctx, namespace, network, client)
if err != nil {
term.Spinner().Fail()
return fmt.Errorf("%w: %s", ErrFetchingEdgeKV, err)
}
term.Spinner().OK()
term.Spinner().Start("Fetching EdgeKV groups in %s", namespace)
groupItems := make(map[string]map[string]edgeworkers.Item, 0)
edgeKVGroups, err := getEdgeKVGroups(ctx, namespace, network, client)
if err != nil {
term.Spinner().Fail()
return fmt.Errorf("%w: %s", ErrFetchingEdgeKV, err)
}
term.Spinner().OK()
term.Spinner().Start("Fetching EdgeKV items in groups in %s", namespace)
for _, group := range edgeKVGroups {
edgeKVItems, err := getEdgeKVItems(ctx, namespace, network, group, client)
if err != nil {
term.Spinner().Fail()
return fmt.Errorf("%w: %s", ErrFetchingEdgeKV, err)
}
items := make(map[string]edgeworkers.Item, 0)
for _, itemID := range *edgeKVItems {
item, err := getEdgeKVItem(ctx, namespace, network, group, itemID, client)
if err != nil {
term.Spinner().Fail()
return fmt.Errorf("%w: %s", ErrFetchingEdgeKV, err)
}
items[itemID] = *item
}
groupItems[group] = items
}
tfEdgeKVData := TFEdgeKVData{
Name: edgeKV.Name,
Network: network,
Retention: *edgeKV.Retention,
GeoLocation: edgeKV.GeoLocation,
Section: section,
GroupItems: groupItems,
}
// Only add GroupID if the API returns it
if edgeKV.GroupID != nil {
tfEdgeKVData.GroupID = *edgeKV.GroupID
}
term.Spinner().OK()
term.Spinner().Start("Saving TF configurations ")
if err := templateProcessor.ProcessTemplates(tfEdgeKVData); err != nil {
term.Spinner().Fail()
return fmt.Errorf("%w: %s", templates.ErrSavingFiles, err)
}
term.Spinner().OK()
fmt.Printf("Terraform configuration for edgeKV '%s' on network '%s' was saved successfully\n", edgeKV.Name, network)
return nil
}
func getEdgeKV(ctx context.Context, namespace string, network edgeworkers.NamespaceNetwork, client edgeworkers.Edgeworkers) (*edgeworkers.Namespace, error) {
edgeKV, err := client.GetEdgeKVNamespace(ctx, edgeworkers.GetEdgeKVNamespaceRequest{
Network: network,
Name: namespace,
})
if err != nil {
return nil, err
}
if edgeKV == nil {
return nil, fmt.Errorf("edgeKV '%s' on network '%s' does not exist", namespace, network)
}
return edgeKV, nil
}
func getEdgeKVItems(ctx context.Context, namespace string, network edgeworkers.NamespaceNetwork, groupID string, client edgeworkers.Edgeworkers) (*edgeworkers.ListItemsResponse, error) {
items, err := client.ListItems(ctx, edgeworkers.ListItemsRequest{
ItemsRequestParams: edgeworkers.ItemsRequestParams{
Network: edgeworkers.ItemNetwork(network),
NamespaceID: namespace,
GroupID: groupID,
},
})
if err != nil {
return nil, fmt.Errorf("%w: %s: %s", ErrFetchingEdgeKVItems, groupID, err)
}
return items, nil
}
func getEdgeKVItem(ctx context.Context, namespace string, network edgeworkers.NamespaceNetwork, groupID, itemID string, client edgeworkers.Edgeworkers) (*edgeworkers.Item, error) {
item, err := client.GetItem(ctx, edgeworkers.GetItemRequest{
ItemID: itemID,
ItemsRequestParams: edgeworkers.ItemsRequestParams{
Network: edgeworkers.ItemNetwork(network),
NamespaceID: namespace,
GroupID: groupID,
},
})
if err != nil {
return nil, fmt.Errorf("%w: %s,%s: %s", ErrFetchingEdgeKVItem, groupID, itemID, err)
}
return item, nil
}
func getEdgeKVGroups(ctx context.Context, namespace string, network edgeworkers.NamespaceNetwork, client edgeworkers.Edgeworkers) ([]string, error) {
items, err := client.ListGroupsWithinNamespace(ctx, edgeworkers.ListGroupsWithinNamespaceRequest{
Network: network,
NamespaceID: namespace,
})
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrFetchingEdgeKVGroups, err)
}
return items, nil
}