Skip to content

Commit f07275a

Browse files
committed
Add tests for Bridge/PGO integration code that hits the Bridge API.
1 parent e8bcff1 commit f07275a

File tree

10 files changed

+2550
-221
lines changed

10 files changed

+2550
-221
lines changed

cmd/postgres-operator/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func addControllersToManager(mgr manager.Manager, openshift bool, log logr.Logge
177177
}
178178

179179
if util.DefaultMutableFeatureGate.Enabled(util.CrunchyBridgeClusters) {
180-
constructor := func() *bridge.Client {
180+
constructor := func() bridge.ClientInterface {
181181
client := bridge.NewClient(os.Getenv("PGO_BRIDGE_URL"), versionString)
182182
client.Transport = otelTransportWrapper()(http.DefaultTransport)
183183
return client

internal/bridge/client.go

+74-42
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ const defaultAPI = "https://api.crunchybridge.com"
3838

3939
var errAuthentication = errors.New("authentication failed")
4040

41+
type ClientInterface interface {
42+
ListClusters(ctx context.Context, apiKey, teamId string) ([]*ClusterApiResource, error)
43+
CreateCluster(ctx context.Context, apiKey string, clusterRequestPayload *PostClustersRequestPayload) (*ClusterApiResource, error)
44+
DeleteCluster(ctx context.Context, apiKey, id string) (*ClusterApiResource, bool, error)
45+
GetCluster(ctx context.Context, apiKey, id string) (*ClusterApiResource, error)
46+
GetClusterStatus(ctx context.Context, apiKey, id string) (*ClusterStatusApiResource, error)
47+
GetClusterUpgrade(ctx context.Context, apiKey, id string) (*ClusterUpgradeApiResource, error)
48+
UpgradeCluster(ctx context.Context, apiKey, id string, clusterRequestPayload *PostClustersUpgradeRequestPayload) (*ClusterUpgradeApiResource, error)
49+
UpgradeClusterHA(ctx context.Context, apiKey, id, action string) (*ClusterUpgradeApiResource, error)
50+
UpdateCluster(ctx context.Context, apiKey, id string, clusterRequestPayload *PatchClustersRequestPayload) (*ClusterApiResource, error)
51+
GetClusterRole(ctx context.Context, apiKey, clusterId, roleName string) (*ClusterRoleApiResource, error)
52+
}
53+
4154
type Client struct {
4255
http.Client
4356
wait.Backoff
@@ -146,13 +159,30 @@ type ClusterUpgradeOperationApiResource struct {
146159
State string `json:"state,omitempty"`
147160
}
148161

162+
// ClusterRoleApiResource is used for retrieving details on ClusterRole from the Bridge API
163+
type ClusterRoleApiResource struct {
164+
AccountEmail string `json:"account_email"`
165+
AccountId string `json:"account_id"`
166+
ClusterId string `json:"cluster_id"`
167+
Flavor string `json:"flavor"`
168+
Name string `json:"name"`
169+
Password string `json:"password"`
170+
Team string `json:"team_id"`
171+
URI string `json:"uri"`
172+
}
173+
174+
// ClusterRoleList holds a slice of ClusterRoleApiResource
175+
type ClusterRoleList struct {
176+
Roles []*ClusterRoleApiResource `json:"roles"`
177+
}
178+
149179
// BRIDGE API REQUEST PAYLOADS
150180

151181
// PatchClustersRequestPayload is used for updating various properties of an existing cluster.
152182
type PatchClustersRequestPayload struct {
153183
ClusterGroup string `json:"cluster_group_id,omitempty"`
154184
// DashboardSettings *ClusterDashboardSettings `json:"dashboard_settings,omitempty"`
155-
// TODO: (dsessler7) Find docs for DashboardSettings and create appropriate struct
185+
// TODO: (crunchybridgecluster) Find docs for DashboardSettings and create appropriate struct
156186
Environment string `json:"environment,omitempty"`
157187
IsProtected *bool `json:"is_protected,omitempty"`
158188
MaintenanceWindowStart int64 `json:"maintenance_window_start,omitempty"`
@@ -194,23 +224,6 @@ type PutClustersUpgradeRequestPayload struct {
194224
UseMaintenanceWindow *bool `json:"use_cluster_maintenance_window,omitempty"`
195225
}
196226

197-
// ClusterRoleApiResource is used for retrieving details on ClusterRole from the Bridge API
198-
type ClusterRoleApiResource struct {
199-
AccountEmail string `json:"account_email"`
200-
AccountId string `json:"account_id"`
201-
ClusterId string `json:"cluster_id"`
202-
Flavor string `json:"flavor"`
203-
Name string `json:"name"`
204-
Password string `json:"password"`
205-
Team string `json:"team_id"`
206-
URI string `json:"uri"`
207-
}
208-
209-
// ClusterRoleList holds a slice of ClusterRoleApiResource
210-
type ClusterRoleList struct {
211-
Roles []*ClusterRoleApiResource `json:"roles"`
212-
}
213-
214227
// BRIDGE CLIENT FUNCTIONS AND METHODS
215228

216229
// NewClient creates a Client with backoff settings that amount to
@@ -415,9 +428,10 @@ func (c *Client) CreateInstallation(ctx context.Context) (Installation, error) {
415428
return result, err
416429
}
417430

418-
// TODO(crunchybridgecluster) Is this where we want CRUD for clusters functions? Or make client `do` funcs
419-
// directly callable?
431+
// CRUNCHYBRIDGECLUSTER CRUD METHODS
420432

433+
// ListClusters makes a GET request to the "/clusters" endpoint to retrieve a list of all clusters
434+
// in Bridge that are owned by the team specified by the provided team id.
421435
func (c *Client) ListClusters(ctx context.Context, apiKey, teamId string) ([]*ClusterApiResource, error) {
422436
result := &ClusterList{}
423437

@@ -450,6 +464,8 @@ func (c *Client) ListClusters(ctx context.Context, apiKey, teamId string) ([]*Cl
450464
return result.Clusters, err
451465
}
452466

467+
// CreateCluster makes a POST request to the "/clusters" endpoint thereby creating a cluster
468+
// in Bridge with the settings specified in the request payload.
453469
func (c *Client) CreateCluster(
454470
ctx context.Context, apiKey string, clusterRequestPayload *PostClustersRequestPayload,
455471
) (*ClusterApiResource, error) {
@@ -534,6 +550,8 @@ func (c *Client) DeleteCluster(ctx context.Context, apiKey, id string) (*Cluster
534550
return result, deletedAlready, err
535551
}
536552

553+
// GetCluster makes a GET request to the "/clusters/<id>" endpoint, thereby retrieving details
554+
// for a given cluster in Bridge specified by the provided cluster id.
537555
func (c *Client) GetCluster(ctx context.Context, apiKey, id string) (*ClusterApiResource, error) {
538556
result := &ClusterApiResource{}
539557

@@ -566,6 +584,8 @@ func (c *Client) GetCluster(ctx context.Context, apiKey, id string) (*ClusterApi
566584
return result, err
567585
}
568586

587+
// GetClusterStatus makes a GET request to the "/clusters/<id>/status" endpoint, thereby retrieving details
588+
// for a given cluster's status in Bridge, specified by the provided cluster id.
569589
func (c *Client) GetClusterStatus(ctx context.Context, apiKey, id string) (*ClusterStatusApiResource, error) {
570590
result := &ClusterStatusApiResource{}
571591

@@ -598,6 +618,8 @@ func (c *Client) GetClusterStatus(ctx context.Context, apiKey, id string) (*Clus
598618
return result, err
599619
}
600620

621+
// GetClusterUpgrade makes a GET request to the "/clusters/<id>/upgrade" endpoint, thereby retrieving details
622+
// for a given cluster's upgrade status in Bridge, specified by the provided cluster id.
601623
func (c *Client) GetClusterUpgrade(ctx context.Context, apiKey, id string) (*ClusterUpgradeApiResource, error) {
602624
result := &ClusterUpgradeApiResource{}
603625

@@ -630,6 +652,8 @@ func (c *Client) GetClusterUpgrade(ctx context.Context, apiKey, id string) (*Clu
630652
return result, err
631653
}
632654

655+
// UpgradeCluster makes a POST request to the "/clusters/<id>/upgrade" endpoint, thereby attempting
656+
// to upgrade certain settings for a given cluster in Bridge.
633657
func (c *Client) UpgradeCluster(
634658
ctx context.Context, apiKey, id string, clusterRequestPayload *PostClustersUpgradeRequestPayload,
635659
) (*ClusterUpgradeApiResource, error) {
@@ -669,6 +693,8 @@ func (c *Client) UpgradeCluster(
669693
return result, err
670694
}
671695

696+
// UpgradeClusterHA makes a PUT request to the "/clusters/<id>/actions/<action>" endpoint, thereby attempting
697+
// to change the HA setting for a given cluster in Bridge.
672698
func (c *Client) UpgradeClusterHA(ctx context.Context, apiKey, id, action string) (*ClusterUpgradeApiResource, error) {
673699
result := &ClusterUpgradeApiResource{}
674700

@@ -701,10 +727,19 @@ func (c *Client) UpgradeClusterHA(ctx context.Context, apiKey, id, action string
701727
return result, err
702728
}
703729

704-
func (c *Client) GetClusterRole(ctx context.Context, apiKey, clusterId, roleName string) (*ClusterRoleApiResource, error) {
705-
result := &ClusterRoleApiResource{}
730+
// UpdateCluster makes a PATCH request to the "/clusters/<id>" endpoint, thereby attempting to
731+
// update certain settings for a given cluster in Bridge.
732+
func (c *Client) UpdateCluster(
733+
ctx context.Context, apiKey, id string, clusterRequestPayload *PatchClustersRequestPayload,
734+
) (*ClusterApiResource, error) {
735+
result := &ClusterApiResource{}
706736

707-
response, err := c.doWithRetry(ctx, "GET", "/clusters/"+clusterId+"/roles/"+roleName, nil, nil, http.Header{
737+
clusterbyte, err := json.Marshal(clusterRequestPayload)
738+
if err != nil {
739+
return result, err
740+
}
741+
742+
response, err := c.doWithRetry(ctx, "PATCH", "/clusters/"+id, nil, clusterbyte, http.Header{
708743
"Accept": []string{"application/json"},
709744
"Authorization": []string{"Bearer " + apiKey},
710745
})
@@ -718,6 +753,10 @@ func (c *Client) GetClusterRole(ctx context.Context, apiKey, clusterId, roleName
718753
case response.StatusCode >= 200 && response.StatusCode < 300:
719754
if err = json.Unmarshal(body, &result); err != nil {
720755
err = fmt.Errorf("%w: %s", err, body)
756+
return result, err
757+
}
758+
if err = json.Unmarshal(body, &result.ResponsePayload); err != nil {
759+
err = fmt.Errorf("%w: %s", err, body)
721760
}
722761

723762
default:
@@ -729,10 +768,12 @@ func (c *Client) GetClusterRole(ctx context.Context, apiKey, clusterId, roleName
729768
return result, err
730769
}
731770

732-
func (c *Client) ListClusterRoles(ctx context.Context, apiKey, id string) ([]*ClusterRoleApiResource, error) {
733-
result := ClusterRoleList{}
771+
// GetClusterRole sends a GET request to the "/clusters/<id>/roles/<roleName>" endpoint, thereby retrieving
772+
// Role information for a specific role from a specific cluster in Bridge.
773+
func (c *Client) GetClusterRole(ctx context.Context, apiKey, clusterId, roleName string) (*ClusterRoleApiResource, error) {
774+
result := &ClusterRoleApiResource{}
734775

735-
response, err := c.doWithRetry(ctx, "GET", "/clusters/"+id+"/roles", nil, nil, http.Header{
776+
response, err := c.doWithRetry(ctx, "GET", "/clusters/"+clusterId+"/roles/"+roleName, nil, nil, http.Header{
736777
"Accept": []string{"application/json"},
737778
"Authorization": []string{"Bearer " + apiKey},
738779
})
@@ -754,20 +795,15 @@ func (c *Client) ListClusterRoles(ctx context.Context, apiKey, id string) ([]*Cl
754795
}
755796
}
756797

757-
return result.Roles, err
798+
return result, err
758799
}
759800

760-
func (c *Client) UpdateCluster(
761-
ctx context.Context, apiKey, id string, clusterRequestPayload *PatchClustersRequestPayload,
762-
) (*ClusterApiResource, error) {
763-
result := &ClusterApiResource{}
764-
765-
clusterbyte, err := json.Marshal(clusterRequestPayload)
766-
if err != nil {
767-
return result, err
768-
}
801+
// ListClusterRoles sends a GET request to the "/clusters/<id>/roles" endpoint thereby retrieving
802+
// a list of all cluster roles for a specific cluster in Bridge.
803+
func (c *Client) ListClusterRoles(ctx context.Context, apiKey, id string) ([]*ClusterRoleApiResource, error) {
804+
result := ClusterRoleList{}
769805

770-
response, err := c.doWithRetry(ctx, "PATCH", "/clusters/"+id, nil, clusterbyte, http.Header{
806+
response, err := c.doWithRetry(ctx, "GET", "/clusters/"+id+"/roles", nil, nil, http.Header{
771807
"Accept": []string{"application/json"},
772808
"Authorization": []string{"Bearer " + apiKey},
773809
})
@@ -781,10 +817,6 @@ func (c *Client) UpdateCluster(
781817
case response.StatusCode >= 200 && response.StatusCode < 300:
782818
if err = json.Unmarshal(body, &result); err != nil {
783819
err = fmt.Errorf("%w: %s", err, body)
784-
return result, err
785-
}
786-
if err = json.Unmarshal(body, &result.ResponsePayload); err != nil {
787-
err = fmt.Errorf("%w: %s", err, body)
788820
}
789821

790822
default:
@@ -793,5 +825,5 @@ func (c *Client) UpdateCluster(
793825
}
794826
}
795827

796-
return result, err
828+
return result.Roles, err
797829
}

0 commit comments

Comments
 (0)