Skip to content

Commit 8f97467

Browse files
Implemented compute_disk_create_with_snapshot_schedule sample, created test
1 parent 484fce8 commit 8f97467

File tree

5 files changed

+303
-4
lines changed

5 files changed

+303
-4
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package compute.disks;
18+
19+
// [START compute_disk_create_with_snapshot_schedule]
20+
import com.google.cloud.compute.v1.Disk;
21+
import com.google.cloud.compute.v1.DisksClient;
22+
import com.google.cloud.compute.v1.Operation;
23+
import java.io.IOException;
24+
import java.util.List;
25+
import java.util.concurrent.ExecutionException;
26+
import java.util.concurrent.TimeUnit;
27+
import java.util.concurrent.TimeoutException;
28+
29+
public class CreateDiskWithSnapshotSchedule {
30+
public static void main(String[] args)
31+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
32+
// TODO(developer): Replace these variables before running the sample.
33+
// Project ID or project number of the Cloud project you want to use.
34+
String projectId = "YOUR_PROJECT_ID";
35+
// Name of the zone in which you want to create the disk.
36+
String zone = "us-central1-a";
37+
// Name of the disk you want to create.
38+
String diskName = "YOUR_DISK_NAME";
39+
// Name of the schedule you want to link to the disk.
40+
String scheduleName = "YOUR_SCHEDULE_NAME";
41+
42+
createDiskWithSnapshotSchedule(projectId, zone, diskName, scheduleName);
43+
}
44+
45+
// Creates disk with linked snapshot schedule.
46+
public static Operation.Status createDiskWithSnapshotSchedule(
47+
String projectId, String zone, String diskName, String scheduleName)
48+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
49+
try (DisksClient disksClient = DisksClient.create()) {
50+
51+
// Get the resource policy to link to the disk
52+
String resourcePolicyLink = String.format("projects/%s/regions/%s/resourcePolicies/%s",
53+
projectId, zone.substring(0, zone.lastIndexOf('-')), scheduleName);
54+
55+
Disk disk = Disk.newBuilder()
56+
.setName(diskName)
57+
.setZone(zone)
58+
.addAllResourcePolicies(List.of(resourcePolicyLink))
59+
.build();
60+
61+
Operation response = disksClient.insertAsync(projectId, zone, disk).get(3, TimeUnit.MINUTES);
62+
63+
if (response.hasError()) {
64+
System.out.printf("Disk creation failed: %s%n", response.getError());
65+
return null;
66+
}
67+
return response.getStatus();
68+
}
69+
}
70+
}
71+
// [END compute_disk_create_with_snapshot_schedule]
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package compute.snapshot;
18+
19+
// [START compute_snapshot_schedule_create]
20+
import com.google.cloud.compute.v1.Operation;
21+
import com.google.cloud.compute.v1.ResourcePoliciesClient;
22+
import com.google.cloud.compute.v1.ResourcePolicy;
23+
import com.google.cloud.compute.v1.ResourcePolicyHourlyCycle;
24+
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicy;
25+
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicyRetentionPolicy;
26+
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySchedule;
27+
import com.google.cloud.compute.v1.ResourcePolicySnapshotSchedulePolicySnapshotProperties;
28+
import java.io.IOException;
29+
import java.util.concurrent.ExecutionException;
30+
import java.util.concurrent.TimeUnit;
31+
import java.util.concurrent.TimeoutException;
32+
33+
public class CreateSnapshotSchedule {
34+
public static void main(String[] args)
35+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
36+
// TODO(developer): Replace these variables before running the sample.
37+
// Project ID or project number of the Cloud project you want to use.
38+
String projectId = "YOUR_PROJECT_ID";
39+
// Name of the region in which you want to create the snapshot schedule.
40+
String region = "us-central1";
41+
// Name of the snapshot schedule you want to create.
42+
String scheduleName = "YOUR_SCHEDULE_NAME";
43+
// Description of the snapshot schedule.
44+
String scheduleDescription = "YOUR_SCHEDULE_DESCRIPTION";
45+
// Maximum number of days to retain snapshots.
46+
int maxRetentionDays = 10;
47+
// Storage location for the snapshots.
48+
// More about storage locations:
49+
// https://cloud.google.com/compute/docs/disks/snapshots?authuser=0#selecting_a_storage_location
50+
String storageLocation = "US";
51+
// Determines what happens to your snapshots if the source disk is deleted.
52+
String onSourceDiskDelete = "KEEP_AUTO_SNAPSHOTS";
53+
54+
createSnapshotSchedule(projectId, region, scheduleName, scheduleDescription, maxRetentionDays,
55+
storageLocation, onSourceDiskDelete);
56+
}
57+
58+
// Creates a snapshot schedule policy.
59+
public static Operation.Status createSnapshotSchedule(String projectId, String region,
60+
String scheduleName, String scheduleDescription, int maxRetentionDays,
61+
String storageLocation, String onSourceDiskDelete)
62+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
63+
String startTime = "08:00";
64+
ResourcePolicySnapshotSchedulePolicySnapshotProperties snapshotProperties =
65+
ResourcePolicySnapshotSchedulePolicySnapshotProperties.newBuilder()
66+
.addStorageLocations(storageLocation)
67+
.build();
68+
69+
// Define the hourly schedule:
70+
int snapshotInterval = 10; // Create a snapshot every 10 hours
71+
ResourcePolicyHourlyCycle hourlyCycle = ResourcePolicyHourlyCycle.newBuilder()
72+
.setHoursInCycle(snapshotInterval)
73+
.setStartTime(startTime)
74+
.build();
75+
76+
// Define the daily schedule.
77+
// ResourcePolicyDailyCycle dailySchedule =
78+
// ResourcePolicyDailyCycle.newBuilder()
79+
// .setDaysInCycle(1) // Every day
80+
// .setStartTime(startTime)
81+
// .build();
82+
83+
// Define the weekly schedule.
84+
// List<ResourcePolicyWeeklyCycleDayOfWeek> dayOfWeeks = new ArrayList<>();
85+
// ResourcePolicyWeeklyCycleDayOfWeek tuesdaySchedule =
86+
// ResourcePolicyWeeklyCycleDayOfWeek.newBuilder()
87+
// .setDay(ResourcePolicyWeeklyCycleDayOfWeek.Day.TUESDAY.toString())
88+
// .setStartTime(startTime)
89+
// .build();
90+
// dayOfWeeks.add(tuesdaySchedule);
91+
//
92+
// ResourcePolicyWeeklyCycle weeklyCycle = ResourcePolicyWeeklyCycle.newBuilder()
93+
// .addAllDayOfWeeks(dayOfWeeks)
94+
// .build();
95+
96+
ResourcePolicySnapshotSchedulePolicyRetentionPolicy retentionPolicy =
97+
ResourcePolicySnapshotSchedulePolicyRetentionPolicy.newBuilder()
98+
.setMaxRetentionDays(maxRetentionDays)
99+
.setOnSourceDiskDelete(onSourceDiskDelete)
100+
.build();
101+
102+
ResourcePolicySnapshotSchedulePolicy snapshotSchedulePolicy =
103+
ResourcePolicySnapshotSchedulePolicy.newBuilder()
104+
.setRetentionPolicy(retentionPolicy)
105+
.setSchedule(ResourcePolicySnapshotSchedulePolicySchedule.newBuilder()
106+
// You can set only one of the following options:
107+
.setHourlySchedule(hourlyCycle) //Set Hourly Schedule
108+
// .setDailySchedule(dailySchedule) //Set Daily Schedule
109+
// .setWeeklySchedule(weeklyCycle) // Set Weekly Schedule
110+
.build())
111+
.setSnapshotProperties(snapshotProperties)
112+
.build();
113+
114+
ResourcePolicy resourcePolicy = ResourcePolicy.newBuilder()
115+
.setName(scheduleName)
116+
.setDescription(scheduleDescription)
117+
.setSnapshotSchedulePolicy(snapshotSchedulePolicy)
118+
.build();
119+
120+
// Initialize client that will be used to send requests. This client only needs to be created
121+
// once, and can be reused for multiple requests.
122+
try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) {
123+
124+
Operation response = resourcePoliciesClient.insertAsync(projectId, region, resourcePolicy)
125+
.get(3, TimeUnit.MINUTES);
126+
127+
if (response.hasError()) {
128+
System.out.printf("Snapshot schedule creation failed: %s%n", response.getError());
129+
return null;
130+
}
131+
return response.getStatus();
132+
}
133+
}
134+
}
135+
// [END compute_snapshot_schedule_create]
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package compute.snapshot;
18+
19+
// [START compute_snapshot_schedule_delete]
20+
import com.google.cloud.compute.v1.ResourcePoliciesClient;
21+
import java.io.IOException;
22+
import java.util.concurrent.ExecutionException;
23+
import java.util.concurrent.TimeUnit;
24+
import java.util.concurrent.TimeoutException;
25+
26+
public class DeleteSnapshotSchedule {
27+
public static void main(String[] args)
28+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
29+
// TODO(developer): Replace these variables before running the sample.
30+
// Project ID or project number of the Cloud project you want to use.
31+
String projectId = "YOUR_PROJECT_ID";
32+
// Name of the region where your snapshot schedule is located.
33+
String region = "us-central1";
34+
// Name of the snapshot schedule you want to delete.
35+
String scheduleName = "YOUR_SCHEDULE_NAME";
36+
37+
deleteSnapshotSchedule(projectId, region, scheduleName);
38+
}
39+
40+
// Deletes a snapshot schedule policy.
41+
public static void deleteSnapshotSchedule(String projectId, String region, String scheduleName)
42+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
43+
44+
try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) {
45+
resourcePoliciesClient.deleteAsync(projectId, region, scheduleName).get(3, TimeUnit.MINUTES);
46+
47+
System.out.println("Snapshot schedule deleted successfully: " + scheduleName);
48+
}
49+
}
50+
}
51+
// [END compute_snapshot_schedule_delete]

compute/cloud-client/src/test/java/compute/Util.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package compute;
1818

19+
import static compute.snapshot.DeleteSnapshotSchedule.deleteSnapshotSchedule;
20+
1921
import com.google.cloud.compute.v1.DeleteStoragePoolRequest;
2022
import com.google.cloud.compute.v1.Disk;
2123
import com.google.cloud.compute.v1.DisksClient;
@@ -30,6 +32,8 @@
3032
import com.google.cloud.compute.v1.RegionInstanceTemplatesClient;
3133
import com.google.cloud.compute.v1.Reservation;
3234
import com.google.cloud.compute.v1.ReservationsClient;
35+
import com.google.cloud.compute.v1.ResourcePoliciesClient;
36+
import com.google.cloud.compute.v1.ResourcePolicy;
3337
import com.google.cloud.compute.v1.Snapshot;
3438
import com.google.cloud.compute.v1.SnapshotsClient;
3539
import com.google.cloud.compute.v1.StoragePool;
@@ -39,6 +43,7 @@
3943
import compute.disks.DeleteSnapshot;
4044
import compute.reservation.DeleteReservation;
4145
import java.io.IOException;
46+
import java.lang.Error;
4247
import java.nio.charset.StandardCharsets;
4348
import java.security.SecureRandom;
4449
import java.time.Instant;
@@ -266,6 +271,21 @@ public static void deleteStoragePool(String project, String zone, String storage
266271
}
267272
}
268273

274+
// Delete storagePools which starts with the given prefixToDelete and
275+
// has creation timestamp >24 hours.
276+
public static void cleanUpExistingSnapshotSchedule(
277+
String prefixToDelete, String projectId, String region)
278+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
279+
try (ResourcePoliciesClient resourcePoliciesClient = ResourcePoliciesClient.create()) {
280+
for (ResourcePolicy resource : resourcePoliciesClient.list(projectId, region).iterateAll()) {
281+
if (containPrefixToDeleteAndZone(resource, prefixToDelete, region)
282+
&& isCreatedBeforeThresholdTime(resource.getCreationTimestamp())) {
283+
deleteSnapshotSchedule(projectId, region, resource.getName());
284+
}
285+
}
286+
}
287+
}
288+
269289
public static boolean containPrefixToDeleteAndZone(
270290
Object resource, String prefixToDelete, String zone) {
271291
boolean containPrefixAndZone = false;
@@ -291,6 +311,11 @@ public static boolean containPrefixToDeleteAndZone(
291311
containPrefixAndZone = ((StoragePool) resource).getName().contains(prefixToDelete)
292312
&& ((StoragePool) resource).getZone().contains(zone);
293313
}
314+
if (resource instanceof ResourcePolicy) {
315+
containPrefixAndZone = ((ResourcePolicy) resource).getName().contains(prefixToDelete)
316+
&& ((ResourcePolicy) resource).getRegion()
317+
.contains(zone.substring(0, zone.lastIndexOf('-')));
318+
}
294319
} catch (NullPointerException e) {
295320
System.out.println("Resource not found, skipping deletion:");
296321
}

compute/cloud-client/src/test/java/compute/disks/DisksIT.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import com.google.cloud.compute.v1.SnapshotsClient;
3636
import compute.DeleteInstance;
3737
import compute.Util;
38+
import compute.snapshot.CreateSnapshotSchedule;
39+
import compute.snapshot.DeleteSnapshotSchedule;
3840
import java.io.ByteArrayOutputStream;
3941
import java.io.IOException;
4042
import java.io.PrintStream;
@@ -69,11 +71,10 @@ public class DisksIT {
6971
private static String EMPTY_DISK_NAME;
7072
private static String SNAPSHOT_NAME;
7173
private static String DISK_TYPE;
72-
7374
private static String ZONAL_BLANK_DISK;
74-
7575
private static String REGIONAL_BLANK_DISK;
76-
76+
private static String DISK_WITH_SNAPSHOT_SCHEDULE;
77+
private static String SNAPSHOT_SCHEDULE;
7778
private ByteArrayOutputStream stdOut;
7879

7980
// Check if the required environment variables are set.
@@ -101,11 +102,14 @@ public static void setup()
101102
DISK_TYPE = String.format("zones/%s/diskTypes/pd-ssd", ZONE);
102103
ZONAL_BLANK_DISK = "gcloud-test-disk-zattach-" + uuid;
103104
REGIONAL_BLANK_DISK = "gcloud-test-disk-rattach-" + uuid;
105+
DISK_WITH_SNAPSHOT_SCHEDULE = "gcloud-test-disk-shapshot-" + uuid;
106+
SNAPSHOT_SCHEDULE = "gcloud-test-snapshot-schedule-" + uuid;
104107

105108
// Cleanup existing stale instances.
106109
Util.cleanUpExistingInstances("test-disks", PROJECT_ID, ZONE);
107110
Util.cleanUpExistingDisks("gcloud-test-", PROJECT_ID, ZONE);
108111
Util.cleanUpExistingSnapshots("gcloud-test-snapshot-", PROJECT_ID);
112+
Util.cleanUpExistingSnapshotSchedule("gcloud-test-snapshot-schedule-", PROJECT_ID, REGION);
109113

110114
// Create disk from image.
111115
Image debianImage = null;
@@ -137,10 +141,12 @@ public static void setup()
137141
TimeUnit.SECONDS.sleep(10);
138142
SetDiskAutodelete.setDiskAutodelete(PROJECT_ID, ZONE, INSTANCE_NAME, DISK_NAME, true);
139143
assertThat(stdOut.toString()).contains("Disk autodelete field updated.");
140-
144+
CreateSnapshotSchedule.createSnapshotSchedule(PROJECT_ID, REGION, SNAPSHOT_SCHEDULE,
145+
"description", 10, "US", "KEEP_AUTO_SNAPSHOTS");
141146
// Create zonal and regional blank disks for testing attach and resize.
142147
createZonalDisk();
143148
createRegionalDisk();
149+
144150
TimeUnit.SECONDS.sleep(30);
145151

146152
stdOut.close();
@@ -170,6 +176,8 @@ public static void cleanUp()
170176
DeleteDisk.deleteDisk(PROJECT_ID, ZONE, EMPTY_DISK_NAME);
171177
DeleteDisk.deleteDisk(PROJECT_ID, ZONE, ZONAL_BLANK_DISK);
172178
RegionalDelete.deleteRegionalDisk(PROJECT_ID, REGION, REGIONAL_BLANK_DISK);
179+
DeleteDisk.deleteDisk(PROJECT_ID, ZONE, DISK_WITH_SNAPSHOT_SCHEDULE);
180+
DeleteSnapshotSchedule.deleteSnapshotSchedule(PROJECT_ID, REGION, SNAPSHOT_SCHEDULE);
173181

174182
stdOut.close();
175183
System.setOut(out);
@@ -301,4 +309,13 @@ public void testDiskAttachResize()
301309
Util.getRegionalDisk(PROJECT_ID, REGION, REGIONAL_BLANK_DISK).getSizeGb());
302310
}
303311

312+
@Test
313+
void testCreateDiskWithSnapshotSchedule()
314+
throws IOException, ExecutionException, InterruptedException, TimeoutException {
315+
Operation.Status status = CreateDiskWithSnapshotSchedule.createDiskWithSnapshotSchedule(
316+
PROJECT_ID, ZONE, DISK_WITH_SNAPSHOT_SCHEDULE, SNAPSHOT_SCHEDULE);
317+
318+
Assert.assertNotNull(Util.getDisk(PROJECT_ID, ZONE, DISK_WITH_SNAPSHOT_SCHEDULE));
319+
assertThat(status).isEqualTo(Operation.Status.DONE);
320+
}
304321
}

0 commit comments

Comments
 (0)