-
Notifications
You must be signed in to change notification settings - Fork 67
/
apply.go
99 lines (80 loc) 路 2.71 KB
/
apply.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
package resourcemanager
import (
"context"
"fmt"
"io"
"net/http"
"github.com/Jeffail/gabs/v2"
"github.com/kubeshop/tracetest/cli/pkg/fileutil"
)
const VerbApply Verb = "apply"
func (c client) Apply(ctx context.Context, filePath string, requestedFormat Format) (string, error) {
inputFile, err := fileutil.Read(filePath)
if err != nil {
return "", fmt.Errorf("cannot read file %s: %w", filePath, err)
}
url := c.client.url(c.resourceNamePlural)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, url.String(), inputFile.Reader())
if err != nil {
return "", fmt.Errorf("cannot build Apply request: %w", err)
}
// we want the response inthe user's requested format
err = requestedFormat.BuildRequest(req, VerbApply)
if err != nil {
return "", fmt.Errorf("cannot build Apply request: %w", err)
}
// the files must be in yaml format, so we can safely force the content type,
// even if it doesn't matcht he user's requested format
yamlFormat, err := Formats.Get(FormatYAML)
if err != nil {
return "", fmt.Errorf("cannot get json format: %w", err)
}
req.Header.Set("Content-Type", yamlFormat.ContentType())
// final request looks like this:
// PUT {server}/{resourceNamePlural}
// Content-Type: text/yaml
// Accept: {requestedFormat.contentType}
//
// {yamlFileContent}
//
// This means that we'll send the request body as YAML (read from the user provided file)
// and we'll get the reponse in the users's requrested format.
resp, err := c.client.do(req)
if err != nil {
return "", fmt.Errorf("cannot execute Apply request: %w", err)
}
defer resp.Body.Close()
if !isSuccessResponse(resp) {
err := parseRequestError(resp, requestedFormat)
return "", fmt.Errorf("could not Apply resource: %w", err)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("cannot read Apply response: %w", err)
}
// if the original file doesn't have an ID, we need to get the server generated ID from the response
// and write it to the original file
if !inputFile.HasID() {
jsonBody, err := requestedFormat.ToJSON(body)
if err != nil {
return "", fmt.Errorf("cannot convert response body to JSON format: %w", err)
}
parsed, err := gabs.ParseJSON(jsonBody)
if err != nil {
return "", fmt.Errorf("cannot parse Apply response: %w", err)
}
id, ok := parsed.Path("spec.id").Data().(string)
if !ok {
return "", fmt.Errorf("cannot get ID from Apply response")
}
inputFile, err = inputFile.SetID(id)
if err != nil {
return "", fmt.Errorf("cannot set ID on input file: %w", err)
}
_, err = inputFile.Write()
if err != nil {
return "", fmt.Errorf("cannot write updated input file: %w", err)
}
}
return requestedFormat.Format(string(body), c.tableConfig)
}