Skip to content

Commit bd78b5c

Browse files
committed
feat: create shared reservation
1 parent fcc49d3 commit bd78b5c

File tree

4 files changed

+217
-46
lines changed

4 files changed

+217
-46
lines changed

compute/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
cloud.google.com/go/storage v1.43.0
88
github.com/GoogleCloudPlatform/golang-samples v0.0.0-20240724083556-7f760db013b7
99
github.com/google/uuid v1.6.0
10+
github.com/googleapis/gax-go/v2 v2.13.0
1011
google.golang.org/api v0.193.0
1112
google.golang.org/protobuf v1.34.2
1213
)
@@ -23,7 +24,6 @@ require (
2324
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
2425
github.com/google/s2a-go v0.1.8 // indirect
2526
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
26-
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
2727
go.opencensus.io v0.24.0 // indirect
2828
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.52.0 // indirect
2929
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package snippets
16+
17+
// [START compute_reservation_create_shared]
18+
import (
19+
"context"
20+
"fmt"
21+
"io"
22+
23+
compute "cloud.google.com/go/compute/apiv1"
24+
computepb "cloud.google.com/go/compute/apiv1/computepb"
25+
gax "github.com/googleapis/gax-go/v2"
26+
"google.golang.org/protobuf/proto"
27+
)
28+
29+
type ClientInterface interface {
30+
Close() error
31+
Delete(context.Context, *computepb.DeleteReservationRequest, ...gax.CallOption) (*compute.Operation, error)
32+
Insert(context.Context, *computepb.InsertReservationRequest, ...gax.CallOption) (*compute.Operation, error)
33+
}
34+
35+
// Creates shared reservation from given template in particular zone
36+
func createSharedReservation(w io.Writer, client ClientInterface, projectID, baseProjectId, zone, reservationName, sourceTemplate string) error {
37+
// client, err := compute.NewReservationsRESTClient(ctx)
38+
// projectID := "your_project_id". Destination of sharing.
39+
// baseProjectId := "your_project_id2". Project where the reservation will be created.
40+
// zone := "us-west3-a"
41+
// reservationName := "your_reservation_name"
42+
// sourceTemplate: existing template path. Following formats are allowed:
43+
// - projects/{project_id}/global/instanceTemplates/{template_name}
44+
// - projects/{project_id}/regions/{region}/instanceTemplates/{template_name}
45+
// - https://www.googleapis.com/compute/v1/projects/{project_id}/global/instanceTemplates/instanceTemplate
46+
// - https://www.googleapis.com/compute/v1/projects/{project_id}/regions/{region}/instanceTemplates/instanceTemplate
47+
48+
ctx := context.Background()
49+
50+
shareSettings := map[string]*computepb.ShareSettingsProjectConfig{
51+
projectID: {ProjectId: proto.String(projectID)},
52+
}
53+
54+
req := &computepb.InsertReservationRequest{
55+
Project: baseProjectId,
56+
ReservationResource: &computepb.Reservation{
57+
Name: proto.String(reservationName),
58+
Zone: proto.String(zone),
59+
SpecificReservation: &computepb.AllocationSpecificSKUReservation{
60+
Count: proto.Int64(2),
61+
SourceInstanceTemplate: proto.String(sourceTemplate),
62+
},
63+
ShareSettings: &computepb.ShareSettings{
64+
ProjectMap: shareSettings,
65+
ShareType: proto.String("SPECIFIC_PROJECTS"),
66+
},
67+
},
68+
Zone: zone,
69+
}
70+
71+
op, err := client.Insert(ctx, req)
72+
if err != nil {
73+
return fmt.Errorf("unable to create reservation: %w", err)
74+
}
75+
76+
if op != nil {
77+
if err = op.Wait(ctx); err != nil {
78+
return fmt.Errorf("unable to wait for the operation: %w", err)
79+
}
80+
}
81+
82+
fmt.Fprintf(w, "Reservation created\n")
83+
84+
return nil
85+
}
86+
87+
// [END compute_reservation_create_shared]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Mock objects for shared project
16+
17+
package snippets
18+
19+
import (
20+
"context"
21+
22+
compute "cloud.google.com/go/compute/apiv1"
23+
computepb "cloud.google.com/go/compute/apiv1/computepb"
24+
gax "github.com/googleapis/gax-go/v2"
25+
)
26+
27+
type ReservationsClient struct{}
28+
29+
func (client ReservationsClient) Close() error {
30+
return nil
31+
}
32+
33+
func (client ReservationsClient) Insert(context.Context, *computepb.InsertReservationRequest, ...gax.CallOption) (*compute.Operation, error) {
34+
return nil, nil
35+
}
36+
37+
func (client ReservationsClient) Delete(context.Context, *computepb.DeleteReservationRequest, ...gax.CallOption) (*compute.Operation, error) {
38+
return nil, nil
39+
}

compute/reservations/reservations_test.go

Lines changed: 90 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -108,49 +108,94 @@ func TestReservations(t *testing.T) {
108108

109109
var buf bytes.Buffer
110110

111-
err := createTemplate(tc.ProjectID, templateName)
112-
if err != nil {
113-
t.Errorf("createTemplate got err: %v", err)
114-
}
115-
defer deleteTemplate(tc.ProjectID, templateName)
116-
117-
sourceTemplate, err := getTemplate(tc.ProjectID, templateName)
118-
if err != nil {
119-
t.Errorf("getTemplate got err: %v", err)
120-
}
121-
122-
want := "Reservation created"
123-
if err := createReservation(&buf, tc.ProjectID, zone, reservationName, *sourceTemplate.SelfLink); err != nil {
124-
t.Errorf("createReservation got err: %v", err)
125-
}
126-
if got := buf.String(); !strings.Contains(got, want) {
127-
t.Errorf("createReservation got %s, want %s", got, want)
128-
}
129-
buf.Reset()
130-
131-
want = fmt.Sprintf("Reservation: %s", reservationName)
132-
if err := getReservation(&buf, tc.ProjectID, zone, reservationName); err != nil {
133-
t.Errorf("getReservation got err: %v", err)
134-
}
135-
if got := buf.String(); !strings.Contains(got, want) {
136-
t.Errorf("getReservation got %s, want %s", got, want)
137-
}
138-
buf.Reset()
139-
140-
want = fmt.Sprintf("- %s %d", reservationName, 2)
141-
if err := listReservations(&buf, tc.ProjectID, zone); err != nil {
142-
t.Errorf("listReservations got err: %v", err)
143-
}
144-
if got := buf.String(); !strings.Contains(got, want) {
145-
t.Errorf("listReservations got %s, want %s", got, want)
146-
}
147-
buf.Reset()
148-
149-
want = "Reservation deleted"
150-
if err := deleteReservation(&buf, tc.ProjectID, zone, reservationName); err != nil {
151-
t.Errorf("deleteReservation got err: %v", err)
152-
}
153-
if got := buf.String(); !strings.Contains(got, want) {
154-
t.Errorf("deleteReservation got %s, want %s", got, want)
155-
}
111+
t.Run("Reservation CRUD", func(t *testing.T) {
112+
err := createTemplate(tc.ProjectID, templateName)
113+
if err != nil {
114+
t.Errorf("createTemplate got err: %v", err)
115+
}
116+
defer deleteTemplate(tc.ProjectID, templateName)
117+
118+
sourceTemplate, err := getTemplate(tc.ProjectID, templateName)
119+
if err != nil {
120+
t.Errorf("getTemplate got err: %v", err)
121+
}
122+
123+
want := "Reservation created"
124+
if err := createReservation(&buf, tc.ProjectID, zone, reservationName, *sourceTemplate.SelfLink); err != nil {
125+
t.Errorf("createReservation got err: %v", err)
126+
}
127+
if got := buf.String(); !strings.Contains(got, want) {
128+
t.Errorf("createReservation got %s, want %s", got, want)
129+
}
130+
buf.Reset()
131+
132+
want = fmt.Sprintf("Reservation: %s", reservationName)
133+
if err := getReservation(&buf, tc.ProjectID, zone, reservationName); err != nil {
134+
t.Errorf("getReservation got err: %v", err)
135+
}
136+
if got := buf.String(); !strings.Contains(got, want) {
137+
t.Errorf("getReservation got %s, want %s", got, want)
138+
}
139+
buf.Reset()
140+
141+
want = fmt.Sprintf("- %s %d", reservationName, 2)
142+
if err := listReservations(&buf, tc.ProjectID, zone); err != nil {
143+
t.Errorf("listReservations got err: %v", err)
144+
}
145+
if got := buf.String(); !strings.Contains(got, want) {
146+
t.Errorf("listReservations got %s, want %s", got, want)
147+
}
148+
buf.Reset()
149+
150+
want = "Reservation deleted"
151+
if err := deleteReservation(&buf, tc.ProjectID, zone, reservationName); err != nil {
152+
t.Errorf("deleteReservation got err: %v", err)
153+
}
154+
if got := buf.String(); !strings.Contains(got, want) {
155+
t.Errorf("deleteReservation got %s, want %s", got, want)
156+
}
157+
})
158+
159+
t.Run("Shared reservation CRUD", func(t *testing.T) {
160+
baseProjectId := "softserve-shared"
161+
err := createTemplate(baseProjectId, templateName)
162+
if err != nil {
163+
t.Errorf("createTemplate got err: %v", err)
164+
}
165+
defer deleteTemplate(baseProjectId, templateName)
166+
167+
sourceTemplate, err := getTemplate(baseProjectId, templateName)
168+
if err != nil {
169+
t.Errorf("getTemplate got err: %v", err)
170+
}
171+
172+
want := "Reservation created"
173+
174+
ctx := context.Background()
175+
reservationsClient := ReservationsClient{}
176+
// reservationsClient, err := compute.NewReservationsRESTClient(ctx)
177+
if err != nil {
178+
t.Errorf("Couldn't create reservationsClient, err: %v", err)
179+
}
180+
defer reservationsClient.Close()
181+
182+
if err := createSharedReservation(&buf, reservationsClient, tc.ProjectID, baseProjectId, zone, reservationName, *sourceTemplate.SelfLink); err != nil {
183+
t.Errorf("createSharedReservation got err: %v", err)
184+
}
185+
if got := buf.String(); !strings.Contains(got, want) {
186+
t.Errorf("createSharedReservation got %s, want %s", got, want)
187+
}
188+
buf.Reset()
189+
190+
req := &computepb.DeleteReservationRequest{
191+
Project: baseProjectId,
192+
Reservation: reservationName,
193+
Zone: zone,
194+
}
195+
196+
_, err = reservationsClient.Delete(ctx, req)
197+
if err != nil {
198+
t.Errorf("unable to delete reservation: %v", err)
199+
}
200+
})
156201
}

0 commit comments

Comments
 (0)