/
droplet.go
105 lines (86 loc) · 3.22 KB
/
droplet.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
package handlers
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/go-logr/logr"
"code.cloudfoundry.org/korifi/api/authorization"
apierrors "code.cloudfoundry.org/korifi/api/errors"
"code.cloudfoundry.org/korifi/api/payloads"
"code.cloudfoundry.org/korifi/api/presenter"
"code.cloudfoundry.org/korifi/api/repositories"
"code.cloudfoundry.org/korifi/api/routing"
)
const (
DropletPath = "/v3/droplets/{guid}"
)
//counterfeiter:generate -o fake -fake-name CFDropletRepository . CFDropletRepository
type CFDropletRepository interface {
GetDroplet(context.Context, authorization.Info, string) (repositories.DropletRecord, error)
ListDroplets(context.Context, authorization.Info, repositories.ListDropletsMessage) ([]repositories.DropletRecord, error)
UpdateDroplet(context.Context, authorization.Info, repositories.UpdateDropletMessage) (repositories.DropletRecord, error)
}
type Droplet struct {
serverURL url.URL
dropletRepo CFDropletRepository
requestValidator RequestValidator
}
func NewDroplet(
serverURL url.URL,
dropletRepo CFDropletRepository,
requestValidator RequestValidator,
) *Droplet {
return &Droplet{
serverURL: serverURL,
dropletRepo: dropletRepo,
requestValidator: requestValidator,
}
}
func (h *Droplet) get(r *http.Request) (*routing.Response, error) {
authInfo, _ := authorization.InfoFromContext(r.Context())
logger := logr.FromContextOrDiscard(r.Context()).WithName("handlers.droplet.get")
dropletGUID := routing.URLParam(r, "guid")
droplet, err := h.dropletRepo.GetDroplet(r.Context(), authInfo, dropletGUID)
if err != nil {
return nil, apierrors.LogAndReturn(
logger,
apierrors.ForbiddenAsNotFound(err),
fmt.Sprintf("Failed to fetch %s from Kubernetes", repositories.DropletResourceType),
"guid", dropletGUID,
)
}
return routing.NewResponse(http.StatusOK).WithBody(presenter.ForDroplet(droplet, h.serverURL)), nil
}
func (h *Droplet) update(r *http.Request) (*routing.Response, error) {
authInfo, _ := authorization.InfoFromContext(r.Context())
logger := logr.FromContextOrDiscard(r.Context()).WithName("handlers.droplet.update")
dropletGUID := routing.URLParam(r, "guid")
var payload payloads.DropletUpdate
if err := h.requestValidator.DecodeAndValidateJSONPayload(r, &payload); err != nil {
return nil, apierrors.LogAndReturn(logger, err, "failed to decode payload")
}
_, err := h.dropletRepo.GetDroplet(r.Context(), authInfo, dropletGUID)
if err != nil {
return nil, apierrors.LogAndReturn(
logger,
apierrors.ForbiddenAsNotFound(err),
fmt.Sprintf("Failed to fetch %s from Kubernetes", repositories.DropletResourceType),
"guid", dropletGUID,
)
}
droplet, err := h.dropletRepo.UpdateDroplet(r.Context(), authInfo, payload.ToMessage(dropletGUID))
if err != nil {
return nil, apierrors.LogAndReturn(logger, err, "Error updating droplet in repository")
}
return routing.NewResponse(http.StatusOK).WithBody(presenter.ForDroplet(droplet, h.serverURL)), nil
}
func (h *Droplet) UnauthenticatedRoutes() []routing.Route {
return nil
}
func (h *Droplet) AuthenticatedRoutes() []routing.Route {
return []routing.Route{
{Method: "GET", Pattern: DropletPath, Handler: h.get},
{Method: "PATCH", Pattern: DropletPath, Handler: h.update},
}
}