forked from kyma-project/control-plane
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
123 lines (103 loc) · 3.3 KB
/
client.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
package broker
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"github.com/kyma-project/control-plane/components/kyma-environment-broker/internal"
"github.com/pkg/errors"
"golang.org/x/oauth2/clientcredentials"
"k8s.io/apimachinery/pkg/util/wait"
log "github.com/sirupsen/logrus"
)
const (
kymaClassID = "47c9dcbf-ff30-448e-ab36-d3bad66ba281"
instancesURL = "/oauth/v2/service_instances"
deprovisionTmpl = "%s%s/%s?service_id=%s&plan_id=%s"
)
type ClientConfig struct {
URL string
TokenURL string
ClientID string
ClientSecret string
Scope string
}
type Client struct {
brokerConfig ClientConfig
httpClient *http.Client
}
func NewClient(ctx context.Context, config ClientConfig) *Client {
cfg := clientcredentials.Config{
ClientID: config.ClientID,
ClientSecret: config.ClientSecret,
TokenURL: config.TokenURL,
Scopes: []string{config.Scope},
}
httpClientOAuth := cfg.Client(ctx)
httpClientOAuth.Timeout = 30 * time.Second
return &Client{
brokerConfig: config,
httpClient: httpClientOAuth,
}
}
type deprovisionResponse struct {
Operation string `json:"operation"`
}
// Deprovision requests Runtime deprovisioning in KEB with given details
func (c *Client) Deprovision(instance internal.Instance) (string, error) {
deprovisionURL, err := c.formatDeprovisionUrl(instance)
if err != nil {
return "", err
}
response := deprovisionResponse{}
log.Infof("Requesting deprovisioning of the environment with instance id: %q", instance.InstanceID)
err = wait.Poll(time.Second, time.Second*5, func() (bool, error) {
err := c.executeRequest(http.MethodDelete, deprovisionURL, http.StatusAccepted, nil, &response)
if err != nil {
log.Warn(errors.Wrap(err, "while executing request").Error())
return false, nil
}
return true, nil
})
if err != nil {
return "", errors.Wrap(err, "while waiting for successful deprovision call")
}
return response.Operation, nil
}
func (c *Client) formatDeprovisionUrl(instance internal.Instance) (string, error) {
if len(instance.ServicePlanID) == 0 {
return "", errors.Errorf("empty ServicePlanID")
}
return fmt.Sprintf(deprovisionTmpl, c.brokerConfig.URL, instancesURL, instance.InstanceID, kymaClassID, instance.ServicePlanID), nil
}
func (c *Client) executeRequest(method, url string, expectedStatus int, body io.Reader, responseBody interface{}) error {
request, err := http.NewRequest(method, url, body)
if err != nil {
return errors.Wrap(err, "while creating request for provisioning")
}
request.Header.Set("X-Broker-API-Version", "2.14")
resp, err := c.httpClient.Do(request)
if err != nil {
return errors.Wrapf(err, "while executing request URL: %s", url)
}
defer c.warnOnError(resp.Body.Close)
if resp.StatusCode != expectedStatus {
return errors.Errorf("got unexpected status code while calling Kyma Environment Broker: want: %d, got: %d", expectedStatus, resp.StatusCode)
}
err = json.NewDecoder(resp.Body).Decode(responseBody)
if err != nil {
return errors.Wrapf(err, "while decoding body")
}
return nil
}
func (c *Client) warnOnError(do func() error) {
if err := do(); err != nil {
log.Warn(err.Error())
}
}
// setHttpClient auxiliary method of testing to get rid of oAuth client wrapper
func (c *Client) setHttpClient(httpClient *http.Client) {
c.httpClient = httpClient
}